/[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 263 by capela, Wed Sep 29 09:01:35 2004 UTC revision 662 by capela, Sat Jun 18 10:46:57 2005 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-2005, 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 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>
# Line 36  Line 37 
37    
38  #include "qsamplerAbout.h"  #include "qsamplerAbout.h"
39  #include "qsamplerOptions.h"  #include "qsamplerOptions.h"
40    #include "qsamplerChannel.h"
41  #include "qsamplerMessages.h"  #include "qsamplerMessages.h"
42    
43  #include "qsamplerChannelStrip.h"  #include "qsamplerChannelStrip.h"
44    
45    #include "qsamplerDeviceForm.h"
46  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
47    
48  #include "config.h"  #include "config.h"
49    
50    #ifdef HAVE_SIGNAL_H
51    #include <signal.h>
52    #endif
53    
54    #ifdef CONFIG_LIBGIG
55    #include <gig.h>
56    #endif
57    
58  // Timer constant stuff.  // Timer constant stuff.
59  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
# Line 100  void qsamplerMainForm::init (void) Line 111  void qsamplerMainForm::init (void)
111      m_pOptions = NULL;      m_pOptions = NULL;
112    
113      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
114      m_pMessages = NULL;      m_pMessages   = NULL;
115        m_pDeviceForm = NULL;
116    
117      // We'll start clean.      // We'll start clean.
118      m_iUntitled = 0;      m_iUntitled   = 0;
119      m_iDirtyCount = 0;      m_iDirtyCount = 0;
120    
121      m_pServer = NULL;      m_pServer = NULL;
# Line 114  void qsamplerMainForm::init (void) Line 126  void qsamplerMainForm::init (void)
126    
127      m_iTimerSlot = 0;      m_iTimerSlot = 0;
128    
129    #ifdef HAVE_SIGNAL_H
130            // Set to ignore any fatal "Broken pipe" signals.
131            ::signal(SIGPIPE, SIG_IGN);
132    #endif
133    
134      // Make it an MDI workspace.      // Make it an MDI workspace.
135      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
136      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
# Line 128  void qsamplerMainForm::init (void) Line 145  void qsamplerMainForm::init (void)
145      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
146      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
147      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
148      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
149      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
150      // Server address.      // Server address.
151      pLabel = new QLabel(this);      pLabel = new QLabel(this);
152      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
153      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
154      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
155      // Channel title.      // Channel title.
156      pLabel = new QLabel(this);      pLabel = new QLabel(this);
157      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
158      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
159      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
160      // Session modification status.      // Session modification status.
161      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
162      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
163      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
164      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
165      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
166    
167      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 163  void qsamplerMainForm::destroy (void) Line 180  void qsamplerMainForm::destroy (void)
180  {  {
181      // Do final processing anyway.      // Do final processing anyway.
182      processServerExit();      processServerExit();
183        
184      // Delete recentfiles menu.  #if defined(WIN32)
185      if (m_pRecentFilesMenu)      WSACleanup();
186          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];  
187    
188      // Finally drop any widgets around...      // Finally drop any widgets around...
189        if (m_pDeviceForm)
190            delete m_pDeviceForm;
191      if (m_pMessages)      if (m_pMessages)
192          delete m_pMessages;          delete m_pMessages;
193      if (m_pWorkspace)      if (m_pWorkspace)
194          delete m_pWorkspace;          delete m_pWorkspace;
195    
196  #if defined(WIN32)      // Delete status item labels one by one.
197      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
198  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
199        if (m_statusItem[QSAMPLER_STATUS_SERVER])
200            delete m_statusItem[QSAMPLER_STATUS_SERVER];
201        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
202            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
203        if (m_statusItem[QSAMPLER_STATUS_SESSION])
204            delete m_statusItem[QSAMPLER_STATUS_SESSION];
205    
206        // Delete recentfiles menu.
207        if (m_pRecentFilesMenu)
208            delete m_pRecentFilesMenu;
209  }  }
210    
211    
# Line 195  void qsamplerMainForm::setup ( qsamplerO Line 215  void qsamplerMainForm::setup ( qsamplerO
215      // We got options?      // We got options?
216      m_pOptions = pOptions;      m_pOptions = pOptions;
217    
218        // What style do we create these forms?
219        WFlags wflags = Qt::WType_TopLevel;
220        if (m_pOptions->bKeepOnTop)
221            wflags |= Qt::WStyle_Tool;
222      // Some child forms are to be created right now.      // Some child forms are to be created right now.
223      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
224        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
225        m_pDeviceForm->setMainForm(this); // An important life immutable!
226      // Set message defaults...      // Set message defaults...
227      updateMessagesFont();      updateMessagesFont();
228      updateMessagesLimit();      updateMessagesLimit();
# Line 225  void qsamplerMainForm::setup ( qsamplerO Line 251  void qsamplerMainForm::setup ( qsamplerO
251          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
252          istr >> *this;          istr >> *this;
253      }      }
254      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
255      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
256        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
257    
258      // Final startup stabilization...      // Final startup stabilization...
259      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 264  bool qsamplerMainForm::queryClose (void) Line 291  bool qsamplerMainForm::queryClose (void)
291              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
292              ostr << *this;              ostr << *this;
293              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
294              // And the main windows state.              // And the children, and the main windows state,.
295              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
296                            m_pOptions->saveWidgetGeometry(this);
297                            // Close popup widgets.
298                            if (m_pDeviceForm)
299                                    m_pDeviceForm->close();
300              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
301              stopServer();              stopServer();
302          }          }
# Line 284  void qsamplerMainForm::closeEvent ( QClo Line 315  void qsamplerMainForm::closeEvent ( QClo
315  }  }
316    
317    
318  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
319  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
320  {  {
321      bool bAccept = false;      bool bDecode = false;
322    
323      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
324          QString sUrl;          QString sText;
325          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
326              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
327                files = QStringList::split('\n', sText);
328                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
329                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
330            }
331      }      }
332    
333      pDragEnterEvent->accept(bAccept);      return bDecode;
334    }
335    
336    
337    // Window drag-n-drop event handlers.
338    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
339    {
340            QStringList files;
341            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
342  }  }
343    
344    
345  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
346  {  {
347      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
348          QString sUrl;  
349          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
350              loadSessionFile(QUrl(sUrl).path());          return;
351      }  
352            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
353                    const QString& sPath = *iter;
354                    if (qsamplerChannel::isInstrumentFile(sPath)) {
355                            // Try to create a new channel from instrument file...
356                            qsamplerChannel *pChannel = new qsamplerChannel(this);
357                            if (pChannel == NULL)
358                                    return;
359                            // Start setting the instrument filename...
360                            pChannel->setInstrument(sPath, 0);
361                            // Before we show it up, may be we'll
362                            // better ask for some initial values?
363                            if (!pChannel->channelSetup(this)) {
364                                    delete pChannel;
365                                    return;
366                            }
367                            // Finally, give it to a new channel strip...
368                            if (!createChannelStrip(pChannel)) {
369                                    delete pChannel;
370                                    return;
371                            }
372                            // Make that an overall update.
373                            m_iDirtyCount++;
374                            stabilizeForm();
375                    }   // Otherwise, load an usual session file (LSCP script)...
376                    else if (closeSession(true))
377                            loadSessionFile(sPath);
378                    // Make it look responsive...:)
379                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
380            }
381  }  }
382    
383    
# Line 318  void qsamplerMainForm::customEvent ( QCu Line 390  void qsamplerMainForm::customEvent ( QCu
390          appendMessagesColor(tr("Notify event: %1 data: %2")          appendMessagesColor(tr("Notify event: %1 data: %2")
391              .arg(::lscp_event_to_text(pEvent->event()))              .arg(::lscp_event_to_text(pEvent->event()))
392              .arg(pEvent->data()), "#996699");              .arg(pEvent->data()), "#996699");
393                    if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
394                            int iChannelID = pEvent->data().toInt();
395                            qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
396                            if (pChannelStrip)
397                                    channelStripChanged(pChannelStrip);
398                    }
399      }      }
400  }  }
401    
# Line 326  void qsamplerMainForm::customEvent ( QCu Line 404  void qsamplerMainForm::customEvent ( QCu
404  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
405  {  {
406      stabilizeForm();      stabilizeForm();
407        
408      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
409  }  }
410    
# Line 370  bool qsamplerMainForm::newSession (void) Line 448  bool qsamplerMainForm::newSession (void)
448      if (!closeSession(true))      if (!closeSession(true))
449          return false;          return false;
450    
451            // Give us what the server has, right now...
452            updateSession();
453    
454      // Ok increment untitled count.      // Ok increment untitled count.
455      m_iUntitled++;      m_iUntitled++;
456    
# Line 483  bool qsamplerMainForm::closeSession ( bo Line 564  bool qsamplerMainForm::closeSession ( bo
564          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
565          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
566          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
567              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
568              if (bForce && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)              if (pChannelStrip) {
569                  appendMessagesClient("lscp_remove_channel");                  qsamplerChannel *pChannel = pChannelStrip->channel();
570              delete pChannel;                  if (bForce && pChannel)
571                        pChannel->removeChannel();
572                    delete pChannelStrip;
573                }
574          }          }
575          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
576          // We're now clean, for sure.          // We're now clean, for sure.
# Line 534  bool qsamplerMainForm::loadSessionFile ( Line 618  bool qsamplerMainForm::loadSessionFile (
618      // Ok. we've read it.      // Ok. we've read it.
619      file.close();      file.close();
620    
621      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
622      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
623    
624      // Now we'll try to create the whole GUI session.          // Have we any errors?
625      int iChannels = ::lscp_get_channels(m_pClient);          if (iErrors > 0)
626      if (iChannels < 0) {                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
         appendMessagesClient("lscp_get_channels");  
         appendMessagesError(tr("Could not get current number of channels.\n\nSorry."));  
     }  
       
     // 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);  
