/[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 1000 by capela, Fri Dec 22 01:31:28 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                            break;
410                    }
411                    // Make it look responsive...:)
412                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
413            }
414  }  }
415    
416    
# Line 328  void qsamplerMainForm::customEvent ( QCu Line 420  void qsamplerMainForm::customEvent ( QCu
420      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
421      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
422          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
423          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
424              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
425              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
426                            if (pChannelStrip)
427                                    channelStripChanged(pChannelStrip);
428                    } else {
429                            appendMessagesColor(tr("Notify event: %1 data: %2")
430                                    .arg(::lscp_event_to_text(pEvent->event()))
431                                    .arg(pEvent->data()), "#996699");
432                    }
433      }      }
434  }  }
435    
# Line 339  void qsamplerMainForm::customEvent ( QCu Line 438  void qsamplerMainForm::customEvent ( QCu
438  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
439  {  {
440      stabilizeForm();      stabilizeForm();
441        
442      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
443  }  }
444    
# Line 353  qsamplerOptions *qsamplerMainForm::optio Line 452  qsamplerOptions *qsamplerMainForm::optio
452      return m_pOptions;      return m_pOptions;
453  }  }
454    
455    
456  // The LSCP client descriptor property.  // The LSCP client descriptor property.
457  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
458  {  {
# Line 360  lscp_client_t *qsamplerMainForm::client Line 460  lscp_client_t *qsamplerMainForm::client
460  }  }
461    
462    
463    // The pseudo-singleton instance accessor.
464    qsamplerMainForm *qsamplerMainForm::getInstance (void)
465    {
466            return g_pMainForm;
467    }
468    
469    
470  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
471  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
472    
# Line 383  bool qsamplerMainForm::newSession (void) Line 490  bool qsamplerMainForm::newSession (void)
490      if (!closeSession(true))      if (!closeSession(true))
491          return false;          return false;
492    
493            // Give us what the server has, right now...
494            updateSession();
495    
496      // Ok increment untitled count.      // Ok increment untitled count.
497      m_iUntitled++;      m_iUntitled++;
498    
# Line 404  bool qsamplerMainForm::openSession (void Line 514  bool qsamplerMainForm::openSession (void
514    
515      // Ask for the filename to open...      // Ask for the filename to open...
516      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
517              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
518              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
519              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
520              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
521      );      );
522    
523      // Have we cancelled?      // Have we cancelled?
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 548  bool qsamplerMainForm::saveSession ( boo
548              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
549          // Prompt the guy...          // Prompt the guy...
550          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
551                  sFilename,                              // Start here.                          sFilename,                              // Start here.
552                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
553                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
554                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
555          );          );
556          // Have we cancelled it?          // Have we cancelled it?
557          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 451  bool qsamplerMainForm::saveSession ( boo Line 561  bool qsamplerMainForm::saveSession ( boo
561              sFilename += ".lscp";              sFilename += ".lscp";
562          // Check if already exists...          // Check if already exists...
563          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
564              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
565                                    QSAMPLER_TITLE ": " + tr("Warning"),
566                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
567                     "\"%1\"\n\n"                     "\"%1\"\n\n"
568                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 473  bool qsamplerMainForm::closeSession ( bo Line 584  bool qsamplerMainForm::closeSession ( bo
584    
585      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
586      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
587          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
588                            QSAMPLER_TITLE ": " + tr("Warning"),
589              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
590              "\"%1\"\n\n"              "\"%1\"\n\n"
591              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 513  bool qsamplerMainForm::closeSession ( bo Line 625  bool qsamplerMainForm::closeSession ( bo
625  }  }
626    
627    
628    // Reset current session.
629    bool qsamplerMainForm::resetSession (void)
630    {
631    #ifdef CONFIG_MIDI_INSTRUMENT
632            // Reset all MIDI instrument mapping, if any.
633            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
634            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; ++iMap) {
635                    int iMidiMap = piMaps[iMap];
636                    if (::lscp_clear_midi_instruments(m_pClient, iMidiMap) != LSCP_OK)
637                            appendMessagesClient("lscp_clear_midi_instruments");
638                    if (::lscp_remove_midi_instrument_map(m_pClient, iMidiMap) != LSCP_OK)
639                            appendMessagesClient("lscp_remove_midi_instrument_map");
640            }
641            // Check for errors...
642            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient))
643                    appendMessagesClient("lscp_list_midi_instrument_maps");
644    #endif  // CONFIG_MIDI_INSTRUMENT
645    
646            // Do the actual sampler reset...
647            if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
648                    appendMessagesClient("lscp_reset_sampler");
649                    appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
650                    return false;
651            }
652    
653            // Done.
654            return true;
655    }
656    
657    
658  // Load a session from specific file path.  // Load a session from specific file path.
659  bool qsamplerMainForm::loadSessionFile ( const QString& sFilename )  bool qsamplerMainForm::loadSessionFile ( const QString& sFilename )
660  {  {
# Line 526  bool qsamplerMainForm::loadSessionFile ( Line 668  bool qsamplerMainForm::loadSessionFile (
668          return false;          return false;
669      }      }
670    
671            // Tell the world we'll take some time...
672            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
673    
674      // Read the file.      // Read the file.
675            int iLine = 0;
676      int iErrors = 0;      int iErrors = 0;
677      QTextStream ts(&file);      QTextStream ts(&file);
678      while (!ts.atEnd()) {      while (!ts.atEnd()) {
679          // Read the line.          // Read the line.
680          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
681                    iLine++;
682          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
683          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
684              appendMessagesColor(sCommand, "#996633");                          // HACK: A very special trap for the global RESET command...
685              // Remember that, no matter what,                          if (sCommand == "RESET") {
686              // all LSCP commands are CR/LF terminated.                                  // Do our own reset...
687              sCommand += "\r\n";                                  if (!resetSession())
688              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {                                          iErrors++;
689                  appendMessagesClient("lscp_client_query");                          } else {
690                  iErrors++;                                  // Remember that, no matter what,
691              }                                  // all LSCP commands are CR/LF terminated.
692                                    sCommand += "\r\n";
693                                    if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
694                                            appendMessagesColor(QString("%1(%2): %3")
695                                                    .arg(QFileInfo(sFilename).fileName()).arg(iLine)
696                                                    .arg(sCommand.simplifyWhiteSpace()), "#996633");
697                                            appendMessagesClient("lscp_client_query");
698                                            iErrors++;
699                                    }
700                            }
701          }          }
702          // Try to make it snappy :)          // Try to make it snappy :)
703          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
# Line 550  bool qsamplerMainForm::loadSessionFile ( Line 706  bool qsamplerMainForm::loadSessionFile (
706      // Ok. we've read it.      // Ok. we've read it.
707      file.close();      file.close();
708    
709      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
710      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
711    
712      // Now we'll try to create the whole GUI session.          // We're fornerly done.
713      int *piChannelIDs = ::lscp_list_channels(m_pClient);          QApplication::restoreOverrideCursor();
714      if (piChannelIDs == NULL) {  
715          appendMessagesClient("lscp_list_channels");          // Have we any errors?
716          appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));          if (iErrors > 0)
717      }                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
       
     // 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);  
