/[svn]/qsampler/trunk/src/qsamplerMainForm.ui.h
ViewVC logotype

Diff of /qsampler/trunk/src/qsamplerMainForm.ui.h

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

revision 162 by capela, Tue Jun 29 22:17:59 2004 UTC revision 1034 by capela, Mon Jan 15 16:21:01 2007 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
33  #include <qtextstream.h>  #include <qtextstream.h>
34  #include <qstatusbar.h>  #include <qstatusbar.h>
35    #include <qslider.h>
36    #include <qspinbox.h>
37  #include <qlabel.h>  #include <qlabel.h>
38  #include <qtimer.h>  #include <qtimer.h>
39    #include <qtooltip.h>
40    
41  #include "qsamplerAbout.h"  #include "qsamplerAbout.h"
42  #include "qsamplerOptions.h"  #include "qsamplerOptions.h"
43    #include "qsamplerChannel.h"
44  #include "qsamplerMessages.h"  #include "qsamplerMessages.h"
45    
46  #include "qsamplerChannelStrip.h"  #include "qsamplerChannelStrip.h"
47    #include "qsamplerInstrumentList.h"
48    
49    #include "qsamplerInstrumentListForm.h"
50    #include "qsamplerDeviceForm.h"
51  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
52    
53  #include "config.h"  #ifdef HAVE_SIGNAL_H
54    #include <signal.h>
55    #endif
56    
57    #ifdef CONFIG_LIBGIG
58    #include <gig.h>
59    #endif
60    
61  // Timer constant stuff.  // Timer constant stuff.
62  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
# Line 93  private: Line 107  private:
107  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
108  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
109    
110    // Kind of singleton reference.
111    qsamplerMainForm *qsamplerMainForm::g_pMainForm = NULL;
112    
113    
114  // Kind of constructor.  // Kind of constructor.
115  void qsamplerMainForm::init (void)  void qsamplerMainForm::init (void)
116  {  {
117            // Pseudo-singleton reference setup.
118            g_pMainForm = this;
119    
120      // Initialize some pointer references.      // Initialize some pointer references.
121      m_pOptions = NULL;      m_pOptions = NULL;
122    
123      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
124      m_pMessages = NULL;      m_pMessages = NULL;
125        m_pInstrumentListForm = NULL;
126        m_pDeviceForm = NULL;
127    
128      // We'll start clean.      // We'll start clean.
129      m_iUntitled = 0;      m_iUntitled   = 0;
130      m_iDirtyCount = 0;      m_iDirtyCount = 0;
131    
132      m_pServer = NULL;      m_pServer = NULL;
# Line 114  void qsamplerMainForm::init (void) Line 137  void qsamplerMainForm::init (void)
137    
138      m_iTimerSlot = 0;      m_iTimerSlot = 0;
139    
140    #ifdef HAVE_SIGNAL_H
141            // Set to ignore any fatal "Broken pipe" signals.
142            ::signal(SIGPIPE, SIG_IGN);
143    #endif
144    
145    #ifdef CONFIG_VOLUME
146        // Make some extras into the toolbar...
147            channelsToolbar->addSeparator();
148            const QString& sVolumeText = tr("Master volume");
149            m_iVolumeChanging = 0;
150            // Volume slider...
151            m_pVolumeSlider = new QSlider(Qt::Horizontal, channelsToolbar);
152    //      m_pVolumeSlider->setTickmarks(QSlider::Below);
153    //      m_pVolumeSlider->setTickInterval(10);
154            m_pVolumeSlider->setPageStep(10);
155            m_pVolumeSlider->setRange(0, 100);
156            m_pVolumeSlider->setMaximumHeight(22);
157            m_pVolumeSlider->setMinimumWidth(160);
158            m_pVolumeSlider->setSizePolicy(
159                    QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
160            QToolTip::add(m_pVolumeSlider, sVolumeText);
161            QObject::connect(m_pVolumeSlider,
162                    SIGNAL(valueChanged(int)),
163                    SLOT(volumeChanged(int)));
164            // Volume spin-box
165            m_pVolumeSpinBox = new QSpinBox(channelsToolbar);
166            m_pVolumeSpinBox->setSuffix(" %");
167            m_pVolumeSpinBox->setRange(0, 100);
168            QToolTip::add(m_pVolumeSpinBox, sVolumeText);
169            QObject::connect(m_pVolumeSpinBox,
170                    SIGNAL(valueChanged(int)),
171                    SLOT(volumeChanged(int)));
172    #endif
173    
174      // Make it an MDI workspace.      // Make it an MDI workspace.
175      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
176      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
177      // Set the activation connection.          // Set the activation connection.
178      QObject::connect(m_pWorkspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(stabilizeForm()));          QObject::connect(m_pWorkspace,
179                    SIGNAL(windowActivated(QWidget *)),
180                    SLOT(stabilizeForm()));
181      // Make it shine :-)      // Make it shine :-)
182      setCentralWidget(m_pWorkspace);      setCentralWidget(m_pWorkspace);
183    
# Line 128  void qsamplerMainForm::init (void) Line 187  void qsamplerMainForm::init (void)
187      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
188      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
189      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
190      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
191      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
192      // Server address.      // Server address.
193      pLabel = new QLabel(this);      pLabel = new QLabel(this);
194      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
195      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
196      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
197      // Channel title.      // Channel title.
198      pLabel = new QLabel(this);      pLabel = new QLabel(this);
199      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
200      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
201      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
202      // Session modification status.      // Session modification status.
203      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
204      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
205      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
206      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
207      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
208    
209      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 163  void qsamplerMainForm::destroy (void) Line 222  void qsamplerMainForm::destroy (void)
222  {  {
223      // Do final processing anyway.      // Do final processing anyway.
224      processServerExit();      processServerExit();
225        
226      // Delete recentfiles menu.  #if defined(WIN32)
227      if (m_pRecentFilesMenu)      WSACleanup();
228          delete m_pRecentFilesMenu;  #endif
     // Delete status item labels one by one.  
     if (m_status[QSAMPLER_STATUS_CLIENT])  
         delete m_status[QSAMPLER_STATUS_CLIENT];  
     if (m_status[QSAMPLER_STATUS_SERVER])  
         delete m_status[QSAMPLER_STATUS_SERVER];  
     if (m_status[QSAMPLER_STATUS_CHANNEL])  
         delete m_status[QSAMPLER_STATUS_CHANNEL];  
     if (m_status[QSAMPLER_STATUS_SESSION])  
         delete m_status[QSAMPLER_STATUS_SESSION];  
229    
230      // Finally drop any widgets around...      // Finally drop any widgets around...
231        if (m_pDeviceForm)
232            delete m_pDeviceForm;
233        if (m_pInstrumentListForm)
234            delete m_pInstrumentListForm;
235      if (m_pMessages)      if (m_pMessages)
236          delete m_pMessages;          delete m_pMessages;
237      if (m_pWorkspace)      if (m_pWorkspace)
238          delete m_pWorkspace;          delete m_pWorkspace;
239    
240  #if defined(WIN32)      // Delete status item labels one by one.
241      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
242            delete m_statusItem[QSAMPLER_STATUS_CLIENT];
243        if (m_statusItem[QSAMPLER_STATUS_SERVER])
244            delete m_statusItem[QSAMPLER_STATUS_SERVER];
245        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
246            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
247        if (m_statusItem[QSAMPLER_STATUS_SESSION])
248            delete m_statusItem[QSAMPLER_STATUS_SESSION];
249    
250    #ifdef CONFIG_VOLUME
251            delete m_pVolumeSpinBox;
252            delete m_pVolumeSlider;
253  #endif  #endif
254    
255        // Delete recentfiles menu.
256        if (m_pRecentFilesMenu)
257            delete m_pRecentFilesMenu;
258    
259            // Pseudo-singleton reference shut-down.
260            g_pMainForm = NULL;
261  }  }
262    
263    
# Line 195  void qsamplerMainForm::setup ( qsamplerO Line 267  void qsamplerMainForm::setup ( qsamplerO
267      // We got options?      // We got options?
268      m_pOptions = pOptions;      m_pOptions = pOptions;
269    
270        // What style do we create these forms?
271            Qt::WFlags wflags = Qt::WStyle_Customize
272                    | Qt::WStyle_NormalBorder
273                    | Qt::WStyle_Title
274                    | Qt::WStyle_SysMenu
275                    | Qt::WStyle_MinMax
276                    | Qt::WType_TopLevel;
277        if (m_pOptions->bKeepOnTop)
278            wflags |= Qt::WStyle_Tool;
279      // Some child forms are to be created right now.      // Some child forms are to be created right now.
280      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
281        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
282    #ifdef CONFIG_MIDI_INSTRUMENT
283        m_pInstrumentListForm = new qsamplerInstrumentListForm(this, 0, wflags);
284            QObject::connect(m_pInstrumentListForm->InstrumentList,
285                    SIGNAL(instrumentsChanged()),
286                    SLOT(sessionDirty()));
287    #else
288            viewInstrumentsAction->setEnabled(false);
289    #endif
290      // Set message defaults...      // Set message defaults...
291      updateMessagesFont();      updateMessagesFont();
292      updateMessagesLimit();      updateMessagesLimit();
293      updateMessagesCapture();      updateMessagesCapture();
294      // Set the visibility signal.      // Set the visibility signal.
295      QObject::connect(m_pMessages, SIGNAL(visibilityChanged(bool)), this, SLOT(stabilizeForm()));          QObject::connect(m_pMessages,
296                    SIGNAL(visibilityChanged(bool)),
297                    SLOT(stabilizeForm()));
298    
299      // Initial decorations toggle state.      // Initial decorations toggle state.
300      viewMenubarAction->setOn(m_pOptions->bMenubar);      viewMenubarAction->setOn(m_pOptions->bMenubar);
# Line 225  void qsamplerMainForm::setup ( qsamplerO Line 317  void qsamplerMainForm::setup ( qsamplerO
317          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
318          istr >> *this;          istr >> *this;
319      }      }
320      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
321      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
322        m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
323        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
324    
325      // Final startup stabilization...      // Final startup stabilization...
326        updateMaxVolume();
327      updateRecentFilesMenu();      updateRecentFilesMenu();
328      stabilizeForm();      stabilizeForm();
329    
# Line 264  bool qsamplerMainForm::queryClose (void) Line 359  bool qsamplerMainForm::queryClose (void)
359              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
360              ostr << *this;              ostr << *this;
361              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
362              // And the main windows state.              // And the children, and the main windows state,.
363              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
364                            m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
365                            m_pOptions->saveWidgetGeometry(this);
366                            // Close popup widgets.
367                            if (m_pInstrumentListForm)
368                                    m_pInstrumentListForm->close();
369                            if (m_pDeviceForm)
370                                    m_pDeviceForm->close();
371              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
372              stopServer();              stopServer();
373          }          }
# Line 284  void qsamplerMainForm::closeEvent ( QClo Line 386  void qsamplerMainForm::closeEvent ( QClo
386  }  }
387    
388    
389  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
390  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
391  {  {
392      bool bAccept = false;      bool bDecode = false;
393    
394      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
395          QString sUrl;          QString sText;
396          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
397              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
398                files = QStringList::split('\n', sText);
399                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
400                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
401            }
402      }      }
403    
404      pDragEnterEvent->accept(bAccept);      return bDecode;
405    }
406    
407    
408    // Window drag-n-drop event handlers.
409    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
410    {
411            QStringList files;
412            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
413  }  }
414    
415    
416  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
417  {  {
418      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
419          QString sUrl;  
420          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
421              loadSessionFile(QUrl(sUrl).path());          return;
422      }  
423            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
424                    const QString& sPath = *iter;
425                    if (qsamplerChannel::isInstrumentFile(sPath)) {
426                            // Try to create a new channel from instrument file...
427                            qsamplerChannel *pChannel = new qsamplerChannel();
428                            if (pChannel == NULL)
429                                    return;
430                            // Start setting the instrument filename...
431                            pChannel->setInstrument(sPath, 0);
432                            // Before we show it up, may be we'll
433                            // better ask for some initial values?
434                            if (!pChannel->channelSetup(this)) {
435                                    delete pChannel;
436                                    return;
437                            }
438                            // Finally, give it to a new channel strip...
439                            if (!createChannelStrip(pChannel)) {
440                                    delete pChannel;
441                                    return;
442                            }
443                            // Make that an overall update.
444                            m_iDirtyCount++;
445                            stabilizeForm();
446                    }   // Otherwise, load an usual session file (LSCP script)...
447                    else if (closeSession(true)) {
448                            loadSessionFile(sPath);
449                            break;
450                    }
451                    // Make it look responsive...:)
452                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
453            }
454  }  }
455    
456    
# Line 315  void qsamplerMainForm::customEvent ( QCu Line 460  void qsamplerMainForm::customEvent ( QCu
460      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
461      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
462          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
463          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
464              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
465              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
466                            if (pChannelStrip)
467                                    channelStripChanged(pChannelStrip);
468                    } else {
469                            appendMessagesColor(tr("Notify event: %1 data: %2")
470                                    .arg(::lscp_event_to_text(pEvent->event()))
471                                    .arg(pEvent->data()), "#996699");
472                    }
473      }      }
474  }  }
475    
# Line 326  void qsamplerMainForm::customEvent ( QCu Line 478  void qsamplerMainForm::customEvent ( QCu
478  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
479  {  {
480      stabilizeForm();      stabilizeForm();
481        
482      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
483  }  }
484    
# Line 340  qsamplerOptions *qsamplerMainForm::optio Line 492  qsamplerOptions *qsamplerMainForm::optio
492      return m_pOptions;      return m_pOptions;
493  }  }
494    
495    
496  // The LSCP client descriptor property.  // The LSCP client descriptor property.
497  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
498  {  {
# Line 347  lscp_client_t *qsamplerMainForm::client Line 500  lscp_client_t *qsamplerMainForm::client
500  }  }
501    
502    
503    // The pseudo-singleton instance accessor.
504    qsamplerMainForm *qsamplerMainForm::getInstance (void)
505    {
506            return g_pMainForm;
507    }
508    
509    
510  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
511  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
512    
# Line 370  bool qsamplerMainForm::newSession (void) Line 530  bool qsamplerMainForm::newSession (void)
530      if (!closeSession(true))      if (!closeSession(true))
531          return false;          return false;
532    
533            // Give us what the server has, right now...
534            updateSession();
535    
536      // Ok increment untitled count.      // Ok increment untitled count.
537      m_iUntitled++;      m_iUntitled++;
538    
# Line 391  bool qsamplerMainForm::openSession (void Line 554  bool qsamplerMainForm::openSession (void
554    
555      // Ask for the filename to open...      // Ask for the filename to open...
556      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
557              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
558              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
559              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
560              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
561      );      );
562    
563      // Have we cancelled?      // Have we cancelled?
# Line 425  bool qsamplerMainForm::saveSession ( boo Line 588  bool qsamplerMainForm::saveSession ( boo
588              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
589          // Prompt the guy...          // Prompt the guy...
590          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
591                  sFilename,                              // Start here.                          sFilename,                              // Start here.
592                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
593                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
594                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
595          );          );
596          // Have we cancelled it?          // Have we cancelled it?
597          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 601  bool qsamplerMainForm::saveSession ( boo
601              sFilename += ".lscp";              sFilename += ".lscp";
602          // Check if already exists...          // Check if already exists...
603          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
604              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
605                                    QSAMPLER_TITLE ": " + tr("Warning"),
606                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
607                     "\"%1\"\n\n"                     "\"%1\"\n\n"
608                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 460  bool qsamplerMainForm::closeSession ( bo Line 624  bool qsamplerMainForm::closeSession ( bo
624    
625      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
626      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
627          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
628                            QSAMPLER_TITLE ": " + tr("Warning"),
629              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
630              "\"%1\"\n\n"              "\"%1\"\n\n"
631              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 483  bool qsamplerMainForm::closeSession ( bo Line 648  bool qsamplerMainForm::closeSession ( bo
648          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
649          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
650          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
651              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
652              if (bForce && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)              if (pChannelStrip) {
653                  appendMessagesClient("lscp_remove_channel");                  qsamplerChannel *pChannel = pChannelStrip->channel();
654              delete pChannel;                  if (bForce && pChannel)
655                        pChannel->removeChannel();
656                    delete pChannelStrip;
657                }
658          }          }
659          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
660          // We're now clean, for sure.          // We're now clean, for sure.
# Line 510  bool qsamplerMainForm::loadSessionFile ( Line 678  bool qsamplerMainForm::loadSessionFile (
678          return false;          return false;
679      }      }
680    
681            // Tell the world we'll take some time...
682            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
683    
684      // Read the file.      // Read the file.
685            int iLine = 0;
686      int iErrors = 0;      int iErrors = 0;
687      QTextStream ts(&file);      QTextStream ts(&file);
688      while (!ts.atEnd()) {      while (!ts.atEnd()) {
689          // Read the line.          // Read the line.
690          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
691                    iLine++;
692          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
693          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
694              appendMessagesColor(sCommand, "#996633");                          // Remember that, no matter what,
695              // Remember that, no matter what,                          // all LSCP commands are CR/LF terminated.
696              // all LSCP commands are CR/LF terminated.                          sCommand += "\r\n";
697              sCommand += "\r\n";                          if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
698              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {                                  appendMessagesColor(QString("%1(%2): %3")
699                  appendMessagesClient("lscp_client_query");                                          .arg(QFileInfo(sFilename).fileName()).arg(iLine)
700                  iErrors++;                                          .arg(sCommand.simplifyWhiteSpace()), "#996633");
701              }                                  appendMessagesClient("lscp_client_query");
702                                    iErrors++;
703                            }
704          }          }
705          // Try to make it snappy :)          // Try to make it snappy :)
706          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
# Line 534  bool qsamplerMainForm::loadSessionFile ( Line 709  bool qsamplerMainForm::loadSessionFile (
709      // Ok. we've read it.      // Ok. we've read it.
710      file.close();      file.close();
711    
712      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
713      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
714    
715      // Now we'll try to create the whole GUI session.          // We're fornerly done.
716      int iChannels = ::lscp_get_channels(m_pClient);          QApplication::restoreOverrideCursor();
717      if (iChannels < 0) {  
718          appendMessagesClient("lscp_get_channels");          // Have we any errors?
719          appendMessagesError(tr("Could not get current number of channels.\n\nSorry."));          if (iErrors > 0)
720      }                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
       
     // Try to (re)create each channel.  
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannelID = 0; iChannelID < iChannels; iChannelID++) {  
         createChannel(iChannelID, false);  
         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
721    
722      // Save as default session directory.      // Save as default session directory.
723      if (m_pOptions)      if (m_pOptions)
724          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
725      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
726      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
727      // Stabilize form...      // Stabilize form...
728      m_sFilename = sFilename;      m_sFilename = sFilename;
729      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
730      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
731    
732        // Make that an overall update.
733      stabilizeForm();      stabilizeForm();
734      return true;      return true;
735  }  }
# Line 570  bool qsamplerMainForm::loadSessionFile ( Line 738  bool qsamplerMainForm::loadSessionFile (
738  // Save current session to specific file path.  // Save current session to specific file path.
739  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
740  {  {
741            if (m_pClient == NULL)
742                    return false;
743    
744            // Check whether server is apparently OK...
745            if (::lscp_get_channels(m_pClient) < 0) {
746                    appendMessagesClient("lscp_get_channels");
747                    return false;
748            }
749    
750      // Open and write into real file.      // Open and write into real file.
751      QFile file(sFilename);      QFile file(sFilename);
752      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 577  bool qsamplerMainForm::saveSessionFile ( Line 754  bool qsamplerMainForm::saveSessionFile (
754          return false;          return false;
755      }      }
756    
757            // Tell the world we'll take some time...
758            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
759    
760      // Write the file.      // Write the file.
761      int iErrors = 0;      int  iErrors = 0;
762      QTextStream ts(&file);      QTextStream ts(&file);
763      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
764      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 589  bool qsamplerMainForm::saveSessionFile ( Line 769  bool qsamplerMainForm::saveSessionFile (
769      ts << "# " << tr("File")      ts << "# " << tr("File")
770         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
771      ts << "# " << tr("Date")      ts << "# " << tr("Date")
772         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
773         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
774      ts << "#"  << endl;      ts << "#"  << endl;
775      ts << endl;      ts << endl;
776    
777            // It is assumed that this new kind of device+session file
778            // will be loaded from a complete initialized server...
779            int *piDeviceIDs;
780            int  iDevice;
781            ts << "RESET" << endl;
782    
783            // Audio device mapping.
784            QMap<int, int> audioDeviceMap;
785            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
786            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
787                    ts << endl;
788                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
789                    // Audio device specification...
790                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
791                            << " " << tr("Device") << " " << iDevice << endl;
792                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
793                    qsamplerDeviceParamMap::ConstIterator deviceParam;
794                    for (deviceParam = device.params().begin();
795                                    deviceParam != device.params().end();
796                                            ++deviceParam) {
797                            const qsamplerDeviceParam& param = deviceParam.data();
798                            if (param.value.isEmpty()) ts << "# ";
799                            ts << " " << deviceParam.key() << "='" << param.value << "'";
800                    }
801                    ts << endl;
802                    // Audio channel parameters...
803                    int iPort = 0;
804                    for (qsamplerDevicePort *pPort = device.ports().first();
805                                    pPort;
806                                            pPort = device.ports().next(), ++iPort) {
807                            qsamplerDeviceParamMap::ConstIterator portParam;
808                            for (portParam = pPort->params().begin();
809                                            portParam != pPort->params().end();
810                                                    ++portParam) {
811                                    const qsamplerDeviceParam& param = portParam.data();
812                                    if (param.fix || param.value.isEmpty()) ts << "# ";
813                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
814                                            << " " << iPort << " " << portParam.key()
815                                            << "='" << param.value << "'" << endl;
816                            }
817                    }
818                    // Audio device index/id mapping.
819                    audioDeviceMap[device.deviceID()] = iDevice;
820                    // Try to keep it snappy :)
821                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
822            }
823    
824            // MIDI device mapping.
825            QMap<int, int> midiDeviceMap;
826            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
827            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
828                    ts << endl;
829                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
830                    // MIDI device specification...
831                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
832                            << " " << tr("Device") << " " << iDevice << endl;
833                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
834                    qsamplerDeviceParamMap::ConstIterator deviceParam;
835                    for (deviceParam = device.params().begin();
836                                    deviceParam != device.params().end();
837                                            ++deviceParam) {
838                            const qsamplerDeviceParam& param = deviceParam.data();
839                            if (param.value.isEmpty()) ts << "# ";
840                            ts << " " << deviceParam.key() << "='" << param.value << "'";
841                    }
842                    ts << endl;
843                    // MIDI port parameters...
844                    int iPort = 0;
845                    for (qsamplerDevicePort *pPort = device.ports().first();
846                                    pPort;
847                                            pPort = device.ports().next(), ++iPort) {
848                            qsamplerDeviceParamMap::ConstIterator portParam;
849                            for (portParam = pPort->params().begin();
850                                            portParam != pPort->params().end();
851                                                    ++portParam) {
852                                    const qsamplerDeviceParam& param = portParam.data();
853                                    if (param.fix || param.value.isEmpty()) ts << "# ";
854                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
855                                       << " " << iPort << " " << portParam.key()
856                                       << "='" << param.value << "'" << endl;
857                            }
858                    }
859                    // MIDI device index/id mapping.
860                    midiDeviceMap[device.deviceID()] = iDevice;
861                    // Try to keep it snappy :)
862                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
863            }
864            ts << endl;
865    
866    #ifdef CONFIG_MIDI_INSTRUMENT
867            // MIDI instrument mapping...
868            QMap<int, int> midiInstrumentMap;
869            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
870            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
871                    int iMidiMap = piMaps[iMap];
872                    const char *pszMapName
873                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
874                    ts << "# " << tr("MIDI instrument map") << " " << iMap;
875                    if (pszMapName)
876                            ts << " - " << pszMapName;
877                    ts << endl;
878                    ts << "ADD MIDI_INSTRUMENT_MAP";
879                    if (pszMapName)
880                            ts << " '" << pszMapName << "'";
881                    ts << endl;
882                    // MIDI instrument mapping...
883                    lscp_midi_instrument_t *pInstrs
884                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
885                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
886                            lscp_midi_instrument_info_t *pInstrInfo
887                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
888                            if (pInstrInfo) {
889                                    ts << "MAP MIDI_INSTRUMENT "
890                                            << iMap                        << " "
891                                            << pInstrs[iInstr].bank        << " "
892                                            << pInstrs[iInstr].prog        << " "
893                                            << pInstrInfo->engine_name     << " '"
894                                            << pInstrInfo->instrument_file << "' "
895                                            << pInstrInfo->instrument_nr   << " "
896                                            << pInstrInfo->volume          << " ";
897                                    switch (pInstrInfo->load_mode) {
898                                            case LSCP_LOAD_PERSISTENT:
899                                                    ts << "PERSISTENT";
900                                                    break;
901                                            case LSCP_LOAD_ON_DEMAND_HOLD:
902                                                    ts << "ON_DEMAND_HOLD";
903                                                    break;
904                                            case LSCP_LOAD_ON_DEMAND:
905                                            case LSCP_LOAD_DEFAULT:
906                                            default:
907                                                    ts << "ON_DEMAND";
908                                                    break;
909                                    }
910                                    if (pInstrInfo->name)
911                                            ts << " '" << pInstrInfo->name << "'";
912                                    ts << endl;
913                            }       // Check for errors...
914                            else if (::lscp_client_get_errno(m_pClient)) {
915                                    appendMessagesClient("lscp_get_midi_instrument_info");
916                                    iErrors++;
917                            }
918                            // Try to keep it snappy :)
919                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
920                    }
921                    ts << endl;
922                    // Check for errors...
923                    if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {
924                            appendMessagesClient("lscp_list_midi_instruments");
925                            iErrors++;
926                    }
927                    // MIDI strument index/id mapping.
928                    midiInstrumentMap[iMidiMap] = iMap;
929            }
930            // Check for errors...
931            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
932                    appendMessagesClient("lscp_list_midi_instrument_maps");
933                    iErrors++;
934            }
935    #endif  // CONFIG_MIDI_INSTRUMENT
936    
937            // Sampler channel mapping.
938      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
939      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
940          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip
941          int iChannelID = pChannel->channelID();                          = static_cast<qsamplerChannelStrip *> (wlist.at(iChannel));
942          ts << "# " << pChannel->caption() << endl;          if (pChannelStrip) {
943          ts << "ADD CHANNEL" << endl;              qsamplerChannel *pChannel = pChannelStrip->channel();
944          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;              if (pChannel) {
945          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                  ts << "# " << tr("Channel") << " " << iChannel << endl;
946          ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                  ts << "ADD CHANNEL" << endl;
947          ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " " << pChannel->midiChannel() << endl;                                  if (audioDeviceMap.isEmpty()) {
948          ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
949          ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                                  << " " << pChannel->audioDriver() << endl;
950          ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  } else {
951          ts << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
952                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
953                                    }
954                                    if (midiDeviceMap.isEmpty()) {
955                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
956                                                    << " " << pChannel->midiDriver() << endl;
957                                    } else {
958                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
959                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
960                                    }
961                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
962                                            << " " << pChannel->midiPort() << endl;
963                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
964                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
965                        ts << "ALL";
966                    else
967                        ts << pChannel->midiChannel();
968                    ts << endl;
969                    ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
970                                    if (pChannel->instrumentStatus() < 100) ts << "# ";
971                                    ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
972                                            << pChannel->instrumentNr() << " " << iChannel << endl;
973                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
974                                    for (audioRoute = pChannel->audioRouting().begin();
975                                                    audioRoute != pChannel->audioRouting().end();
976                                                            ++audioRoute) {
977                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
978                                                    << " " << audioRoute.key()
979                                                    << " " << audioRoute.data() << endl;
980                                    }
981                                    ts << "SET CHANNEL VOLUME " << iChannel
982                                            << " " << pChannel->volume() << endl;
983                                    if (pChannel->channelMute())
984                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
985                                    if (pChannel->channelSolo())
986                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
987    #ifdef CONFIG_MIDI_INSTRUMENT
988                                    if (pChannel->midiMap() >= 0) {
989                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
990                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
991                                    }
992    #endif
993    #ifdef CONFIG_FXSEND
994                                    int iChannelID = pChannel->channelID();
995                                    int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
996                                    for (int iFxSend = 0;
997                                                    piFxSends && piFxSends[iFxSend] >= 0;
998                                                            iFxSend++) {
999                                            lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1000                                                    m_pClient, iChannelID, piFxSends[iFxSend]);
1001                                            if (pFxSendInfo) {
1002                                                    ts << "CREATE FX_SEND " << iChannel
1003                                                            << " " << pFxSendInfo->midi_controller;
1004                                                    if (pFxSendInfo->name)
1005                                                            ts << " '" << pFxSendInfo->name << "'";
1006                                                    ts << endl;
1007                                                    int *piRouting = pFxSendInfo->audio_routing;
1008                                                    for (int iAudioSrc = 0;
1009                                                                    piRouting && piRouting[iAudioSrc] >= 0;
1010                                                                            iAudioSrc++) {
1011                                                            ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1012                                                                    << iChannel
1013                                                                    << " " << iFxSend
1014                                                                    << " " << iAudioSrc
1015                                                                    << " " << piRouting[iAudioSrc] << endl;
1016                                                    }
1017    #ifdef CONFIG_FXSEND_LEVEL
1018                                                    ts << "SET FX_SEND LEVEL " << iChannel
1019                                                            << " " << iFxSend
1020                                                            << " " << pFxSendInfo->level << endl;                                                  
1021    #endif
1022                                            }       // Check for errors...
1023                                            else if (::lscp_client_get_errno(m_pClient)) {
1024                                                    appendMessagesClient("lscp_get_fxsend_info");
1025                                                    iErrors++;
1026                                            }
1027                                    }
1028    #endif
1029                    ts << endl;
1030                }
1031            }
1032          // Try to keep it snappy :)          // Try to keep it snappy :)
1033          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1034      }      }
1035    
1036    #ifdef CONFIG_VOLUME
1037            ts << "# " << tr("Global volume level") << endl;
1038            ts << "SET VOLUME " << ::lscp_get_volume(m_pClient) << endl;
1039            ts << endl;
1040    #endif
1041    
1042      // Ok. we've wrote it.      // Ok. we've wrote it.
1043      file.close();      file.close();
1044    
1045            // We're fornerly done.
1046            QApplication::restoreOverrideCursor();
1047    
1048      // Have we any errors?      // Have we any errors?
1049      if (iErrors > 0)      if (iErrors > 0)
1050          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));
# Line 632  bool qsamplerMainForm::saveSessionFile ( Line 1063  bool qsamplerMainForm::saveSessionFile (
1063  }  }
1064    
1065    
1066    // Session change receiver slot.
1067    void qsamplerMainForm::sessionDirty (void)
1068    {
1069        // Just mark the dirty form.
1070        m_iDirtyCount++;
1071        // and update the form status...
1072        stabilizeForm();
1073    }
1074    
1075    
1076  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1077  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
1078    
# Line 678  void qsamplerMainForm::fileSaveAs (void) Line 1119  void qsamplerMainForm::fileSaveAs (void)
1119  }  }
1120    
1121    
1122    // Reset the sampler instance.
1123    void qsamplerMainForm::fileReset (void)
1124    {
1125        if (m_pClient == NULL)
1126            return;
1127    
1128        // Ask user whether he/she want's an internal sampler reset...
1129        if (QMessageBox::warning(this,
1130                    QSAMPLER_TITLE ": " + tr("Warning"),
1131            tr("Resetting the sampler instance will close\n"
1132               "all device and channel configurations.\n\n"
1133               "Please note that this operation may cause\n"
1134               "temporary MIDI and Audio disruption.\n\n"
1135               "Do you want to reset the sampler engine now?"),
1136            tr("Reset"), tr("Cancel")) > 0)
1137            return;
1138    
1139            // Trye closing the current session, first...
1140            if (!closeSession(true))
1141                    return;
1142    
1143        // Just do the reset, after closing down current session...
1144            // Do the actual sampler reset...
1145            if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1146                    appendMessagesClient("lscp_reset_sampler");
1147                    appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
1148                    return;
1149            }
1150    
1151        // Log this.
1152        appendMessages(tr("Sampler reset."));
1153    
1154            // Make it a new session...
1155            newSession();
1156    }
1157    
1158    
1159  // Restart the client/server instance.  // Restart the client/server instance.
1160  void qsamplerMainForm::fileRestart (void)  void qsamplerMainForm::fileRestart (void)
1161  {  {
1162      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1163          return;          return;
1164            
1165      bool bRestart = true;      bool bRestart = true;
1166        
1167      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1168      // (if we're currently up and running)      // (if we're currently up and running)
1169      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1170          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1171                            QSAMPLER_TITLE ": " + tr("Warning"),
1172              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1173                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1174                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1175                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1176                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1177              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1178      }      }
# Line 725  void qsamplerMainForm::editAddChannel (v Line 1204  void qsamplerMainForm::editAddChannel (v
1204      if (m_pClient == NULL)      if (m_pClient == NULL)
1205          return;          return;
1206    
1207      // Create the new sampler channel.      // Just create the channel instance...
1208      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel();
1209      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
1210          return;          return;
     }  