627    
628      // Save as default session directory.      // Save as default session directory.
629      if (m_pOptions)      if (m_pOptions)
630          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
631      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
632      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
633      // Stabilize form...      // Stabilize form...
634      m_sFilename = sFilename;      m_sFilename = sFilename;
635      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
636      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
637    
638        // Make that an overall update.
639      stabilizeForm();      stabilizeForm();
640      return true;      return true;
641  }  }
# Line 578  bool qsamplerMainForm::saveSessionFile ( Line 652  bool qsamplerMainForm::saveSessionFile (
652      }      }
653    
654      // Write the file.      // Write the file.
655      int iErrors = 0;      int  iErrors = 0;
656      QTextStream ts(&file);      QTextStream ts(&file);
657      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
658      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 589  bool qsamplerMainForm::saveSessionFile ( Line 663  bool qsamplerMainForm::saveSessionFile (
663      ts << "# " << tr("File")      ts << "# " << tr("File")
664         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
665      ts << "# " << tr("Date")      ts << "# " << tr("Date")
666         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
667         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
668      ts << "#"  << endl;      ts << "#"  << endl;
669      ts << endl;      ts << endl;
670            // It is assumed that this new kind of device+session file
671            // will be loaded from a complete
672            int *piDeviceIDs;
673            int  iDevice;
674            ts << "RESET" << endl;
675            // Audio device mapping.
676            QMap<int, int> audioDeviceMap;
677            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
678            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
679                    ts << endl;
680                    qsamplerDevice device(this, qsamplerDevice::Audio, piDeviceIDs[iDevice]);
681                    // Audio device specification...
682                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
683                            << " " << tr("Device") << " " << iDevice << endl;
684                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
685                    qsamplerDeviceParamMap::ConstIterator deviceParam;
686                    for (deviceParam = device.params().begin();
687                                    deviceParam != device.params().end();
688                                            ++deviceParam) {
689                            const qsamplerDeviceParam& param = deviceParam.data();
690                            if (param.value.isEmpty()) ts << "# ";
691                            ts << " " << deviceParam.key() << "='" << param.value << "'";
692                    }
693                    ts << endl;
694                    // Audio channel parameters...
695                    int iPort = 0;
696                    for (qsamplerDevicePort *pPort = device.ports().first();
697                                    pPort;
698                                            pPort = device.ports().next(), ++iPort) {
699                            qsamplerDeviceParamMap::ConstIterator portParam;
700                            for (portParam = pPort->params().begin();
701                                            portParam != pPort->params().end();
702                                                    ++portParam) {
703                                    const qsamplerDeviceParam& param = portParam.data();
704                                    if (param.fix || param.value.isEmpty()) ts << "# ";
705                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
706                                            << " " << iPort << " " << portParam.key()
707                                            << "='" << param.value << "'" << endl;
708                            }
709                    }
710                    // Audio device index/id mapping.
711                    audioDeviceMap[device.deviceID()] = iDevice;
712            // Try to keep it snappy :)
713            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
714            }
715            // MIDI device mapping.
716            QMap<int, int> midiDeviceMap;
717            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
718            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
719                    ts << endl;
720                    qsamplerDevice device(this, qsamplerDevice::Midi, piDeviceIDs[iDevice]);
721                    // MIDI device specification...
722                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
723                            << " " << tr("Device") << " " << iDevice << endl;
724                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
725                    qsamplerDeviceParamMap::ConstIterator deviceParam;
726                    for (deviceParam = device.params().begin();
727                                    deviceParam != device.params().end();
728                                            ++deviceParam) {
729                            const qsamplerDeviceParam& param = deviceParam.data();
730                            if (param.value.isEmpty()) ts << "# ";
731                            ts << " " << deviceParam.key() << "='" << param.value << "'";
732                    }
733                    ts << endl;
734                    // MIDI port parameters...
735                    int iPort = 0;
736                    for (qsamplerDevicePort *pPort = device.ports().first();
737                                    pPort;
738                                            pPort = device.ports().next(), ++iPort) {
739                            qsamplerDeviceParamMap::ConstIterator portParam;
740                            for (portParam = pPort->params().begin();
741                                            portParam != pPort->params().end();
742                                                    ++portParam) {
743                                    const qsamplerDeviceParam& param = portParam.data();
744                                    if (param.fix || param.value.isEmpty()) ts << "# ";
745                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
746                                       << " " << iPort << " " << portParam.key()
747                                       << "='" << param.value << "'" << endl;
748                            }
749                    }
750                    // MIDI device index/id mapping.
751                    midiDeviceMap[device.deviceID()] = iDevice;
752            // Try to keep it snappy :)
753            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
754            }
755            ts << endl;
756            // Sampler channel mapping.
757      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
758      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
759          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
760          int iChannelID = pChannel->channelID();          if (pChannelStrip) {
761          ts << "# " << pChannel->caption() << endl;              qsamplerChannel *pChannel = pChannelStrip->channel();
762          ts << "ADD CHANNEL" << endl;              if (pChannel) {
763          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                  ts << "# " << tr("Channel") << " " << iChannel << endl;
764          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                  ts << "ADD CHANNEL" << endl;
765          ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                  if (audioDeviceMap.isEmpty()) {
766          ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
767          if (pChannel->midiChannel() > 0)                                                  << " " << pChannel->audioDriver() << endl;
768              ts << pChannel->midiChannel();                                  } else {
769           else                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
770              ts << "ALL";                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
771          ts << endl;                                  }
772          ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                                  if (midiDeviceMap.isEmpty()) {
773          ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
774          ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                                  << " " << pChannel->midiDriver() << endl;
775          ts << endl;                                  } else {
776                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
777                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
778                                    }
779                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
780                                            << " " << pChannel->midiPort() << endl;
781                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
782                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
783                        ts << "ALL";
784                    else
785                        ts << pChannel->midiChannel();
786                    ts << endl;
787                    ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
788                    ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannel << endl;
789                    ts << "SET CHANNEL VOLUME " << iChannel << " " << pChannel->volume() << endl;
790                    ts << endl;
791                }
792            }
793          // Try to keep it snappy :)          // Try to keep it snappy :)
794          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
795      }      }
# Line 637  bool qsamplerMainForm::saveSessionFile ( Line 815  bool qsamplerMainForm::saveSessionFile (
815  }  }
816    
817    
818    // Session change receiver slot.
819    void qsamplerMainForm::sessionDirty (void)
820    {
821        // Just mark the dirty form.
822        m_iDirtyCount++;
823        // and update the form status...
824        stabilizeForm();
825    }
826    
827    
828  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
829  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
830    
# Line 694  void qsamplerMainForm::fileReset (void) Line 882  void qsamplerMainForm::fileReset (void)
882          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
883             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
884             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
885             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
886             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
887          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
888          return;          return;
# Line 708  void qsamplerMainForm::fileReset (void) Line 896  void qsamplerMainForm::fileReset (void)
896    
897      // Log this.      // Log this.
898      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
899    
900            // Make it a new session...
901            newSession();
902  }  }
903    
904    
# Line 716  void qsamplerMainForm::fileRestart (void Line 907  void qsamplerMainForm::fileRestart (void
907  {  {
908      if (m_pOptions == NULL)      if (m_pOptions == NULL)
909          return;          return;
910            
911      bool bRestart = true;      bool bRestart = true;
912        
913      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
914      // (if we're currently up and running)      // (if we're currently up and running)
915      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
# Line 726  void qsamplerMainForm::fileRestart (void Line 917  void qsamplerMainForm::fileRestart (void
917              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
918                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
919                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
920                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
921                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
922              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
923      }      }
# Line 758  void qsamplerMainForm::editAddChannel (v Line 949  void qsamplerMainForm::editAddChannel (v
949      if (m_pClient == NULL)      if (m_pClient == NULL)
950          return;          return;
951    
952      // Create the new sampler channel.      // Just create the channel instance...
953      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel(this);
954      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
955          return;          return;
     }  
