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

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

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

revision 162 by capela, Tue Jun 29 22:17:59 2004 UTC revision 1033 by capela, Mon Jan 15 11:27:22 2007 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
# 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    #include "qsamplerInstrumentList.h"
45    
46    #include "qsamplerInstrumentListForm.h"
47    #include "qsamplerDeviceForm.h"
48  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
49    
50  #include "config.h"  #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 93  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;
128    
129      m_pServer = NULL;      m_pServer = NULL;
# Line 114  void qsamplerMainForm::init (void) Line 134  void qsamplerMainForm::init (void)
134    
135      m_iTimerSlot = 0;      m_iTimerSlot = 0;
136    
137    #ifdef HAVE_SIGNAL_H
138            // Set to ignore any fatal "Broken pipe" signals.
139            ::signal(SIGPIPE, SIG_IGN);
140    #endif
141    
142      // Make it an MDI workspace.      // Make it an MDI workspace.
143      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
144      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
145      // Set the activation connection.          // Set the activation connection.
146      QObject::connect(m_pWorkspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(stabilizeForm()));          QObject::connect(m_pWorkspace,
147                    SIGNAL(windowActivated(QWidget *)),
148                    SLOT(stabilizeForm()));
149      // Make it shine :-)      // Make it shine :-)
150      setCentralWidget(m_pWorkspace);      setCentralWidget(m_pWorkspace);
151    
# Line 128  void qsamplerMainForm::init (void) Line 155  void qsamplerMainForm::init (void)
155      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
156      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
157      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
158      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
159      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
160      // Server address.      // Server address.
161      pLabel = new QLabel(this);      pLabel = new QLabel(this);
162      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
163      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
164      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
165      // Channel title.      // Channel title.
166      pLabel = new QLabel(this);      pLabel = new QLabel(this);
167      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
168      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
169      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
170      // Session modification status.      // Session modification status.
171      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
172      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
173      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
174      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
175      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
176    
177      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 163  void qsamplerMainForm::destroy (void) Line 190  void qsamplerMainForm::destroy (void)
190  {  {
191      // Do final processing anyway.      // Do final processing anyway.
192      processServerExit();      processServerExit();
193        
194      // Delete recentfiles menu.  #if defined(WIN32)
195      if (m_pRecentFilesMenu)      WSACleanup();
196          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];  
197    
198      // Finally drop any widgets around...      // Finally drop any widgets around...
199        if (m_pDeviceForm)
200            delete m_pDeviceForm;
201        if (m_pInstrumentListForm)
202            delete m_pInstrumentListForm;
203      if (m_pMessages)      if (m_pMessages)
204          delete m_pMessages;          delete m_pMessages;
205      if (m_pWorkspace)      if (m_pWorkspace)
206          delete m_pWorkspace;          delete m_pWorkspace;
207    
208  #if defined(WIN32)      // Delete status item labels one by one.
209      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
210  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
211        if (m_statusItem[QSAMPLER_STATUS_SERVER])
212            delete m_statusItem[QSAMPLER_STATUS_SERVER];
213        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
214            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
215        if (m_statusItem[QSAMPLER_STATUS_SESSION])
216            delete m_statusItem[QSAMPLER_STATUS_SESSION];
217    
218        // Delete recentfiles menu.
219        if (m_pRecentFilesMenu)
220            delete m_pRecentFilesMenu;
221    
222            // Pseudo-singleton reference shut-down.
223            g_pMainForm = NULL;
224  }  }
225    
226    
# Line 195  void qsamplerMainForm::setup ( qsamplerO Line 230  void qsamplerMainForm::setup ( qsamplerO
230      // We got options?      // We got options?
231      m_pOptions = pOptions;      m_pOptions = pOptions;
232    
233        // What style do we create these forms?
234            Qt::WFlags wflags = Qt::WStyle_Customize
235                    | Qt::WStyle_NormalBorder
236                    | Qt::WStyle_Title
237                    | Qt::WStyle_SysMenu
238                    | Qt::WStyle_MinMax
239                    | Qt::WType_TopLevel;
240        if (m_pOptions->bKeepOnTop)
241            wflags |= Qt::WStyle_Tool;
242      // Some child forms are to be created right now.      // Some child forms are to be created right now.
243      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
244        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
245    #ifdef CONFIG_MIDI_INSTRUMENT
246        m_pInstrumentListForm = new qsamplerInstrumentListForm(this, 0, wflags);
247            QObject::connect(m_pInstrumentListForm->InstrumentList,
248                    SIGNAL(instrumentsChanged()),
249                    SLOT(sessionDirty()));
250    #else
251            viewInstrumentsAction->setEnabled(false);
252    #endif
253      // Set message defaults...      // Set message defaults...
254      updateMessagesFont();      updateMessagesFont();
255      updateMessagesLimit();      updateMessagesLimit();
256      updateMessagesCapture();      updateMessagesCapture();
257      // Set the visibility signal.      // Set the visibility signal.
258      QObject::connect(m_pMessages, SIGNAL(visibilityChanged(bool)), this, SLOT(stabilizeForm()));          QObject::connect(m_pMessages,
259                    SIGNAL(visibilityChanged(bool)),
260                    SLOT(stabilizeForm()));
261    
262      // Initial decorations toggle state.      // Initial decorations toggle state.
263      viewMenubarAction->setOn(m_pOptions->bMenubar);      viewMenubarAction->setOn(m_pOptions->bMenubar);
# Line 225  void qsamplerMainForm::setup ( qsamplerO Line 280  void qsamplerMainForm::setup ( qsamplerO
280          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
281          istr >> *this;          istr >> *this;
282      }      }
283      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
284      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
285        m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
286        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
287    
288      // Final startup stabilization...      // Final startup stabilization...
289      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 264  bool qsamplerMainForm::queryClose (void) Line 321  bool qsamplerMainForm::queryClose (void)
321              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
322              ostr << *this;              ostr << *this;
323              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
324              // And the main windows state.              // And the children, and the main windows state,.
325              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
326                            m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
327                            m_pOptions->saveWidgetGeometry(this);
328                            // Close popup widgets.
329                            if (m_pInstrumentListForm)
330                                    m_pInstrumentListForm->close();
331                            if (m_pDeviceForm)
332                                    m_pDeviceForm->close();
333              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
334              stopServer();              stopServer();
335          }          }
# Line 284  void qsamplerMainForm::closeEvent ( QClo Line 348  void qsamplerMainForm::closeEvent ( QClo
348  }  }
349    
350    
351  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
352  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
353  {  {
354      bool bAccept = false;      bool bDecode = false;
355    
356      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
357          QString sUrl;          QString sText;
358          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
359              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
360                files = QStringList::split('\n', sText);
361                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
362                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
363            }
364      }      }
365    
366      pDragEnterEvent->accept(bAccept);      return bDecode;
367    }
368    
369    
370    // Window drag-n-drop event handlers.
371    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
372    {
373            QStringList files;
374            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
375  }  }
376    
377    
378  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
379  {  {
380      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
381          QString sUrl;  
382          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
383              loadSessionFile(QUrl(sUrl).path());          return;
384      }  
385            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
386                    const QString& sPath = *iter;
387                    if (qsamplerChannel::isInstrumentFile(sPath)) {
388                            // Try to create a new channel from instrument file...
389                            qsamplerChannel *pChannel = new qsamplerChannel();
390                            if (pChannel == NULL)
391                                    return;
392                            // Start setting the instrument filename...
393                            pChannel->setInstrument(sPath, 0);
394                            // Before we show it up, may be we'll
395                            // better ask for some initial values?
396                            if (!pChannel->channelSetup(this)) {
397                                    delete pChannel;
398                                    return;
399                            }
400                            // Finally, give it to a new channel strip...
401                            if (!createChannelStrip(pChannel)) {
402                                    delete pChannel;
403                                    return;
404                            }
405                            // Make that an overall update.
406                            m_iDirtyCount++;
407                            stabilizeForm();
408                    }   // Otherwise, load an usual session file (LSCP script)...
409                    else if (closeSession(true)) {
410                            loadSessionFile(sPath);
411                            break;
412                    }
413                    // Make it look responsive...:)
414                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
415            }
416  }  }
417    
418    
# Line 315  void qsamplerMainForm::customEvent ( QCu Line 422  void qsamplerMainForm::customEvent ( QCu
422      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
423      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
424          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
425          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
426              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
427              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
428                            if (pChannelStrip)
429                                    channelStripChanged(pChannelStrip);
430                    } else {
431                            appendMessagesColor(tr("Notify event: %1 data: %2")
432                                    .arg(::lscp_event_to_text(pEvent->event()))
433                                    .arg(pEvent->data()), "#996699");
434                    }
435      }      }
436  }  }
437    
# Line 326  void qsamplerMainForm::customEvent ( QCu Line 440  void qsamplerMainForm::customEvent ( QCu
440  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
441  {  {
442      stabilizeForm();      stabilizeForm();
443        
444      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
445  }  }
446    
# Line 340  qsamplerOptions *qsamplerMainForm::optio Line 454  qsamplerOptions *qsamplerMainForm::optio
454      return m_pOptions;      return m_pOptions;
455  }  }
456    
457    
458  // The LSCP client descriptor property.  // The LSCP client descriptor property.
459  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
460  {  {
# Line 347  lscp_client_t *qsamplerMainForm::client Line 462  lscp_client_t *qsamplerMainForm::client
462  }  }
463    
464    
465    // The pseudo-singleton instance accessor.
466    qsamplerMainForm *qsamplerMainForm::getInstance (void)
467    {
468            return g_pMainForm;
469    }
470    
471    
472  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
473  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
474    
# Line 370  bool qsamplerMainForm::newSession (void) Line 492  bool qsamplerMainForm::newSession (void)
492      if (!closeSession(true))      if (!closeSession(true))
493          return false;          return false;
494    
495            // Give us what the server has, right now...
496            updateSession();
497    
498      // Ok increment untitled count.      // Ok increment untitled count.
499      m_iUntitled++;      m_iUntitled++;
500    
# Line 391  bool qsamplerMainForm::openSession (void Line 516  bool qsamplerMainForm::openSession (void
516    
517      // Ask for the filename to open...      // Ask for the filename to open...
518      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
519              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
520              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
521              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
522              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
523      );      );
524    
525      // Have we cancelled?      // Have we cancelled?
# Line 425  bool qsamplerMainForm::saveSession ( boo Line 550  bool qsamplerMainForm::saveSession ( boo
550              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
551          // Prompt the guy...          // Prompt the guy...
552          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
553                  sFilename,                              // Start here.                          sFilename,                              // Start here.
554                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
555                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
556                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
557          );          );
558          // Have we cancelled it?          // Have we cancelled it?
559          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 563  bool qsamplerMainForm::saveSession ( boo
563              sFilename += ".lscp";              sFilename += ".lscp";
564          // Check if already exists...          // Check if already exists...
565          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
566              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
567                                    QSAMPLER_TITLE ": " + tr("Warning"),
568                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
569                     "\"%1\"\n\n"                     "\"%1\"\n\n"
570                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 460  bool qsamplerMainForm::closeSession ( bo Line 586  bool qsamplerMainForm::closeSession ( bo
586    
587      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
588      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
589          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
590                            QSAMPLER_TITLE ": " + tr("Warning"),
591              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
592              "\"%1\"\n\n"              "\"%1\"\n\n"
593              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 483  bool qsamplerMainForm::closeSession ( bo Line 610  bool qsamplerMainForm::closeSession ( bo
610          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
611          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
612          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
613              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
614              if (bForce && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)              if (pChannelStrip) {
615                  appendMessagesClient("lscp_remove_channel");                  qsamplerChannel *pChannel = pChannelStrip->channel();
616              delete pChannel;                  if (bForce && pChannel)
617                        pChannel->removeChannel();
618                    delete pChannelStrip;
619                }
620          }          }
621          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
622          // We're now clean, for sure.          // We're now clean, for sure.
# Line 510  bool qsamplerMainForm::loadSessionFile ( Line 640  bool qsamplerMainForm::loadSessionFile (
640          return false;          return false;
641      }      }
642    
643            // Tell the world we'll take some time...
644            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
645    
646      // Read the file.      // Read the file.
647            int iLine = 0;
648      int iErrors = 0;      int iErrors = 0;
649      QTextStream ts(&file);      QTextStream ts(&file);
650      while (!ts.atEnd()) {      while (!ts.atEnd()) {
651          // Read the line.          // Read the line.
652          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
653                    iLine++;
654          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
655          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
656              appendMessagesColor(sCommand, "#996633");                          // Remember that, no matter what,
657              // Remember that, no matter what,                          // all LSCP commands are CR/LF terminated.
658              // all LSCP commands are CR/LF terminated.                          sCommand += "\r\n";
659              sCommand += "\r\n";                          if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
660              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {                                  appendMessagesColor(QString("%1(%2): %3")
661                  appendMessagesClient("lscp_client_query");                                          .arg(QFileInfo(sFilename).fileName()).arg(iLine)
662                  iErrors++;                                          .arg(sCommand.simplifyWhiteSpace()), "#996633");
663              }                                  appendMessagesClient("lscp_client_query");
664                                    iErrors++;
665                            }
666          }          }
667          // Try to make it snappy :)          // Try to make it snappy :)
668          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
# Line 534  bool qsamplerMainForm::loadSessionFile ( Line 671  bool qsamplerMainForm::loadSessionFile (
671      // Ok. we've read it.      // Ok. we've read it.
672      file.close();      file.close();
673    
674      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
675      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
676    
677      // Now we'll try to create the whole GUI session.          // We're fornerly done.
678      int iChannels = ::lscp_get_channels(m_pClient);          QApplication::restoreOverrideCursor();
679      if (iChannels < 0) {  
680          appendMessagesClient("lscp_get_channels");          // Have we any errors?
681          appendMessagesError(tr("Could not get current number of channels.\n\nSorry."));          if (iErrors > 0)
682      }                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
       
     // Try to (re)create each channel.  
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannelID = 0; iChannelID < iChannels; iChannelID++) {  
         createChannel(iChannelID, false);  
         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
683    
684      // Save as default session directory.      // Save as default session directory.
685      if (m_pOptions)      if (m_pOptions)
686          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
687      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
688      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
689      // Stabilize form...      // Stabilize form...
690      m_sFilename = sFilename;      m_sFilename = sFilename;
691      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
692      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
693    
694        // Make that an overall update.
695      stabilizeForm();      stabilizeForm();
696      return true;      return true;
697  }  }
# Line 570  bool qsamplerMainForm::loadSessionFile ( Line 700  bool qsamplerMainForm::loadSessionFile (
700  // Save current session to specific file path.  // Save current session to specific file path.
701  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
702  {  {
703            if (m_pClient == NULL)
704                    return false;
705    
706            // Check whether server is apparently OK...
707            if (::lscp_get_channels(m_pClient) < 0) {
708                    appendMessagesClient("lscp_get_channels");
709                    return false;
710            }
711    
712      // Open and write into real file.      // Open and write into real file.
713      QFile file(sFilename);      QFile file(sFilename);
714      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 577  bool qsamplerMainForm::saveSessionFile ( Line 716  bool qsamplerMainForm::saveSessionFile (
716          return false;          return false;
717      }      }
718    
719            // Tell the world we'll take some time...
720            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
721    
722      // Write the file.      // Write the file.
723      int iErrors = 0;      int  iErrors = 0;
724      QTextStream ts(&file);      QTextStream ts(&file);
725      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
726      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 589  bool qsamplerMainForm::saveSessionFile ( Line 731  bool qsamplerMainForm::saveSessionFile (
731      ts << "# " << tr("File")      ts << "# " << tr("File")
732         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
733      ts << "# " << tr("Date")      ts << "# " << tr("Date")
734         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
735         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
736      ts << "#"  << endl;      ts << "#"  << endl;
737      ts << endl;      ts << endl;
738    
739            // It is assumed that this new kind of device+session file
740            // will be loaded from a complete initialized server...
741            int *piDeviceIDs;
742            int  iDevice;
743            ts << "RESET" << endl;
744    
745            // Audio device mapping.
746            QMap<int, int> audioDeviceMap;
747            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
748            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
749                    ts << endl;
750                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
751                    // Audio device specification...
752                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
753                            << " " << tr("Device") << " " << iDevice << endl;
754                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
755                    qsamplerDeviceParamMap::ConstIterator deviceParam;
756                    for (deviceParam = device.params().begin();
757                                    deviceParam != device.params().end();
758                                            ++deviceParam) {
759                            const qsamplerDeviceParam& param = deviceParam.data();
760                            if (param.value.isEmpty()) ts << "# ";
761                            ts << " " << deviceParam.key() << "='" << param.value << "'";
762                    }
763                    ts << endl;
764                    // Audio channel parameters...
765                    int iPort = 0;
766                    for (qsamplerDevicePort *pPort = device.ports().first();
767                                    pPort;
768                                            pPort = device.ports().next(), ++iPort) {
769                            qsamplerDeviceParamMap::ConstIterator portParam;
770                            for (portParam = pPort->params().begin();
771                                            portParam != pPort->params().end();
772                                                    ++portParam) {
773                                    const qsamplerDeviceParam& param = portParam.data();
774                                    if (param.fix || param.value.isEmpty()) ts << "# ";
775                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
776                                            << " " << iPort << " " << portParam.key()
777                                            << "='" << param.value << "'" << endl;
778                            }
779                    }
780                    // Audio device index/id mapping.
781                    audioDeviceMap[device.deviceID()] = iDevice;
782                    // Try to keep it snappy :)
783                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
784            }
785    
786            // MIDI device mapping.
787            QMap<int, int> midiDeviceMap;
788            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
789            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
790                    ts << endl;
791                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
792                    // MIDI device specification...
793                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
794                            << " " << tr("Device") << " " << iDevice << endl;
795                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
796                    qsamplerDeviceParamMap::ConstIterator deviceParam;
797                    for (deviceParam = device.params().begin();
798                                    deviceParam != device.params().end();
799                                            ++deviceParam) {
800                            const qsamplerDeviceParam& param = deviceParam.data();
801                            if (param.value.isEmpty()) ts << "# ";
802                            ts << " " << deviceParam.key() << "='" << param.value << "'";
803                    }
804                    ts << endl;
805                    // MIDI port parameters...
806                    int iPort = 0;
807                    for (qsamplerDevicePort *pPort = device.ports().first();
808                                    pPort;
809                                            pPort = device.ports().next(), ++iPort) {
810                            qsamplerDeviceParamMap::ConstIterator portParam;
811                            for (portParam = pPort->params().begin();
812                                            portParam != pPort->params().end();
813                                                    ++portParam) {
814                                    const qsamplerDeviceParam& param = portParam.data();
815                                    if (param.fix || param.value.isEmpty()) ts << "# ";
816                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
817                                       << " " << iPort << " " << portParam.key()
818                                       << "='" << param.value << "'" << endl;
819                            }
820                    }
821                    // MIDI device index/id mapping.
822                    midiDeviceMap[device.deviceID()] = iDevice;
823                    // Try to keep it snappy :)
824                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
825            }
826            ts << endl;
827    
828    #ifdef CONFIG_MIDI_INSTRUMENT
829            // MIDI instrument mapping...
830            QMap<int, int> midiInstrumentMap;
831            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
832            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
833                    int iMidiMap = piMaps[iMap];
834                    const char *pszMapName
835                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
836                    ts << "# " << tr("MIDI instrument map") << " " << iMap;
837                    if (pszMapName)
838                            ts << " - " << pszMapName;
839                    ts << endl;
840                    ts << "ADD MIDI_INSTRUMENT_MAP";
841                    if (pszMapName)
842                            ts << " '" << pszMapName << "'";
843                    ts << endl;
844                    // MIDI instrument mapping...
845                    lscp_midi_instrument_t *pInstrs
846                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
847                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
848                            lscp_midi_instrument_info_t *pInstrInfo
849                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
850                            if (pInstrInfo) {
851                                    ts << "MAP MIDI_INSTRUMENT "
852                                            << iMap                        << " "
853                                            << pInstrs[iInstr].bank        << " "
854                                            << pInstrs[iInstr].prog        << " "
855                                            << pInstrInfo->engine_name     << " '"
856                                            << pInstrInfo->instrument_file << "' "
857                                            << pInstrInfo->instrument_nr   << " "
858                                            << pInstrInfo->volume          << " ";
859                                    switch (pInstrInfo->load_mode) {
860                                            case LSCP_LOAD_PERSISTENT:
861                                                    ts << "PERSISTENT";
862                                                    break;
863                                            case LSCP_LOAD_ON_DEMAND_HOLD:
864                                                    ts << "ON_DEMAND_HOLD";
865                                                    break;
866                                            case LSCP_LOAD_ON_DEMAND:
867                                            case LSCP_LOAD_DEFAULT:
868                                            default:
869                                                    ts << "ON_DEMAND";
870                                                    break;
871                                    }
872                                    if (pInstrInfo->name)
873                                            ts << " '" << pInstrInfo->name << "'";
874                                    ts << endl;
875                            }       // Check for errors...
876                            else if (::lscp_client_get_errno(m_pClient)) {
877                                    appendMessagesClient("lscp_get_midi_instrument_info");
878                                    iErrors++;
879                            }
880                            // Try to keep it snappy :)
881                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
882                    }
883                    ts << endl;
884                    // Check for errors...
885                    if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {
886                            appendMessagesClient("lscp_list_midi_instruments");
887                            iErrors++;
888                    }
889                    // MIDI strument index/id mapping.
890                    midiInstrumentMap[iMidiMap] = iMap;
891            }
892            // Check for errors...
893            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
894                    appendMessagesClient("lscp_list_midi_instrument_maps");
895                    iErrors++;
896            }
897    #endif  // CONFIG_MIDI_INSTRUMENT
898    
899            // Sampler channel mapping.
900      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
901      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
902          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip
903          int iChannelID = pChannel->channelID();                          = static_cast<qsamplerChannelStrip *> (wlist.at(iChannel));
904          ts << "# " << pChannel->caption() << endl;          if (pChannelStrip) {
905          ts << "ADD CHANNEL" << endl;              qsamplerChannel *pChannel = pChannelStrip->channel();
906          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;              if (pChannel) {
907          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                  ts << "# " << tr("Channel") << " " << iChannel << endl;
908          ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                  ts << "ADD CHANNEL" << endl;
909          ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " " << pChannel->midiChannel() << endl;                                  if (audioDeviceMap.isEmpty()) {
910          ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
911          ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                                  << " " << pChannel->audioDriver() << endl;
912          ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  } else {
913          ts << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
914                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
915                                    }
916                                    if (midiDeviceMap.isEmpty()) {
917                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
918                                                    << " " << pChannel->midiDriver() << endl;
919                                    } else {
920                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
921                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
922                                    }
923                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
924                                            << " " << pChannel->midiPort() << endl;
925                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
926                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
927                        ts << "ALL";
928                    else
929                        ts << pChannel->midiChannel();
930                    ts << endl;
931                    ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
932                                    if (pChannel->instrumentStatus() < 100) ts << "# ";
933                                    ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
934                                            << pChannel->instrumentNr() << " " << iChannel << endl;
935                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
936                                    for (audioRoute = pChannel->audioRouting().begin();
937                                                    audioRoute != pChannel->audioRouting().end();
938                                                            ++audioRoute) {
939                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
940                                                    << " " << audioRoute.key()
941                                                    << " " << audioRoute.data() << endl;
942                                    }
943                                    ts << "SET CHANNEL VOLUME " << iChannel
944                                            << " " << pChannel->volume() << endl;
945                                    if (pChannel->channelMute())
946                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
947                                    if (pChannel->channelSolo())
948                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
949    #ifdef CONFIG_MIDI_INSTRUMENT
950                                    if (pChannel->midiMap() >= 0) {
951                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
952                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
953                                    }
954    #endif
955    #ifdef CONFIG_FXSEND
956                                    int iChannelID = pChannel->channelID();
957                                    int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
958                                    for (int iFxSend = 0;
959                                                    piFxSends && piFxSends[iFxSend] >= 0;
960                                                            iFxSend++) {
961                                            lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
962                                                    m_pClient, iChannelID, piFxSends[iFxSend]);
963                                            if (pFxSendInfo) {
964                                                    ts << "CREATE FX_SEND " << iChannel
965                                                            << " " << pFxSendInfo->midi_controller;
966                                                    if (pFxSendInfo->name)
967                                                            ts << " '" << pFxSendInfo->name << "'";
968                                                    ts << endl;
969                                                    int *piRouting = pFxSendInfo->audio_routing;
970                                                    for (int iAudioSrc = 0;
971                                                                    piRouting && piRouting[iAudioSrc] >= 0;
972                                                                            iAudioSrc++) {
973                                                            ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
974                                                                    << iChannel
975                                                                    << " " << iFxSend
976                                                                    << " " << iAudioSrc
977                                                                    << " " << piRouting[iAudioSrc] << endl;
978                                                    }
979    #ifdef CONFIG_FXSEND_LEVEL
980                                                    ts << "SET FX_SEND LEVEL " << iChannel
981                                                            << " " << iFxSend
982                                                            << " " << pFxSendInfo->level << endl;                                                  
983    #endif
984                                            }       // Check for errors...
985                                            else if (::lscp_client_get_errno(m_pClient)) {
986                                                    appendMessagesClient("lscp_get_fxsend_info");
987                                                    iErrors++;
988                                            }
989                                    }
990    #endif
991                    ts << endl;
992                }
993            }
994          // Try to keep it snappy :)          // Try to keep it snappy :)
995          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
996      }      }
# Line 614  bool qsamplerMainForm::saveSessionFile ( Line 998  bool qsamplerMainForm::saveSessionFile (
998      // Ok. we've wrote it.      // Ok. we've wrote it.
999      file.close();      file.close();
1000    
1001            // We're fornerly done.
1002            QApplication::restoreOverrideCursor();
1003    
1004      // Have we any errors?      // Have we any errors?
1005      if (iErrors > 0)      if (iErrors > 0)
1006          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));
# Line 632  bool qsamplerMainForm::saveSessionFile ( Line 1019  bool qsamplerMainForm::saveSessionFile (
1019  }  }
1020    
1021    
1022    // Session change receiver slot.
1023    void qsamplerMainForm::sessionDirty (void)
1024    {
1025        // Just mark the dirty form.
1026        m_iDirtyCount++;
1027        // and update the form status...
1028        stabilizeForm();
1029    }
1030    
1031    
1032  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1033  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
1034    
# Line 678  void qsamplerMainForm::fileSaveAs (void) Line 1075  void qsamplerMainForm::fileSaveAs (void)
1075  }  }
1076    
1077    
1078    // Reset the sampler instance.
1079    void qsamplerMainForm::fileReset (void)
1080    {
1081        if (m_pClient == NULL)
1082            return;
1083    
1084        // Ask user whether he/she want's an internal sampler reset...
1085        if (QMessageBox::warning(this,
1086                    QSAMPLER_TITLE ": " + tr("Warning"),
1087            tr("Resetting the sampler instance will close\n"
1088               "all device and channel configurations.\n\n"
1089               "Please note that this operation may cause\n"
1090               "temporary MIDI and Audio disruption.\n\n"
1091               "Do you want to reset the sampler engine now?"),
1092            tr("Reset"), tr("Cancel")) > 0)
1093            return;
1094    
1095            // Trye closing the current session, first...
1096            if (!closeSession(true))
1097                    return;
1098    
1099        // Just do the reset, after closing down current session...
1100            // Do the actual sampler reset...
1101            if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1102                    appendMessagesClient("lscp_reset_sampler");
1103                    appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
1104                    return;
1105            }
1106    
1107        // Log this.
1108        appendMessages(tr("Sampler reset."));
1109    
1110            // Make it a new session...
1111            newSession();
1112    }
1113    
1114    
1115  // Restart the client/server instance.  // Restart the client/server instance.
1116  void qsamplerMainForm::fileRestart (void)  void qsamplerMainForm::fileRestart (void)
1117  {  {
1118      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1119          return;          return;
1120            
1121      bool bRestart = true;      bool bRestart = true;
1122        
1123      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1124      // (if we're currently up and running)      // (if we're currently up and running)
1125      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1126          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1127                            QSAMPLER_TITLE ": " + tr("Warning"),
1128              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1129                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1130                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1131                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1132                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1133              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1134      }      }
# Line 725  void qsamplerMainForm::editAddChannel (v Line 1160  void qsamplerMainForm::editAddChannel (v
1160      if (m_pClient == NULL)      if (m_pClient == NULL)
1161          return;          return;
1162    
1163      // Create the new sampler channel.      // Just create the channel instance...
1164      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel();
1165      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
1166          return;          return;
     }  