718    
719      // Save as default session directory.      // Save as default session directory.
720      if (m_pOptions)      if (m_pOptions)
721          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
722      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
723      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
724      // Stabilize form...      // Stabilize form...
725      m_sFilename = sFilename;      m_sFilename = sFilename;
726      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
727      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
728        
729      // Make that an overall update.      // Make that an overall update.
     m_iChangeCount++;  
730      stabilizeForm();      stabilizeForm();
731      return true;      return true;
732  }  }
# Line 589  bool qsamplerMainForm::loadSessionFile ( Line 735  bool qsamplerMainForm::loadSessionFile (
735  // Save current session to specific file path.  // Save current session to specific file path.
736  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
737  {  {
738            if (m_pClient == NULL)
739                    return false;
740    
741            // Check whether server is apparently OK...
742            if (::lscp_get_channels(m_pClient) < 0) {
743                    appendMessagesClient("lscp_get_channels");
744                    return false;
745            }
746    
747      // Open and write into real file.      // Open and write into real file.
748      QFile file(sFilename);      QFile file(sFilename);
749      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 596  bool qsamplerMainForm::saveSessionFile ( Line 751  bool qsamplerMainForm::saveSessionFile (
751          return false;          return false;
752      }      }
753    
754            // Tell the world we'll take some time...
755            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
756    
757      // Write the file.      // Write the file.
758      int iErrors = 0;      int  iErrors = 0;
759      QTextStream ts(&file);      QTextStream ts(&file);
760      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
761      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 608  bool qsamplerMainForm::saveSessionFile ( Line 766  bool qsamplerMainForm::saveSessionFile (
766      ts << "# " << tr("File")      ts << "# " << tr("File")
767         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
768      ts << "# " << tr("Date")      ts << "# " << tr("Date")
769         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
770         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
771      ts << "#"  << endl;      ts << "#"  << endl;
772      ts << endl;      ts << endl;
773    
774            // It is assumed that this new kind of device+session file
775            // will be loaded from a complete initialized server...
776            int *piDeviceIDs;
777            int  iDevice;
778            ts << "RESET" << endl;
779    
780            // Audio device mapping.
781            QMap<int, int> audioDeviceMap;
782            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
783            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
784                    ts << endl;
785                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
786                    // Audio device specification...
787                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
788                            << " " << tr("Device") << " " << iDevice << endl;
789                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
790                    qsamplerDeviceParamMap::ConstIterator deviceParam;
791                    for (deviceParam = device.params().begin();
792                                    deviceParam != device.params().end();
793                                            ++deviceParam) {
794                            const qsamplerDeviceParam& param = deviceParam.data();
795                            if (param.value.isEmpty()) ts << "# ";
796                            ts << " " << deviceParam.key() << "='" << param.value << "'";
797                    }
798                    ts << endl;
799                    // Audio channel parameters...
800                    int iPort = 0;
801                    for (qsamplerDevicePort *pPort = device.ports().first();
802                                    pPort;
803                                            pPort = device.ports().next(), ++iPort) {
804                            qsamplerDeviceParamMap::ConstIterator portParam;
805                            for (portParam = pPort->params().begin();
806                                            portParam != pPort->params().end();
807                                                    ++portParam) {
808                                    const qsamplerDeviceParam& param = portParam.data();
809                                    if (param.fix || param.value.isEmpty()) ts << "# ";
810                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
811                                            << " " << iPort << " " << portParam.key()
812                                            << "='" << param.value << "'" << endl;
813                            }
814                    }
815                    // Audio device index/id mapping.
816                    audioDeviceMap[device.deviceID()] = iDevice;
817                    // Try to keep it snappy :)
818                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
819            }
820    
821            // MIDI device mapping.
822            QMap<int, int> midiDeviceMap;
823            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
824            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
825                    ts << endl;
826                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
827                    // MIDI device specification...
828                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
829                            << " " << tr("Device") << " " << iDevice << endl;
830                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
831                    qsamplerDeviceParamMap::ConstIterator deviceParam;
832                    for (deviceParam = device.params().begin();
833                                    deviceParam != device.params().end();
834                                            ++deviceParam) {
835                            const qsamplerDeviceParam& param = deviceParam.data();
836                            if (param.value.isEmpty()) ts << "# ";
837                            ts << " " << deviceParam.key() << "='" << param.value << "'";
838                    }
839                    ts << endl;
840                    // MIDI port parameters...
841                    int iPort = 0;
842                    for (qsamplerDevicePort *pPort = device.ports().first();
843                                    pPort;
844                                            pPort = device.ports().next(), ++iPort) {
845                            qsamplerDeviceParamMap::ConstIterator portParam;
846                            for (portParam = pPort->params().begin();
847                                            portParam != pPort->params().end();
848                                                    ++portParam) {
849                                    const qsamplerDeviceParam& param = portParam.data();
850                                    if (param.fix || param.value.isEmpty()) ts << "# ";
851                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
852                                       << " " << iPort << " " << portParam.key()
853                                       << "='" << param.value << "'" << endl;
854                            }
855                    }
856                    // MIDI device index/id mapping.
857                    midiDeviceMap[device.deviceID()] = iDevice;
858                    // Try to keep it snappy :)
859                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
860            }
861            ts << endl;
862    
863    #ifdef CONFIG_MIDI_INSTRUMENT
864            // MIDI instrument mapping...
865            QMap<int, int> midiInstrumentMap;
866            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
867            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
868                    int iMidiMap = piMaps[iMap];
869                    const char *pszMapName
870                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
871                    ts << "# " << tr("MIDI instrument map") << " " << iMap;
872                    if (pszMapName)
873                            ts << " - " << pszMapName;
874                    ts << endl;
875                    ts << "ADD MIDI_INSTRUMENT_MAP";
876                    if (pszMapName)
877                            ts << " '" << pszMapName << "'";
878                    ts << endl;
879                    // MIDI instrument mapping...
880                    lscp_midi_instrument_t *pInstrs
881                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
882                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
883                            lscp_midi_instrument_info_t *pInstrInfo
884                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
885                            if (pInstrInfo) {
886                                    ts << "MAP MIDI_INSTRUMENT "
887                                            << iMap                        << " "
888                                            << pInstrs[iInstr].bank        << " "
889                                            << pInstrs[iInstr].prog        << " "
890                                            << pInstrInfo->engine_name     << " '"
891                                            << pInstrInfo->instrument_file << "' "
892                                            << pInstrInfo->instrument_nr   << " "
893                                            << pInstrInfo->volume          << " ";
894                                    switch (pInstrInfo->load_mode) {
895                                            case LSCP_LOAD_PERSISTENT:
896                                                    ts << "PERSISTENT";
897                                                    break;
898                                            case LSCP_LOAD_ON_DEMAND_HOLD:
899                                                    ts << "ON_DEMAND_HOLD";
900                                                    break;
901                                            case LSCP_LOAD_ON_DEMAND:
902                                            case LSCP_LOAD_DEFAULT:
903                                            default:
904                                                    ts << "ON_DEMAND";
905                                                    break;
906                                    }
907                                    if (pInstrInfo->name)
908                                            ts << " '" << pInstrInfo->name << "'";
909                                    ts << endl;
910                            }       // Check for errors...
911                            else if (::lscp_client_get_errno(m_pClient)) {
912                                    appendMessagesClient("lscp_get_midi_instrument_info");
913                                    iErrors++;
914                            }
915                            // Try to keep it snappy :)
916                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
917                    }
918                    // Check for errors...
919                    if (pInstrs)
920                            ts << endl;
921                    else if (::lscp_client_get_errno(m_pClient)) {
922                            appendMessagesClient("lscp_list_midi_instruments");
923                            iErrors++;
924                    }
925                    // MIDI strument index/id mapping.
926                    midiInstrumentMap[iMidiMap] = iMap;
927            }
928            // Check for errors...
929            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
930                    appendMessagesClient("lscp_list_midi_instrument_maps");
931                    iErrors++;
932            }
933    #endif  // CONFIG_MIDI_INSTRUMENT
934    
935            // Sampler channel mapping.
936      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
937      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
938          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
939          if (pChannelStrip) {          if (pChannelStrip) {
940              qsamplerChannel *pChannel = pChannelStrip->channel();              qsamplerChannel *pChannel = pChannelStrip->channel();
941              if (pChannel) {              if (pChannel) {
942                  int iChannelID = pChannel->channelID();                  ts << "# " << tr("Channel") << " " << iChannel << endl;
                 ts << "# " << pChannelStrip->caption() << endl;  
943                  ts << "ADD CHANNEL" << endl;                  ts << "ADD CHANNEL" << endl;
944                  ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                                  if (audioDeviceMap.isEmpty()) {
945                  ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
946                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                                  << " " << pChannel->audioDriver() << endl;
947                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  } else {
948                                            ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
949                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
950                                    }
951                                    if (midiDeviceMap.isEmpty()) {
952                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
953                                                    << " " << pChannel->midiDriver() << endl;
954                                    } else {
955                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
956                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
957                                    }
958                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
959                                            << " " << pChannel->midiPort() << endl;
960                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
961                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
962                      ts << "ALL";                      ts << "ALL";
963                  else                  else
964                      ts << pChannel->midiChannel();                      ts << pChannel->midiChannel();
965                  ts << endl;                  ts << endl;
966                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
967                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
968                  ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
969                                            << pChannel->instrumentNr() << " " << iChannel << endl;
970                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
971                                    for (audioRoute = pChannel->audioRouting().begin();
972                                                    audioRoute != pChannel->audioRouting().end();
973                                                            ++audioRoute) {
974                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
975                                                    << " " << audioRoute.key()
976                                                    << " " << audioRoute.data() << endl;
977                                    }
978                                    ts << "SET CHANNEL VOLUME " << iChannel
979                                            << " " << pChannel->volume() << endl;
980                                    if (pChannel->channelMute())
981                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
982                                    if (pChannel->channelSolo())
983                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
984    #ifdef CONFIG_MIDI_INSTRUMENT
985                                    if (pChannel->midiMap() >= 0) {
986                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
987                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
988                                    }
989    #endif
990                  ts << endl;                  ts << endl;
991              }              }
992          }          }
# Line 643  bool qsamplerMainForm::saveSessionFile ( Line 997  bool qsamplerMainForm::saveSessionFile (
997      // Ok. we've wrote it.      // Ok. we've wrote it.
998      file.close();      file.close();
999    
1000            // We're fornerly done.
1001            QApplication::restoreOverrideCursor();
1002    
1003      // Have we any errors?      // Have we any errors?
1004      if (iErrors > 0)      if (iErrors > 0)
1005          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 661  bool qsamplerMainForm::saveSessionFile ( Line 1018  bool qsamplerMainForm::saveSessionFile (
1018  }  }
1019    
1020    
1021    // Session change receiver slot.
1022    void qsamplerMainForm::sessionDirty (void)
1023    {
1024        // Just mark the dirty form.
1025        m_iDirtyCount++;
1026        // and update the form status...
1027        stabilizeForm();
1028    }
1029    
1030    
1031  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1032  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
1033    
# Line 714  void qsamplerMainForm::fileReset (void) Line 1081  void qsamplerMainForm::fileReset (void)
1081          return;          return;
1082    
1083      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
1084      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
1085                    QSAMPLER_TITLE ": " + tr("Warning"),
1086          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
1087             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
1088             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
1089             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
1090             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
1091          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
1092          return;          return;
1093    
1094            // Trye closing the current session, first...
1095            if (!closeSession(true))
1096                    return;
1097    
1098      // Just do the reset, after closing down current session...      // Just do the reset, after closing down current session...
1099      if (closeSession(true) && ::lscp_reset_sampler(m_pClient) != LSCP_OK) {          if (!resetSession())
1100          appendMessagesClient("lscp_reset_sampler");                  return;
         appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));  
         return;  
     }  