956    
957      // Log this happening.      // Before we show it up, may be we'll
958      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
959        if (!pChannel->channelSetup(this)) {
960            delete pChannel;
961            return;
962        }
963    
964      // Just create the channel strip with given id.      // And give it to the strip (will own the channel instance, if successful).
965      createChannel(iChannelID, true);      if (!createChannelStrip(pChannel)) {
966            delete pChannel;
967            return;
968        }
969    
970      // We'll be dirty, for sure...      // Make that an overall update.
971      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
972      stabilizeForm();      stabilizeForm();
973  }  }
974    
# Line 785  void qsamplerMainForm::editRemoveChannel Line 979  void qsamplerMainForm::editRemoveChannel
979      if (m_pClient == NULL)      if (m_pClient == NULL)
980          return;          return;
981    
982      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
983        if (pChannelStrip == NULL)
984            return;
985    
986        qsamplerChannel *pChannel = pChannelStrip->channel();
987      if (pChannel == NULL)      if (pChannel == NULL)
988          return;          return;
989    
# Line 795  void qsamplerMainForm::editRemoveChannel Line 993  void qsamplerMainForm::editRemoveChannel
993              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
994                 "%1\n\n"                 "%1\n\n"
995                 "Are you sure?")                 "Are you sure?")
996                 .arg(pChannel->caption()),                 .arg(pChannelStrip->caption()),
997              tr("OK"), tr("Cancel")) > 0)              tr("OK"), tr("Cancel")) > 0)
998              return;              return;
999      }      }
1000    
1001      // Remove the existing sampler channel.      // Remove the existing sampler channel.
1002      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."));  
1003          return;          return;
     }  