1167    
1168      // Log this happening.      // Before we show it up, may be we'll
1169      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
1170        if (!pChannel->channelSetup(this)) {
1171            delete pChannel;
1172            return;
1173        }
1174    
1175      // Just create the channel strip with given id.      // And give it to the strip (will own the channel instance, if successful).
1176      createChannel(iChannelID, true);      if (!createChannelStrip(pChannel)) {
1177            delete pChannel;
1178            return;
1179        }
1180    
1181      // We'll be dirty, for sure...      // Make that an overall update.
1182      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
1183      stabilizeForm();      stabilizeForm();
1184  }  }
1185    
# Line 752  void qsamplerMainForm::editRemoveChannel Line 1190  void qsamplerMainForm::editRemoveChannel
1190      if (m_pClient == NULL)      if (m_pClient == NULL)
1191          return;          return;
1192    
1193      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1194        if (pChannelStrip == NULL)
1195            return;
1196    
1197        qsamplerChannel *pChannel = pChannelStrip->channel();
1198      if (pChannel == NULL)      if (pChannel == NULL)
1199          return;          return;
1200    
1201      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1202      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1203          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1204                            QSAMPLER_TITLE ": " + tr("Warning"),
1205              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1206                 "%1\n\n"                 "%1\n\n"
1207                 "Are you sure?")                 "Are you sure?")
1208                 .arg(pChannel->caption()),                 .arg(pChannelStrip->caption()),
1209              tr("OK"), tr("Cancel")) > 0)              tr("OK"), tr("Cancel")) > 0)
1210              return;              return;
1211      }      }
1212    
1213      // Remove the existing sampler channel.      // Remove the existing sampler channel.
1214      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."));  
1215          return;          return;
     }  
