/[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 341 by capela, Tue Jan 18 11:29:01 2005 UTC revision 961 by capela, Sun Dec 3 18:26:13 2006 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-2005, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2006, 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>
# Line 40  Line 41 
41  #include "qsamplerMessages.h"  #include "qsamplerMessages.h"
42    
43  #include "qsamplerChannelStrip.h"  #include "qsamplerChannelStrip.h"
44  #include "qsamplerOptionsForm.h"  #include "qsamplerInstrumentList.h"
45    
46  #include "config.h"  #include "qsamplerInstrumentListForm.h"
47    #include "qsamplerDeviceForm.h"
48    #include "qsamplerOptionsForm.h"
49    
50  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
51  #include <signal.h>  #include <signal.h>
52  #endif  #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
60    
# Line 97  private: Line 104  private:
104  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
105  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
106    
107    // Kind of singleton reference.
108    qsamplerMainForm *qsamplerMainForm::g_pMainForm = NULL;
109    
110    
111  // Kind of constructor.  // Kind of constructor.
112  void qsamplerMainForm::init (void)  void qsamplerMainForm::init (void)
113  {  {
114            // Pseudo-singleton reference setup.
115            g_pMainForm = this;
116    
117      // Initialize some pointer references.      // Initialize some pointer references.
118      m_pOptions = NULL;      m_pOptions = NULL;
119    
120      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
121      m_pMessages = NULL;      m_pMessages = NULL;
122        m_pInstrumentListForm = NULL;
123        m_pDeviceForm = NULL;
124    
125      // We'll start clean.      // We'll start clean.
126      m_iUntitled    = 0;      m_iUntitled   = 0;
127      m_iDirtyCount  = 0;      m_iDirtyCount = 0;
     m_iChangeCount = 0;  
128    
129      m_pServer = NULL;      m_pServer = NULL;
130      m_pClient = NULL;      m_pClient = NULL;
# Line 138  void qsamplerMainForm::init (void) Line 153  void qsamplerMainForm::init (void)
153      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
154      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
155      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
156      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
157      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
158      // Server address.      // Server address.
159      pLabel = new QLabel(this);      pLabel = new QLabel(this);
160      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
161      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
162      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
163      // Channel title.      // Channel title.
164      pLabel = new QLabel(this);      pLabel = new QLabel(this);
165      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
166      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
167      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
168      // Session modification status.      // Session modification status.
169      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
170      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
171      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
172      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
173      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
174    
175      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 173  void qsamplerMainForm::destroy (void) Line 188  void qsamplerMainForm::destroy (void)
188  {  {
189      // Do final processing anyway.      // Do final processing anyway.
190      processServerExit();      processServerExit();
191        
192      // Delete recentfiles menu.  #if defined(WIN32)
193      if (m_pRecentFilesMenu)      WSACleanup();
194          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];  
195    
196      // Finally drop any widgets around...      // Finally drop any widgets around...
197        if (m_pDeviceForm)
198            delete m_pDeviceForm;
199        if (m_pInstrumentListForm)
200            delete m_pInstrumentListForm;
201      if (m_pMessages)      if (m_pMessages)
202          delete m_pMessages;          delete m_pMessages;
203      if (m_pWorkspace)      if (m_pWorkspace)
204          delete m_pWorkspace;          delete m_pWorkspace;
205    
206  #if defined(WIN32)      // Delete status item labels one by one.
207      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
208  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
209        if (m_statusItem[QSAMPLER_STATUS_SERVER])
210            delete m_statusItem[QSAMPLER_STATUS_SERVER];
211        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
212            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
213        if (m_statusItem[QSAMPLER_STATUS_SESSION])
214            delete m_statusItem[QSAMPLER_STATUS_SESSION];
215    
216        // Delete recentfiles menu.
217        if (m_pRecentFilesMenu)
218            delete m_pRecentFilesMenu;
219    
220            // Pseudo-singleton reference shut-down.
221            g_pMainForm = NULL;
222  }  }
223    
224    
# Line 205  void qsamplerMainForm::setup ( qsamplerO Line 228  void qsamplerMainForm::setup ( qsamplerO
228      // We got options?      // We got options?
229      m_pOptions = pOptions;      m_pOptions = pOptions;
230    
231          // Set initial instrument name display mode.      // What style do we create these forms?
232      qsamplerChannel::setInstrumentNames(m_pOptions->bInstrumentNames);          Qt::WFlags wflags = Qt::WStyle_Customize
233                    | Qt::WStyle_Title
234                    | Qt::WStyle_SysMenu
235                    | Qt::WStyle_MinMax
236                    | Qt::WType_TopLevel;
237        if (m_pOptions->bKeepOnTop)
238            wflags |= Qt::WStyle_Tool;
239      // Some child forms are to be created right now.      // Some child forms are to be created right now.
240      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
241        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
242    #ifdef CONFIG_MIDI_INSTRUMENT
243        m_pInstrumentListForm = new qsamplerInstrumentListForm(this, 0, wflags);
244            QObject::connect(m_pInstrumentListForm->InstrumentList,
245                    SIGNAL(instrumentsChanged()),
246                    SLOT(sessionDirty()));
247    #else
248            viewInstrumentsAction->setEnabled(false);
249    #endif
250      // Set message defaults...      // Set message defaults...
251      updateMessagesFont();      updateMessagesFont();
252      updateMessagesLimit();      updateMessagesLimit();
253      updateMessagesCapture();      updateMessagesCapture();
254      // Set the visibility signal.      // Set the visibility signal.
255      QObject::connect(m_pMessages, SIGNAL(visibilityChanged(bool)), this, SLOT(stabilizeForm()));      QObject::connect(m_pMessages,
256                    SIGNAL(visibilityChanged(bool)),
257                    SLOT(stabilizeForm()));
258    
259      // Initial decorations toggle state.      // Initial decorations toggle state.
260      viewMenubarAction->setOn(m_pOptions->bMenubar);      viewMenubarAction->setOn(m_pOptions->bMenubar);
# Line 238  void qsamplerMainForm::setup ( qsamplerO Line 277  void qsamplerMainForm::setup ( qsamplerO
277          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
278          istr >> *this;          istr >> *this;
279      }      }
280      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
281      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
282        m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
283        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
284    
285      // Final startup stabilization...      // Final startup stabilization...
286      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 277  bool qsamplerMainForm::queryClose (void) Line 318  bool qsamplerMainForm::queryClose (void)
318              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
319              ostr << *this;              ostr << *this;
320              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
321              // And the main windows state.              // And the children, and the main windows state,.
322              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
323                            m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
324                            m_pOptions->saveWidgetGeometry(this);
325                            // Close popup widgets.
326                            if (m_pInstrumentListForm)
327                                    m_pInstrumentListForm->close();
328                            if (m_pDeviceForm)
329                                    m_pDeviceForm->close();
330              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
331              stopServer();              stopServer();
332          }          }
# Line 297  void qsamplerMainForm::closeEvent ( QClo Line 345  void qsamplerMainForm::closeEvent ( QClo
345  }  }
346    
347    
348  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
349  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
350  {  {
351      bool bAccept = false;      bool bDecode = false;
352    
353      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
354          QString sUrl;          QString sText;
355          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
356              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
357                files = QStringList::split('\n', sText);
358                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
359                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
360            }
361      }      }
362    
363      pDragEnterEvent->accept(bAccept);      return bDecode;
364    }
365    
366    
367    // Window drag-n-drop event handlers.
368    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
369    {
370            QStringList files;
371            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
372  }  }
373    
374    
375  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
376  {  {
377      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
378          QString sUrl;  
379          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
380              loadSessionFile(QUrl(sUrl).path());          return;
381      }  
382            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
383                    const QString& sPath = *iter;
384                    if (qsamplerChannel::isInstrumentFile(sPath)) {
385                            // Try to create a new channel from instrument file...
386                            qsamplerChannel *pChannel = new qsamplerChannel();
387                            if (pChannel == NULL)
388                                    return;
389                            // Start setting the instrument filename...
390                            pChannel->setInstrument(sPath, 0);
391                            // Before we show it up, may be we'll
392                            // better ask for some initial values?
393                            if (!pChannel->channelSetup(this)) {
394                                    delete pChannel;
395                                    return;
396                            }
397                            // Finally, give it to a new channel strip...
398                            if (!createChannelStrip(pChannel)) {
399                                    delete pChannel;
400                                    return;
401                            }
402                            // Make that an overall update.
403                            m_iDirtyCount++;
404                            stabilizeForm();
405                    }   // Otherwise, load an usual session file (LSCP script)...
406                    else if (closeSession(true))
407                            loadSessionFile(sPath);
408                    // Make it look responsive...:)
409                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
410            }
411  }  }
412    
413    
# Line 328  void qsamplerMainForm::customEvent ( QCu Line 417  void qsamplerMainForm::customEvent ( QCu
417      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
418      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
419          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
420          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
421              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
422              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
423                            if (pChannelStrip)
424                                    channelStripChanged(pChannelStrip);
425                    } else {
426                            appendMessagesColor(tr("Notify event: %1 data: %2")
427                                    .arg(::lscp_event_to_text(pEvent->event()))
428                                    .arg(pEvent->data()), "#996699");
429                    }
430      }      }
431  }  }
432    
# Line 339  void qsamplerMainForm::customEvent ( QCu Line 435  void qsamplerMainForm::customEvent ( QCu
435  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
436  {  {
437      stabilizeForm();      stabilizeForm();
438        
439      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
440  }  }
441    
# Line 353  qsamplerOptions *qsamplerMainForm::optio Line 449  qsamplerOptions *qsamplerMainForm::optio
449      return m_pOptions;      return m_pOptions;
450  }  }
451    
452    
453  // The LSCP client descriptor property.  // The LSCP client descriptor property.
454  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
455  {  {
# Line 360  lscp_client_t *qsamplerMainForm::client Line 457  lscp_client_t *qsamplerMainForm::client
457  }  }
458    
459    
460    // The pseudo-singleton instance accessor.
461    qsamplerMainForm *qsamplerMainForm::getInstance (void)
462    {
463            return g_pMainForm;
464    }
465    
466    
467  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
468  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
469    
# Line 383  bool qsamplerMainForm::newSession (void) Line 487  bool qsamplerMainForm::newSession (void)
487      if (!closeSession(true))      if (!closeSession(true))
488          return false;          return false;
489    
490            // Give us what the server has, right now...
491            updateSession();
492    
493      // Ok increment untitled count.      // Ok increment untitled count.
494      m_iUntitled++;      m_iUntitled++;
495    
# Line 404  bool qsamplerMainForm::openSession (void Line 511  bool qsamplerMainForm::openSession (void
511    
512      // Ask for the filename to open...      // Ask for the filename to open...
513      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
514              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
515              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
516              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
517              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
518      );      );
519    
520      // Have we cancelled?      // Have we cancelled?
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 545  bool qsamplerMainForm::saveSession ( boo
545              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
546          // Prompt the guy...          // Prompt the guy...
547          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
548                  sFilename,                              // Start here.                          sFilename,                              // Start here.
549                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
550                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
551                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
552          );          );
553          // Have we cancelled it?          // Have we cancelled it?
554          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 451  bool qsamplerMainForm::saveSession ( boo Line 558  bool qsamplerMainForm::saveSession ( boo
558              sFilename += ".lscp";              sFilename += ".lscp";
559          // Check if already exists...          // Check if already exists...
560          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
561              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
562                                    QSAMPLER_TITLE ": " + tr("Warning"),
563                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
564                     "\"%1\"\n\n"                     "\"%1\"\n\n"
565                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 473  bool qsamplerMainForm::closeSession ( bo Line 581  bool qsamplerMainForm::closeSession ( bo
581    
582      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
583      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
584          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
585                            QSAMPLER_TITLE ": " + tr("Warning"),
586              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
587              "\"%1\"\n\n"              "\"%1\"\n\n"
588              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 531  bool qsamplerMainForm::loadSessionFile ( Line 640  bool qsamplerMainForm::loadSessionFile (
640      QTextStream ts(&file);      QTextStream ts(&file);
641      while (!ts.atEnd()) {      while (!ts.atEnd()) {
642          // Read the line.          // Read the line.
643          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
644          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
645          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
646              appendMessagesColor(sCommand, "#996633");              appendMessagesColor(sCommand, "#996633");
# Line 550  bool qsamplerMainForm::loadSessionFile ( Line 659  bool qsamplerMainForm::loadSessionFile (
659      // Ok. we've read it.      // Ok. we've read it.
660      file.close();      file.close();
661    
662      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
663      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
664    
665      // Now we'll try to create the whole GUI session.          // Have we any errors?
666      int *piChannelIDs = ::lscp_list_channels(m_pClient);          if (iErrors > 0)
667      if (piChannelIDs == NULL) {                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
         appendMessagesClient("lscp_list_channels");  
         appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));  
     }  
       
     // Try to (re)create each channel.  
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {  
         createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));  
         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
668    
669      // Save as default session directory.      // Save as default session directory.
670      if (m_pOptions)      if (m_pOptions)
671          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
672      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
673      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
674      // Stabilize form...      // Stabilize form...
675      m_sFilename = sFilename;      m_sFilename = sFilename;
676      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
677      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
678        
679      // Make that an overall update.      // Make that an overall update.
     m_iChangeCount++;  
680      stabilizeForm();      stabilizeForm();
681      return true;      return true;
682  }  }
# Line 597  bool qsamplerMainForm::saveSessionFile ( Line 693  bool qsamplerMainForm::saveSessionFile (
693      }      }
694    
695      // Write the file.      // Write the file.
696      int iErrors = 0;      int  iErrors = 0;
697      QTextStream ts(&file);      QTextStream ts(&file);
698      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
699      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 608  bool qsamplerMainForm::saveSessionFile ( Line 704  bool qsamplerMainForm::saveSessionFile (
704      ts << "# " << tr("File")      ts << "# " << tr("File")
705         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
706      ts << "# " << tr("Date")      ts << "# " << tr("Date")
707         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
708         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
709      ts << "#"  << endl;      ts << "#"  << endl;
710      ts << endl;      ts << endl;
711            // It is assumed that this new kind of device+session file
712            // will be loaded from a complete
713            int *piDeviceIDs;
714            int  iDevice;
715            ts << "RESET" << endl;
716            // Audio device mapping.
717            QMap<int, int> audioDeviceMap;
718            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
719            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
720                    ts << endl;
721                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
722                    // Audio device specification...
723                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
724                            << " " << tr("Device") << " " << iDevice << endl;
725                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
726                    qsamplerDeviceParamMap::ConstIterator deviceParam;
727                    for (deviceParam = device.params().begin();
728                                    deviceParam != device.params().end();
729                                            ++deviceParam) {
730                            const qsamplerDeviceParam& param = deviceParam.data();
731                            if (param.value.isEmpty()) ts << "# ";
732                            ts << " " << deviceParam.key() << "='" << param.value << "'";
733                    }
734                    ts << endl;
735                    // Audio channel parameters...
736                    int iPort = 0;
737                    for (qsamplerDevicePort *pPort = device.ports().first();
738                                    pPort;
739                                            pPort = device.ports().next(), ++iPort) {
740                            qsamplerDeviceParamMap::ConstIterator portParam;
741                            for (portParam = pPort->params().begin();
742                                            portParam != pPort->params().end();
743                                                    ++portParam) {
744                                    const qsamplerDeviceParam& param = portParam.data();
745                                    if (param.fix || param.value.isEmpty()) ts << "# ";
746                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
747                                            << " " << iPort << " " << portParam.key()
748                                            << "='" << param.value << "'" << endl;
749                            }
750                    }
751                    // Audio device index/id mapping.
752                    audioDeviceMap[device.deviceID()] = iDevice;
753            // Try to keep it snappy :)
754            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
755            }
756            // MIDI device mapping.
757            QMap<int, int> midiDeviceMap;
758            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
759            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
760                    ts << endl;
761                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
762                    // MIDI device specification...
763                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
764                            << " " << tr("Device") << " " << iDevice << endl;
765                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
766                    qsamplerDeviceParamMap::ConstIterator deviceParam;
767                    for (deviceParam = device.params().begin();
768                                    deviceParam != device.params().end();
769                                            ++deviceParam) {
770                            const qsamplerDeviceParam& param = deviceParam.data();
771                            if (param.value.isEmpty()) ts << "# ";
772                            ts << " " << deviceParam.key() << "='" << param.value << "'";
773                    }
774                    ts << endl;
775                    // MIDI port parameters...
776                    int iPort = 0;
777                    for (qsamplerDevicePort *pPort = device.ports().first();
778                                    pPort;
779                                            pPort = device.ports().next(), ++iPort) {
780                            qsamplerDeviceParamMap::ConstIterator portParam;
781                            for (portParam = pPort->params().begin();
782                                            portParam != pPort->params().end();
783                                                    ++portParam) {
784                                    const qsamplerDeviceParam& param = portParam.data();
785                                    if (param.fix || param.value.isEmpty()) ts << "# ";
786                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
787                                       << " " << iPort << " " << portParam.key()
788                                       << "='" << param.value << "'" << endl;
789                            }
790                    }
791                    // MIDI device index/id mapping.
792                    midiDeviceMap[device.deviceID()] = iDevice;
793            // Try to keep it snappy :)
794            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
795            }
796            ts << endl;
797            // Sampler channel mapping.
798      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
799      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
800          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
801          if (pChannelStrip) {          if (pChannelStrip) {
802              qsamplerChannel *pChannel = pChannelStrip->channel();              qsamplerChannel *pChannel = pChannelStrip->channel();
803              if (pChannel) {              if (pChannel) {
804                  int iChannelID = pChannel->channelID();                  ts << "# " << tr("Channel") << " " << iChannel << endl;
                 ts << "# " << pChannelStrip->caption() << endl;  
805                  ts << "ADD CHANNEL" << endl;                  ts << "ADD CHANNEL" << endl;
806                  ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                                  if (audioDeviceMap.isEmpty()) {
807                  ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
808                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                                  << " " << pChannel->audioDriver() << endl;
809                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  } else {
810                                            ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
811                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
812                                    }
813                                    if (midiDeviceMap.isEmpty()) {
814                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
815                                                    << " " << pChannel->midiDriver() << endl;
816                                    } else {
817                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
818                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
819                                    }
820                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
821                                            << " " << pChannel->midiPort() << endl;
822                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
823                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
824                      ts << "ALL";                      ts << "ALL";
825                  else                  else
826                      ts << pChannel->midiChannel();                      ts << pChannel->midiChannel();
827                  ts << endl;                  ts << endl;
828                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
829                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannel << endl;
830                  ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;
831                                    for (audioRoute = pChannel->audioRouting().begin();
832                                                    audioRoute != pChannel->audioRouting().end();
833                                                            ++audioRoute) {
834                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
835                                                    << " " << audioRoute.key()
836                                                    << " " << audioRoute.data() << endl;
837                                    }
838                    ts << "SET CHANNEL VOLUME " << iChannel << " " << pChannel->volume() << endl;
839                                    if (pChannel->channelMute())
840                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
841                                    if (pChannel->channelSolo())
842                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
843                  ts << endl;                  ts << endl;
844              }              }
845          }          }
# Line 640  bool qsamplerMainForm::saveSessionFile ( Line 847  bool qsamplerMainForm::saveSessionFile (
847          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
848      }      }
849    
850    #ifdef CONFIG_MIDI_INSTRUMENT
851            // MIDI instrument mapping...
852            lscp_midi_instrument_t *pInstrs = ::lscp_list_midi_instruments(m_pClient);
853            if (pInstrs)
854            ts << "# " << tr("MIDI instrument mapping") << endl;
855            for (int iInstr = 0; pInstrs && pInstrs[iInstr].program >= 0; iInstr++) {
856                    lscp_midi_instrument_info_t *pInstrInfo
857                            = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
858                    if (pInstrInfo) {
859                            ts << "MAP MIDI_INSTRUMENT "
860                                    << pInstrs[iInstr].bank_msb    << " "
861                                    << pInstrs[iInstr].bank_lsb    << " "
862                                    << pInstrs[iInstr].program     << " "
863                                    << pInstrInfo->engine_name     << " '"
864                                    << pInstrInfo->instrument_file << "' "
865                                    << pInstrInfo->instrument_nr   << " "
866                                    << pInstrInfo->volume          << " ";
867                            switch (pInstrInfo->load_mode) {
868                                    case LSCP_LOAD_PERSISTENT:
869                                            ts << "PERSISTENT";
870                                            break;
871                                    case LSCP_LOAD_ON_DEMAND_HOLD:
872                                            ts << "ON_DEMAND_HOLD";
873                                            break;
874                                    case LSCP_LOAD_ON_DEMAND:
875                                    case LSCP_LOAD_DEFAULT:
876                                    default:
877                                            ts << "ON_DEMAND";
878                                            break;
879                            }
880                            if (pInstrInfo->name)
881                                    ts << " '" << pInstrInfo->name << "'";
882                            ts << endl;
883                    }
884                    ts << endl;
885            // Try to keep it snappy :)
886            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
887            }
888    #endif //  CONFIG_MIDI_INSTRUMENT
889    
890      // Ok. we've wrote it.      // Ok. we've wrote it.
891      file.close();      file.close();
892    
# Line 661  bool qsamplerMainForm::saveSessionFile ( Line 908  bool qsamplerMainForm::saveSessionFile (
908  }  }
909    
910    
911    // Session change receiver slot.
912    void qsamplerMainForm::sessionDirty (void)
913    {
914        // Just mark the dirty form.
915        m_iDirtyCount++;
916        // and update the form status...
917        stabilizeForm();
918    }
919    
920    
921  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
922  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
923    
# Line 714  void qsamplerMainForm::fileReset (void) Line 971  void qsamplerMainForm::fileReset (void)
971          return;          return;
972    
973      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
974      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
975                    QSAMPLER_TITLE ": " + tr("Warning"),
976          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
977             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
978             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
979             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
980             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
981          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
982          return;          return;
# Line 732  void qsamplerMainForm::fileReset (void) Line 990  void qsamplerMainForm::fileReset (void)
990    
991      // Log this.      // Log this.
992      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
993    
994            // Make it a new session...
995            newSession();
996  }  }
997    
998    
# Line 740  void qsamplerMainForm::fileRestart (void Line 1001  void qsamplerMainForm::fileRestart (void
1001  {  {
1002      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1003          return;          return;
1004            
1005      bool bRestart = true;      bool bRestart = true;
1006        
1007      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1008      // (if we're currently up and running)      // (if we're currently up and running)
1009      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1010          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1011                            QSAMPLER_TITLE ": " + tr("Warning"),
1012              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1013                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1014                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1015                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1016                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1017              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1018      }      }
# Line 783  void qsamplerMainForm::editAddChannel (v Line 1045  void qsamplerMainForm::editAddChannel (v
1045          return;          return;
1046    
1047      // Just create the channel instance...      // Just create the channel instance...
1048      qsamplerChannel *pChannel = new qsamplerChannel(this);      qsamplerChannel *pChannel = new qsamplerChannel();
1049      if (pChannel == NULL)      if (pChannel == NULL)
1050          return;          return;
1051    
# Line 793  void qsamplerMainForm::editAddChannel (v Line 1055  void qsamplerMainForm::editAddChannel (v
1055          delete pChannel;          delete pChannel;
1056          return;          return;
1057      }      }
1058        
1059      // And give it to the strip (will own the channel instance, if successful).      // And give it to the strip (will own the channel instance, if successful).
1060      if (!createChannelStrip(pChannel)) {      if (!createChannelStrip(pChannel)) {
1061          delete pChannel;          delete pChannel;
# Line 802  void qsamplerMainForm::editAddChannel (v Line 1064  void qsamplerMainForm::editAddChannel (v
1064    
1065      // Make that an overall update.      // Make that an overall update.
1066      m_iDirtyCount++;      m_iDirtyCount++;
     m_iChangeCount++;  
1067      stabilizeForm();      stabilizeForm();
1068  }  }
1069    
# Line 816  void qsamplerMainForm::editRemoveChannel Line 1077  void qsamplerMainForm::editRemoveChannel
1077      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1078      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1079          return;          return;
1080            
1081      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
1082      if (pChannel == NULL)      if (pChannel == NULL)
1083          return;          return;
1084    
1085      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1086      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1087          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1088                            QSAMPLER_TITLE ": " + tr("Warning"),
1089              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1090                 "%1\n\n"                 "%1\n\n"
1091                 "Are you sure?")                 "Are you sure?")
# Line 838  void qsamplerMainForm::editRemoveChannel Line 1100  void qsamplerMainForm::editRemoveChannel
1100    
1101      // Just delete the channel strip.      // Just delete the channel strip.
1102      delete pChannelStrip;      delete pChannelStrip;
1103        
1104      // Do we auto-arrange?      // Do we auto-arrange?
1105      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1106          channelsArrange();          channelsArrange();
# Line 874  void qsamplerMainForm::editResetChannel Line 1136  void qsamplerMainForm::editResetChannel
1136      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1137          return;          return;
1138    
1139      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1140      if (pChannel == NULL)      pChannelStrip->channelReset();
1141          return;  }
1142    
     // Reset the existing sampler channel.  
     pChannel->resetChannel();  