1211    
1212      // Log this happening.      // Before we show it up, may be we'll
1213      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
1214        if (!pChannel->channelSetup(this)) {
1215            delete pChannel;
1216            return;
1217        }
1218    
1219      // Just create the channel strip with given id.      // And give it to the strip (will own the channel instance, if successful).
1220      createChannel(iChannelID, true);      if (!createChannelStrip(pChannel)) {
1221            delete pChannel;
1222            return;
1223        }
1224    
1225      // We'll be dirty, for sure...      // Make that an overall update.
1226      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
1227      stabilizeForm();      stabilizeForm();
1228  }  }
1229    
# Line 752  void qsamplerMainForm::editRemoveChannel Line 1234  void qsamplerMainForm::editRemoveChannel
1234      if (m_pClient == NULL)      if (m_pClient == NULL)
1235          return;          return;
1236    
1237      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1238        if (pChannelStrip == NULL)
1239            return;
1240    
1241        qsamplerChannel *pChannel = pChannelStrip->channel();
1242      if (pChannel == NULL)      if (pChannel == NULL)
1243          return;          return;
1244    
1245      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1246      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1247          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1248                            QSAMPLER_TITLE ": " + tr("Warning"),
1249              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1250                 "%1\n\n"                 "%1\n\n"
1251                 "Are you sure?")                 "Are you sure?")
1252                 .arg(pChannel->caption()),                 .arg(pChannelStrip->caption()),
1253              tr("OK"), tr("Cancel")) > 0)              tr("OK"), tr("Cancel")) > 0)
1254              return;              return;
1255      }      }
1256    
1257      // Remove the existing sampler channel.      // Remove the existing sampler channel.
1258      if (::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      if (!pChannel->removeChannel())
         appendMessagesClient("lscp_remove_channel");  
         appendMessagesError(tr("Could not remove channel.\n\nSorry."));  
1259          return;          return;
     }  
