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

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

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

revision 341 by capela, Tue Jan 18 11:29:01 2005 UTC revision 986 by capela, Mon Dec 18 16:51:50 2006 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004-2005, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
# Line 40  Line 41 
41  #include "qsamplerMessages.h"  #include "qsamplerMessages.h"
42    
43  #include "qsamplerChannelStrip.h"  #include "qsamplerChannelStrip.h"
44  #include "qsamplerOptionsForm.h"  #include "qsamplerInstrumentList.h"
45    
46  #include "config.h"  #include "qsamplerInstrumentListForm.h"
47    #include "qsamplerDeviceForm.h"
48    #include "qsamplerOptionsForm.h"
49    
50  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
51  #include <signal.h>  #include <signal.h>
52  #endif  #endif
53    
54    #ifdef CONFIG_LIBGIG
55    #include <gig.h>
56    #endif
57    
58  // Timer constant stuff.  // Timer constant stuff.
59  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
60    
# Line 97  private: Line 104  private:
104  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
105  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
106    
107    // Kind of singleton reference.
108    qsamplerMainForm *qsamplerMainForm::g_pMainForm = NULL;
109    
110    
111  // Kind of constructor.  // Kind of constructor.
112  void qsamplerMainForm::init (void)  void qsamplerMainForm::init (void)
113  {  {
114            // Pseudo-singleton reference setup.
115            g_pMainForm = this;
116    
117      // Initialize some pointer references.      // Initialize some pointer references.
118      m_pOptions = NULL;      m_pOptions = NULL;
119    
120      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
121      m_pMessages = NULL;      m_pMessages = NULL;
122        m_pInstrumentListForm = NULL;
123        m_pDeviceForm = NULL;
124    
125      // We'll start clean.      // We'll start clean.
126      m_iUntitled    = 0;      m_iUntitled   = 0;
127      m_iDirtyCount  = 0;      m_iDirtyCount = 0;
     m_iChangeCount = 0;  
128    
129      m_pServer = NULL;      m_pServer = NULL;
130      m_pClient = NULL;      m_pClient = NULL;
# Line 138  void qsamplerMainForm::init (void) Line 153  void qsamplerMainForm::init (void)
153      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
154      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
155      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
156      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
157      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
158      // Server address.      // Server address.
159      pLabel = new QLabel(this);      pLabel = new QLabel(this);
160      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
161      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
162      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
163      // Channel title.      // Channel title.
164      pLabel = new QLabel(this);      pLabel = new QLabel(this);
165      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
166      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
167      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
168      // Session modification status.      // Session modification status.
169      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
170      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
171      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
172      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
173      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
174    
175      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 173  void qsamplerMainForm::destroy (void) Line 188  void qsamplerMainForm::destroy (void)
188  {  {
189      // Do final processing anyway.      // Do final processing anyway.
190      processServerExit();      processServerExit();
191        
192      // Delete recentfiles menu.  #if defined(WIN32)
193      if (m_pRecentFilesMenu)      WSACleanup();
194          delete m_pRecentFilesMenu;  #endif
     // Delete status item labels one by one.  
     if (m_status[QSAMPLER_STATUS_CLIENT])  
         delete m_status[QSAMPLER_STATUS_CLIENT];  
     if (m_status[QSAMPLER_STATUS_SERVER])  
         delete m_status[QSAMPLER_STATUS_SERVER];  
     if (m_status[QSAMPLER_STATUS_CHANNEL])  
         delete m_status[QSAMPLER_STATUS_CHANNEL];  
     if (m_status[QSAMPLER_STATUS_SESSION])  
         delete m_status[QSAMPLER_STATUS_SESSION];  
195    
196      // Finally drop any widgets around...      // Finally drop any widgets around...
197        if (m_pDeviceForm)
198            delete m_pDeviceForm;
199        if (m_pInstrumentListForm)
200            delete m_pInstrumentListForm;
201      if (m_pMessages)      if (m_pMessages)
202          delete m_pMessages;          delete m_pMessages;
203      if (m_pWorkspace)      if (m_pWorkspace)
204          delete m_pWorkspace;          delete m_pWorkspace;
205    
206  #if defined(WIN32)      // Delete status item labels one by one.
207      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
208  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
209        if (m_statusItem[QSAMPLER_STATUS_SERVER])
210            delete m_statusItem[QSAMPLER_STATUS_SERVER];
211        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
212            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
213        if (m_statusItem[QSAMPLER_STATUS_SESSION])
214            delete m_statusItem[QSAMPLER_STATUS_SESSION];
215    
216        // Delete recentfiles menu.
217        if (m_pRecentFilesMenu)
218            delete m_pRecentFilesMenu;
219    
220            // Pseudo-singleton reference shut-down.
221            g_pMainForm = NULL;
222  }  }
223    
224    
# Line 205  void qsamplerMainForm::setup ( qsamplerO Line 228  void qsamplerMainForm::setup ( qsamplerO
228      // We got options?      // We got options?
229      m_pOptions = pOptions;      m_pOptions = pOptions;
230    
231          // Set initial instrument name display mode.      // What style do we create these forms?
232      qsamplerChannel::setInstrumentNames(m_pOptions->bInstrumentNames);          Qt::WFlags wflags = Qt::WStyle_Customize
233                    | Qt::WStyle_NormalBorder
234                    | Qt::WStyle_Title
235                    | Qt::WStyle_SysMenu
236                    | Qt::WStyle_MinMax
237                    | Qt::WType_TopLevel;
238        if (m_pOptions->bKeepOnTop)
239            wflags |= Qt::WStyle_Tool;
240      // Some child forms are to be created right now.      // Some child forms are to be created right now.
241      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
242        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
243    #ifdef CONFIG_MIDI_INSTRUMENT
244        m_pInstrumentListForm = new qsamplerInstrumentListForm(this, 0, wflags);
245            QObject::connect(m_pInstrumentListForm->InstrumentList,
246                    SIGNAL(instrumentsChanged()),
247                    SLOT(sessionDirty()));
248    #else
249            viewInstrumentsAction->setEnabled(false);
250    #endif
251      // Set message defaults...      // Set message defaults...
252      updateMessagesFont();      updateMessagesFont();
253      updateMessagesLimit();      updateMessagesLimit();
254      updateMessagesCapture();      updateMessagesCapture();
255      // Set the visibility signal.      // Set the visibility signal.
256      QObject::connect(m_pMessages, SIGNAL(visibilityChanged(bool)), this, SLOT(stabilizeForm()));      QObject::connect(m_pMessages,
257                    SIGNAL(visibilityChanged(bool)),
258                    SLOT(stabilizeForm()));
259    
260      // Initial decorations toggle state.      // Initial decorations toggle state.
261      viewMenubarAction->setOn(m_pOptions->bMenubar);      viewMenubarAction->setOn(m_pOptions->bMenubar);
# Line 238  void qsamplerMainForm::setup ( qsamplerO Line 278  void qsamplerMainForm::setup ( qsamplerO
278          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
279          istr >> *this;          istr >> *this;
280      }      }
281      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
282      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
283        m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
284        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
285    
286      // Final startup stabilization...      // Final startup stabilization...
287      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 277  bool qsamplerMainForm::queryClose (void) Line 319  bool qsamplerMainForm::queryClose (void)
319              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
320              ostr << *this;              ostr << *this;
321              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
322              // And the main windows state.              // And the children, and the main windows state,.
323              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
324                            m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
325                            m_pOptions->saveWidgetGeometry(this);
326                            // Close popup widgets.
327                            if (m_pInstrumentListForm)
328                                    m_pInstrumentListForm->close();
329                            if (m_pDeviceForm)
330                                    m_pDeviceForm->close();
331              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
332              stopServer();              stopServer();
333          }          }
# Line 297  void qsamplerMainForm::closeEvent ( QClo Line 346  void qsamplerMainForm::closeEvent ( QClo
346  }  }
347    
348    
349  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
350  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
351  {  {
352      bool bAccept = false;      bool bDecode = false;
353    
354      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
355          QString sUrl;          QString sText;
356          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
357              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
358                files = QStringList::split('\n', sText);
359                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
360                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
361            }
362      }      }
363    
364      pDragEnterEvent->accept(bAccept);      return bDecode;
365    }
366    
367    
368    // Window drag-n-drop event handlers.
369    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
370    {
371            QStringList files;
372            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
373  }  }
374    
375    
376  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
377  {  {
378      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
379          QString sUrl;  
380          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
381              loadSessionFile(QUrl(sUrl).path());          return;
382      }  
383            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
384                    const QString& sPath = *iter;
385                    if (qsamplerChannel::isInstrumentFile(sPath)) {
386                            // Try to create a new channel from instrument file...
387                            qsamplerChannel *pChannel = new qsamplerChannel();
388                            if (pChannel == NULL)
389                                    return;
390                            // Start setting the instrument filename...
391                            pChannel->setInstrument(sPath, 0);
392                            // Before we show it up, may be we'll
393                            // better ask for some initial values?
394                            if (!pChannel->channelSetup(this)) {
395                                    delete pChannel;
396                                    return;
397                            }
398                            // Finally, give it to a new channel strip...
399                            if (!createChannelStrip(pChannel)) {
400                                    delete pChannel;
401                                    return;
402                            }
403                            // Make that an overall update.
404                            m_iDirtyCount++;
405                            stabilizeForm();
406                    }   // Otherwise, load an usual session file (LSCP script)...
407                    else if (closeSession(true))
408                            loadSessionFile(sPath);
409                    // Make it look responsive...:)
410                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
411            }
412  }  }
413    
414    
# Line 328  void qsamplerMainForm::customEvent ( QCu Line 418  void qsamplerMainForm::customEvent ( QCu
418      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
419      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
420          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
421          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
422              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
423              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
424                            if (pChannelStrip)
425                                    channelStripChanged(pChannelStrip);
426                    } else {
427                            appendMessagesColor(tr("Notify event: %1 data: %2")
428                                    .arg(::lscp_event_to_text(pEvent->event()))
429                                    .arg(pEvent->data()), "#996699");
430                    }
431      }      }
432  }  }
433    
# Line 339  void qsamplerMainForm::customEvent ( QCu Line 436  void qsamplerMainForm::customEvent ( QCu
436  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
437  {  {
438      stabilizeForm();      stabilizeForm();
439        
440      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
441  }  }
442    
# Line 353  qsamplerOptions *qsamplerMainForm::optio Line 450  qsamplerOptions *qsamplerMainForm::optio
450      return m_pOptions;      return m_pOptions;
451  }  }
452    
453    
454  // The LSCP client descriptor property.  // The LSCP client descriptor property.
455  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
456  {  {
# Line 360  lscp_client_t *qsamplerMainForm::client Line 458  lscp_client_t *qsamplerMainForm::client
458  }  }
459    
460    
461    // The pseudo-singleton instance accessor.
462    qsamplerMainForm *qsamplerMainForm::getInstance (void)
463    {
464            return g_pMainForm;
465    }
466    
467    
468  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
469  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
470    
# Line 383  bool qsamplerMainForm::newSession (void) Line 488  bool qsamplerMainForm::newSession (void)
488      if (!closeSession(true))      if (!closeSession(true))
489          return false;          return false;
490    
491            // Give us what the server has, right now...
492            updateSession();
493    
494      // Ok increment untitled count.      // Ok increment untitled count.
495      m_iUntitled++;      m_iUntitled++;
496    
# Line 404  bool qsamplerMainForm::openSession (void Line 512  bool qsamplerMainForm::openSession (void
512    
513      // Ask for the filename to open...      // Ask for the filename to open...
514      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
515              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
516              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
517              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
518              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
519      );      );
520    
521      // Have we cancelled?      // Have we cancelled?
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 546  bool qsamplerMainForm::saveSession ( boo
546              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
547          // Prompt the guy...          // Prompt the guy...
548          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
549                  sFilename,                              // Start here.                          sFilename,                              // Start here.
550                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
551                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
552                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
553          );          );
554          // Have we cancelled it?          // Have we cancelled it?
555          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 451  bool qsamplerMainForm::saveSession ( boo Line 559  bool qsamplerMainForm::saveSession ( boo
559              sFilename += ".lscp";              sFilename += ".lscp";
560          // Check if already exists...          // Check if already exists...
561          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
562              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
563                                    QSAMPLER_TITLE ": " + tr("Warning"),
564                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
565                     "\"%1\"\n\n"                     "\"%1\"\n\n"
566                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 473  bool qsamplerMainForm::closeSession ( bo Line 582  bool qsamplerMainForm::closeSession ( bo
582    
583      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
584      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
585          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
586                            QSAMPLER_TITLE ": " + tr("Warning"),
587              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
588              "\"%1\"\n\n"              "\"%1\"\n\n"
589              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 531  bool qsamplerMainForm::loadSessionFile ( Line 641  bool qsamplerMainForm::loadSessionFile (
641      QTextStream ts(&file);      QTextStream ts(&file);
642      while (!ts.atEnd()) {      while (!ts.atEnd()) {
643          // Read the line.          // Read the line.
644          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
645          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
646          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
647              appendMessagesColor(sCommand, "#996633");              appendMessagesColor(sCommand, "#996633");
# Line 550  bool qsamplerMainForm::loadSessionFile ( Line 660  bool qsamplerMainForm::loadSessionFile (
660      // Ok. we've read it.      // Ok. we've read it.
661      file.close();      file.close();
662    
663      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
664      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
665    
666      // Now we'll try to create the whole GUI session.          // Have we any errors?
667      int *piChannelIDs = ::lscp_list_channels(m_pClient);          if (iErrors > 0)
668      if (piChannelIDs == NULL) {                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
         appendMessagesClient("lscp_list_channels");  
         appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));  
     }  
       
     // Try to (re)create each channel.  
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {  
         createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));  
         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
669    
670      // Save as default session directory.      // Save as default session directory.
671      if (m_pOptions)      if (m_pOptions)
672          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
673      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
674      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
675      // Stabilize form...      // Stabilize form...
676      m_sFilename = sFilename;      m_sFilename = sFilename;
677      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
678      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
679        
680      // Make that an overall update.      // Make that an overall update.
     m_iChangeCount++;  
681      stabilizeForm();      stabilizeForm();
682      return true;      return true;
683  }  }
# Line 589  bool qsamplerMainForm::loadSessionFile ( Line 686  bool qsamplerMainForm::loadSessionFile (
686  // Save current session to specific file path.  // Save current session to specific file path.
687  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
688  {  {
689            if (m_pClient == NULL)
690                    return false;
691    
692            // Check whether server is apparently OK...
693            if (::lscp_get_channels(m_pClient) < 0) {
694                    appendMessagesClient("lscp_get_channels");
695                    return false;
696            }
697    
698      // Open and write into real file.      // Open and write into real file.
699      QFile file(sFilename);      QFile file(sFilename);
700      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 597  bool qsamplerMainForm::saveSessionFile ( Line 703  bool qsamplerMainForm::saveSessionFile (
703      }      }
704    
705      // Write the file.      // Write the file.
706      int iErrors = 0;      int  iErrors = 0;
707      QTextStream ts(&file);      QTextStream ts(&file);
708      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
709      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 608  bool qsamplerMainForm::saveSessionFile ( Line 714  bool qsamplerMainForm::saveSessionFile (
714      ts << "# " << tr("File")      ts << "# " << tr("File")
715         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
716      ts << "# " << tr("Date")      ts << "# " << tr("Date")
717         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
718         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
719      ts << "#"  << endl;      ts << "#"  << endl;
720      ts << endl;      ts << endl;
721    
722            // It is assumed that this new kind of device+session file
723            // will be loaded from a complete initialized server...
724            int *piDeviceIDs;
725            int  iDevice;
726            ts << "RESET" << endl;
727    
728            // Audio device mapping.
729            QMap<int, int> audioDeviceMap;
730            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
731            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
732                    ts << endl;
733                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
734                    // Audio device specification...
735                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
736                            << " " << tr("Device") << " " << iDevice << endl;
737                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
738                    qsamplerDeviceParamMap::ConstIterator deviceParam;
739                    for (deviceParam = device.params().begin();
740                                    deviceParam != device.params().end();
741                                            ++deviceParam) {
742                            const qsamplerDeviceParam& param = deviceParam.data();
743                            if (param.value.isEmpty()) ts << "# ";
744                            ts << " " << deviceParam.key() << "='" << param.value << "'";
745                    }
746                    ts << endl;
747                    // Audio channel parameters...
748                    int iPort = 0;
749                    for (qsamplerDevicePort *pPort = device.ports().first();
750                                    pPort;
751                                            pPort = device.ports().next(), ++iPort) {
752                            qsamplerDeviceParamMap::ConstIterator portParam;
753                            for (portParam = pPort->params().begin();
754                                            portParam != pPort->params().end();
755                                                    ++portParam) {
756                                    const qsamplerDeviceParam& param = portParam.data();
757                                    if (param.fix || param.value.isEmpty()) ts << "# ";
758                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
759                                            << " " << iPort << " " << portParam.key()
760                                            << "='" << param.value << "'" << endl;
761                            }
762                    }
763                    // Audio device index/id mapping.
764                    audioDeviceMap[device.deviceID()] = iDevice;
765                    // Try to keep it snappy :)
766                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
767            }
768    
769            // MIDI device mapping.
770            QMap<int, int> midiDeviceMap;
771            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
772            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
773                    ts << endl;
774                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
775                    // MIDI device specification...
776                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
777                            << " " << tr("Device") << " " << iDevice << endl;
778                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
779                    qsamplerDeviceParamMap::ConstIterator deviceParam;
780                    for (deviceParam = device.params().begin();
781                                    deviceParam != device.params().end();
782                                            ++deviceParam) {
783                            const qsamplerDeviceParam& param = deviceParam.data();
784                            if (param.value.isEmpty()) ts << "# ";
785                            ts << " " << deviceParam.key() << "='" << param.value << "'";
786                    }
787                    ts << endl;
788                    // MIDI port parameters...
789                    int iPort = 0;
790                    for (qsamplerDevicePort *pPort = device.ports().first();
791                                    pPort;
792                                            pPort = device.ports().next(), ++iPort) {
793                            qsamplerDeviceParamMap::ConstIterator portParam;
794                            for (portParam = pPort->params().begin();
795                                            portParam != pPort->params().end();
796                                                    ++portParam) {
797                                    const qsamplerDeviceParam& param = portParam.data();
798                                    if (param.fix || param.value.isEmpty()) ts << "# ";
799                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
800                                       << " " << iPort << " " << portParam.key()
801                                       << "='" << param.value << "'" << endl;
802                            }
803                    }
804                    // MIDI device index/id mapping.
805                    midiDeviceMap[device.deviceID()] = iDevice;
806                    // Try to keep it snappy :)
807                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
808            }
809            ts << endl;
810    
811    #ifdef CONFIG_MIDI_INSTRUMENT
812            // MIDI instrument mapping...
813            QMap<int, int> midiInstrumentMap;
814            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
815            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
816                    int iMidiMap = piMaps[iMap];
817                    const char *pszMapName
818                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
819                    ts << "# " << tr("MIDI instrument map") << " " << iMap;
820                    if (pszMapName)
821                            ts << " - " << pszMapName;
822                    ts << endl;
823                    ts << "ADD MIDI_INSTRUMENT_MAP";
824                    if (pszMapName)
825                            ts << " '" << pszMapName << "'";
826                    ts << endl;
827                    // MIDI instrument mapping...
828                    lscp_midi_instrument_t *pInstrs
829                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
830                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
831                            lscp_midi_instrument_info_t *pInstrInfo
832                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
833                            if (pInstrInfo) {
834                                    ts << "MAP MIDI_INSTRUMENT "
835                                            << iMap                        << " "
836                                            << pInstrs[iInstr].bank        << " "
837                                            << pInstrs[iInstr].prog        << " "
838                                            << pInstrInfo->engine_name     << " '"
839                                            << pInstrInfo->instrument_file << "' "
840                                            << pInstrInfo->instrument_nr   << " "
841                                            << pInstrInfo->volume          << " ";
842                                    switch (pInstrInfo->load_mode) {
843                                            case LSCP_LOAD_PERSISTENT:
844                                                    ts << "PERSISTENT";
845                                                    break;
846                                            case LSCP_LOAD_ON_DEMAND_HOLD:
847                                                    ts << "ON_DEMAND_HOLD";
848                                                    break;
849                                            case LSCP_LOAD_ON_DEMAND:
850                                            case LSCP_LOAD_DEFAULT:
851                                            default:
852                                                    ts << "ON_DEMAND";
853                                                    break;
854                                    }
855                                    if (pInstrInfo->name)
856                                            ts << " '" << pInstrInfo->name << "'";
857                                    ts << endl;
858                            }
859                            // MIDI device index/id mapping.
860                            midiInstrumentMap[iMidiMap] = iMap;
861                            // Try to keep it snappy :)
862                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
863                    }
864                    if (pInstrs)
865                            ts << endl;
866            }
867    #endif //  CONFIG_MIDI_INSTRUMENT
868    
869            // Sampler channel mapping.
870      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
871      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
872          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
873          if (pChannelStrip) {          if (pChannelStrip) {
874              qsamplerChannel *pChannel = pChannelStrip->channel();              qsamplerChannel *pChannel = pChannelStrip->channel();
875              if (pChannel) {              if (pChannel) {
876                  int iChannelID = pChannel->channelID();                  ts << "# " << tr("Channel") << " " << iChannel << endl;
                 ts << "# " << pChannelStrip->caption() << endl;  
877                  ts << "ADD CHANNEL" << endl;                  ts << "ADD CHANNEL" << endl;
878                  ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                                  if (audioDeviceMap.isEmpty()) {
879                  ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
880                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                                  << " " << pChannel->audioDriver() << endl;
881                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  } else {
882                                            ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
883                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
884                                    }
885                                    if (midiDeviceMap.isEmpty()) {
886                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
887                                                    << " " << pChannel->midiDriver() << endl;
888                                    } else {
889                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
890                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
891                                    }
892                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
893                                            << " " << pChannel->midiPort() << endl;
894                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
895                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
896                      ts << "ALL";                      ts << "ALL";
897                  else                  else
898                      ts << pChannel->midiChannel();                      ts << pChannel->midiChannel();
899                  ts << endl;                  ts << endl;
900                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
901                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
902                  ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
903                                            << pChannel->instrumentNr() << " " << iChannel << endl;
904                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
905                                    for (audioRoute = pChannel->audioRouting().begin();
906                                                    audioRoute != pChannel->audioRouting().end();
907                                                            ++audioRoute) {
908                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
909                                                    << " " << audioRoute.key()
910                                                    << " " << audioRoute.data() << endl;
911                                    }
912                                    ts << "SET CHANNEL VOLUME " << iChannel
913                                            << " " << pChannel->volume() << endl;
914                                    if (pChannel->channelMute())
915                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
916                                    if (pChannel->channelSolo())
917                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
918    #ifdef CONFIG_MIDI_INSTRUMENT
919                                    if (pChannel->midiMap() >= 0) {
920                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
921                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
922                                    }
923    #endif
924                  ts << endl;                  ts << endl;
925              }              }
926          }          }
# Line 661  bool qsamplerMainForm::saveSessionFile ( Line 949  bool qsamplerMainForm::saveSessionFile (
949  }  }
950    
951    
952    // Session change receiver slot.
953    void qsamplerMainForm::sessionDirty (void)
954    {
955        // Just mark the dirty form.
956        m_iDirtyCount++;
957        // and update the form status...
958        stabilizeForm();
959    }
960    
961    
962  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
963  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
964    
# Line 714  void qsamplerMainForm::fileReset (void) Line 1012  void qsamplerMainForm::fileReset (void)
1012          return;          return;
1013    
1014      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
1015      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
1016                    QSAMPLER_TITLE ": " + tr("Warning"),
1017          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
1018             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
1019             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
1020             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
1021             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
1022          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
1023          return;          return;
# Line 732  void qsamplerMainForm::fileReset (void) Line 1031  void qsamplerMainForm::fileReset (void)
1031    
1032      // Log this.      // Log this.
1033      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
1034    
1035            // Make it a new session...
1036            newSession();
1037  }  }
1038    
1039    
# Line 740  void qsamplerMainForm::fileRestart (void Line 1042  void qsamplerMainForm::fileRestart (void
1042  {  {
1043      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1044          return;          return;
1045            
1046      bool bRestart = true;      bool bRestart = true;
1047        
1048      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1049      // (if we're currently up and running)      // (if we're currently up and running)
1050      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1051          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1052                            QSAMPLER_TITLE ": " + tr("Warning"),
1053              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1054                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1055                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1056                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1057                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1058              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1059      }      }
# Line 783  void qsamplerMainForm::editAddChannel (v Line 1086  void qsamplerMainForm::editAddChannel (v
1086          return;          return;
1087    
1088      // Just create the channel instance...      // Just create the channel instance...
1089      qsamplerChannel *pChannel = new qsamplerChannel(this);      qsamplerChannel *pChannel = new qsamplerChannel();
1090      if (pChannel == NULL)      if (pChannel == NULL)
1091          return;          return;
1092    
# Line 793  void qsamplerMainForm::editAddChannel (v Line 1096  void qsamplerMainForm::editAddChannel (v
1096          delete pChannel;          delete pChannel;
1097          return;          return;
1098      }      }
1099        
1100      // And give it to the strip (will own the channel instance, if successful).      // And give it to the strip (will own the channel instance, if successful).
1101      if (!createChannelStrip(pChannel)) {      if (!createChannelStrip(pChannel)) {
1102          delete pChannel;          delete pChannel;
# Line 802  void qsamplerMainForm::editAddChannel (v Line 1105  void qsamplerMainForm::editAddChannel (v
1105    
1106      // Make that an overall update.      // Make that an overall update.
1107      m_iDirtyCount++;      m_iDirtyCount++;
     m_iChangeCount++;  
1108      stabilizeForm();      stabilizeForm();
1109  }  }
1110    
# Line 816  void qsamplerMainForm::editRemoveChannel Line 1118  void qsamplerMainForm::editRemoveChannel
1118      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1119      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1120          return;          return;
1121            
1122      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
1123      if (pChannel == NULL)      if (pChannel == NULL)
1124          return;          return;
1125    
1126      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1127      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1128          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1129                            QSAMPLER_TITLE ": " + tr("Warning"),
1130              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1131                 "%1\n\n"                 "%1\n\n"
1132                 "Are you sure?")                 "Are you sure?")
# Line 838  void qsamplerMainForm::editRemoveChannel Line 1141  void qsamplerMainForm::editRemoveChannel
1141    
1142      // Just delete the channel strip.      // Just delete the channel strip.
1143      delete pChannelStrip;      delete pChannelStrip;
1144        
1145      // Do we auto-arrange?      // Do we auto-arrange?
1146      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1147          channelsArrange();          channelsArrange();
# Line 874  void qsamplerMainForm::editResetChannel Line 1177  void qsamplerMainForm::editResetChannel
1177      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1178          return;          return;
1179    
1180      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1181      if (pChannel == NULL)      pChannelStrip->channelReset();
1182          return;  }
1183    
     // Reset the existing sampler channel.  
     pChannel->resetChannel();  