1143    
1144      // And force a deferred update.  // Reset all sampler channels.
1145      m_iChangeCount++;  void qsamplerMainForm::editResetAllChannels (void)
1146    {
1147            if (m_pClient == NULL)
1148                    return;
1149    
1150            // Invoque the channel strip procedure,
1151            // for all channels out there...
1152            m_pWorkspace->setUpdatesEnabled(false);
1153            QWidgetList wlist = m_pWorkspace->windowList();
1154            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1155                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1156                    if (pChannelStrip)
1157                            pChannelStrip->channelReset();
1158            }
1159            m_pWorkspace->setUpdatesEnabled(true);
1160  }  }
1161    
1162    
# Line 934  void qsamplerMainForm::viewMessages ( bo Line 1208  void qsamplerMainForm::viewMessages ( bo
1208  }  }
1209    
1210    
1211    // Show/hide the MIDI instrument list-view form.
1212    void qsamplerMainForm::viewInstruments (void)
1213    {
1214            if (m_pOptions == NULL)
1215                    return;
1216    
1217            if (m_pInstrumentListForm) {
1218                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1219                    if (m_pInstrumentListForm->isVisible()) {
1220                            m_pInstrumentListForm->hide();
1221                    } else {
1222                            m_pInstrumentListForm->show();
1223                            m_pInstrumentListForm->raise();
1224                            m_pInstrumentListForm->setActiveWindow();
1225                    }
1226            }
1227    }
1228    
1229    
1230    // Show/hide the device configurator form.
1231    void qsamplerMainForm::viewDevices (void)
1232    {
1233            if (m_pOptions == NULL)
1234                    return;
1235    
1236            if (m_pDeviceForm) {
1237                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1238                    if (m_pDeviceForm->isVisible()) {
1239                            m_pDeviceForm->hide();
1240                    } else {
1241                            m_pDeviceForm->show();
1242                            m_pDeviceForm->raise();
1243                            m_pDeviceForm->setActiveWindow();
1244                    }
1245            }
1246    }
1247    
1248    
1249  // Show options dialog.  // Show options dialog.
1250  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1251  {  {
# Line 958  void qsamplerMainForm::viewOptions (void Line 1270  void qsamplerMainForm::viewOptions (void
1270          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1271          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1272          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1273            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1274          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1275          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1276          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1277          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
         int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;  
1278          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1279            int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1280          // Load the current setup settings.          // Load the current setup settings.
1281          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
1282          // Show the setup dialog...          // Show the setup dialog...
1283          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1284              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1285              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1286                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1287                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1288                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1289                    QMessageBox::information(this,
1290                                            QSAMPLER_TITLE ": " + tr("Information"),
1291                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1292                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1293                  updateMessagesCapture();                  updateMessagesCapture();
1294              }              }
1295              // Check wheather something immediate has changed.              // Check wheather something immediate has changed.
             if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||  
                 (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))  
                 qsamplerChannel::setInstrumentNames(m_pOptions->bInstrumentNames);  