1216    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
1217      // Just delete the channel strip.      // Just delete the channel strip.
1218      delete pChannel;      delete pChannelStrip;
1219    
1220      // Do we auto-arrange?      // Do we auto-arrange?
1221      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1222          channelsArrange();          channelsArrange();
# Line 795  void qsamplerMainForm::editSetupChannel Line 1233  void qsamplerMainForm::editSetupChannel
1233      if (m_pClient == NULL)      if (m_pClient == NULL)
1234          return;          return;
1235    
1236      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1237      if (pChannel == NULL)      if (pChannelStrip == NULL)
1238          return;          return;
1239    
1240      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
1241      pChannel->channelSetup();      pChannelStrip->channelSetup();
1242  }  }
1243    
1244    
# Line 810  void qsamplerMainForm::editResetChannel Line 1248  void qsamplerMainForm::editResetChannel
1248      if (m_pClient == NULL)      if (m_pClient == NULL)
1249          return;          return;
1250    
1251      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1252      if (pChannel == NULL)      if (pChannelStrip == NULL)
1253          return;          return;
1254    
1255      // Remove the existing sampler channel.      // Just invoque the channel strip procedure.
1256      if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      pChannelStrip->channelReset();
1257          appendMessagesClient("lscp_reset_channel");  }
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
1258    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
1259    
1260      // Refresh channel strip info.  // Reset all sampler channels.
1261      pChannel->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
1262    {
1263            if (m_pClient == NULL)
1264                    return;
1265    
1266            // Invoque the channel strip procedure,
1267            // for all channels out there...
1268            m_pWorkspace->setUpdatesEnabled(false);
1269            QWidgetList wlist = m_pWorkspace->windowList();
1270            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1271                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1272                    if (pChannelStrip)
1273                            pChannelStrip->channelReset();
1274            }
1275            m_pWorkspace->setUpdatesEnabled(true);
1276  }  }
1277    
1278    
# Line 877  void qsamplerMainForm::viewMessages ( bo Line 1324  void qsamplerMainForm::viewMessages ( bo
1324  }  }
1325    
1326    
1327    // Show/hide the MIDI instrument list-view form.
1328    void qsamplerMainForm::viewInstruments (void)
1329    {
1330            if (m_pOptions == NULL)
1331                    return;
1332    
1333            if (m_pInstrumentListForm) {
1334                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1335                    if (m_pInstrumentListForm->isVisible()) {
1336                            m_pInstrumentListForm->hide();
1337                    } else {
1338                            m_pInstrumentListForm->show();
1339                            m_pInstrumentListForm->raise();
1340                            m_pInstrumentListForm->setActiveWindow();
1341                    }
1342            }
1343    }
1344    
1345    
1346    // Show/hide the device configurator form.
1347    void qsamplerMainForm::viewDevices (void)
1348    {
1349            if (m_pOptions == NULL)
1350                    return;
1351    
1352            if (m_pDeviceForm) {
1353                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1354                    if (m_pDeviceForm->isVisible()) {
1355                            m_pDeviceForm->hide();
1356                    } else {
1357                            m_pDeviceForm->show();
1358                            m_pDeviceForm->raise();
1359                            m_pDeviceForm->setActiveWindow();
1360                    }
1361            }
1362    }
1363    
1364    
1365  // Show options dialog.  // Show options dialog.
1366  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1367  {  {
# Line 886  void qsamplerMainForm::viewOptions (void Line 1371  void qsamplerMainForm::viewOptions (void
1371      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);
1372      if (pOptionsForm) {      if (pOptionsForm) {
1373          // Check out some initial nullities(tm)...          // Check out some initial nullities(tm)...
1374          qsamplerChannelStrip *pChannel = activeChannel();          qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1375          if (m_pOptions->sDisplayFont.isEmpty() && pChannel)          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1376              m_pOptions->sDisplayFont = pChannel->displayFont().toString();              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1377          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1378              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1379          // To track down deferred or immediate changes.          // To track down deferred or immediate changes.
# Line 898  void qsamplerMainForm::viewOptions (void Line 1383  void qsamplerMainForm::viewOptions (void
1383          bool    bOldServerStart     = m_pOptions->bServerStart;          bool    bOldServerStart     = m_pOptions->bServerStart;
1384          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1385          QString sOldDisplayFont     = m_pOptions->sDisplayFont;          QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1386            bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1387          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1388          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1389            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1390          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1391          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1392          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1393          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1394            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1395          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1396          // Load the current setup settings.          // Load the current setup settings.
1397          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 911  void qsamplerMainForm::viewOptions (void Line 1399  void qsamplerMainForm::viewOptions (void
1399          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1400              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1401              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1402                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1403                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1404                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1405                    QMessageBox::information(this,
1406                                            QSAMPLER_TITLE ": " + tr("Information"),
1407                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1408                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1409                  updateMessagesCapture();                  updateMessagesCapture();
# Line 922  void qsamplerMainForm::viewOptions (void Line 1413  void qsamplerMainForm::viewOptions (void
1413                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1414                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1415                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1416                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1417                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1418                    updateInstrumentNames();
1419                if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1420                    (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1421                    updateDisplayEffect();
1422              if (sOldDisplayFont != m_pOptions->sDisplayFont)              if (sOldDisplayFont != m_pOptions->sDisplayFont)
1423                  updateDisplayFont();                  updateDisplayFont();
1424              if (iOldMaxVolume != m_pOptions->iMaxVolume)              if (iOldMaxVolume != m_pOptions->iMaxVolume)
# Line 964  void qsamplerMainForm::channelsArrange ( Line 1461  void qsamplerMainForm::channelsArrange (
1461      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1462      int y = 0;      int y = 0;
1463      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1464          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1465      /*  if (pChannel->testWState(WState_Maximized | WState_Minimized)) {      /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1466              // Prevent flicker...              // Prevent flicker...
1467              pChannel->hide();              pChannelStrip->hide();
1468              pChannel->showNormal();              pChannelStrip->showNormal();
1469          }   */          }   */
1470          pChannel->adjustSize();          pChannelStrip->adjustSize();
1471          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1472          if (iWidth < pChannel->width())          if (iWidth < pChannelStrip->width())
1473              iWidth = pChannel->width();              iWidth = pChannelStrip->width();
1474      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1475          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1476          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1477          y += iHeight;          y += iHeight;
1478      }      }
1479      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1480        
1481      stabilizeForm();      stabilizeForm();
1482  }  }
1483    
# Line 1024  void qsamplerMainForm::helpAbout (void) Line 1521  void qsamplerMainForm::helpAbout (void)
1521      sText += tr("Debugging option enabled.");      sText += tr("Debugging option enabled.");
1522      sText += "</font></small><br />";      sText += "</font></small><br />";
1523  #endif  #endif
1524    #ifndef CONFIG_LIBGIG
1525        sText += "<small><font color=\"red\">";
1526        sText += tr("GIG (libgig) file support disabled.");
1527        sText += "</font></small><br />";
1528    #endif
1529    #ifndef CONFIG_INSTRUMENT_NAME
1530        sText += "<small><font color=\"red\">";
1531        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1532        sText += "</font></small><br />";
1533    #endif
1534    #ifndef CONFIG_MUTE_SOLO
1535        sText += "<small><font color=\"red\">";
1536        sText += tr("Sampler channel Mute/Solo support disabled.");
1537        sText += "</font></small><br />";
1538    #endif
1539    #ifndef CONFIG_AUDIO_ROUTING
1540        sText += "<small><font color=\"red\">";
1541        sText += tr("LSCP (liblscp) audio_routing support disabled.");
1542        sText += "</font></small><br />";
1543    #endif
1544    #ifndef CONFIG_FXSEND
1545        sText += "<small><font color=\"red\">";
1546        sText += tr("Sampler channel Effect Sends support disabled.");
1547        sText += "</font></small><br />";
1548    #endif
1549    #ifndef CONFIG_MIDI_INSTRUMENT
1550        sText += "<small><font color=\"red\">";
1551        sText += tr("MIDI instrument mapping support disabled.");
1552        sText += "</font></small><br />";
1553    #endif
1554      sText += "<br />\n";      sText += "<br />\n";
1555      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1556      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1557      sText += " ";      sText += " ";
1558      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1559    #ifdef CONFIG_LIBGIG
1560        sText += ", ";
1561        sText += gig::libraryName().c_str();
1562        sText += " ";
1563        sText += gig::libraryVersion().c_str();
1564    #endif
1565      sText += "<br />\n";      sText += "<br />\n";
1566      sText += "<br />\n";      sText += "<br />\n";
1567      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";
# Line 1051  void qsamplerMainForm::helpAbout (void) Line 1584  void qsamplerMainForm::helpAbout (void)
1584  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1585  {  {
1586      // Update the main application caption...      // Update the main application caption...
1587      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1588      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1589          sSessioName += '*';          sSessionName += " *";
1590      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1591    
1592      // Update the main menu state...      // Update the main menu state...
1593      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1594      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1595      bool bHasChannel = (bHasClient && pChannel != NULL);      bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1596      fileNewAction->setEnabled(bHasClient);      fileNewAction->setEnabled(bHasClient);
1597      fileOpenAction->setEnabled(bHasClient);      fileOpenAction->setEnabled(bHasClient);
1598      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1599      fileSaveAsAction->setEnabled(bHasClient);      fileSaveAsAction->setEnabled(bHasClient);
1600        fileResetAction->setEnabled(bHasClient);
1601      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1602      editAddChannelAction->setEnabled(bHasClient);      editAddChannelAction->setEnabled(bHasClient);
1603      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1604      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1605      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1606      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1607      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1608    #ifdef CONFIG_MIDI_INSTRUMENT
1609            viewInstrumentsAction->setOn(m_pInstrumentListForm
1610                    && m_pInstrumentListForm->isVisible());
1611            viewInstrumentsAction->setEnabled(bHasClient);
1612    #endif
1613            viewDevicesAction->setOn(m_pDeviceForm
1614                    && m_pDeviceForm->isVisible());
1615        viewDevicesAction->setEnabled(bHasClient);
1616        channelsArrangeAction->setEnabled(bHasChannel);
1617    
1618      // Client/Server status...      // Client/Server status...
1619      if (bHasClient) {      if (bHasClient) {
1620          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1621          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));
1622      } else {      } else {
1623          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1624          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1625      }      }
1626      // Channel status...      // Channel status...
1627      if (bHasChannel)      if (bHasChannel)
1628          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannel->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1629      else      else
1630          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1631      // Session status...      // Session status...
1632      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1633          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1634      else      else
1635          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1636    
1637      // Recent files menu.      // Recent files menu.
1638      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1101  void qsamplerMainForm::stabilizeForm (vo Line 1644  void qsamplerMainForm::stabilizeForm (vo
1644    
1645    
1646  // Channel change receiver slot.  // Channel change receiver slot.
1647  void qsamplerMainForm::channelChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1648  {  {
1649            // Add this strip to the changed list...
1650            if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1651                    m_changedStrips.append(pChannelStrip);
1652                    pChannelStrip->resetErrorCount();
1653            }
1654    
1655      // Just mark the dirty form.      // Just mark the dirty form.
1656      m_iDirtyCount++;      m_iDirtyCount++;
1657      // and update the form status...      // and update the form status...
# Line 1110  void qsamplerMainForm::channelChanged( q Line 1659  void qsamplerMainForm::channelChanged( q
1659  }  }
1660    
1661    
1662    // Grab and restore current sampler channels session.
1663    void qsamplerMainForm::updateSession (void)
1664    {
1665    #ifdef CONFIG_MIDI_INSTRUMENT
1666            // FIXME: Make some room for default instrument maps...
1667            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1668            if (iMaps < 0)
1669                    appendMessagesClient("lscp_get_midi_instrument_maps");
1670            else if (iMaps < 1) {
1671                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1672                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1673            }
1674    #endif
1675    
1676            // Retrieve the current channel list.
1677            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1678            if (piChannelIDs == NULL) {
1679                    if (::lscp_client_get_errno(m_pClient)) {
1680                            appendMessagesClient("lscp_list_channels");
1681                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1682                    }
1683            } else {
1684                    // Try to (re)create each channel.
1685                    m_pWorkspace->setUpdatesEnabled(false);
1686                    for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1687                            // Check if theres already a channel strip for this one...
1688                            if (!channelStrip(piChannelIDs[iChannel]))
1689                                    createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1690                    }
1691                    m_pWorkspace->setUpdatesEnabled(true);
1692            }
1693    
1694        // Do we auto-arrange?
1695        if (m_pOptions && m_pOptions->bAutoArrange)
1696            channelsArrange();
1697    
1698            // Remember to refresh devices and instruments...
1699            if (m_pInstrumentListForm)
1700                m_pInstrumentListForm->refreshInstruments();
1701            if (m_pDeviceForm)
1702                m_pDeviceForm->refreshDevices();
1703    }
1704    
1705    
1706  // Update the recent files list and menu.  // Update the recent files list and menu.
1707  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1708  {  {
# Line 1154  void qsamplerMainForm::updateRecentFiles Line 1747  void qsamplerMainForm::updateRecentFiles
1747  }  }
1748    
1749    
1750    // Force update of the channels instrument names mode.
1751    void qsamplerMainForm::updateInstrumentNames (void)
1752    {
1753        // Full channel list update...
1754        QWidgetList wlist = m_pWorkspace->windowList();
1755        if (wlist.isEmpty())
1756            return;
1757    
1758        m_pWorkspace->setUpdatesEnabled(false);
1759        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1760            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1761            if (pChannelStrip)
1762                pChannelStrip->updateInstrumentName(true);
1763        }
1764        m_pWorkspace->setUpdatesEnabled(true);
1765    }
1766    
1767    
1768  // Force update of the channels display font.  // Force update of the channels display font.
1769  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1770  {  {
# Line 1175  void qsamplerMainForm::updateDisplayFont Line 1786  void qsamplerMainForm::updateDisplayFont
1786    
1787      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1788      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1789          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1790          pChannel->setDisplayFont(font);          if (pChannelStrip)
1791                pChannelStrip->setDisplayFont(font);
1792        }
1793        m_pWorkspace->setUpdatesEnabled(true);
1794    }
1795    
1796    
1797    // Update channel strips background effect.
1798    void qsamplerMainForm::updateDisplayEffect (void)
1799    {
1800       QPixmap pm;
1801        if (m_pOptions->bDisplayEffect)
1802            pm = QPixmap::fromMimeSource("displaybg1.png");
1803    
1804        // Full channel list update...
1805        QWidgetList wlist = m_pWorkspace->windowList();
1806        if (wlist.isEmpty())
1807            return;
1808    
1809        m_pWorkspace->setUpdatesEnabled(false);
1810        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1811            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1812            if (pChannelStrip)
1813                pChannelStrip->setDisplayBackground(pm);
1814      }      }
1815      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1816  }  }
# Line 1195  void qsamplerMainForm::updateMaxVolume ( Line 1829  void qsamplerMainForm::updateMaxVolume (
1829    
1830      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1831      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1832          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1833          pChannel->setMaxVolume(m_pOptions->iMaxVolume);          if (pChannelStrip)
1834                pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1835      }      }
1836      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1837  }  }
# Line 1235  void qsamplerMainForm::appendMessagesErr Line 1870  void qsamplerMainForm::appendMessagesErr
1870    
1871      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1872    
1873      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));          // Make it look responsive...:)
1874            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1875    
1876        QMessageBox::critical(this,
1877                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1878  }  }
1879    
1880    
# Line 1248  void qsamplerMainForm::appendMessagesCli Line 1887  void qsamplerMainForm::appendMessagesCli
1887      appendMessagesColor(s + QString(": %1 (errno=%2)")      appendMessagesColor(s + QString(": %1 (errno=%2)")
1888          .arg(::lscp_client_get_result(m_pClient))          .arg(::lscp_client_get_result(m_pClient))
1889          .arg(::lscp_client_get_errno(m_pClient)), "#996666");          .arg(::lscp_client_get_errno(m_pClient)), "#996666");
1890    
1891            // Make it look responsive...:)
1892            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1893  }  }
1894    
1895    
# Line 1275  void qsamplerMainForm::updateMessagesLim Line 1917  void qsamplerMainForm::updateMessagesLim
1917          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1918              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1919          else          else
1920              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1921      }      }
1922  }  }
1923    
# Line 1295  void qsamplerMainForm::updateMessagesCap Line 1937  void qsamplerMainForm::updateMessagesCap
1937  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
1938    
1939  // The channel strip creation executive.  // The channel strip creation executive.
1940  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
1941  {  {
1942      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
1943          return;          return NULL;
1944    
1945      // Prepare for auto-arrange?      // Prepare for auto-arrange?
1946      qsamplerChannelStrip *pChannel = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
1947      int y = 0;      int y = 0;
1948      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1949          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1950          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1951              pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1952          //  y += pChannel->height() + pChannel->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1953              y += pChannel->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1954                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1955                            }
1956          }          }
1957      }      }
1958    
1959      // Add a new channel itema...      // Add a new channel itema...
1960      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;
1961      pChannel = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1962      pChannel->setMaxVolume(m_pOptions->iMaxVolume);      if (pChannelStrip == NULL)
1963      pChannel->setup(this, iChannelID);          return NULL;
1964      // We'll need a display font.  
1965      QFont font;      // Actual channel strip setup...
1966      if (m_pOptions && font.fromString(m_pOptions->sDisplayFont))      pChannelStrip->setup(pChannel);
1967          pChannel->setDisplayFont(font);          QObject::connect(pChannelStrip,
1968      // Track channel setup changes.                  SIGNAL(channelChanged(qsamplerChannelStrip *)),
1969      QObject::connect(pChannel, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelChanged(qsamplerChannelStrip *)));                  SLOT(channelStripChanged(qsamplerChannelStrip *)));
1970      // Before we show it up, may be we'll      // Set some initial aesthetic options...
1971      // better ask for some initial values?      if (m_pOptions) {
1972      if (bPrompt)          // Background display effect...
1973          pChannel->channelSetup();                pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
1974            // We'll need a display font.
1975            QFont font;
1976            if (font.fromString(m_pOptions->sDisplayFont))
1977                pChannelStrip->setDisplayFont(font);
1978            // Maximum allowed volume setting.
1979            pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1980        }
1981    
1982      // Now we show up us to the world.      // Now we show up us to the world.
1983      pChannel->show();      pChannelStrip->show();
1984      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
1985      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1986          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1987      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();
1988          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1989          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1990      }      }
1991    
1992            // This is pretty new, so we'll watch for it closely.
1993            channelStripChanged(pChannelStrip);
1994    
1995        // Return our successful reference...
1996        return pChannelStrip;
1997  }  }
1998    
1999    
2000  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2001  qsamplerChannelStrip *qsamplerMainForm::activeChannel (void)  qsamplerChannelStrip *qsamplerMainForm::activeChannelStrip (void)
2002  {  {
2003      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();
2004  }  }
2005    
2006    
2007  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2008  qsamplerChannelStrip *qsamplerMainForm::channelAt ( int iChannel )  qsamplerChannelStrip *qsamplerMainForm::channelStripAt ( int iChannel )
2009  {  {
2010      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
2011      if (wlist.isEmpty())      if (wlist.isEmpty())
2012          return 0;          return NULL;
2013    
2014      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
2015  }  }
2016    
2017    
2018    // Retrieve a channel strip by sampler channel id.
2019    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
2020    {
2021            QWidgetList wlist = m_pWorkspace->windowList();
2022            if (wlist.isEmpty())
2023                    return NULL;
2024    
2025            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2026                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2027                    if (pChannelStrip) {
2028                            qsamplerChannel *pChannel = pChannelStrip->channel();
2029                            if (pChannel && pChannel->channelID() == iChannelID)
2030                                    return pChannelStrip;
2031                    }
2032            }
2033    
2034            // Not found.
2035            return NULL;
2036    }
2037    
2038    
2039  // Construct the windows menu.  // Construct the windows menu.
2040  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
2041  {  {
# Line 1368  void qsamplerMainForm::channelsMenuAbout Line 2047  void qsamplerMainForm::channelsMenuAbout
2047      if (!wlist.isEmpty()) {      if (!wlist.isEmpty()) {
2048          channelsMenu->insertSeparator();          channelsMenu->insertSeparator();
2049          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2050              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2051              int iItemID = channelsMenu->insertItem(pChannel->caption(), this, SLOT(channelsMenuActivated(int)));              if (pChannelStrip) {
2052              channelsMenu->setItemParameter(iItemID, iChannel);                  int iItemID = channelsMenu->insertItem(pChannelStrip->caption(), this, SLOT(channelsMenuActivated(int)));
2053              channelsMenu->setItemChecked(iItemID, activeChannel() == pChannel);                  channelsMenu->setItemParameter(iItemID, iChannel);
2054                    channelsMenu->setItemChecked(iItemID, activeChannelStrip() == pChannelStrip);
2055                }
2056          }          }
2057      }      }
2058  }  }
# Line 1380  void qsamplerMainForm::channelsMenuAbout Line 2061  void qsamplerMainForm::channelsMenuAbout
2061  // Windows menu activation slot  // Windows menu activation slot
2062  void qsamplerMainForm::channelsMenuActivated ( int iChannel )  void qsamplerMainForm::channelsMenuActivated ( int iChannel )
2063  {  {
2064      qsamplerChannelStrip *pChannel = channelAt(iChannel);      qsamplerChannelStrip *pChannelStrip = channelStripAt(iChannel);
2065      if (pChannel)      if (pChannelStrip)
2066          pChannel->showNormal();          pChannelStrip->showNormal();
2067      pChannel->setFocus();      pChannelStrip->setFocus();
2068  }  }
2069    
2070    
# Line 1421  void qsamplerMainForm::timerSlot (void) Line 2102  void qsamplerMainForm::timerSlot (void)
2102              }              }
2103          }          }
2104      }      }
2105        
2106          // Refresh each channel usage, on each period...          if (m_pClient) {
2107      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {                  // Update the channel information for each pending strip...
2108          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2109          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2110              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2111              QWidgetList wlist = m_pWorkspace->windowList();                                  // If successfull, remove from pending list...
2112              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                  if (pChannelStrip->updateChannelInfo())
2113                  qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);                                          m_changedStrips.remove(pChannelStrip);
2114                  if (pChannel->isVisible())                          }
2115                      pChannel->updateChannelUsage();                  }
2116              }                  // Refresh each channel usage, on each period...
2117          }                  if (m_pOptions->bAutoRefresh) {
2118      }                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2119                            if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2120                                    m_iTimerSlot = 0;
2121                                    // Update the channel stream usage for each strip...
2122                                    QWidgetList wlist = m_pWorkspace->windowList();
2123                                    for (int iChannel = 0;
2124                                                    iChannel < (int) wlist.count(); iChannel++) {
2125                                            qsamplerChannelStrip *pChannelStrip
2126                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2127                                            if (pChannelStrip && pChannelStrip->isVisible())
2128                                                    pChannelStrip->updateChannelUsage();
2129                                    }
2130                            }
2131                    }
2132            }
2133    
2134      // Register the next timer slot.      // Register the next timer slot.
2135      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1456  void qsamplerMainForm::startServer (void Line 2151  void qsamplerMainForm::startServer (void
2151    
2152      // Is the server process instance still here?      // Is the server process instance still here?
2153      if (m_pServer) {      if (m_pServer) {
2154          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2155                            QSAMPLER_TITLE ": " + tr("Warning"),
2156              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2157                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2158              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1477  void qsamplerMainForm::startServer (void Line 2173  void qsamplerMainForm::startServer (void
2173      m_pServer = new QProcess(this);      m_pServer = new QProcess(this);
2174    
2175      // Setup stdout/stderr capture...      // Setup stdout/stderr capture...
2176      //if (m_pOptions->bStdoutCapture) {          //      if (m_pOptions->bStdoutCapture) {
2177          m_pServer->setCommunication(QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);                  m_pServer->setCommunication(
2178          QObject::connect(m_pServer, SIGNAL(readyReadStdout()), this, SLOT(readServerStdout()));                          QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);
2179          QObject::connect(m_pServer, SIGNAL(readyReadStderr()), this, SLOT(readServerStdout()));                  QObject::connect(m_pServer,
2180      //}                          SIGNAL(readyReadStdout()),
2181      // The unforgiveable signal communication...                          SLOT(readServerStdout()));
2182      QObject::connect(m_pServer, SIGNAL(processExited()), this, SLOT(processServerExit()));                  QObject::connect(m_pServer,
2183                            SIGNAL(readyReadStderr()),
2184                            SLOT(readServerStdout()));
2185            //      }
2186            // The unforgiveable signal communication...
2187            QObject::connect(m_pServer,
2188                    SIGNAL(processExited()),
2189                    SLOT(processServerExit()));
2190    
2191      // Build process arguments...      // Build process arguments...
2192      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));
# Line 1615  bool qsamplerMainForm::startClient (void Line 2318  bool qsamplerMainForm::startClient (void
2318      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2319      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)));
2320    
2321            // Subscribe to channel info change notifications...
2322            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2323                    appendMessagesClient("lscp_client_subscribe");
2324    
2325      // We may stop scheduling around.      // We may stop scheduling around.
2326      stopSchedule();      stopSchedule();
2327    
# Line 1624  bool qsamplerMainForm::startClient (void Line 2331  bool qsamplerMainForm::startClient (void
2331      // Log success here.      // Log success here.
2332      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2333    
2334            // Hard-notify instrumnet and device configuration forms,
2335            // if visible, that we're ready...
2336            if (m_pInstrumentListForm)
2337                m_pInstrumentListForm->refreshInstruments();
2338            if (m_pDeviceForm)
2339                m_pDeviceForm->refreshDevices();
2340    
2341      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2342      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2343          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1658  void qsamplerMainForm::stopClient (void) Line 2372  void qsamplerMainForm::stopClient (void)
2372      // channels from the back-end server.      // channels from the back-end server.
2373      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2374      closeSession(false);      closeSession(false);
2375        
2376      // Close us as a client...      // Close us as a client...
2377      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2378        ::lscp_client_destroy(m_pClient);
2379      m_pClient = NULL;      m_pClient = NULL;
2380    
2381            // Hard-notify instrumnet and device configuration forms,
2382            // if visible, that we're running out...
2383            if (m_pInstrumentListForm)
2384                m_pInstrumentListForm->refreshInstruments();
2385            if (m_pDeviceForm)
2386                m_pDeviceForm->refreshDevices();
2387    
2388      // Log final here.      // Log final here.
2389      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2390    

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

  ViewVC Help
Powered by ViewVC