1184    
1185      // And force a deferred update.  // Reset all sampler channels.
1186      m_iChangeCount++;  void qsamplerMainForm::editResetAllChannels (void)
1187    {
1188            if (m_pClient == NULL)
1189                    return;
1190    
1191            // Invoque the channel strip procedure,
1192            // for all channels out there...
1193            m_pWorkspace->setUpdatesEnabled(false);
1194            QWidgetList wlist = m_pWorkspace->windowList();
1195            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1196                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1197                    if (pChannelStrip)
1198                            pChannelStrip->channelReset();
1199            }
1200            m_pWorkspace->setUpdatesEnabled(true);
1201  }  }
1202    
1203    
# Line 934  void qsamplerMainForm::viewMessages ( bo Line 1249  void qsamplerMainForm::viewMessages ( bo
1249  }  }
1250    
1251    
1252    // Show/hide the MIDI instrument list-view form.
1253    void qsamplerMainForm::viewInstruments (void)
1254    {
1255            if (m_pOptions == NULL)
1256                    return;
1257    
1258            if (m_pInstrumentListForm) {
1259                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1260                    if (m_pInstrumentListForm->isVisible()) {
1261                            m_pInstrumentListForm->hide();
1262                    } else {
1263                            m_pInstrumentListForm->show();
1264                            m_pInstrumentListForm->raise();
1265                            m_pInstrumentListForm->setActiveWindow();
1266                    }
1267            }
1268    }
1269    
1270    
1271    // Show/hide the device configurator form.
1272    void qsamplerMainForm::viewDevices (void)
1273    {
1274            if (m_pOptions == NULL)
1275                    return;
1276    
1277            if (m_pDeviceForm) {
1278                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1279                    if (m_pDeviceForm->isVisible()) {
1280                            m_pDeviceForm->hide();
1281                    } else {
1282                            m_pDeviceForm->show();
1283                            m_pDeviceForm->raise();
1284                            m_pDeviceForm->setActiveWindow();
1285                    }
1286            }
1287    }
1288    
1289    
1290  // Show options dialog.  // Show options dialog.
1291  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1292  {  {
# Line 958  void qsamplerMainForm::viewOptions (void Line 1311  void qsamplerMainForm::viewOptions (void
1311          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1312          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1313          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1314            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1315          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1316          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1317          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1318          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
         int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;  
1319          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1320            int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1321          // Load the current setup settings.          // Load the current setup settings.
1322          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
1323          // Show the setup dialog...          // Show the setup dialog...
1324          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1325              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1326              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1327                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1328                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1329                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1330                    QMessageBox::information(this,
1331                                            QSAMPLER_TITLE ": " + tr("Information"),
1332                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1333                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1334                  updateMessagesCapture();                  updateMessagesCapture();
1335              }              }
1336              // Check wheather something immediate has changed.              // Check wheather something immediate has changed.
             if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||  
                 (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))  
                 qsamplerChannel::setInstrumentNames(m_pOptions->bInstrumentNames);  