1296              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1297                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1298                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1299                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1300                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1301                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1302                    updateInstrumentNames();
1303              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1304                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1305                  updateDisplayEffect();                  updateDisplayEffect();
# Line 1045  void qsamplerMainForm::channelsArrange ( Line 1361  void qsamplerMainForm::channelsArrange (
1361          y += iHeight;          y += iHeight;
1362      }      }
1363      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1364        
1365      stabilizeForm();      stabilizeForm();
1366  }  }
1367    
# Line 1094  void qsamplerMainForm::helpAbout (void) Line 1410  void qsamplerMainForm::helpAbout (void)
1410      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1411      sText += "</font></small><br />";      sText += "</font></small><br />";
1412  #endif  #endif
1413    #ifndef CONFIG_INSTRUMENT_NAME
1414        sText += "<small><font color=\"red\">";
1415        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1416        sText += "</font></small><br />";
1417    #endif
1418    #ifndef CONFIG_MUTE_SOLO
1419        sText += "<small><font color=\"red\">";
1420        sText += tr("Sampler channel Mute/Solo support disabled.");
1421        sText += "</font></small><br />";
1422    #endif
1423    #ifndef CONFIG_MIDI_INSTRUMENT
1424        sText += "<small><font color=\"red\">";
1425        sText += tr("MIDI instrument mapping support disabled.");
1426        sText += "</font></small><br />";
1427    #endif
1428      sText += "<br />\n";      sText += "<br />\n";
1429      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1430      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1431      sText += " ";      sText += " ";
1432      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1433    #ifdef CONFIG_LIBGIG
1434        sText += ", ";
1435        sText += gig::libraryName().c_str();
1436        sText += " ";
1437        sText += gig::libraryVersion().c_str();
1438    #endif
1439      sText += "<br />\n";      sText += "<br />\n";
1440      sText += "<br />\n";      sText += "<br />\n";
1441      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 1121  void qsamplerMainForm::helpAbout (void) Line 1458  void qsamplerMainForm::helpAbout (void)
1458  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1459  {  {
1460      // Update the main application caption...      // Update the main application caption...
1461      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1462      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1463          sSessioName += '*';          sSessionName += " *";
1464      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1465    
1466      // Update the main menu state...      // Update the main menu state...
1467      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1140  void qsamplerMainForm::stabilizeForm (vo Line 1477  void qsamplerMainForm::stabilizeForm (vo
1477      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1478      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1479      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1480      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1481      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1482    #ifdef CONFIG_MIDI_INSTRUMENT
1483            viewInstrumentsAction->setOn(m_pInstrumentListForm
1484                    && m_pInstrumentListForm->isVisible());
1485            viewInstrumentsAction->setEnabled(bHasClient);
1486    #endif
1487            viewDevicesAction->setOn(m_pDeviceForm
1488                    && m_pDeviceForm->isVisible());
1489        viewDevicesAction->setEnabled(bHasClient);
1490        channelsArrangeAction->setEnabled(bHasChannel);
1491    
1492      // Client/Server status...      // Client/Server status...
1493      if (bHasClient) {      if (bHasClient) {
1494          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1495          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));
1496      } else {      } else {
1497          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1498          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1499      }      }
1500      // Channel status...      // Channel status...
1501      if (bHasChannel)      if (bHasChannel)
1502          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1503      else      else
1504          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1505      // Session status...      // Session status...
1506      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1507          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1508      else      else
1509          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1510    
1511      // Recent files menu.      // Recent files menu.
1512      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1172  void qsamplerMainForm::stabilizeForm (vo Line 1518  void qsamplerMainForm::stabilizeForm (vo
1518    
1519    
1520  // Channel change receiver slot.  // Channel change receiver slot.
1521  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1522  {  {
1523      // Flag that we're update those channel strips.          // Add this strip to the changed list...
1524      m_iChangeCount++;          if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1525                    m_changedStrips.append(pChannelStrip);
1526                    pChannelStrip->resetErrorCount();
1527            }
1528    
1529      // Just mark the dirty form.      // Just mark the dirty form.
1530      m_iDirtyCount++;      m_iDirtyCount++;
1531      // and update the form status...      // and update the form status...
# Line 1183  void qsamplerMainForm::channelStripChang Line 1533  void qsamplerMainForm::channelStripChang
1533  }  }
1534    
1535    
1536    // Grab and restore current sampler channels session.
1537    void qsamplerMainForm::updateSession (void)
1538    {
1539            // Retrieve the current channel list.
1540            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1541            if (piChannelIDs == NULL) {
1542                    if (::lscp_client_get_errno(m_pClient)) {
1543                            appendMessagesClient("lscp_list_channels");
1544                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1545                    }
1546                    return;
1547            }
1548    
1549            // Try to (re)create each channel.
1550            m_pWorkspace->setUpdatesEnabled(false);
1551            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1552                    // Check if theres already a channel strip for this one...
1553                    if (!channelStrip(piChannelIDs[iChannel]))
1554                            createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1555                    // Make it visibly responsive...
1556                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1557            }
1558            m_pWorkspace->setUpdatesEnabled(true);
1559            
1560            // Remember to refresh devices and instruments...
1561            if (m_pInstrumentListForm)
1562                m_pInstrumentListForm->refreshInstruments();
1563            if (m_pDeviceForm)
1564                m_pDeviceForm->refreshDevices();
1565    }
1566    
1567    
1568  // Update the recent files list and menu.  // Update the recent files list and menu.
1569  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1570  {  {
# Line 1227  void qsamplerMainForm::updateRecentFiles Line 1609  void qsamplerMainForm::updateRecentFiles
1609  }  }
1610    
1611    
1612    // Force update of the channels instrument names mode.
1613    void qsamplerMainForm::updateInstrumentNames (void)
1614    {
1615        // Full channel list update...
1616        QWidgetList wlist = m_pWorkspace->windowList();
1617        if (wlist.isEmpty())
1618            return;
1619    
1620        m_pWorkspace->setUpdatesEnabled(false);
1621        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1622            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1623            if (pChannelStrip)
1624                pChannelStrip->updateInstrumentName(true);
1625        }
1626        m_pWorkspace->setUpdatesEnabled(true);
1627    }
1628    
1629    
1630  // Force update of the channels display font.  // Force update of the channels display font.
1631  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1632  {  {
# Line 1332  void qsamplerMainForm::appendMessagesErr Line 1732  void qsamplerMainForm::appendMessagesErr
1732    
1733      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1734    
1735      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));      QMessageBox::critical(this,
1736                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1737  }  }
1738    
1739    
# Line 1372  void qsamplerMainForm::updateMessagesLim Line 1773  void qsamplerMainForm::updateMessagesLim
1773          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1774              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1775          else          else
1776              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1777      }      }
1778  }  }
1779    
# Line 1404  qsamplerChannelStrip *qsamplerMainForm:: Line 1805  qsamplerChannelStrip *qsamplerMainForm::
1805          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1806          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1807              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1808          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1809              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1810                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1811                            }
1812          }          }
1813      }      }
1814    
# Line 1414  qsamplerChannelStrip *qsamplerMainForm:: Line 1817  qsamplerChannelStrip *qsamplerMainForm::
1817      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1818      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1819          return NULL;          return NULL;
1820            
1821      // Actual channel strip setup...      // Actual channel strip setup...
1822      pChannelStrip->setup(pChannel);      pChannelStrip->setup(pChannel);
1823      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
# Line 1439  qsamplerChannelStrip *qsamplerMainForm:: Line 1842  qsamplerChannelStrip *qsamplerMainForm::
1842          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1843          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1844      }      }
1845        
1846            // This is pretty new, so we'll watch for it closely.
1847            channelStripChanged(pChannelStrip);
1848    
1849      // Return our successful reference...      // Return our successful reference...
1850      return pChannelStrip;      return pChannelStrip;
1851  }  }
# Line 1457  qsamplerChannelStrip *qsamplerMainForm:: Line 1863  qsamplerChannelStrip *qsamplerMainForm::
1863  {  {
1864      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1865      if (wlist.isEmpty())      if (wlist.isEmpty())
1866          return 0;          return NULL;
1867    
1868      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1869  }  }
1870    
1871    
1872    // Retrieve a channel strip by sampler channel id.
1873    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1874    {
1875            QWidgetList wlist = m_pWorkspace->windowList();
1876            if (wlist.isEmpty())
1877                    return NULL;
1878    
1879            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1880                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1881                    if (pChannelStrip) {
1882                            qsamplerChannel *pChannel = pChannelStrip->channel();
1883                            if (pChannel && pChannel->channelID() == iChannelID)
1884                                    return pChannelStrip;
1885                    }
1886            }
1887    
1888            // Not found.
1889            return NULL;
1890    }
1891    
1892    
1893  // Construct the windows menu.  // Construct the windows menu.
1894  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1895  {  {
# Line 1529  void qsamplerMainForm::timerSlot (void) Line 1956  void qsamplerMainForm::timerSlot (void)
1956              }              }
1957          }          }
1958      }      }
1959        
1960          // Refresh each channel usage, on each period...          if (m_pClient) {
1961      if (m_pClient && (m_iChangeCount > 0 || m_pOptions->bAutoRefresh)) {                  // Update the channel information for each pending strip...
1962          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
1963          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
1964              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
1965              m_iChangeCount = 0;                                  // If successfull, remove from pending list...
1966              QWidgetList wlist = m_pWorkspace->windowList();                                  if (pChannelStrip->updateChannelInfo())
1967              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                          m_changedStrips.remove(pChannelStrip);
1968                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                          }
1969                  if (pChannelStrip && pChannelStrip->isVisible()) {                  }
1970                      // If we can't make it clean, try next time.                  // Refresh each channel usage, on each period...
1971                      if (!pChannelStrip->updateChannelUsage())                  if (m_pOptions->bAutoRefresh) {
1972                          m_iChangeCount++;                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
1973                  }                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
1974              }                                  m_iTimerSlot = 0;
1975          }                                  // Update the channel stream usage for each strip...
1976      }                                  QWidgetList wlist = m_pWorkspace->windowList();
1977                                    for (int iChannel = 0;
1978                                                    iChannel < (int) wlist.count(); iChannel++) {
1979                                            qsamplerChannelStrip *pChannelStrip
1980                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
1981                                            if (pChannelStrip && pChannelStrip->isVisible())
1982                                                    pChannelStrip->updateChannelUsage();
1983                                    }
1984                            }
1985                    }
1986            }
1987    
1988      // Register the next timer slot.      // Register the next timer slot.
1989      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1568  void qsamplerMainForm::startServer (void Line 2005  void qsamplerMainForm::startServer (void
2005    
2006      // Is the server process instance still here?      // Is the server process instance still here?
2007      if (m_pServer) {      if (m_pServer) {
2008          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2009                            QSAMPLER_TITLE ": " + tr("Warning"),
2010              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2011                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2012              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1727  bool qsamplerMainForm::startClient (void Line 2165  bool qsamplerMainForm::startClient (void
2165      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2166      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)));
2167    
2168            // Subscribe to channel info change notifications...
2169            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2170                    appendMessagesClient("lscp_client_subscribe");
2171    
2172      // We may stop scheduling around.      // We may stop scheduling around.
2173      stopSchedule();      stopSchedule();
2174    
# Line 1736  bool qsamplerMainForm::startClient (void Line 2178  bool qsamplerMainForm::startClient (void
2178      // Log success here.      // Log success here.
2179      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2180    
2181            // Hard-notify instrumnet and device configuration forms,
2182            // if visible, that we're ready...
2183            if (m_pInstrumentListForm)
2184                m_pInstrumentListForm->refreshInstruments();
2185            if (m_pDeviceForm)
2186                m_pDeviceForm->refreshDevices();
2187    
2188      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2189      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2190          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1770  void qsamplerMainForm::stopClient (void) Line 2219  void qsamplerMainForm::stopClient (void)
2219      // channels from the back-end server.      // channels from the back-end server.
2220      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2221      closeSession(false);      closeSession(false);
2222        
2223      // Close us as a client...      // Close us as a client...
2224      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2225        ::lscp_client_destroy(m_pClient);
2226      m_pClient = NULL;      m_pClient = NULL;
2227    
2228            // Hard-notify instrumnet and device configuration forms,
2229            // if visible, that we're running out...
2230            if (m_pInstrumentListForm)
2231                m_pInstrumentListForm->refreshInstruments();
2232            if (m_pDeviceForm)
2233                m_pDeviceForm->refreshDevices();
2234    
2235      // Log final here.      // Log final here.
2236      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2237    

Legend:
Removed from v.341  
changed lines
  Added in v.961

  ViewVC Help
Powered by ViewVC