1260    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
1261      // Just delete the channel strip.      // Just delete the channel strip.
1262      delete pChannel;      delete pChannelStrip;
1263    
1264      // Do we auto-arrange?      // Do we auto-arrange?
1265      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1266          channelsArrange();          channelsArrange();
# Line 795  void qsamplerMainForm::editSetupChannel Line 1277  void qsamplerMainForm::editSetupChannel
1277      if (m_pClient == NULL)      if (m_pClient == NULL)
1278          return;          return;
1279    
1280      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1281      if (pChannel == NULL)      if (pChannelStrip == NULL)
1282          return;          return;
1283    
1284      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
1285      pChannel->channelSetup();      pChannelStrip->channelSetup();
1286  }  }
1287    
1288    
# Line 810  void qsamplerMainForm::editResetChannel Line 1292  void qsamplerMainForm::editResetChannel
1292      if (m_pClient == NULL)      if (m_pClient == NULL)
1293          return;          return;
1294    
1295      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1296      if (pChannel == NULL)      if (pChannelStrip == NULL)
1297          return;          return;
1298    
1299      // Remove the existing sampler channel.      // Just invoque the channel strip procedure.
1300      if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      pChannelStrip->channelReset();
1301          appendMessagesClient("lscp_reset_channel");  }
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
1302    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
1303    
1304      // Refresh channel strip info.  // Reset all sampler channels.
1305      pChannel->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
1306    {
1307            if (m_pClient == NULL)
1308                    return;
1309    
1310            // Invoque the channel strip procedure,
1311            // for all channels out there...
1312            m_pWorkspace->setUpdatesEnabled(false);
1313            QWidgetList wlist = m_pWorkspace->windowList();
1314            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1315                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1316                    if (pChannelStrip)
1317                            pChannelStrip->channelReset();
1318            }
1319            m_pWorkspace->setUpdatesEnabled(true);
1320  }  }
1321    
1322    
# Line 877  void qsamplerMainForm::viewMessages ( bo Line 1368  void qsamplerMainForm::viewMessages ( bo
1368  }  }
1369    
1370    
1371    // Show/hide the MIDI instrument list-view form.
1372    void qsamplerMainForm::viewInstruments (void)
1373    {
1374            if (m_pOptions == NULL)
1375                    return;
1376    
1377            if (m_pInstrumentListForm) {
1378                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1379                    if (m_pInstrumentListForm->isVisible()) {
1380                            m_pInstrumentListForm->hide();
1381                    } else {
1382                            m_pInstrumentListForm->show();
1383                            m_pInstrumentListForm->raise();
1384                            m_pInstrumentListForm->setActiveWindow();
1385                    }
1386            }
1387    }
1388    
1389    
1390    // Show/hide the device configurator form.
1391    void qsamplerMainForm::viewDevices (void)
1392    {
1393            if (m_pOptions == NULL)
1394                    return;
1395    
1396            if (m_pDeviceForm) {
1397                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1398                    if (m_pDeviceForm->isVisible()) {
1399                            m_pDeviceForm->hide();
1400                    } else {
1401                            m_pDeviceForm->show();
1402                            m_pDeviceForm->raise();
1403                            m_pDeviceForm->setActiveWindow();
1404                    }
1405            }
1406    }
1407    
1408    
1409  // Show options dialog.  // Show options dialog.
1410  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1411  {  {
# Line 886  void qsamplerMainForm::viewOptions (void Line 1415  void qsamplerMainForm::viewOptions (void
1415      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);
1416      if (pOptionsForm) {      if (pOptionsForm) {
1417          // Check out some initial nullities(tm)...          // Check out some initial nullities(tm)...
1418          qsamplerChannelStrip *pChannel = activeChannel();          qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1419          if (m_pOptions->sDisplayFont.isEmpty() && pChannel)          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1420              m_pOptions->sDisplayFont = pChannel->displayFont().toString();              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1421          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1422              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1423          // To track down deferred or immediate changes.          // To track down deferred or immediate changes.
# Line 898  void qsamplerMainForm::viewOptions (void Line 1427  void qsamplerMainForm::viewOptions (void
1427          bool    bOldServerStart     = m_pOptions->bServerStart;          bool    bOldServerStart     = m_pOptions->bServerStart;
1428          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1429          QString sOldDisplayFont     = m_pOptions->sDisplayFont;          QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1430            bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1431          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1432          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1433            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1434          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1435          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1436          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1437          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1438            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1439          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1440          // Load the current setup settings.          // Load the current setup settings.
1441          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 911  void qsamplerMainForm::viewOptions (void Line 1443  void qsamplerMainForm::viewOptions (void
1443          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1444              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1445              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1446                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1447                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1448                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1449                    QMessageBox::information(this,
1450                                            QSAMPLER_TITLE ": " + tr("Information"),
1451                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1452                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1453                  updateMessagesCapture();                  updateMessagesCapture();
# Line 922  void qsamplerMainForm::viewOptions (void Line 1457  void qsamplerMainForm::viewOptions (void
1457                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1458                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1459                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1460                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1461                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1462                    updateInstrumentNames();
1463                if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1464                    (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1465                    updateDisplayEffect();
1466              if (sOldDisplayFont != m_pOptions->sDisplayFont)              if (sOldDisplayFont != m_pOptions->sDisplayFont)
1467                  updateDisplayFont();                  updateDisplayFont();
1468              if (iOldMaxVolume != m_pOptions->iMaxVolume)              if (iOldMaxVolume != m_pOptions->iMaxVolume)
# Line 964  void qsamplerMainForm::channelsArrange ( Line 1505  void qsamplerMainForm::channelsArrange (
1505      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1506      int y = 0;      int y = 0;
1507      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1508          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1509      /*  if (pChannel->testWState(WState_Maximized | WState_Minimized)) {      /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1510              // Prevent flicker...              // Prevent flicker...
1511              pChannel->hide();              pChannelStrip->hide();
1512              pChannel->showNormal();              pChannelStrip->showNormal();
1513          }   */          }   */
1514          pChannel->adjustSize();          pChannelStrip->adjustSize();
1515          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1516          if (iWidth < pChannel->width())          if (iWidth < pChannelStrip->width())
1517              iWidth = pChannel->width();              iWidth = pChannelStrip->width();
1518      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1519          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1520          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1521          y += iHeight;          y += iHeight;
1522      }      }
1523      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1524        
1525      stabilizeForm();      stabilizeForm();
1526  }  }
1527    
# Line 1024  void qsamplerMainForm::helpAbout (void) Line 1565  void qsamplerMainForm::helpAbout (void)
1565      sText += tr("Debugging option enabled.");      sText += tr("Debugging option enabled.");
1566      sText += "</font></small><br />";      sText += "</font></small><br />";
1567  #endif  #endif
1568    #ifndef CONFIG_LIBGIG
1569        sText += "<small><font color=\"red\">";
1570        sText += tr("GIG (libgig) file support disabled.");
1571        sText += "</font></small><br />";
1572    #endif
1573    #ifndef CONFIG_INSTRUMENT_NAME
1574        sText += "<small><font color=\"red\">";
1575        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1576        sText += "</font></small><br />";
1577    #endif
1578    #ifndef CONFIG_MUTE_SOLO
1579        sText += "<small><font color=\"red\">";
1580        sText += tr("Sampler channel Mute/Solo support disabled.");
1581        sText += "</font></small><br />";
1582    #endif
1583    #ifndef CONFIG_AUDIO_ROUTING
1584        sText += "<small><font color=\"red\">";
1585        sText += tr("LSCP (liblscp) audio_routing support disabled.");
1586        sText += "</font></small><br />";
1587    #endif
1588    #ifndef CONFIG_FXSEND
1589        sText += "<small><font color=\"red\">";
1590        sText += tr("Sampler channel Effect Sends support disabled.");
1591        sText += "</font></small><br />";
1592    #endif
1593    #ifndef CONFIG_VOLUME
1594        sText += "<small><font color=\"red\">";
1595        sText += tr("Global volume support disabled.");
1596        sText += "</font></small><br />";
1597    #endif
1598    #ifndef CONFIG_MIDI_INSTRUMENT
1599        sText += "<small><font color=\"red\">";
1600        sText += tr("MIDI instrument mapping support disabled.");
1601        sText += "</font></small><br />";
1602    #endif
1603      sText += "<br />\n";      sText += "<br />\n";
1604      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1605      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1606      sText += " ";      sText += " ";
1607      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1608    #ifdef CONFIG_LIBGIG
1609        sText += ", ";
1610        sText += gig::libraryName().c_str();
1611        sText += " ";
1612        sText += gig::libraryVersion().c_str();
1613    #endif
1614      sText += "<br />\n";      sText += "<br />\n";
1615      sText += "<br />\n";      sText += "<br />\n";
1616      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";
# Line 1051  void qsamplerMainForm::helpAbout (void) Line 1633  void qsamplerMainForm::helpAbout (void)
1633  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1634  {  {
1635      // Update the main application caption...      // Update the main application caption...
1636      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1637      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1638          sSessioName += '*';          sSessionName += " *";
1639      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1640    
1641      // Update the main menu state...      // Update the main menu state...
1642      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1643      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1644      bool bHasChannel = (bHasClient && pChannel != NULL);      bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1645      fileNewAction->setEnabled(bHasClient);      fileNewAction->setEnabled(bHasClient);
1646      fileOpenAction->setEnabled(bHasClient);      fileOpenAction->setEnabled(bHasClient);
1647      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1648      fileSaveAsAction->setEnabled(bHasClient);      fileSaveAsAction->setEnabled(bHasClient);
1649        fileResetAction->setEnabled(bHasClient);
1650      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1651      editAddChannelAction->setEnabled(bHasClient);      editAddChannelAction->setEnabled(bHasClient);
1652      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1653      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1654      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1655      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1656      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1657    #ifdef CONFIG_MIDI_INSTRUMENT
1658            viewInstrumentsAction->setOn(m_pInstrumentListForm
1659                    && m_pInstrumentListForm->isVisible());
1660            viewInstrumentsAction->setEnabled(bHasClient);
1661    #endif
1662            viewDevicesAction->setOn(m_pDeviceForm
1663                    && m_pDeviceForm->isVisible());
1664        viewDevicesAction->setEnabled(bHasClient);
1665        channelsArrangeAction->setEnabled(bHasChannel);
1666    
1667    #ifdef CONFIG_VOLUME
1668            // Toolbar widgets are also affected...
1669        m_pVolumeSlider->setEnabled(bHasClient);
1670        m_pVolumeSpinBox->setEnabled(bHasClient);
1671    #endif
1672    
1673      // Client/Server status...      // Client/Server status...
1674      if (bHasClient) {      if (bHasClient) {
1675          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1676          m_status[QSAMPLER_STATUS_SERVER]->setText(m_pOptions->sServerHost + ":" + QString::number(m_pOptions->iServerPort));          m_statusItem[QSAMPLER_STATUS_SERVER]->setText(m_pOptions->sServerHost + ":" + QString::number(m_pOptions->iServerPort));
1677      } else {      } else {
1678          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1679          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1680      }      }
1681      // Channel status...      // Channel status...
1682      if (bHasChannel)      if (bHasChannel)
1683          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannel->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1684      else      else
1685          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1686      // Session status...      // Session status...
1687      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1688          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1689      else      else
1690          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1691    
1692      // Recent files menu.      // Recent files menu.
1693      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1100  void qsamplerMainForm::stabilizeForm (vo Line 1698  void qsamplerMainForm::stabilizeForm (vo
1698  }  }
1699    
1700    
1701    // Global volume change receiver slot.
1702    void qsamplerMainForm::volumeChanged ( int iVolume )
1703    {
1704    #ifdef CONFIG_VOLUME
1705    
1706            if (m_iVolumeChanging > 0)
1707                    return;
1708            
1709            m_iVolumeChanging++;
1710    
1711            // Update the toolbar widgets...
1712            if (m_pVolumeSlider->value() != iVolume)
1713                    m_pVolumeSlider->setValue(iVolume);
1714            if (m_pVolumeSpinBox->value() != iVolume)
1715                    m_pVolumeSpinBox->setValue(iVolume);
1716    
1717            // Do it as commanded...
1718            float fVolume = 0.01f * float(iVolume);
1719            if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
1720                    appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
1721            else
1722                    appendMessagesClient("lscp_set_channel_volume");
1723    
1724            m_iVolumeChanging--;
1725    
1726            m_iDirtyCount++;
1727            stabilizeForm();
1728    
1729    #endif
1730    }
1731    
1732    
1733  // Channel change receiver slot.  // Channel change receiver slot.
1734  void qsamplerMainForm::channelChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1735  {  {
1736            // Add this strip to the changed list...
1737            if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1738                    m_changedStrips.append(pChannelStrip);
1739                    pChannelStrip->resetErrorCount();
1740            }
1741    
1742      // Just mark the dirty form.      // Just mark the dirty form.
1743      m_iDirtyCount++;      m_iDirtyCount++;
1744      // and update the form status...      // and update the form status...
# Line 1110  void qsamplerMainForm::channelChanged( q Line 1746  void qsamplerMainForm::channelChanged( q
1746  }  }
1747    
1748    
1749    // Grab and restore current sampler channels session.
1750    void qsamplerMainForm::updateSession (void)
1751    {
1752    #ifdef CONFIG_VOLUME
1753            int iVolume = 100.0f * ::lscp_get_volume(m_pClient);
1754            m_iVolumeChanging++;
1755            m_pVolumeSlider->setValue(iVolume);
1756            m_pVolumeSpinBox->setValue(iVolume);
1757            m_iVolumeChanging--;
1758    #endif
1759    #ifdef CONFIG_MIDI_INSTRUMENT
1760            // FIXME: Make some room for default instrument maps...
1761            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1762            if (iMaps < 0)
1763                    appendMessagesClient("lscp_get_midi_instrument_maps");
1764            else if (iMaps < 1) {
1765                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1766                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1767            }
1768    #endif
1769    
1770            // Retrieve the current channel list.
1771            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1772            if (piChannelIDs == NULL) {
1773                    if (::lscp_client_get_errno(m_pClient)) {
1774                            appendMessagesClient("lscp_list_channels");
1775                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1776                    }
1777            } else {
1778                    // Try to (re)create each channel.
1779                    m_pWorkspace->setUpdatesEnabled(false);
1780                    for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1781                            // Check if theres already a channel strip for this one...
1782                            if (!channelStrip(piChannelIDs[iChannel]))
1783                                    createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1784                    }
1785                    m_pWorkspace->setUpdatesEnabled(true);
1786            }
1787    
1788        // Do we auto-arrange?
1789        if (m_pOptions && m_pOptions->bAutoArrange)
1790            channelsArrange();
1791    
1792            // Remember to refresh devices and instruments...
1793            if (m_pInstrumentListForm)
1794                m_pInstrumentListForm->refreshInstruments();
1795            if (m_pDeviceForm)
1796                m_pDeviceForm->refreshDevices();
1797    }
1798    
1799    
1800  // Update the recent files list and menu.  // Update the recent files list and menu.
1801  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1802  {  {
# Line 1154  void qsamplerMainForm::updateRecentFiles Line 1841  void qsamplerMainForm::updateRecentFiles
1841  }  }
1842    
1843    
1844    // Force update of the channels instrument names mode.
1845    void qsamplerMainForm::updateInstrumentNames (void)
1846    {
1847        // Full channel list update...
1848        QWidgetList wlist = m_pWorkspace->windowList();
1849        if (wlist.isEmpty())
1850            return;
1851    
1852        m_pWorkspace->setUpdatesEnabled(false);
1853        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1854            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1855            if (pChannelStrip)
1856                pChannelStrip->updateInstrumentName(true);
1857        }
1858        m_pWorkspace->setUpdatesEnabled(true);
1859    }
1860    
1861    
1862  // Force update of the channels display font.  // Force update of the channels display font.
1863  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1864  {  {
# Line 1175  void qsamplerMainForm::updateDisplayFont Line 1880  void qsamplerMainForm::updateDisplayFont
1880    
1881      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1882      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1883          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1884          pChannel->setDisplayFont(font);          if (pChannelStrip)
1885                pChannelStrip->setDisplayFont(font);
1886        }
1887        m_pWorkspace->setUpdatesEnabled(true);
1888    }
1889    
1890    
1891    // Update channel strips background effect.
1892    void qsamplerMainForm::updateDisplayEffect (void)
1893    {
1894       QPixmap pm;
1895        if (m_pOptions->bDisplayEffect)
1896            pm = QPixmap::fromMimeSource("displaybg1.png");
1897    
1898        // Full channel list update...
1899        QWidgetList wlist = m_pWorkspace->windowList();
1900        if (wlist.isEmpty())
1901            return;
1902    
1903        m_pWorkspace->setUpdatesEnabled(false);
1904        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1905            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1906            if (pChannelStrip)
1907                pChannelStrip->setDisplayBackground(pm);
1908      }      }
1909      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1910  }  }
# Line 1188  void qsamplerMainForm::updateMaxVolume ( Line 1916  void qsamplerMainForm::updateMaxVolume (
1916      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1917          return;          return;
1918    
1919    #ifdef CONFIG_VOLUME
1920            m_iVolumeChanging++;
1921            m_pVolumeSlider->setMaxValue(m_pOptions->iMaxVolume);
1922            m_pVolumeSpinBox->setMaxValue(m_pOptions->iMaxVolume);
1923            m_iVolumeChanging--;
1924    #endif
1925    
1926      // Full channel list update...      // Full channel list update...
1927      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1928      if (wlist.isEmpty())      if (wlist.isEmpty())
# Line 1195  void qsamplerMainForm::updateMaxVolume ( Line 1930  void qsamplerMainForm::updateMaxVolume (
1930    
1931      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1932      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1933          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1934          pChannel->setMaxVolume(m_pOptions->iMaxVolume);          if (pChannelStrip)
1935                pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1936      }      }
1937      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1938  }  }
# Line 1235  void qsamplerMainForm::appendMessagesErr Line 1971  void qsamplerMainForm::appendMessagesErr
1971    
1972      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1973    
1974      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));          // Make it look responsive...:)
1975            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1976    
1977        QMessageBox::critical(this,
1978                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1979  }  }
1980    
1981    
# Line 1248  void qsamplerMainForm::appendMessagesCli Line 1988  void qsamplerMainForm::appendMessagesCli
1988      appendMessagesColor(s + QString(": %1 (errno=%2)")      appendMessagesColor(s + QString(": %1 (errno=%2)")
1989          .arg(::lscp_client_get_result(m_pClient))          .arg(::lscp_client_get_result(m_pClient))
1990          .arg(::lscp_client_get_errno(m_pClient)), "#996666");          .arg(::lscp_client_get_errno(m_pClient)), "#996666");
1991    
1992            // Make it look responsive...:)
1993            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1994  }  }
1995    
1996    
# Line 1275  void qsamplerMainForm::updateMessagesLim Line 2018  void qsamplerMainForm::updateMessagesLim
2018          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
2019              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
2020          else          else
2021              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
2022      }      }
2023  }  }
2024    
# Line 1295  void qsamplerMainForm::updateMessagesCap Line 2038  void qsamplerMainForm::updateMessagesCap
2038  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2039    
2040  // The channel strip creation executive.  // The channel strip creation executive.
2041  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
2042  {  {
2043      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
2044          return;          return NULL;
2045    
2046      // Prepare for auto-arrange?      // Prepare for auto-arrange?
2047      qsamplerChannelStrip *pChannel = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
2048      int y = 0;      int y = 0;
2049      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
2050          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2051          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2052              pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2053          //  y += pChannel->height() + pChannel->parentWidget()->baseSize().height();                          if (pChannelStrip) {
2054              y += pChannel->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
2055                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
2056                            }
2057          }          }
2058      }      }
2059    
2060      // Add a new channel itema...      // Add a new channel itema...
2061      WFlags wflags = Qt::WStyle_Customize | Qt::WStyle_Tool | Qt::WStyle_Title | Qt::WStyle_NoBorder;      WFlags wflags = Qt::WStyle_Customize | Qt::WStyle_Tool | Qt::WStyle_Title | Qt::WStyle_NoBorder;
2062      pChannel = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
2063      pChannel->setMaxVolume(m_pOptions->iMaxVolume);      if (pChannelStrip == NULL)
2064      pChannel->setup(this, iChannelID);          return NULL;
2065      // We'll need a display font.  
2066      QFont font;      // Actual channel strip setup...
2067      if (m_pOptions && font.fromString(m_pOptions->sDisplayFont))      pChannelStrip->setup(pChannel);
2068          pChannel->setDisplayFont(font);          QObject::connect(pChannelStrip,
2069      // Track channel setup changes.                  SIGNAL(channelChanged(qsamplerChannelStrip *)),
2070      QObject::connect(pChannel, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelChanged(qsamplerChannelStrip *)));                  SLOT(channelStripChanged(qsamplerChannelStrip *)));
2071      // Before we show it up, may be we'll      // Set some initial aesthetic options...
2072      // better ask for some initial values?      if (m_pOptions) {
2073      if (bPrompt)          // Background display effect...
2074          pChannel->channelSetup();                pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
2075            // We'll need a display font.
2076            QFont font;
2077            if (font.fromString(m_pOptions->sDisplayFont))
2078                pChannelStrip->setDisplayFont(font);
2079            // Maximum allowed volume setting.
2080            pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
2081        }
2082    
2083      // Now we show up us to the world.      // Now we show up us to the world.
2084      pChannel->show();      pChannelStrip->show();
2085      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
2086      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
2087          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
2088      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();
2089          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
2090          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
2091      }      }
2092    
2093            // This is pretty new, so we'll watch for it closely.
2094            channelStripChanged(pChannelStrip);
2095    
2096        // Return our successful reference...
2097        return pChannelStrip;
2098  }  }
2099    
2100    
2101  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2102  qsamplerChannelStrip *qsamplerMainForm::activeChannel (void)  qsamplerChannelStrip *qsamplerMainForm::activeChannelStrip (void)
2103  {  {
2104      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();
2105  }  }
2106    
2107    
2108  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2109  qsamplerChannelStrip *qsamplerMainForm::channelAt ( int iChannel )  qsamplerChannelStrip *qsamplerMainForm::channelStripAt ( int iChannel )
2110  {  {
2111      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
2112      if (wlist.isEmpty())      if (wlist.isEmpty())
2113          return 0;          return NULL;
2114    
2115      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
2116  }  }
2117    
2118    
2119    // Retrieve a channel strip by sampler channel id.
2120    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
2121    {
2122            QWidgetList wlist = m_pWorkspace->windowList();
2123            if (wlist.isEmpty())
2124                    return NULL;
2125    
2126            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2127                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2128                    if (pChannelStrip) {
2129                            qsamplerChannel *pChannel = pChannelStrip->channel();
2130                            if (pChannel && pChannel->channelID() == iChannelID)
2131                                    return pChannelStrip;
2132                    }
2133            }
2134    
2135            // Not found.
2136            return NULL;
2137    }
2138    
2139    
2140  // Construct the windows menu.  // Construct the windows menu.
2141  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
2142  {  {
# Line 1368  void qsamplerMainForm::channelsMenuAbout Line 2148  void qsamplerMainForm::channelsMenuAbout
2148      if (!wlist.isEmpty()) {      if (!wlist.isEmpty()) {
2149          channelsMenu->insertSeparator();          channelsMenu->insertSeparator();
2150          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2151              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2152              int iItemID = channelsMenu->insertItem(pChannel->caption(), this, SLOT(channelsMenuActivated(int)));              if (pChannelStrip) {
2153              channelsMenu->setItemParameter(iItemID, iChannel);                  int iItemID = channelsMenu->insertItem(pChannelStrip->caption(), this, SLOT(channelsMenuActivated(int)));
2154              channelsMenu->setItemChecked(iItemID, activeChannel() == pChannel);                  channelsMenu->setItemParameter(iItemID, iChannel);
2155                    channelsMenu->setItemChecked(iItemID, activeChannelStrip() == pChannelStrip);
2156                }
2157          }          }
2158      }      }
2159  }  }
# Line 1380  void qsamplerMainForm::channelsMenuAbout Line 2162  void qsamplerMainForm::channelsMenuAbout
2162  // Windows menu activation slot  // Windows menu activation slot
2163  void qsamplerMainForm::channelsMenuActivated ( int iChannel )  void qsamplerMainForm::channelsMenuActivated ( int iChannel )
2164  {  {
2165      qsamplerChannelStrip *pChannel = channelAt(iChannel);      qsamplerChannelStrip *pChannelStrip = channelStripAt(iChannel);
2166      if (pChannel)      if (pChannelStrip)
2167          pChannel->showNormal();          pChannelStrip->showNormal();
2168      pChannel->setFocus();      pChannelStrip->setFocus();
2169  }  }
2170    
2171    
# Line 1421  void qsamplerMainForm::timerSlot (void) Line 2203  void qsamplerMainForm::timerSlot (void)
2203              }              }
2204          }          }
2205      }      }
2206        
2207          // Refresh each channel usage, on each period...          if (m_pClient) {
2208      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {                  // Update the channel information for each pending strip...
2209          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2210          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2211              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2212              QWidgetList wlist = m_pWorkspace->windowList();                                  // If successfull, remove from pending list...
2213              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                  if (pChannelStrip->updateChannelInfo())
2214                  qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);                                          m_changedStrips.remove(pChannelStrip);
2215                  if (pChannel->isVisible())                          }
2216                      pChannel->updateChannelUsage();                  }
2217              }                  // Refresh each channel usage, on each period...
2218          }                  if (m_pOptions->bAutoRefresh) {
2219      }                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2220                            if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2221                                    m_iTimerSlot = 0;
2222                                    // Update the channel stream usage for each strip...
2223                                    QWidgetList wlist = m_pWorkspace->windowList();
2224                                    for (int iChannel = 0;
2225                                                    iChannel < (int) wlist.count(); iChannel++) {
2226                                            qsamplerChannelStrip *pChannelStrip
2227                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2228                                            if (pChannelStrip && pChannelStrip->isVisible())
2229                                                    pChannelStrip->updateChannelUsage();
2230                                    }
2231                            }
2232                    }
2233            }
2234    
2235      // Register the next timer slot.      // Register the next timer slot.
2236      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1456  void qsamplerMainForm::startServer (void Line 2252  void qsamplerMainForm::startServer (void
2252    
2253      // Is the server process instance still here?      // Is the server process instance still here?
2254      if (m_pServer) {      if (m_pServer) {
2255          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2256                            QSAMPLER_TITLE ": " + tr("Warning"),
2257              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2258                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2259              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1477  void qsamplerMainForm::startServer (void Line 2274  void qsamplerMainForm::startServer (void
2274      m_pServer = new QProcess(this);      m_pServer = new QProcess(this);
2275    
2276      // Setup stdout/stderr capture...      // Setup stdout/stderr capture...
2277      //if (m_pOptions->bStdoutCapture) {          //      if (m_pOptions->bStdoutCapture) {
2278          m_pServer->setCommunication(QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);                  m_pServer->setCommunication(
2279          QObject::connect(m_pServer, SIGNAL(readyReadStdout()), this, SLOT(readServerStdout()));                          QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);
2280          QObject::connect(m_pServer, SIGNAL(readyReadStderr()), this, SLOT(readServerStdout()));                  QObject::connect(m_pServer,
2281      //}                          SIGNAL(readyReadStdout()),
2282      // The unforgiveable signal communication...                          SLOT(readServerStdout()));
2283      QObject::connect(m_pServer, SIGNAL(processExited()), this, SLOT(processServerExit()));                  QObject::connect(m_pServer,
2284                            SIGNAL(readyReadStderr()),
2285                            SLOT(readServerStdout()));
2286            //      }
2287            // The unforgiveable signal communication...
2288            QObject::connect(m_pServer,
2289                    SIGNAL(processExited()),
2290                    SLOT(processServerExit()));
2291    
2292      // Build process arguments...      // Build process arguments...
2293      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));
# Line 1615  bool qsamplerMainForm::startClient (void Line 2419  bool qsamplerMainForm::startClient (void
2419      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2420      appendMessages(tr("Client receive timeout is set to %1 msec.").arg(::lscp_client_get_timeout(m_pClient)));      appendMessages(tr("Client receive timeout is set to %1 msec.").arg(::lscp_client_get_timeout(m_pClient)));
2421    
2422            // Subscribe to channel info change notifications...
2423            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2424                    appendMessagesClient("lscp_client_subscribe");
2425    
2426      // We may stop scheduling around.      // We may stop scheduling around.
2427      stopSchedule();      stopSchedule();
2428    
# Line 1624  bool qsamplerMainForm::startClient (void Line 2432  bool qsamplerMainForm::startClient (void
2432      // Log success here.      // Log success here.
2433      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2434    
2435            // Hard-notify instrumnet and device configuration forms,
2436            // if visible, that we're ready...
2437            if (m_pInstrumentListForm)
2438                m_pInstrumentListForm->refreshInstruments();
2439            if (m_pDeviceForm)
2440                m_pDeviceForm->refreshDevices();
2441    
2442      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2443      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2444          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1658  void qsamplerMainForm::stopClient (void) Line 2473  void qsamplerMainForm::stopClient (void)
2473      // channels from the back-end server.      // channels from the back-end server.
2474      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2475      closeSession(false);      closeSession(false);
2476        
2477      // Close us as a client...      // Close us as a client...
2478      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2479        ::lscp_client_destroy(m_pClient);
2480      m_pClient = NULL;      m_pClient = NULL;
2481    
2482            // Hard-notify instrumnet and device configuration forms,
2483            // if visible, that we're running out...
2484            if (m_pInstrumentListForm)
2485                m_pInstrumentListForm->refreshInstruments();
2486            if (m_pDeviceForm)
2487                m_pDeviceForm->refreshDevices();
2488    
2489      // Log final here.      // Log final here.
2490      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2491    

Legend:
Removed from v.162  
changed lines
  Added in v.1034

  ViewVC Help
Powered by ViewVC