1101    
1102      // Log this.      // Log this.
1103      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
1104    
1105            // Make it a new session...
1106            newSession();
1107  }  }
1108    
1109    
# Line 740  void qsamplerMainForm::fileRestart (void Line 1112  void qsamplerMainForm::fileRestart (void
1112  {  {
1113      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1114          return;          return;
1115            
1116      bool bRestart = true;      bool bRestart = true;
1117        
1118      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1119      // (if we're currently up and running)      // (if we're currently up and running)
1120      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1121          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1122                            QSAMPLER_TITLE ": " + tr("Warning"),
1123              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1124                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1125                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1126                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1127                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1128              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1129      }      }
# Line 783  void qsamplerMainForm::editAddChannel (v Line 1156  void qsamplerMainForm::editAddChannel (v
1156          return;          return;
1157    
1158      // Just create the channel instance...      // Just create the channel instance...
1159      qsamplerChannel *pChannel = new qsamplerChannel(this);      qsamplerChannel *pChannel = new qsamplerChannel();
1160      if (pChannel == NULL)      if (pChannel == NULL)
1161          return;          return;
1162    
# Line 793  void qsamplerMainForm::editAddChannel (v Line 1166  void qsamplerMainForm::editAddChannel (v
1166          delete pChannel;          delete pChannel;
1167          return;          return;
1168      }      }
1169        
1170      // 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).
1171      if (!createChannelStrip(pChannel)) {      if (!createChannelStrip(pChannel)) {
1172          delete pChannel;          delete pChannel;
# Line 802  void qsamplerMainForm::editAddChannel (v Line 1175  void qsamplerMainForm::editAddChannel (v
1175    
1176      // Make that an overall update.      // Make that an overall update.
1177      m_iDirtyCount++;      m_iDirtyCount++;
     m_iChangeCount++;  
1178      stabilizeForm();      stabilizeForm();
1179  }  }
1180    
# Line 816  void qsamplerMainForm::editRemoveChannel Line 1188  void qsamplerMainForm::editRemoveChannel
1188      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1189      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1190          return;          return;
1191            
1192      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
1193      if (pChannel == NULL)      if (pChannel == NULL)
1194          return;          return;
1195    
1196      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1197      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1198          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1199                            QSAMPLER_TITLE ": " + tr("Warning"),
1200              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1201                 "%1\n\n"                 "%1\n\n"
1202                 "Are you sure?")                 "Are you sure?")
# Line 838  void qsamplerMainForm::editRemoveChannel Line 1211  void qsamplerMainForm::editRemoveChannel
1211    
1212      // Just delete the channel strip.      // Just delete the channel strip.
1213      delete pChannelStrip;      delete pChannelStrip;
1214        
1215      // Do we auto-arrange?      // Do we auto-arrange?
1216      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1217          channelsArrange();          channelsArrange();
# Line 874  void qsamplerMainForm::editResetChannel Line 1247  void qsamplerMainForm::editResetChannel
1247      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1248          return;          return;
1249    
1250      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1251      if (pChannel == NULL)      pChannelStrip->channelReset();
1252          return;  }
1253    
     // Reset the existing sampler channel.  
     pChannel->resetChannel();  