1337              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1338                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1339                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1340                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1341                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1342                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1343                    updateInstrumentNames();
1344              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1345                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1346                  updateDisplayEffect();                  updateDisplayEffect();
# Line 1045  void qsamplerMainForm::channelsArrange ( Line 1402  void qsamplerMainForm::channelsArrange (
1402          y += iHeight;          y += iHeight;
1403      }      }
1404      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1405        
1406      stabilizeForm();      stabilizeForm();
1407  }  }
1408    
# Line 1094  void qsamplerMainForm::helpAbout (void) Line 1451  void qsamplerMainForm::helpAbout (void)
1451      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1452      sText += "</font></small><br />";      sText += "</font></small><br />";
1453  #endif  #endif
1454    #ifndef CONFIG_INSTRUMENT_NAME
1455        sText += "<small><font color=\"red\">";
1456        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1457        sText += "</font></small><br />";
1458    #endif
1459    #ifndef CONFIG_MUTE_SOLO
1460        sText += "<small><font color=\"red\">";
1461        sText += tr("Sampler channel Mute/Solo support disabled.");
1462        sText += "</font></small><br />";
1463    #endif
1464    #ifndef CONFIG_MIDI_INSTRUMENT
1465        sText += "<small><font color=\"red\">";
1466        sText += tr("MIDI instrument mapping support disabled.");
1467        sText += "</font></small><br />";
1468    #endif
1469      sText += "<br />\n";      sText += "<br />\n";
1470      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1471      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1472      sText += " ";      sText += " ";
1473      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1474    #ifdef CONFIG_LIBGIG
1475        sText += ", ";
1476        sText += gig::libraryName().c_str();
1477        sText += " ";
1478        sText += gig::libraryVersion().c_str();
1479    #endif
1480      sText += "<br />\n";      sText += "<br />\n";
1481      sText += "<br />\n";      sText += "<br />\n";
1482      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";      sText += tr("Website") + ": <a href=\"" QSAMPLER_WEBSITE "\">" QSAMPLER_WEBSITE "</a><br />\n";
# Line 1121  void qsamplerMainForm::helpAbout (void) Line 1499  void qsamplerMainForm::helpAbout (void)
1499  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1500  {  {
1501      // Update the main application caption...      // Update the main application caption...
1502      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1503      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1504          sSessioName += '*';          sSessionName += " *";
1505      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1506    
1507      // Update the main menu state...      // Update the main menu state...
1508      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1140  void qsamplerMainForm::stabilizeForm (vo Line 1518  void qsamplerMainForm::stabilizeForm (vo
1518      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1519      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1520      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1521      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1522      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1523    #ifdef CONFIG_MIDI_INSTRUMENT
1524            viewInstrumentsAction->setOn(m_pInstrumentListForm
1525                    && m_pInstrumentListForm->isVisible());
1526            viewInstrumentsAction->setEnabled(bHasClient);
1527    #endif
1528            viewDevicesAction->setOn(m_pDeviceForm
1529                    && m_pDeviceForm->isVisible());
1530        viewDevicesAction->setEnabled(bHasClient);
1531        channelsArrangeAction->setEnabled(bHasChannel);
1532    
1533      // Client/Server status...      // Client/Server status...
1534      if (bHasClient) {      if (bHasClient) {
1535          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1536          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));
1537      } else {      } else {
1538          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1539          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1540      }      }
1541      // Channel status...      // Channel status...
1542      if (bHasChannel)      if (bHasChannel)
1543          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1544      else      else
1545          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1546      // Session status...      // Session status...
1547      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1548          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1549      else      else
1550          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1551    
1552      // Recent files menu.      // Recent files menu.
1553      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1172  void qsamplerMainForm::stabilizeForm (vo Line 1559  void qsamplerMainForm::stabilizeForm (vo
1559    
1560    
1561  // Channel change receiver slot.  // Channel change receiver slot.
1562  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1563  {  {
1564      // Flag that we're update those channel strips.          // Add this strip to the changed list...
1565      m_iChangeCount++;          if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1566                    m_changedStrips.append(pChannelStrip);
1567                    pChannelStrip->resetErrorCount();
1568            }
1569    
1570      // Just mark the dirty form.      // Just mark the dirty form.
1571      m_iDirtyCount++;      m_iDirtyCount++;
1572      // and update the form status...      // and update the form status...
# Line 1183  void qsamplerMainForm::channelStripChang Line 1574  void qsamplerMainForm::channelStripChang
1574  }  }
1575    
1576    
1577    // Grab and restore current sampler channels session.
1578    void qsamplerMainForm::updateSession (void)
1579    {
1580    #ifdef CONFIG_MIDI_INSTRUMENT
1581            // FIXME Make some room for default instrument maps...
1582            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1583            if (iMaps < 0)
1584                    appendMessagesClient("lscp_get_midi_instrument_maps");
1585            else if (iMaps < 1) {
1586                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1587                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1588            }
1589    #endif
1590    
1591            // Retrieve the current channel list.
1592            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1593            if (piChannelIDs == NULL) {
1594                    if (::lscp_client_get_errno(m_pClient)) {
1595                            appendMessagesClient("lscp_list_channels");
1596                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1597                    }
1598                    return;
1599            }
1600    
1601            // Try to (re)create each channel.
1602            m_pWorkspace->setUpdatesEnabled(false);
1603            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1604                    // Check if theres already a channel strip for this one...
1605                    if (!channelStrip(piChannelIDs[iChannel]))
1606                            createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1607                    // Make it visibly responsive...
1608                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1609            }
1610            m_pWorkspace->setUpdatesEnabled(true);
1611    
1612            // Remember to refresh devices and instruments...
1613            if (m_pInstrumentListForm)
1614                m_pInstrumentListForm->refreshInstruments();
1615            if (m_pDeviceForm)
1616                m_pDeviceForm->refreshDevices();
1617    }
1618    
1619    
1620  // Update the recent files list and menu.  // Update the recent files list and menu.
1621  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1622  {  {
# Line 1227  void qsamplerMainForm::updateRecentFiles Line 1661  void qsamplerMainForm::updateRecentFiles
1661  }  }
1662    
1663    
1664    // Force update of the channels instrument names mode.
1665    void qsamplerMainForm::updateInstrumentNames (void)
1666    {
1667        // Full channel list update...
1668        QWidgetList wlist = m_pWorkspace->windowList();
1669        if (wlist.isEmpty())
1670            return;
1671    
1672        m_pWorkspace->setUpdatesEnabled(false);
1673        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1674            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1675            if (pChannelStrip)
1676                pChannelStrip->updateInstrumentName(true);
1677        }
1678        m_pWorkspace->setUpdatesEnabled(true);
1679    }
1680    
1681    
1682  // Force update of the channels display font.  // Force update of the channels display font.
1683  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1684  {  {
# Line 1332  void qsamplerMainForm::appendMessagesErr Line 1784  void qsamplerMainForm::appendMessagesErr
1784    
1785      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1786    
1787      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));      QMessageBox::critical(this,
1788                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1789  }  }
1790    
1791    
# Line 1372  void qsamplerMainForm::updateMessagesLim Line 1825  void qsamplerMainForm::updateMessagesLim
1825          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1826              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1827          else          else
1828              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1829      }      }
1830  }  }
1831    
# Line 1404  qsamplerChannelStrip *qsamplerMainForm:: Line 1857  qsamplerChannelStrip *qsamplerMainForm::
1857          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1858          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1859              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1860          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1861              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1862                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1863                            }
1864          }          }
1865      }      }
1866    
# Line 1414  qsamplerChannelStrip *qsamplerMainForm:: Line 1869  qsamplerChannelStrip *qsamplerMainForm::
1869      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1870      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1871          return NULL;          return NULL;
1872            
1873      // Actual channel strip setup...      // Actual channel strip setup...
1874      pChannelStrip->setup(pChannel);      pChannelStrip->setup(pChannel);
1875      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
# Line 1439  qsamplerChannelStrip *qsamplerMainForm:: Line 1894  qsamplerChannelStrip *qsamplerMainForm::
1894          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1895          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1896      }      }
1897        
1898            // This is pretty new, so we'll watch for it closely.
1899            channelStripChanged(pChannelStrip);
1900    
1901      // Return our successful reference...      // Return our successful reference...
1902      return pChannelStrip;      return pChannelStrip;
1903  }  }
# Line 1457  qsamplerChannelStrip *qsamplerMainForm:: Line 1915  qsamplerChannelStrip *qsamplerMainForm::
1915  {  {
1916      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1917      if (wlist.isEmpty())      if (wlist.isEmpty())
1918          return 0;          return NULL;
1919    
1920      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1921  }  }
1922    
1923    
1924    // Retrieve a channel strip by sampler channel id.
1925    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1926    {
1927            QWidgetList wlist = m_pWorkspace->windowList();
1928            if (wlist.isEmpty())
1929                    return NULL;
1930    
1931            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1932                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1933                    if (pChannelStrip) {
1934                            qsamplerChannel *pChannel = pChannelStrip->channel();
1935                            if (pChannel && pChannel->channelID() == iChannelID)
1936                                    return pChannelStrip;
1937                    }
1938            }
1939    
1940            // Not found.
1941            return NULL;
1942    }
1943    
1944    
1945  // Construct the windows menu.  // Construct the windows menu.
1946  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1947  {  {
# Line 1529  void qsamplerMainForm::timerSlot (void) Line 2008  void qsamplerMainForm::timerSlot (void)
2008              }              }
2009          }          }
2010      }      }
2011        
2012          // Refresh each channel usage, on each period...          if (m_pClient) {
2013      if (m_pClient && (m_iChangeCount > 0 || m_pOptions->bAutoRefresh)) {                  // Update the channel information for each pending strip...
2014          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2015          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2016              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2017              m_iChangeCount = 0;                                  // If successfull, remove from pending list...
2018              QWidgetList wlist = m_pWorkspace->windowList();                                  if (pChannelStrip->updateChannelInfo())
2019              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                          m_changedStrips.remove(pChannelStrip);
2020                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                          }
2021                  if (pChannelStrip && pChannelStrip->isVisible()) {                  }
2022                      // If we can't make it clean, try next time.                  // Refresh each channel usage, on each period...
2023                      if (!pChannelStrip->updateChannelUsage())                  if (m_pOptions->bAutoRefresh) {
2024                          m_iChangeCount++;                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2025                  }                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2026              }                                  m_iTimerSlot = 0;
2027          }                                  // Update the channel stream usage for each strip...
2028      }                                  QWidgetList wlist = m_pWorkspace->windowList();
2029                                    for (int iChannel = 0;
2030                                                    iChannel < (int) wlist.count(); iChannel++) {
2031                                            qsamplerChannelStrip *pChannelStrip
2032                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2033                                            if (pChannelStrip && pChannelStrip->isVisible())
2034                                                    pChannelStrip->updateChannelUsage();
2035                                    }
2036                            }
2037                    }
2038            }
2039    
2040      // Register the next timer slot.      // Register the next timer slot.
2041      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1568  void qsamplerMainForm::startServer (void Line 2057  void qsamplerMainForm::startServer (void
2057    
2058      // Is the server process instance still here?      // Is the server process instance still here?
2059      if (m_pServer) {      if (m_pServer) {
2060          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2061                            QSAMPLER_TITLE ": " + tr("Warning"),
2062              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2063                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2064              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1727  bool qsamplerMainForm::startClient (void Line 2217  bool qsamplerMainForm::startClient (void
2217      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2218      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)));
2219    
2220            // Subscribe to channel info change notifications...
2221            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2222                    appendMessagesClient("lscp_client_subscribe");
2223    
2224      // We may stop scheduling around.      // We may stop scheduling around.
2225      stopSchedule();      stopSchedule();
2226    
# Line 1736  bool qsamplerMainForm::startClient (void Line 2230  bool qsamplerMainForm::startClient (void
2230      // Log success here.      // Log success here.
2231      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2232    
2233            // Hard-notify instrumnet and device configuration forms,
2234            // if visible, that we're ready...
2235            if (m_pInstrumentListForm)
2236                m_pInstrumentListForm->refreshInstruments();
2237            if (m_pDeviceForm)
2238                m_pDeviceForm->refreshDevices();
2239    
2240      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2241      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2242          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1770  void qsamplerMainForm::stopClient (void) Line 2271  void qsamplerMainForm::stopClient (void)
2271      // channels from the back-end server.      // channels from the back-end server.
2272      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2273      closeSession(false);      closeSession(false);
2274        
2275      // Close us as a client...      // Close us as a client...
2276      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2277        ::lscp_client_destroy(m_pClient);
2278      m_pClient = NULL;      m_pClient = NULL;
2279    
2280            // Hard-notify instrumnet and device configuration forms,
2281            // if visible, that we're running out...
2282            if (m_pInstrumentListForm)
2283                m_pInstrumentListForm->refreshInstruments();
2284            if (m_pDeviceForm)
2285                m_pDeviceForm->refreshDevices();
2286    
2287      // Log final here.      // Log final here.
2288      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2289    

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

  ViewVC Help
Powered by ViewVC