1004    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
1005      // Just delete the channel strip.      // Just delete the channel strip.
1006      delete pChannel;      delete pChannelStrip;
1007    
1008      // Do we auto-arrange?      // Do we auto-arrange?
1009      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1010          channelsArrange();          channelsArrange();
# Line 828  void qsamplerMainForm::editSetupChannel Line 1021  void qsamplerMainForm::editSetupChannel
1021      if (m_pClient == NULL)      if (m_pClient == NULL)
1022          return;          return;
1023    
1024      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1025      if (pChannel == NULL)      if (pChannelStrip == NULL)
1026          return;          return;
1027    
1028      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
1029      pChannel->showChannelSetup(false);      pChannelStrip->channelSetup();
1030  }  }
1031    
1032    
# Line 843  void qsamplerMainForm::editResetChannel Line 1036  void qsamplerMainForm::editResetChannel
1036      if (m_pClient == NULL)      if (m_pClient == NULL)
1037          return;          return;
1038    
1039      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1040      if (pChannel == NULL)      if (pChannelStrip == NULL)
1041          return;          return;
1042    
1043      // Remove the existing sampler channel.      // Just invoque the channel strip procedure.
1044      if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      pChannelStrip->channelReset();
1045          appendMessagesClient("lscp_reset_channel");  }
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
1046    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
1047    
1048      // Refresh channel strip info.  // Reset all sampler channels.
1049      pChannel->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
1050    {
1051            if (m_pClient == NULL)
1052                    return;
1053    
1054            // Invoque the channel strip procedure,
1055            // for all channels out there...
1056            m_pWorkspace->setUpdatesEnabled(false);
1057            QWidgetList wlist = m_pWorkspace->windowList();
1058            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1059                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1060                    if (pChannelStrip)
1061                            pChannelStrip->channelReset();
1062            }
1063            m_pWorkspace->setUpdatesEnabled(true);
1064  }  }
1065    
1066    
# Line 910  void qsamplerMainForm::viewMessages ( bo Line 1112  void qsamplerMainForm::viewMessages ( bo
1112  }  }
1113    
1114    
1115    // Show/hide the device configurator form.
1116    void qsamplerMainForm::viewDevices (void)
1117    {
1118            if (m_pOptions == NULL)
1119                    return;
1120    
1121            if (m_pDeviceForm) {
1122                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1123                    m_pDeviceForm->setClient(m_pClient);
1124                    if (m_pDeviceForm->isVisible()) {
1125                            m_pDeviceForm->hide();
1126                    } else {
1127                            m_pDeviceForm->show();
1128                            m_pDeviceForm->raise();
1129                            m_pDeviceForm->setActiveWindow();
1130                    }
1131            }
1132    }
1133    
1134    
1135  // Show options dialog.  // Show options dialog.
1136  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1137  {  {
# Line 919  void qsamplerMainForm::viewOptions (void Line 1141  void qsamplerMainForm::viewOptions (void
1141      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);
1142      if (pOptionsForm) {      if (pOptionsForm) {
1143          // Check out some initial nullities(tm)...          // Check out some initial nullities(tm)...
1144          qsamplerChannelStrip *pChannel = activeChannel();          qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1145          if (m_pOptions->sDisplayFont.isEmpty() && pChannel)          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1146              m_pOptions->sDisplayFont = pChannel->displayFont().toString();              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1147          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1148              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1149          // To track down deferred or immediate changes.          // To track down deferred or immediate changes.
# Line 931  void qsamplerMainForm::viewOptions (void Line 1153  void qsamplerMainForm::viewOptions (void
1153          bool    bOldServerStart     = m_pOptions->bServerStart;          bool    bOldServerStart     = m_pOptions->bServerStart;
1154          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1155          QString sOldDisplayFont     = m_pOptions->sDisplayFont;          QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1156            bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1157          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1158          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1159            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1160          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1161          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1162          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1163          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1164            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1165          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1166          // Load the current setup settings.          // Load the current setup settings.
1167          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 944  void qsamplerMainForm::viewOptions (void Line 1169  void qsamplerMainForm::viewOptions (void
1169          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1170              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1171              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1172                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1173                    ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1174                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1175                  QMessageBox::information(this, tr("Information"),                  QMessageBox::information(this, tr("Information"),
1176                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1177                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
# Line 955  void qsamplerMainForm::viewOptions (void Line 1182  void qsamplerMainForm::viewOptions (void
1182                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1183                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1184                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1185                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1186                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1187                    updateInstrumentNames();
1188                if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1189                    (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1190                    updateDisplayEffect();
1191              if (sOldDisplayFont != m_pOptions->sDisplayFont)              if (sOldDisplayFont != m_pOptions->sDisplayFont)
1192                  updateDisplayFont();                  updateDisplayFont();
1193              if (iOldMaxVolume != m_pOptions->iMaxVolume)              if (iOldMaxVolume != m_pOptions->iMaxVolume)
# Line 997  void qsamplerMainForm::channelsArrange ( Line 1230  void qsamplerMainForm::channelsArrange (
1230      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1231      int y = 0;      int y = 0;
1232      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1233          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1234      /*  if (pChannel->testWState(WState_Maximized | WState_Minimized)) {      /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1235              // Prevent flicker...              // Prevent flicker...
1236              pChannel->hide();              pChannelStrip->hide();
1237              pChannel->showNormal();              pChannelStrip->showNormal();
1238          }   */          }   */
1239          pChannel->adjustSize();          pChannelStrip->adjustSize();
1240          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1241          if (iWidth < pChannel->width())          if (iWidth < pChannelStrip->width())
1242              iWidth = pChannel->width();              iWidth = pChannelStrip->width();
1243      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1244          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1245          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1246          y += iHeight;          y += iHeight;
1247      }      }
1248      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1249        
1250      stabilizeForm();      stabilizeForm();
1251  }  }
1252    
# Line 1062  void qsamplerMainForm::helpAbout (void) Line 1295  void qsamplerMainForm::helpAbout (void)
1295      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1296      sText += "</font></small><br />";      sText += "</font></small><br />";
1297  #endif  #endif
1298    #ifndef CONFIG_INSTRUMENT_NAME
1299        sText += "<small><font color=\"red\">";
1300        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1301        sText += "</font></small><br />";
1302    #endif
1303      sText += "<br />\n";      sText += "<br />\n";
1304      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1305      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1306      sText += " ";      sText += " ";
1307      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1308    #ifdef CONFIG_LIBGIG
1309        sText += ", ";
1310        sText += gig::libraryName();
1311        sText += " ";
1312        sText += gig::libraryVersion();
1313    #endif
1314      sText += "<br />\n";      sText += "<br />\n";
1315      sText += "<br />\n";      sText += "<br />\n";
1316      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 1089  void qsamplerMainForm::helpAbout (void) Line 1333  void qsamplerMainForm::helpAbout (void)
1333  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1334  {  {
1335      // Update the main application caption...      // Update the main application caption...
1336      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1337      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1338          sSessioName += '*';          sSessionName += '*';
1339      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1340    
1341      // Update the main menu state...      // Update the main menu state...
1342      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1343      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1344      bool bHasChannel = (bHasClient && pChannel != NULL);      bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1345      fileNewAction->setEnabled(bHasClient);      fileNewAction->setEnabled(bHasClient);
1346      fileOpenAction->setEnabled(bHasClient);      fileOpenAction->setEnabled(bHasClient);
1347      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1108  void qsamplerMainForm::stabilizeForm (vo Line 1352  void qsamplerMainForm::stabilizeForm (vo
1352      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1353      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1354      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1355      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1356      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1357        viewDevicesAction->setOn(m_pDeviceForm && m_pDeviceForm->isVisible());
1358        viewDevicesAction->setEnabled(bHasClient);
1359        channelsArrangeAction->setEnabled(bHasChannel);
1360    
1361      // Client/Server status...      // Client/Server status...
1362      if (bHasClient) {      if (bHasClient) {
1363          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1364          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));
1365      } else {      } else {
1366          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1367          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1368      }      }
1369      // Channel status...      // Channel status...
1370      if (bHasChannel)      if (bHasChannel)
1371          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannel->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1372      else      else
1373          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1374      // Session status...      // Session status...
1375      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1376          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1377      else      else
1378          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1379    
1380      // Recent files menu.      // Recent files menu.
1381      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1140  void qsamplerMainForm::stabilizeForm (vo Line 1387  void qsamplerMainForm::stabilizeForm (vo
1387    
1388    
1389  // Channel change receiver slot.  // Channel change receiver slot.
1390  void qsamplerMainForm::channelChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1391  {  {
1392            // Add this strip to the changed list...
1393            if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1394                    m_changedStrips.append(pChannelStrip);
1395                    pChannelStrip->resetErrorCount();
1396            }
1397    
1398      // Just mark the dirty form.      // Just mark the dirty form.
1399      m_iDirtyCount++;      m_iDirtyCount++;
1400      // and update the form status...      // and update the form status...
# Line 1149  void qsamplerMainForm::channelChanged( q Line 1402  void qsamplerMainForm::channelChanged( q
1402  }  }
1403    
1404    
1405    // Grab and restore current sampler channels session.
1406    void qsamplerMainForm::updateSession (void)
1407    {
1408            // Retrieve the current channel list.
1409            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1410            if (piChannelIDs == NULL) {
1411                    if (::lscp_client_get_errno(m_pClient)) {
1412                            appendMessagesClient("lscp_list_channels");
1413                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1414                    }
1415                    return;
1416            }
1417    
1418            // Try to (re)create each channel.
1419            m_pWorkspace->setUpdatesEnabled(false);
1420            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1421                    // Check if theres already a channel strip for this one...
1422                    if (!channelStrip(piChannelIDs[iChannel]))
1423                            createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));
1424                    // Make it visibly responsive...
1425                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1426            }
1427            m_pWorkspace->setUpdatesEnabled(true);
1428            
1429            // Remember to refresh devices
1430            if (m_pDeviceForm)
1431                m_pDeviceForm->refreshDevices();
1432    }
1433    
1434    
1435  // Update the recent files list and menu.  // Update the recent files list and menu.
1436  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1437  {  {
# Line 1193  void qsamplerMainForm::updateRecentFiles Line 1476  void qsamplerMainForm::updateRecentFiles
1476  }  }
1477    
1478    
1479    // Force update of the channels instrument names mode.
1480    void qsamplerMainForm::updateInstrumentNames (void)
1481    {
1482        // Full channel list update...
1483        QWidgetList wlist = m_pWorkspace->windowList();
1484        if (wlist.isEmpty())
1485            return;
1486    
1487        m_pWorkspace->setUpdatesEnabled(false);
1488        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1489            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1490            if (pChannelStrip)
1491                pChannelStrip->updateInstrumentName(true);
1492        }
1493        m_pWorkspace->setUpdatesEnabled(true);
1494    }
1495    
1496    
1497  // Force update of the channels display font.  // Force update of the channels display font.
1498  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1499  {  {
# Line 1214  void qsamplerMainForm::updateDisplayFont Line 1515  void qsamplerMainForm::updateDisplayFont
1515    
1516      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1517      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1518          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1519          pChannel->setDisplayFont(font);          if (pChannelStrip)
1520                pChannelStrip->setDisplayFont(font);
1521        }
1522        m_pWorkspace->setUpdatesEnabled(true);
1523    }
1524    
1525    
1526    // Update channel strips background effect.
1527    void qsamplerMainForm::updateDisplayEffect (void)
1528    {
1529       QPixmap pm;
1530        if (m_pOptions->bDisplayEffect)
1531            pm = QPixmap::fromMimeSource("displaybg1.png");
1532    
1533        // Full channel list update...
1534        QWidgetList wlist = m_pWorkspace->windowList();
1535        if (wlist.isEmpty())
1536            return;
1537    
1538        m_pWorkspace->setUpdatesEnabled(false);
1539        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1540            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1541            if (pChannelStrip)
1542                pChannelStrip->setDisplayBackground(pm);
1543      }      }
1544      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1545  }  }
# Line 1234  void qsamplerMainForm::updateMaxVolume ( Line 1558  void qsamplerMainForm::updateMaxVolume (
1558    
1559      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1560      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1561          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1562          pChannel->setMaxVolume(m_pOptions->iMaxVolume);          if (pChannelStrip)
1563                pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1564      }      }
1565      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1566  }  }
# Line 1314  void qsamplerMainForm::updateMessagesLim Line 1639  void qsamplerMainForm::updateMessagesLim
1639          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1640              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1641          else          else
1642              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1643      }      }
1644  }  }
1645    
# Line 1334  void qsamplerMainForm::updateMessagesCap Line 1659  void qsamplerMainForm::updateMessagesCap
1659  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
1660    
1661  // The channel strip creation executive.  // The channel strip creation executive.
1662  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
1663  {  {
1664      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
1665          return;          return NULL;
1666    
1667      // Prepare for auto-arrange?      // Prepare for auto-arrange?
1668      qsamplerChannelStrip *pChannel = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
1669      int y = 0;      int y = 0;
1670      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1671          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1672          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1673              pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1674          //  y += pChannel->height() + pChannel->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1675              y += pChannel->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1676                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1677                            }
1678          }          }
1679      }      }
1680    
1681      // Add a new channel itema...      // Add a new channel itema...
1682      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;
1683      pChannel = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1684      pChannel->setMaxVolume(m_pOptions->iMaxVolume);      if (pChannelStrip == NULL)
1685      pChannel->setup(this, iChannelID);          return NULL;
1686      // We'll need a display font.  
1687      QFont font;      // Actual channel strip setup...
1688      if (m_pOptions && font.fromString(m_pOptions->sDisplayFont))      pChannelStrip->setup(pChannel);
1689          pChannel->setDisplayFont(font);      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
1690      // Track channel setup changes.      // Set some initial aesthetic options...
1691      QObject::connect(pChannel, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelChanged(qsamplerChannelStrip *)));      if (m_pOptions) {
1692      // Before we show it up, may be we'll          // Background display effect...
1693      // better ask for some initial values?          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
1694      if (bPrompt)          // We'll need a display font.
1695          pChannel->showChannelSetup(true);          QFont font;
1696            if (font.fromString(m_pOptions->sDisplayFont))
1697                pChannelStrip->setDisplayFont(font);
1698            // Maximum allowed volume setting.
1699            pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1700        }
1701    
1702      // Now we show up us to the world.      // Now we show up us to the world.
1703      pChannel->show();      pChannelStrip->show();
1704      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
1705      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1706          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1707      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();
1708          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1709          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1710      }      }
1711    
1712            // This is pretty new, so we'll watch for it closely.
1713            channelStripChanged(pChannelStrip);
1714    
1715        // Return our successful reference...
1716        return pChannelStrip;
1717  }  }
1718    
1719    
1720  // Retrieve the active channel strip.  // Retrieve the active channel strip.
1721  qsamplerChannelStrip *qsamplerMainForm::activeChannel (void)  qsamplerChannelStrip *qsamplerMainForm::activeChannelStrip (void)
1722  {  {
1723      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();
1724  }  }
1725    
1726    
1727  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
1728  qsamplerChannelStrip *qsamplerMainForm::channelAt ( int iChannel )  qsamplerChannelStrip *qsamplerMainForm::channelStripAt ( int iChannel )
1729  {  {
1730      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1731      if (wlist.isEmpty())      if (wlist.isEmpty())
1732          return 0;          return NULL;
1733    
1734      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1735  }  }
1736    
1737    
1738    // Retrieve a channel strip by sampler channel id.
1739    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1740    {
1741            QWidgetList wlist = m_pWorkspace->windowList();
1742            if (wlist.isEmpty())
1743                    return NULL;
1744    
1745            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1746                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1747                    if (pChannelStrip) {
1748                            qsamplerChannel *pChannel = pChannelStrip->channel();
1749                            if (pChannel && pChannel->channelID() == iChannelID)
1750                                    return pChannelStrip;
1751                    }
1752            }
1753    
1754            // Not found.
1755            return NULL;
1756    }
1757    
1758    
1759  // Construct the windows menu.  // Construct the windows menu.
1760  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1761  {  {
# Line 1407  void qsamplerMainForm::channelsMenuAbout Line 1767  void qsamplerMainForm::channelsMenuAbout
1767      if (!wlist.isEmpty()) {      if (!wlist.isEmpty()) {
1768          channelsMenu->insertSeparator();          channelsMenu->insertSeparator();
1769          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1770              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1771              int iItemID = channelsMenu->insertItem(pChannel->caption(), this, SLOT(channelsMenuActivated(int)));              if (pChannelStrip) {
1772              channelsMenu->setItemParameter(iItemID, iChannel);                  int iItemID = channelsMenu->insertItem(pChannelStrip->caption(), this, SLOT(channelsMenuActivated(int)));
1773              channelsMenu->setItemChecked(iItemID, activeChannel() == pChannel);                  channelsMenu->setItemParameter(iItemID, iChannel);
1774                    channelsMenu->setItemChecked(iItemID, activeChannelStrip() == pChannelStrip);
1775                }
1776          }          }
1777      }      }
1778  }  }
# Line 1419  void qsamplerMainForm::channelsMenuAbout Line 1781  void qsamplerMainForm::channelsMenuAbout
1781  // Windows menu activation slot  // Windows menu activation slot
1782  void qsamplerMainForm::channelsMenuActivated ( int iChannel )  void qsamplerMainForm::channelsMenuActivated ( int iChannel )
1783  {  {
1784      qsamplerChannelStrip *pChannel = channelAt(iChannel);      qsamplerChannelStrip *pChannelStrip = channelStripAt(iChannel);
1785      if (pChannel)      if (pChannelStrip)
1786          pChannel->showNormal();          pChannelStrip->showNormal();
1787      pChannel->setFocus();      pChannelStrip->setFocus();
1788  }  }
1789    
1790    
# Line 1460  void qsamplerMainForm::timerSlot (void) Line 1822  void qsamplerMainForm::timerSlot (void)
1822              }              }
1823          }          }
1824      }      }
1825        
1826          // Refresh each channel usage, on each period...          // Refresh each channel usage, on each period...
1827      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {          if (m_pClient && (m_changedStrips.count() > 0 || m_pOptions->bAutoRefresh)) {
1828          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  m_iTimerSlot += QSAMPLER_TIMER_MSECS;
1829          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                  if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {
1830              m_iTimerSlot = 0;                          m_iTimerSlot = 0;
1831              QWidgetList wlist = m_pWorkspace->windowList();                          // Update the channel information for each pending strip...
1832              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
1833                  qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);                                          pChannelStrip;
1834                  if (pChannel->isVisible())                                                  pChannelStrip = m_changedStrips.next()) {
1835                      pChannel->updateChannelUsage();                                  // If successfull, remove from pending list...
1836              }                                  if (pChannelStrip->updateChannelInfo())
1837          }                                          m_changedStrips.remove(pChannelStrip);
1838      }                          }
1839                            // Update the channel stream usage for each strip...
1840                            QWidgetList wlist = m_pWorkspace->windowList();
1841                            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1842                                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1843                                    if (pChannelStrip && pChannelStrip->isVisible())
1844                                            pChannelStrip->updateChannelUsage();
1845                            }
1846                    }
1847            }
1848    
1849      // Register the next timer slot.      // Register the next timer slot.
1850      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1654  bool qsamplerMainForm::startClient (void Line 2025  bool qsamplerMainForm::startClient (void
2025      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2026      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)));
2027    
2028            // Subscribe to channel info change notifications...
2029            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2030                    appendMessagesClient("lscp_client_subscribe");
2031    
2032      // We may stop scheduling around.      // We may stop scheduling around.
2033      stopSchedule();      stopSchedule();
2034    
# Line 1663  bool qsamplerMainForm::startClient (void Line 2038  bool qsamplerMainForm::startClient (void
2038      // Log success here.      // Log success here.
2039      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2040    
2041            // Hard-notify device configuration form,
2042            // if visible, that we're ready...
2043            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2044                m_pDeviceForm->setClient(m_pClient);
2045    
2046      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2047      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2048          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1683  void qsamplerMainForm::stopClient (void) Line 2063  void qsamplerMainForm::stopClient (void)
2063      if (m_pClient == NULL)      if (m_pClient == NULL)
2064          return;          return;
2065    
2066            // Hard-notify device configuration form,
2067            // if visible, that we're running out...
2068            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2069                m_pDeviceForm->setClient(NULL);
2070    
2071      // Log prepare here.      // Log prepare here.
2072      appendMessages(tr("Client disconnecting..."));      appendMessages(tr("Client disconnecting..."));
2073    
# Line 1697  void qsamplerMainForm::stopClient (void) Line 2082  void qsamplerMainForm::stopClient (void)
2082      // channels from the back-end server.      // channels from the back-end server.
2083      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2084      closeSession(false);      closeSession(false);
2085        
2086      // Close us as a client...      // Close us as a client...
2087      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2088        ::lscp_client_destroy(m_pClient);
2089      m_pClient = NULL;      m_pClient = NULL;
2090    
2091      // Log final here.      // Log final here.

Legend:
Removed from v.263  
changed lines
  Added in v.662

  ViewVC Help
Powered by ViewVC