1254    
1255      // And force a deferred update.  // Reset all sampler channels.
1256      m_iChangeCount++;  void qsamplerMainForm::editResetAllChannels (void)
1257    {
1258            if (m_pClient == NULL)
1259                    return;
1260    
1261            // Invoque the channel strip procedure,
1262            // for all channels out there...
1263            m_pWorkspace->setUpdatesEnabled(false);
1264            QWidgetList wlist = m_pWorkspace->windowList();
1265            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1266                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1267                    if (pChannelStrip)
1268                            pChannelStrip->channelReset();
1269            }
1270            m_pWorkspace->setUpdatesEnabled(true);
1271  }  }
1272    
1273    
# Line 934  void qsamplerMainForm::viewMessages ( bo Line 1319  void qsamplerMainForm::viewMessages ( bo
1319  }  }
1320    
1321    
1322    // Show/hide the MIDI instrument list-view form.
1323    void qsamplerMainForm::viewInstruments (void)
1324    {
1325            if (m_pOptions == NULL)
1326                    return;
1327    
1328            if (m_pInstrumentListForm) {
1329                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1330                    if (m_pInstrumentListForm->isVisible()) {
1331                            m_pInstrumentListForm->hide();
1332                    } else {
1333                            m_pInstrumentListForm->show();
1334                            m_pInstrumentListForm->raise();
1335                            m_pInstrumentListForm->setActiveWindow();
1336                    }
1337            }
1338    }
1339    
1340    
1341    // Show/hide the device configurator form.
1342    void qsamplerMainForm::viewDevices (void)
1343    {
1344            if (m_pOptions == NULL)
1345                    return;
1346    
1347            if (m_pDeviceForm) {
1348                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1349                    if (m_pDeviceForm->isVisible()) {
1350                            m_pDeviceForm->hide();
1351                    } else {
1352                            m_pDeviceForm->show();
1353                            m_pDeviceForm->raise();
1354                            m_pDeviceForm->setActiveWindow();
1355                    }
1356            }
1357    }
1358    
1359    
1360  // Show options dialog.  // Show options dialog.
1361  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1362  {  {
# Line 958  void qsamplerMainForm::viewOptions (void Line 1381  void qsamplerMainForm::viewOptions (void
1381          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1382          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1383          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1384            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1385          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1386          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1387          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1388          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
         int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;  
1389          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1390            int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1391          // Load the current setup settings.          // Load the current setup settings.
1392          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
1393          // Show the setup dialog...          // Show the setup dialog...
1394          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1395              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1396              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1397                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1398                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1399                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1400                    QMessageBox::information(this,
1401                                            QSAMPLER_TITLE ": " + tr("Information"),
1402                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1403                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1404                  updateMessagesCapture();                  updateMessagesCapture();
1405              }              }
1406              // 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);  
1407              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1408                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1409                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1410                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1411                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1412                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1413                    updateInstrumentNames();
1414              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1415                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1416                  updateDisplayEffect();                  updateDisplayEffect();
# Line 1045  void qsamplerMainForm::channelsArrange ( Line 1472  void qsamplerMainForm::channelsArrange (
1472          y += iHeight;          y += iHeight;
1473      }      }
1474      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1475        
1476      stabilizeForm();      stabilizeForm();
1477  }  }
1478    
# Line 1094  void qsamplerMainForm::helpAbout (void) Line 1521  void qsamplerMainForm::helpAbout (void)
1521      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1522      sText += "</font></small><br />";      sText += "</font></small><br />";
1523  #endif  #endif
1524    #ifndef CONFIG_INSTRUMENT_NAME
1525        sText += "<small><font color=\"red\">";
1526        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1527        sText += "</font></small><br />";
1528    #endif
1529    #ifndef CONFIG_MUTE_SOLO
1530        sText += "<small><font color=\"red\">";
1531        sText += tr("Sampler channel Mute/Solo support disabled.");
1532        sText += "</font></small><br />";
1533    #endif
1534    #ifndef CONFIG_MIDI_INSTRUMENT
1535        sText += "<small><font color=\"red\">";
1536        sText += tr("MIDI instrument mapping support disabled.");
1537        sText += "</font></small><br />";
1538    #endif
1539      sText += "<br />\n";      sText += "<br />\n";
1540      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1541      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1542      sText += " ";      sText += " ";
1543      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1544    #ifdef CONFIG_LIBGIG
1545        sText += ", ";
1546        sText += gig::libraryName().c_str();
1547        sText += " ";
1548        sText += gig::libraryVersion().c_str();
1549    #endif
1550      sText += "<br />\n";      sText += "<br />\n";
1551      sText += "<br />\n";      sText += "<br />\n";
1552      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 1569  void qsamplerMainForm::helpAbout (void)
1569  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1570  {  {
1571      // Update the main application caption...      // Update the main application caption...
1572      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1573      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1574          sSessioName += '*';          sSessionName += " *";
1575      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1576    
1577      // Update the main menu state...      // Update the main menu state...
1578      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1140  void qsamplerMainForm::stabilizeForm (vo Line 1588  void qsamplerMainForm::stabilizeForm (vo
1588      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1589      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1590      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1591      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1592      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1593    #ifdef CONFIG_MIDI_INSTRUMENT
1594            viewInstrumentsAction->setOn(m_pInstrumentListForm
1595                    && m_pInstrumentListForm->isVisible());
1596            viewInstrumentsAction->setEnabled(bHasClient);
1597    #endif
1598            viewDevicesAction->setOn(m_pDeviceForm
1599                    && m_pDeviceForm->isVisible());
1600        viewDevicesAction->setEnabled(bHasClient);
1601        channelsArrangeAction->setEnabled(bHasChannel);
1602    
1603      // Client/Server status...      // Client/Server status...
1604      if (bHasClient) {      if (bHasClient) {
1605          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1606          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));
1607      } else {      } else {
1608          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1609          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1610      }      }
1611      // Channel status...      // Channel status...
1612      if (bHasChannel)      if (bHasChannel)
1613          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1614      else      else
1615          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1616      // Session status...      // Session status...
1617      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1618          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1619      else      else
1620          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1621    
1622      // Recent files menu.      // Recent files menu.
1623      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 1629  void qsamplerMainForm::stabilizeForm (vo
1629    
1630    
1631  // Channel change receiver slot.  // Channel change receiver slot.
1632  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1633  {  {
1634      // Flag that we're update those channel strips.          // Add this strip to the changed list...
1635      m_iChangeCount++;          if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1636                    m_changedStrips.append(pChannelStrip);
1637                    pChannelStrip->resetErrorCount();
1638            }
1639    
1640      // Just mark the dirty form.      // Just mark the dirty form.
1641      m_iDirtyCount++;      m_iDirtyCount++;
1642      // and update the form status...      // and update the form status...
# Line 1183  void qsamplerMainForm::channelStripChang Line 1644  void qsamplerMainForm::channelStripChang
1644  }  }
1645    
1646    
1647    // Grab and restore current sampler channels session.
1648    void qsamplerMainForm::updateSession (void)
1649    {
1650    #ifdef CONFIG_MIDI_INSTRUMENT
1651            // FIXME Make some room for default instrument maps...
1652            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1653            if (iMaps < 0)
1654                    appendMessagesClient("lscp_get_midi_instrument_maps");
1655            else if (iMaps < 1) {
1656                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1657                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1658            }
1659    #endif
1660    
1661            // Retrieve the current channel list.
1662            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1663            if (piChannelIDs == NULL) {
1664                    if (::lscp_client_get_errno(m_pClient)) {
1665                            appendMessagesClient("lscp_list_channels");
1666                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1667                    }
1668            } else {
1669                    // Try to (re)create each channel.
1670                    m_pWorkspace->setUpdatesEnabled(false);
1671                    for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1672                            // Check if theres already a channel strip for this one...
1673                            if (!channelStrip(piChannelIDs[iChannel]))
1674                                    createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1675                    }
1676                    m_pWorkspace->setUpdatesEnabled(true);
1677            }
1678    
1679        // Do we auto-arrange?
1680        if (m_pOptions && m_pOptions->bAutoArrange)
1681            channelsArrange();
1682    
1683            // Remember to refresh devices and instruments...
1684            if (m_pInstrumentListForm)
1685                m_pInstrumentListForm->refreshInstruments();
1686            if (m_pDeviceForm)
1687                m_pDeviceForm->refreshDevices();
1688    }
1689    
1690    
1691  // Update the recent files list and menu.  // Update the recent files list and menu.
1692  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1693  {  {
# Line 1227  void qsamplerMainForm::updateRecentFiles Line 1732  void qsamplerMainForm::updateRecentFiles
1732  }  }
1733    
1734    
1735    // Force update of the channels instrument names mode.
1736    void qsamplerMainForm::updateInstrumentNames (void)
1737    {
1738        // Full channel list update...
1739        QWidgetList wlist = m_pWorkspace->windowList();
1740        if (wlist.isEmpty())
1741            return;
1742    
1743        m_pWorkspace->setUpdatesEnabled(false);
1744        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1745            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1746            if (pChannelStrip)
1747                pChannelStrip->updateInstrumentName(true);
1748        }
1749        m_pWorkspace->setUpdatesEnabled(true);
1750    }
1751    
1752    
1753  // Force update of the channels display font.  // Force update of the channels display font.
1754  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1755  {  {
# Line 1332  void qsamplerMainForm::appendMessagesErr Line 1855  void qsamplerMainForm::appendMessagesErr
1855    
1856      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1857    
1858      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));          // Make it look responsive...:)
1859            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1860    
1861        QMessageBox::critical(this,
1862                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1863  }  }
1864    
1865    
# Line 1345  void qsamplerMainForm::appendMessagesCli Line 1872  void qsamplerMainForm::appendMessagesCli
1872      appendMessagesColor(s + QString(": %1 (errno=%2)")      appendMessagesColor(s + QString(": %1 (errno=%2)")
1873          .arg(::lscp_client_get_result(m_pClient))          .arg(::lscp_client_get_result(m_pClient))
1874          .arg(::lscp_client_get_errno(m_pClient)), "#996666");          .arg(::lscp_client_get_errno(m_pClient)), "#996666");
1875    
1876            // Make it look responsive...:)
1877            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1878  }  }
1879    
1880    
# Line 1372  void qsamplerMainForm::updateMessagesLim Line 1902  void qsamplerMainForm::updateMessagesLim
1902          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1903              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1904          else          else
1905              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1906      }      }
1907  }  }
1908    
# Line 1404  qsamplerChannelStrip *qsamplerMainForm:: Line 1934  qsamplerChannelStrip *qsamplerMainForm::
1934          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1935          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1936              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1937          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1938              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1939                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1940                            }
1941          }          }
1942      }      }
1943    
# Line 1414  qsamplerChannelStrip *qsamplerMainForm:: Line 1946  qsamplerChannelStrip *qsamplerMainForm::
1946      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1947      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1948          return NULL;          return NULL;
1949            
1950      // Actual channel strip setup...      // Actual channel strip setup...
1951      pChannelStrip->setup(pChannel);      pChannelStrip->setup(pChannel);
1952      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 1971  qsamplerChannelStrip *qsamplerMainForm::
1971          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1972          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1973      }      }
1974        
1975            // This is pretty new, so we'll watch for it closely.
1976            channelStripChanged(pChannelStrip);
1977    
1978      // Return our successful reference...      // Return our successful reference...
1979      return pChannelStrip;      return pChannelStrip;
1980  }  }
# Line 1457  qsamplerChannelStrip *qsamplerMainForm:: Line 1992  qsamplerChannelStrip *qsamplerMainForm::
1992  {  {
1993      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1994      if (wlist.isEmpty())      if (wlist.isEmpty())
1995          return 0;          return NULL;
1996    
1997      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1998  }  }
1999    
2000    
2001    // Retrieve a channel strip by sampler channel id.
2002    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
2003    {
2004            QWidgetList wlist = m_pWorkspace->windowList();
2005            if (wlist.isEmpty())
2006                    return NULL;
2007    
2008            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2009                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2010                    if (pChannelStrip) {
2011                            qsamplerChannel *pChannel = pChannelStrip->channel();
2012                            if (pChannel && pChannel->channelID() == iChannelID)
2013                                    return pChannelStrip;
2014                    }
2015            }
2016    
2017            // Not found.
2018            return NULL;
2019    }
2020    
2021    
2022  // Construct the windows menu.  // Construct the windows menu.
2023  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
2024  {  {
# Line 1529  void qsamplerMainForm::timerSlot (void) Line 2085  void qsamplerMainForm::timerSlot (void)
2085              }              }
2086          }          }
2087      }      }
2088        
2089          // Refresh each channel usage, on each period...          if (m_pClient) {
2090      if (m_pClient && (m_iChangeCount > 0 || m_pOptions->bAutoRefresh)) {                  // Update the channel information for each pending strip...
2091          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2092          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2093              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2094              m_iChangeCount = 0;                                  // If successfull, remove from pending list...
2095              QWidgetList wlist = m_pWorkspace->windowList();                                  if (pChannelStrip->updateChannelInfo())
2096              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                          m_changedStrips.remove(pChannelStrip);
2097                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                          }
2098                  if (pChannelStrip && pChannelStrip->isVisible()) {                  }
2099                      // If we can't make it clean, try next time.                  // Refresh each channel usage, on each period...
2100                      if (!pChannelStrip->updateChannelUsage())                  if (m_pOptions->bAutoRefresh) {
2101                          m_iChangeCount++;                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2102                  }                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2103              }                                  m_iTimerSlot = 0;
2104          }                                  // Update the channel stream usage for each strip...
2105      }                                  QWidgetList wlist = m_pWorkspace->windowList();
2106                                    for (int iChannel = 0;
2107                                                    iChannel < (int) wlist.count(); iChannel++) {
2108                                            qsamplerChannelStrip *pChannelStrip
2109                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2110                                            if (pChannelStrip && pChannelStrip->isVisible())
2111                                                    pChannelStrip->updateChannelUsage();
2112                                    }
2113                            }
2114                    }
2115            }
2116    
2117      // Register the next timer slot.      // Register the next timer slot.
2118      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1568  void qsamplerMainForm::startServer (void Line 2134  void qsamplerMainForm::startServer (void
2134    
2135      // Is the server process instance still here?      // Is the server process instance still here?
2136      if (m_pServer) {      if (m_pServer) {
2137          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2138                            QSAMPLER_TITLE ": " + tr("Warning"),
2139              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2140                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2141              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1727  bool qsamplerMainForm::startClient (void Line 2294  bool qsamplerMainForm::startClient (void
2294      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2295      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)));
2296    
2297            // Subscribe to channel info change notifications...
2298            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2299                    appendMessagesClient("lscp_client_subscribe");
2300    
2301      // We may stop scheduling around.      // We may stop scheduling around.
2302      stopSchedule();      stopSchedule();
2303    
# Line 1736  bool qsamplerMainForm::startClient (void Line 2307  bool qsamplerMainForm::startClient (void
2307      // Log success here.      // Log success here.
2308      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2309    
2310            // Hard-notify instrumnet and device configuration forms,
2311            // if visible, that we're ready...
2312            if (m_pInstrumentListForm)
2313                m_pInstrumentListForm->refreshInstruments();
2314            if (m_pDeviceForm)
2315                m_pDeviceForm->refreshDevices();
2316    
2317      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2318      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2319          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1770  void qsamplerMainForm::stopClient (void) Line 2348  void qsamplerMainForm::stopClient (void)
2348      // channels from the back-end server.      // channels from the back-end server.
2349      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2350      closeSession(false);      closeSession(false);
2351        
2352      // Close us as a client...      // Close us as a client...
2353      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2354        ::lscp_client_destroy(m_pClient);
2355      m_pClient = NULL;      m_pClient = NULL;
2356    
2357            // Hard-notify instrumnet and device configuration forms,
2358            // if visible, that we're running out...
2359            if (m_pInstrumentListForm)
2360                m_pInstrumentListForm->refreshInstruments();
2361            if (m_pDeviceForm)
2362                m_pDeviceForm->refreshDevices();
2363    
2364      // Log final here.      // Log final here.
2365      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2366    

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

  ViewVC Help
Powered by ViewVC