/[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 1024 by capela, Fri Jan 12 10:56:31 2007 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004-2005, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
# Line 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 127  void qsamplerMainForm::init (void) Line 142  void qsamplerMainForm::init (void)
142      // Make it an MDI workspace.      // Make it an MDI workspace.
143      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
144      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
145      // Set the activation connection.          // Set the activation connection.
146      QObject::connect(m_pWorkspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(stabilizeForm()));          QObject::connect(m_pWorkspace,
147                    SIGNAL(windowActivated(QWidget *)),
148                    SLOT(stabilizeForm()));
149      // Make it shine :-)      // Make it shine :-)
150      setCentralWidget(m_pWorkspace);      setCentralWidget(m_pWorkspace);
151    
# Line 138  void qsamplerMainForm::init (void) Line 155  void qsamplerMainForm::init (void)
155      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
156      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
157      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
158      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
159      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
160      // Server address.      // Server address.
161      pLabel = new QLabel(this);      pLabel = new QLabel(this);
162      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
163      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
164      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
165      // Channel title.      // Channel title.
166      pLabel = new QLabel(this);      pLabel = new QLabel(this);
167      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
168      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
169      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
170      // Session modification status.      // Session modification status.
171      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
172      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
173      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
174      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
175      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
176    
177      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 173  void qsamplerMainForm::destroy (void) Line 190  void qsamplerMainForm::destroy (void)
190  {  {
191      // Do final processing anyway.      // Do final processing anyway.
192      processServerExit();      processServerExit();
193        
194      // Delete recentfiles menu.  #if defined(WIN32)
195      if (m_pRecentFilesMenu)      WSACleanup();
196          delete m_pRecentFilesMenu;  #endif
     // Delete status item labels one by one.  
     if (m_status[QSAMPLER_STATUS_CLIENT])  
         delete m_status[QSAMPLER_STATUS_CLIENT];  
     if (m_status[QSAMPLER_STATUS_SERVER])  
         delete m_status[QSAMPLER_STATUS_SERVER];  
     if (m_status[QSAMPLER_STATUS_CHANNEL])  
         delete m_status[QSAMPLER_STATUS_CHANNEL];  
     if (m_status[QSAMPLER_STATUS_SESSION])  
         delete m_status[QSAMPLER_STATUS_SESSION];  
197    
198      // Finally drop any widgets around...      // Finally drop any widgets around...
199        if (m_pDeviceForm)
200            delete m_pDeviceForm;
201        if (m_pInstrumentListForm)
202            delete m_pInstrumentListForm;
203      if (m_pMessages)      if (m_pMessages)
204          delete m_pMessages;          delete m_pMessages;
205      if (m_pWorkspace)      if (m_pWorkspace)
206          delete m_pWorkspace;          delete m_pWorkspace;
207    
208  #if defined(WIN32)      // Delete status item labels one by one.
209      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
210  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
211        if (m_statusItem[QSAMPLER_STATUS_SERVER])
212            delete m_statusItem[QSAMPLER_STATUS_SERVER];
213        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
214            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
215        if (m_statusItem[QSAMPLER_STATUS_SESSION])
216            delete m_statusItem[QSAMPLER_STATUS_SESSION];
217    
218        // Delete recentfiles menu.
219        if (m_pRecentFilesMenu)
220            delete m_pRecentFilesMenu;
221    
222            // Pseudo-singleton reference shut-down.
223            g_pMainForm = NULL;
224  }  }
225    
226    
# Line 205  void qsamplerMainForm::setup ( qsamplerO Line 230  void qsamplerMainForm::setup ( qsamplerO
230      // We got options?      // We got options?
231      m_pOptions = pOptions;      m_pOptions = pOptions;
232    
233          // Set initial instrument name display mode.      // What style do we create these forms?
234      qsamplerChannel::setInstrumentNames(m_pOptions->bInstrumentNames);          Qt::WFlags wflags = Qt::WStyle_Customize
235                    | Qt::WStyle_NormalBorder
236                    | Qt::WStyle_Title
237                    | Qt::WStyle_SysMenu
238                    | Qt::WStyle_MinMax
239                    | Qt::WType_TopLevel;
240        if (m_pOptions->bKeepOnTop)
241            wflags |= Qt::WStyle_Tool;
242      // Some child forms are to be created right now.      // Some child forms are to be created right now.
243      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
244        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
245    #ifdef CONFIG_MIDI_INSTRUMENT
246        m_pInstrumentListForm = new qsamplerInstrumentListForm(this, 0, wflags);
247            QObject::connect(m_pInstrumentListForm->InstrumentList,
248                    SIGNAL(instrumentsChanged()),
249                    SLOT(sessionDirty()));
250    #else
251            viewInstrumentsAction->setEnabled(false);
252    #endif
253      // Set message defaults...      // Set message defaults...
254      updateMessagesFont();      updateMessagesFont();
255      updateMessagesLimit();      updateMessagesLimit();
256      updateMessagesCapture();      updateMessagesCapture();
257      // Set the visibility signal.      // Set the visibility signal.
258      QObject::connect(m_pMessages, SIGNAL(visibilityChanged(bool)), this, SLOT(stabilizeForm()));          QObject::connect(m_pMessages,
259                    SIGNAL(visibilityChanged(bool)),
260                    SLOT(stabilizeForm()));
261    
262      // Initial decorations toggle state.      // Initial decorations toggle state.
263      viewMenubarAction->setOn(m_pOptions->bMenubar);      viewMenubarAction->setOn(m_pOptions->bMenubar);
# Line 238  void qsamplerMainForm::setup ( qsamplerO Line 280  void qsamplerMainForm::setup ( qsamplerO
280          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
281          istr >> *this;          istr >> *this;
282      }      }
283      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
284      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
285        m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
286        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
287    
288      // Final startup stabilization...      // Final startup stabilization...
289      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 277  bool qsamplerMainForm::queryClose (void) Line 321  bool qsamplerMainForm::queryClose (void)
321              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
322              ostr << *this;              ostr << *this;
323              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
324              // And the main windows state.              // And the children, and the main windows state,.
325              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
326                            m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
327                            m_pOptions->saveWidgetGeometry(this);
328                            // Close popup widgets.
329                            if (m_pInstrumentListForm)
330                                    m_pInstrumentListForm->close();
331                            if (m_pDeviceForm)
332                                    m_pDeviceForm->close();
333              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
334              stopServer();              stopServer();
335          }          }
# Line 297  void qsamplerMainForm::closeEvent ( QClo Line 348  void qsamplerMainForm::closeEvent ( QClo
348  }  }
349    
350    
351  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
352  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
353  {  {
354      bool bAccept = false;      bool bDecode = false;
355    
356      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
357          QString sUrl;          QString sText;
358          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
359              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
360                files = QStringList::split('\n', sText);
361                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
362                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
363            }
364      }      }
365    
366      pDragEnterEvent->accept(bAccept);      return bDecode;
367    }
368    
369    
370    // Window drag-n-drop event handlers.
371    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
372    {
373            QStringList files;
374            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
375  }  }
376    
377    
378  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
379  {  {
380      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
381          QString sUrl;  
382          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
383              loadSessionFile(QUrl(sUrl).path());          return;
384      }  
385            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
386                    const QString& sPath = *iter;
387                    if (qsamplerChannel::isInstrumentFile(sPath)) {
388                            // Try to create a new channel from instrument file...
389                            qsamplerChannel *pChannel = new qsamplerChannel();
390                            if (pChannel == NULL)
391                                    return;
392                            // Start setting the instrument filename...
393                            pChannel->setInstrument(sPath, 0);
394                            // Before we show it up, may be we'll
395                            // better ask for some initial values?
396                            if (!pChannel->channelSetup(this)) {
397                                    delete pChannel;
398                                    return;
399                            }
400                            // Finally, give it to a new channel strip...
401                            if (!createChannelStrip(pChannel)) {
402                                    delete pChannel;
403                                    return;
404                            }
405                            // Make that an overall update.
406                            m_iDirtyCount++;
407                            stabilizeForm();
408                    }   // Otherwise, load an usual session file (LSCP script)...
409                    else if (closeSession(true)) {
410                            loadSessionFile(sPath);
411                            break;
412                    }
413                    // Make it look responsive...:)
414                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
415            }
416  }  }
417    
418    
# Line 328  void qsamplerMainForm::customEvent ( QCu Line 422  void qsamplerMainForm::customEvent ( QCu
422      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
423      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
424          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
425          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
426              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
427              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
428                            if (pChannelStrip)
429                                    channelStripChanged(pChannelStrip);
430                    } else {
431                            appendMessagesColor(tr("Notify event: %1 data: %2")
432                                    .arg(::lscp_event_to_text(pEvent->event()))
433                                    .arg(pEvent->data()), "#996699");
434                    }
435      }      }
436  }  }
437    
# Line 339  void qsamplerMainForm::customEvent ( QCu Line 440  void qsamplerMainForm::customEvent ( QCu
440  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
441  {  {
442      stabilizeForm();      stabilizeForm();
443        
444      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
445  }  }
446    
# Line 353  qsamplerOptions *qsamplerMainForm::optio Line 454  qsamplerOptions *qsamplerMainForm::optio
454      return m_pOptions;      return m_pOptions;
455  }  }
456    
457    
458  // The LSCP client descriptor property.  // The LSCP client descriptor property.
459  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
460  {  {
# Line 360  lscp_client_t *qsamplerMainForm::client Line 462  lscp_client_t *qsamplerMainForm::client
462  }  }
463    
464    
465    // The pseudo-singleton instance accessor.
466    qsamplerMainForm *qsamplerMainForm::getInstance (void)
467    {
468            return g_pMainForm;
469    }
470    
471    
472  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
473  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
474    
# Line 383  bool qsamplerMainForm::newSession (void) Line 492  bool qsamplerMainForm::newSession (void)
492      if (!closeSession(true))      if (!closeSession(true))
493          return false;          return false;
494    
495            // Give us what the server has, right now...
496            updateSession();
497    
498      // Ok increment untitled count.      // Ok increment untitled count.
499      m_iUntitled++;      m_iUntitled++;
500    
# Line 404  bool qsamplerMainForm::openSession (void Line 516  bool qsamplerMainForm::openSession (void
516    
517      // Ask for the filename to open...      // Ask for the filename to open...
518      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
519              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
520              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
521              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
522              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
523      );      );
524    
525      // Have we cancelled?      // Have we cancelled?
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 550  bool qsamplerMainForm::saveSession ( boo
550              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
551          // Prompt the guy...          // Prompt the guy...
552          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
553                  sFilename,                              // Start here.                          sFilename,                              // Start here.
554                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
555                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
556                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
557          );          );
558          // Have we cancelled it?          // Have we cancelled it?
559          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 451  bool qsamplerMainForm::saveSession ( boo Line 563  bool qsamplerMainForm::saveSession ( boo
563              sFilename += ".lscp";              sFilename += ".lscp";
564          // Check if already exists...          // Check if already exists...
565          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
566              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
567                                    QSAMPLER_TITLE ": " + tr("Warning"),
568                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
569                     "\"%1\"\n\n"                     "\"%1\"\n\n"
570                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 473  bool qsamplerMainForm::closeSession ( bo Line 586  bool qsamplerMainForm::closeSession ( bo
586    
587      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
588      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
589          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
590                            QSAMPLER_TITLE ": " + tr("Warning"),
591              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
592              "\"%1\"\n\n"              "\"%1\"\n\n"
593              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 526  bool qsamplerMainForm::loadSessionFile ( Line 640  bool qsamplerMainForm::loadSessionFile (
640          return false;          return false;
641      }      }
642    
643            // Tell the world we'll take some time...
644            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
645    
646      // Read the file.      // Read the file.
647            int iLine = 0;
648      int iErrors = 0;      int iErrors = 0;
649      QTextStream ts(&file);      QTextStream ts(&file);
650      while (!ts.atEnd()) {      while (!ts.atEnd()) {
651          // Read the line.          // Read the line.
652          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
653                    iLine++;
654          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
655          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
656              appendMessagesColor(sCommand, "#996633");                          // Remember that, no matter what,
657              // Remember that, no matter what,                          // all LSCP commands are CR/LF terminated.
658              // all LSCP commands are CR/LF terminated.                          sCommand += "\r\n";
659              sCommand += "\r\n";                          if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
660              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {                                  appendMessagesColor(QString("%1(%2): %3")
661                  appendMessagesClient("lscp_client_query");                                          .arg(QFileInfo(sFilename).fileName()).arg(iLine)
662                  iErrors++;                                          .arg(sCommand.simplifyWhiteSpace()), "#996633");
663              }                                  appendMessagesClient("lscp_client_query");
664                                    iErrors++;
665                            }
666          }          }
667          // Try to make it snappy :)          // Try to make it snappy :)
668          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
# Line 550  bool qsamplerMainForm::loadSessionFile ( Line 671  bool qsamplerMainForm::loadSessionFile (
671      // Ok. we've read it.      // Ok. we've read it.
672      file.close();      file.close();
673    
674      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
675      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
676    
677      // Now we'll try to create the whole GUI session.          // We're fornerly done.
678      int *piChannelIDs = ::lscp_list_channels(m_pClient);          QApplication::restoreOverrideCursor();
679      if (piChannelIDs == NULL) {  
680          appendMessagesClient("lscp_list_channels");          // Have we any errors?
681          appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));          if (iErrors > 0)
682      }                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
       
     // Try to (re)create each channel.  
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {  
         createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));  
         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
683    
684      // Save as default session directory.      // Save as default session directory.
685      if (m_pOptions)      if (m_pOptions)
686          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
687      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
688      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
689      // Stabilize form...      // Stabilize form...
690      m_sFilename = sFilename;      m_sFilename = sFilename;
691      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
692      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
693        
694      // Make that an overall update.      // Make that an overall update.
     m_iChangeCount++;  
695      stabilizeForm();      stabilizeForm();
696      return true;      return true;
697  }  }
# Line 589  bool qsamplerMainForm::loadSessionFile ( Line 700  bool qsamplerMainForm::loadSessionFile (
700  // Save current session to specific file path.  // Save current session to specific file path.
701  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
702  {  {
703            if (m_pClient == NULL)
704                    return false;
705    
706            // Check whether server is apparently OK...
707            if (::lscp_get_channels(m_pClient) < 0) {
708                    appendMessagesClient("lscp_get_channels");
709                    return false;
710            }
711    
712      // Open and write into real file.      // Open and write into real file.
713      QFile file(sFilename);      QFile file(sFilename);
714      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 596  bool qsamplerMainForm::saveSessionFile ( Line 716  bool qsamplerMainForm::saveSessionFile (
716          return false;          return false;
717      }      }
718    
719            // Tell the world we'll take some time...
720            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
721    
722      // Write the file.      // Write the file.
723      int iErrors = 0;      int  iErrors = 0;
724      QTextStream ts(&file);      QTextStream ts(&file);
725      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
726      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 608  bool qsamplerMainForm::saveSessionFile ( Line 731  bool qsamplerMainForm::saveSessionFile (
731      ts << "# " << tr("File")      ts << "# " << tr("File")
732         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
733      ts << "# " << tr("Date")      ts << "# " << tr("Date")
734         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
735         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
736      ts << "#"  << endl;      ts << "#"  << endl;
737      ts << endl;      ts << endl;
738    
739            // It is assumed that this new kind of device+session file
740            // will be loaded from a complete initialized server...
741            int *piDeviceIDs;
742            int  iDevice;
743            ts << "RESET" << endl;
744    
745            // Audio device mapping.
746            QMap<int, int> audioDeviceMap;
747            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
748            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
749                    ts << endl;
750                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
751                    // Audio device specification...
752                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
753                            << " " << tr("Device") << " " << iDevice << endl;
754                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
755                    qsamplerDeviceParamMap::ConstIterator deviceParam;
756                    for (deviceParam = device.params().begin();
757                                    deviceParam != device.params().end();
758                                            ++deviceParam) {
759                            const qsamplerDeviceParam& param = deviceParam.data();
760                            if (param.value.isEmpty()) ts << "# ";
761                            ts << " " << deviceParam.key() << "='" << param.value << "'";
762                    }
763                    ts << endl;
764                    // Audio channel parameters...
765                    int iPort = 0;
766                    for (qsamplerDevicePort *pPort = device.ports().first();
767                                    pPort;
768                                            pPort = device.ports().next(), ++iPort) {
769                            qsamplerDeviceParamMap::ConstIterator portParam;
770                            for (portParam = pPort->params().begin();
771                                            portParam != pPort->params().end();
772                                                    ++portParam) {
773                                    const qsamplerDeviceParam& param = portParam.data();
774                                    if (param.fix || param.value.isEmpty()) ts << "# ";
775                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
776                                            << " " << iPort << " " << portParam.key()
777                                            << "='" << param.value << "'" << endl;
778                            }
779                    }
780                    // Audio device index/id mapping.
781                    audioDeviceMap[device.deviceID()] = iDevice;
782                    // Try to keep it snappy :)
783                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
784            }
785    
786            // MIDI device mapping.
787            QMap<int, int> midiDeviceMap;
788            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
789            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
790                    ts << endl;
791                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
792                    // MIDI device specification...
793                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
794                            << " " << tr("Device") << " " << iDevice << endl;
795                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
796                    qsamplerDeviceParamMap::ConstIterator deviceParam;
797                    for (deviceParam = device.params().begin();
798                                    deviceParam != device.params().end();
799                                            ++deviceParam) {
800                            const qsamplerDeviceParam& param = deviceParam.data();
801                            if (param.value.isEmpty()) ts << "# ";
802                            ts << " " << deviceParam.key() << "='" << param.value << "'";
803                    }
804                    ts << endl;
805                    // MIDI port parameters...
806                    int iPort = 0;
807                    for (qsamplerDevicePort *pPort = device.ports().first();
808                                    pPort;
809                                            pPort = device.ports().next(), ++iPort) {
810                            qsamplerDeviceParamMap::ConstIterator portParam;
811                            for (portParam = pPort->params().begin();
812                                            portParam != pPort->params().end();
813                                                    ++portParam) {
814                                    const qsamplerDeviceParam& param = portParam.data();
815                                    if (param.fix || param.value.isEmpty()) ts << "# ";
816                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
817                                       << " " << iPort << " " << portParam.key()
818                                       << "='" << param.value << "'" << endl;
819                            }
820                    }
821                    // MIDI device index/id mapping.
822                    midiDeviceMap[device.deviceID()] = iDevice;
823                    // Try to keep it snappy :)
824                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
825            }
826            ts << endl;
827    
828    #ifdef CONFIG_MIDI_INSTRUMENT
829            // MIDI instrument mapping...
830            QMap<int, int> midiInstrumentMap;
831            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
832            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
833                    int iMidiMap = piMaps[iMap];
834                    const char *pszMapName
835                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
836                    ts << "# " << tr("MIDI instrument map") << " " << iMap;
837                    if (pszMapName)
838                            ts << " - " << pszMapName;
839                    ts << endl;
840                    ts << "ADD MIDI_INSTRUMENT_MAP";
841                    if (pszMapName)
842                            ts << " '" << pszMapName << "'";
843                    ts << endl;
844                    // MIDI instrument mapping...
845                    lscp_midi_instrument_t *pInstrs
846                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
847                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
848                            lscp_midi_instrument_info_t *pInstrInfo
849                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
850                            if (pInstrInfo) {
851                                    ts << "MAP MIDI_INSTRUMENT "
852                                            << iMap                        << " "
853                                            << pInstrs[iInstr].bank        << " "
854                                            << pInstrs[iInstr].prog        << " "
855                                            << pInstrInfo->engine_name     << " '"
856                                            << pInstrInfo->instrument_file << "' "
857                                            << pInstrInfo->instrument_nr   << " "
858                                            << pInstrInfo->volume          << " ";
859                                    switch (pInstrInfo->load_mode) {
860                                            case LSCP_LOAD_PERSISTENT:
861                                                    ts << "PERSISTENT";
862                                                    break;
863                                            case LSCP_LOAD_ON_DEMAND_HOLD:
864                                                    ts << "ON_DEMAND_HOLD";
865                                                    break;
866                                            case LSCP_LOAD_ON_DEMAND:
867                                            case LSCP_LOAD_DEFAULT:
868                                            default:
869                                                    ts << "ON_DEMAND";
870                                                    break;
871                                    }
872                                    if (pInstrInfo->name)
873                                            ts << " '" << pInstrInfo->name << "'";
874                                    ts << endl;
875                            }       // Check for errors...
876                            else if (::lscp_client_get_errno(m_pClient)) {
877                                    appendMessagesClient("lscp_get_midi_instrument_info");
878                                    iErrors++;
879                            }
880                            // Try to keep it snappy :)
881                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
882                    }
883                    ts << endl;
884                    // Check for errors...
885                    if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {
886                            appendMessagesClient("lscp_list_midi_instruments");
887                            iErrors++;
888                    }
889                    // MIDI strument index/id mapping.
890                    midiInstrumentMap[iMidiMap] = iMap;
891            }
892            // Check for errors...
893            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
894                    appendMessagesClient("lscp_list_midi_instrument_maps");
895                    iErrors++;
896            }
897    #endif  // CONFIG_MIDI_INSTRUMENT
898    
899    #ifdef CONFIG_FXSEND
900            int iFxSend = 0;
901    #endif
902            // Sampler channel mapping.
903      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
904      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
905          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip
906                            = static_cast<qsamplerChannelStrip *> (wlist.at(iChannel));
907          if (pChannelStrip) {          if (pChannelStrip) {
908              qsamplerChannel *pChannel = pChannelStrip->channel();              qsamplerChannel *pChannel = pChannelStrip->channel();
909              if (pChannel) {              if (pChannel) {
910                  int iChannelID = pChannel->channelID();                  ts << "# " << tr("Channel") << " " << iChannel << endl;
                 ts << "# " << pChannelStrip->caption() << endl;  
911                  ts << "ADD CHANNEL" << endl;                  ts << "ADD CHANNEL" << endl;
912                  ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                                  if (audioDeviceMap.isEmpty()) {
913                  ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
914                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                                  << " " << pChannel->audioDriver() << endl;
915                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  } else {
916                                            ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
917                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
918                                    }
919                                    if (midiDeviceMap.isEmpty()) {
920                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
921                                                    << " " << pChannel->midiDriver() << endl;
922                                    } else {
923                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
924                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
925                                    }
926                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
927                                            << " " << pChannel->midiPort() << endl;
928                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
929                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
930                      ts << "ALL";                      ts << "ALL";
931                  else                  else
932                      ts << pChannel->midiChannel();                      ts << pChannel->midiChannel();
933                  ts << endl;                  ts << endl;
934                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
935                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
936                  ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
937                                            << pChannel->instrumentNr() << " " << iChannel << endl;
938                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
939                                    for (audioRoute = pChannel->audioRouting().begin();
940                                                    audioRoute != pChannel->audioRouting().end();
941                                                            ++audioRoute) {
942                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
943                                                    << " " << audioRoute.key()
944                                                    << " " << audioRoute.data() << endl;
945                                    }
946                                    ts << "SET CHANNEL VOLUME " << iChannel
947                                            << " " << pChannel->volume() << endl;
948                                    if (pChannel->channelMute())
949                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
950                                    if (pChannel->channelSolo())
951                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
952    #ifdef CONFIG_MIDI_INSTRUMENT
953                                    if (pChannel->midiMap() >= 0) {
954                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
955                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
956                                    }
957    #endif
958    #ifdef CONFIG_FXSEND
959                                    int iChannelID = pChannel->channelID();
960                                    int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
961                                    for (int iFx = 0; piFxSends && piFxSends[iFx] >= 0; iFx++) {
962                                            lscp_fxsend_info_t *pFxSendInfo
963                                                    = ::lscp_get_fxsend_info(m_pClient, iChannelID, piFxSends[iFx]);
964                                            if (pFxSendInfo) {
965                                                    ts << "CREATE FX_SEND " << iChannel
966                                                            << " " << pFxSendInfo->midi_controller;
967                                                    if (pFxSendInfo->name)
968                                                            ts << " '" << pFxSendInfo->name << "'";
969                                                    ts << endl;
970                                                    int *piRouting = pFxSendInfo->audio_routing;
971                                                    for (int i = 0; piRouting && piRouting[i] >= 0; i++) {
972                                                            ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL " << iChannel
973                                                                    << " " << iFxSend
974                                                                    << " " << i     << " " << piRouting[i] << endl;
975                                                    }
976                                                    // Increment logical FX send identifier...
977                                                    iFxSend++;
978                                            }       // Check for errors...
979                                            else if (::lscp_client_get_errno(m_pClient)) {
980                                                    appendMessagesClient("lscp_get_fxsend_info");
981                                                    iErrors++;
982                                            }
983                                    }
984    #endif
985                  ts << endl;                  ts << endl;
986              }              }
987          }          }
# Line 643  bool qsamplerMainForm::saveSessionFile ( Line 992  bool qsamplerMainForm::saveSessionFile (
992      // Ok. we've wrote it.      // Ok. we've wrote it.
993      file.close();      file.close();
994    
995            // We're fornerly done.
996            QApplication::restoreOverrideCursor();
997    
998      // Have we any errors?      // Have we any errors?
999      if (iErrors > 0)      if (iErrors > 0)
1000          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 1013  bool qsamplerMainForm::saveSessionFile (
1013  }  }
1014    
1015    
1016    // Session change receiver slot.
1017    void qsamplerMainForm::sessionDirty (void)
1018    {
1019        // Just mark the dirty form.
1020        m_iDirtyCount++;
1021        // and update the form status...
1022        stabilizeForm();
1023    }
1024    
1025    
1026  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1027  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
1028    
# Line 714  void qsamplerMainForm::fileReset (void) Line 1076  void qsamplerMainForm::fileReset (void)
1076          return;          return;
1077    
1078      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
1079      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
1080                    QSAMPLER_TITLE ": " + tr("Warning"),
1081          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
1082             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
1083             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
1084             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
1085             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
1086          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
1087          return;          return;
1088    
1089            // Trye closing the current session, first...
1090            if (!closeSession(true))
1091                    return;
1092    
1093      // Just do the reset, after closing down current session...      // Just do the reset, after closing down current session...
1094      if (closeSession(true) && ::lscp_reset_sampler(m_pClient) != LSCP_OK) {          // Do the actual sampler reset...
1095          appendMessagesClient("lscp_reset_sampler");          if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1096          appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));                  appendMessagesClient("lscp_reset_sampler");
1097          return;                  appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
1098      }                  return;
1099            }
1100    
1101      // Log this.      // Log this.
1102      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
1103    
1104            // Make it a new session...
1105            newSession();
1106  }  }
1107    
1108    
# Line 740  void qsamplerMainForm::fileRestart (void Line 1111  void qsamplerMainForm::fileRestart (void
1111  {  {
1112      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1113          return;          return;
1114            
1115      bool bRestart = true;      bool bRestart = true;
1116        
1117      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1118      // (if we're currently up and running)      // (if we're currently up and running)
1119      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1120          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1121                            QSAMPLER_TITLE ": " + tr("Warning"),
1122              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1123                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1124                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1125                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1126                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1127              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1128      }      }
# Line 783  void qsamplerMainForm::editAddChannel (v Line 1155  void qsamplerMainForm::editAddChannel (v
1155          return;          return;
1156    
1157      // Just create the channel instance...      // Just create the channel instance...
1158      qsamplerChannel *pChannel = new qsamplerChannel(this);      qsamplerChannel *pChannel = new qsamplerChannel();
1159      if (pChannel == NULL)      if (pChannel == NULL)
1160          return;          return;
1161    
# Line 793  void qsamplerMainForm::editAddChannel (v Line 1165  void qsamplerMainForm::editAddChannel (v
1165          delete pChannel;          delete pChannel;
1166          return;          return;
1167      }      }
1168        
1169      // 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).
1170      if (!createChannelStrip(pChannel)) {      if (!createChannelStrip(pChannel)) {
1171          delete pChannel;          delete pChannel;
# Line 802  void qsamplerMainForm::editAddChannel (v Line 1174  void qsamplerMainForm::editAddChannel (v
1174    
1175      // Make that an overall update.      // Make that an overall update.
1176      m_iDirtyCount++;      m_iDirtyCount++;
     m_iChangeCount++;  
1177      stabilizeForm();      stabilizeForm();
1178  }  }
1179    
# Line 816  void qsamplerMainForm::editRemoveChannel Line 1187  void qsamplerMainForm::editRemoveChannel
1187      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1188      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1189          return;          return;
1190            
1191      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
1192      if (pChannel == NULL)      if (pChannel == NULL)
1193          return;          return;
1194    
1195      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1196      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1197          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1198                            QSAMPLER_TITLE ": " + tr("Warning"),
1199              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1200                 "%1\n\n"                 "%1\n\n"
1201                 "Are you sure?")                 "Are you sure?")
# Line 838  void qsamplerMainForm::editRemoveChannel Line 1210  void qsamplerMainForm::editRemoveChannel
1210    
1211      // Just delete the channel strip.      // Just delete the channel strip.
1212      delete pChannelStrip;      delete pChannelStrip;
1213        
1214      // Do we auto-arrange?      // Do we auto-arrange?
1215      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1216          channelsArrange();          channelsArrange();
# Line 874  void qsamplerMainForm::editResetChannel Line 1246  void qsamplerMainForm::editResetChannel
1246      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1247          return;          return;
1248    
1249      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1250      if (pChannel == NULL)      pChannelStrip->channelReset();
1251          return;  }
1252    
     // Reset the existing sampler channel.  
     pChannel->resetChannel();  
1253    
1254      // And force a deferred update.  // Reset all sampler channels.
1255      m_iChangeCount++;  void qsamplerMainForm::editResetAllChannels (void)
1256    {
1257            if (m_pClient == NULL)
1258                    return;
1259    
1260            // Invoque the channel strip procedure,
1261            // for all channels out there...
1262            m_pWorkspace->setUpdatesEnabled(false);
1263            QWidgetList wlist = m_pWorkspace->windowList();
1264            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1265                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1266                    if (pChannelStrip)
1267                            pChannelStrip->channelReset();
1268            }
1269            m_pWorkspace->setUpdatesEnabled(true);
1270  }  }
1271    
1272    
# Line 934  void qsamplerMainForm::viewMessages ( bo Line 1318  void qsamplerMainForm::viewMessages ( bo
1318  }  }
1319    
1320    
1321    // Show/hide the MIDI instrument list-view form.
1322    void qsamplerMainForm::viewInstruments (void)
1323    {
1324            if (m_pOptions == NULL)
1325                    return;
1326    
1327            if (m_pInstrumentListForm) {
1328                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1329                    if (m_pInstrumentListForm->isVisible()) {
1330                            m_pInstrumentListForm->hide();
1331                    } else {
1332                            m_pInstrumentListForm->show();
1333                            m_pInstrumentListForm->raise();
1334                            m_pInstrumentListForm->setActiveWindow();
1335                    }
1336            }
1337    }
1338    
1339    
1340    // Show/hide the device configurator form.
1341    void qsamplerMainForm::viewDevices (void)
1342    {
1343            if (m_pOptions == NULL)
1344                    return;
1345    
1346            if (m_pDeviceForm) {
1347                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1348                    if (m_pDeviceForm->isVisible()) {
1349                            m_pDeviceForm->hide();
1350                    } else {
1351                            m_pDeviceForm->show();
1352                            m_pDeviceForm->raise();
1353                            m_pDeviceForm->setActiveWindow();
1354                    }
1355            }
1356    }
1357    
1358    
1359  // Show options dialog.  // Show options dialog.
1360  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1361  {  {
# Line 958  void qsamplerMainForm::viewOptions (void Line 1380  void qsamplerMainForm::viewOptions (void
1380          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1381          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1382          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1383            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1384          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1385          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1386          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1387          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
         int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;  
1388          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1389            int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1390          // Load the current setup settings.          // Load the current setup settings.
1391          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
1392          // Show the setup dialog...          // Show the setup dialog...
1393          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1394              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1395              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1396                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1397                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1398                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1399                    QMessageBox::information(this,
1400                                            QSAMPLER_TITLE ": " + tr("Information"),
1401                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1402                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1403                  updateMessagesCapture();                  updateMessagesCapture();
1404              }              }
1405              // 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);  
1406              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1407                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1408                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1409                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1410                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1411                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1412                    updateInstrumentNames();
1413              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1414                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1415                  updateDisplayEffect();                  updateDisplayEffect();
# Line 1045  void qsamplerMainForm::channelsArrange ( Line 1471  void qsamplerMainForm::channelsArrange (
1471          y += iHeight;          y += iHeight;
1472      }      }
1473      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1474        
1475      stabilizeForm();      stabilizeForm();
1476  }  }
1477    
# Line 1094  void qsamplerMainForm::helpAbout (void) Line 1520  void qsamplerMainForm::helpAbout (void)
1520      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1521      sText += "</font></small><br />";      sText += "</font></small><br />";
1522  #endif  #endif
1523    #ifndef CONFIG_INSTRUMENT_NAME
1524        sText += "<small><font color=\"red\">";
1525        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1526        sText += "</font></small><br />";
1527    #endif
1528    #ifndef CONFIG_MUTE_SOLO
1529        sText += "<small><font color=\"red\">";
1530        sText += tr("Sampler channel Mute/Solo support disabled.");
1531        sText += "</font></small><br />";
1532    #endif
1533    #ifndef CONFIG_AUDIO_ROUTING
1534        sText += "<small><font color=\"red\">";
1535        sText += tr("LSCP (liblscp) audio_routing support disabled.");
1536        sText += "</font></small><br />";
1537    #endif
1538    #ifndef CONFIG_FXSEND
1539        sText += "<small><font color=\"red\">";
1540        sText += tr("Sampler channel Effect Sends support disabled.");
1541        sText += "</font></small><br />";
1542    #endif
1543    #ifndef CONFIG_MIDI_INSTRUMENT
1544        sText += "<small><font color=\"red\">";
1545        sText += tr("MIDI instrument mapping support disabled.");
1546        sText += "</font></small><br />";
1547    #endif
1548      sText += "<br />\n";      sText += "<br />\n";
1549      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1550      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1551      sText += " ";      sText += " ";
1552      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1553    #ifdef CONFIG_LIBGIG
1554        sText += ", ";
1555        sText += gig::libraryName().c_str();
1556        sText += " ";
1557        sText += gig::libraryVersion().c_str();
1558    #endif
1559      sText += "<br />\n";      sText += "<br />\n";
1560      sText += "<br />\n";      sText += "<br />\n";
1561      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 1578  void qsamplerMainForm::helpAbout (void)
1578  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1579  {  {
1580      // Update the main application caption...      // Update the main application caption...
1581      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1582      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1583          sSessioName += '*';          sSessionName += " *";
1584      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1585    
1586      // Update the main menu state...      // Update the main menu state...
1587      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1140  void qsamplerMainForm::stabilizeForm (vo Line 1597  void qsamplerMainForm::stabilizeForm (vo
1597      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1598      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1599      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1600      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1601      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1602    #ifdef CONFIG_MIDI_INSTRUMENT
1603            viewInstrumentsAction->setOn(m_pInstrumentListForm
1604                    && m_pInstrumentListForm->isVisible());
1605            viewInstrumentsAction->setEnabled(bHasClient);
1606    #endif
1607            viewDevicesAction->setOn(m_pDeviceForm
1608                    && m_pDeviceForm->isVisible());
1609        viewDevicesAction->setEnabled(bHasClient);
1610        channelsArrangeAction->setEnabled(bHasChannel);
1611    
1612      // Client/Server status...      // Client/Server status...
1613      if (bHasClient) {      if (bHasClient) {
1614          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1615          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));
1616      } else {      } else {
1617          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1618          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1619      }      }
1620      // Channel status...      // Channel status...
1621      if (bHasChannel)      if (bHasChannel)
1622          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1623      else      else
1624          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1625      // Session status...      // Session status...
1626      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1627          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1628      else      else
1629          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1630    
1631      // Recent files menu.      // Recent files menu.
1632      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 1638  void qsamplerMainForm::stabilizeForm (vo
1638    
1639    
1640  // Channel change receiver slot.  // Channel change receiver slot.
1641  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1642  {  {
1643      // Flag that we're update those channel strips.          // Add this strip to the changed list...
1644      m_iChangeCount++;          if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1645                    m_changedStrips.append(pChannelStrip);
1646                    pChannelStrip->resetErrorCount();
1647            }
1648    
1649      // Just mark the dirty form.      // Just mark the dirty form.
1650      m_iDirtyCount++;      m_iDirtyCount++;
1651      // and update the form status...      // and update the form status...
# Line 1183  void qsamplerMainForm::channelStripChang Line 1653  void qsamplerMainForm::channelStripChang
1653  }  }
1654    
1655    
1656    // Grab and restore current sampler channels session.
1657    void qsamplerMainForm::updateSession (void)
1658    {
1659    #ifdef CONFIG_MIDI_INSTRUMENT
1660            // FIXME: Make some room for default instrument maps...
1661            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1662            if (iMaps < 0)
1663                    appendMessagesClient("lscp_get_midi_instrument_maps");
1664            else if (iMaps < 1) {
1665                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1666                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1667            }
1668    #endif
1669    
1670            // Retrieve the current channel list.
1671            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1672            if (piChannelIDs == NULL) {
1673                    if (::lscp_client_get_errno(m_pClient)) {
1674                            appendMessagesClient("lscp_list_channels");
1675                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1676                    }
1677            } else {
1678                    // Try to (re)create each channel.
1679                    m_pWorkspace->setUpdatesEnabled(false);
1680                    for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1681                            // Check if theres already a channel strip for this one...
1682                            if (!channelStrip(piChannelIDs[iChannel]))
1683                                    createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1684                    }
1685                    m_pWorkspace->setUpdatesEnabled(true);
1686            }
1687    
1688        // Do we auto-arrange?
1689        if (m_pOptions && m_pOptions->bAutoArrange)
1690            channelsArrange();
1691    
1692            // Remember to refresh devices and instruments...
1693            if (m_pInstrumentListForm)
1694                m_pInstrumentListForm->refreshInstruments();
1695            if (m_pDeviceForm)
1696                m_pDeviceForm->refreshDevices();
1697    }
1698    
1699    
1700  // Update the recent files list and menu.  // Update the recent files list and menu.
1701  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1702  {  {
# Line 1227  void qsamplerMainForm::updateRecentFiles Line 1741  void qsamplerMainForm::updateRecentFiles
1741  }  }
1742    
1743    
1744    // Force update of the channels instrument names mode.
1745    void qsamplerMainForm::updateInstrumentNames (void)
1746    {
1747        // Full channel list update...
1748        QWidgetList wlist = m_pWorkspace->windowList();
1749        if (wlist.isEmpty())
1750            return;
1751    
1752        m_pWorkspace->setUpdatesEnabled(false);
1753        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1754            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1755            if (pChannelStrip)
1756                pChannelStrip->updateInstrumentName(true);
1757        }
1758        m_pWorkspace->setUpdatesEnabled(true);
1759    }
1760    
1761    
1762  // Force update of the channels display font.  // Force update of the channels display font.
1763  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1764  {  {
# Line 1332  void qsamplerMainForm::appendMessagesErr Line 1864  void qsamplerMainForm::appendMessagesErr
1864    
1865      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1866    
1867      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));          // Make it look responsive...:)
1868            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1869    
1870        QMessageBox::critical(this,
1871                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1872  }  }
1873    
1874    
# Line 1345  void qsamplerMainForm::appendMessagesCli Line 1881  void qsamplerMainForm::appendMessagesCli
1881      appendMessagesColor(s + QString(": %1 (errno=%2)")      appendMessagesColor(s + QString(": %1 (errno=%2)")
1882          .arg(::lscp_client_get_result(m_pClient))          .arg(::lscp_client_get_result(m_pClient))
1883          .arg(::lscp_client_get_errno(m_pClient)), "#996666");          .arg(::lscp_client_get_errno(m_pClient)), "#996666");
1884    
1885            // Make it look responsive...:)
1886            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1887  }  }
1888    
1889    
# Line 1372  void qsamplerMainForm::updateMessagesLim Line 1911  void qsamplerMainForm::updateMessagesLim
1911          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1912              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1913          else          else
1914              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1915      }      }
1916  }  }
1917    
# Line 1404  qsamplerChannelStrip *qsamplerMainForm:: Line 1943  qsamplerChannelStrip *qsamplerMainForm::
1943          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1944          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1945              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1946          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1947              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1948                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1949                            }
1950          }          }
1951      }      }
1952    
# Line 1414  qsamplerChannelStrip *qsamplerMainForm:: Line 1955  qsamplerChannelStrip *qsamplerMainForm::
1955      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1956      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1957          return NULL;          return NULL;
1958            
1959      // Actual channel strip setup...      // Actual channel strip setup...
1960      pChannelStrip->setup(pChannel);      pChannelStrip->setup(pChannel);
1961      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));          QObject::connect(pChannelStrip,
1962                    SIGNAL(channelChanged(qsamplerChannelStrip *)),
1963                    SLOT(channelStripChanged(qsamplerChannelStrip *)));
1964      // Set some initial aesthetic options...      // Set some initial aesthetic options...
1965      if (m_pOptions) {      if (m_pOptions) {
1966          // Background display effect...          // Background display effect...
# Line 1439  qsamplerChannelStrip *qsamplerMainForm:: Line 1982  qsamplerChannelStrip *qsamplerMainForm::
1982          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1983          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1984      }      }
1985        
1986            // This is pretty new, so we'll watch for it closely.
1987            channelStripChanged(pChannelStrip);
1988    
1989      // Return our successful reference...      // Return our successful reference...
1990      return pChannelStrip;      return pChannelStrip;
1991  }  }
# Line 1457  qsamplerChannelStrip *qsamplerMainForm:: Line 2003  qsamplerChannelStrip *qsamplerMainForm::
2003  {  {
2004      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
2005      if (wlist.isEmpty())      if (wlist.isEmpty())
2006          return 0;          return NULL;
2007    
2008      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
2009  }  }
2010    
2011    
2012    // Retrieve a channel strip by sampler channel id.
2013    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
2014    {
2015            QWidgetList wlist = m_pWorkspace->windowList();
2016            if (wlist.isEmpty())
2017                    return NULL;
2018    
2019            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2020                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2021                    if (pChannelStrip) {
2022                            qsamplerChannel *pChannel = pChannelStrip->channel();
2023                            if (pChannel && pChannel->channelID() == iChannelID)
2024                                    return pChannelStrip;
2025                    }
2026            }
2027    
2028            // Not found.
2029            return NULL;
2030    }
2031    
2032    
2033  // Construct the windows menu.  // Construct the windows menu.
2034  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
2035  {  {
# Line 1529  void qsamplerMainForm::timerSlot (void) Line 2096  void qsamplerMainForm::timerSlot (void)
2096              }              }
2097          }          }
2098      }      }
2099        
2100          // Refresh each channel usage, on each period...          if (m_pClient) {
2101      if (m_pClient && (m_iChangeCount > 0 || m_pOptions->bAutoRefresh)) {                  // Update the channel information for each pending strip...
2102          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2103          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2104              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2105              m_iChangeCount = 0;                                  // If successfull, remove from pending list...
2106              QWidgetList wlist = m_pWorkspace->windowList();                                  if (pChannelStrip->updateChannelInfo())
2107              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                          m_changedStrips.remove(pChannelStrip);
2108                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                          }
2109                  if (pChannelStrip && pChannelStrip->isVisible()) {                  }
2110                      // If we can't make it clean, try next time.                  // Refresh each channel usage, on each period...
2111                      if (!pChannelStrip->updateChannelUsage())                  if (m_pOptions->bAutoRefresh) {
2112                          m_iChangeCount++;                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2113                  }                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2114              }                                  m_iTimerSlot = 0;
2115          }                                  // Update the channel stream usage for each strip...
2116      }                                  QWidgetList wlist = m_pWorkspace->windowList();
2117                                    for (int iChannel = 0;
2118                                                    iChannel < (int) wlist.count(); iChannel++) {
2119                                            qsamplerChannelStrip *pChannelStrip
2120                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2121                                            if (pChannelStrip && pChannelStrip->isVisible())
2122                                                    pChannelStrip->updateChannelUsage();
2123                                    }
2124                            }
2125                    }
2126            }
2127    
2128      // Register the next timer slot.      // Register the next timer slot.
2129      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1568  void qsamplerMainForm::startServer (void Line 2145  void qsamplerMainForm::startServer (void
2145    
2146      // Is the server process instance still here?      // Is the server process instance still here?
2147      if (m_pServer) {      if (m_pServer) {
2148          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2149                            QSAMPLER_TITLE ": " + tr("Warning"),
2150              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2151                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2152              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1589  void qsamplerMainForm::startServer (void Line 2167  void qsamplerMainForm::startServer (void
2167      m_pServer = new QProcess(this);      m_pServer = new QProcess(this);
2168    
2169      // Setup stdout/stderr capture...      // Setup stdout/stderr capture...
2170      //if (m_pOptions->bStdoutCapture) {          //      if (m_pOptions->bStdoutCapture) {
2171          m_pServer->setCommunication(QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);                  m_pServer->setCommunication(
2172          QObject::connect(m_pServer, SIGNAL(readyReadStdout()), this, SLOT(readServerStdout()));                          QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);
2173          QObject::connect(m_pServer, SIGNAL(readyReadStderr()), this, SLOT(readServerStdout()));                  QObject::connect(m_pServer,
2174      //}                          SIGNAL(readyReadStdout()),
2175      // The unforgiveable signal communication...                          SLOT(readServerStdout()));
2176      QObject::connect(m_pServer, SIGNAL(processExited()), this, SLOT(processServerExit()));                  QObject::connect(m_pServer,
2177                            SIGNAL(readyReadStderr()),
2178                            SLOT(readServerStdout()));
2179            //      }
2180            // The unforgiveable signal communication...
2181            QObject::connect(m_pServer,
2182                    SIGNAL(processExited()),
2183                    SLOT(processServerExit()));
2184    
2185      // Build process arguments...      // Build process arguments...
2186      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));
# Line 1727  bool qsamplerMainForm::startClient (void Line 2312  bool qsamplerMainForm::startClient (void
2312      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2313      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)));
2314    
2315            // Subscribe to channel info change notifications...
2316            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2317                    appendMessagesClient("lscp_client_subscribe");
2318    
2319      // We may stop scheduling around.      // We may stop scheduling around.
2320      stopSchedule();      stopSchedule();
2321    
# Line 1736  bool qsamplerMainForm::startClient (void Line 2325  bool qsamplerMainForm::startClient (void
2325      // Log success here.      // Log success here.
2326      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2327    
2328            // Hard-notify instrumnet and device configuration forms,
2329            // if visible, that we're ready...
2330            if (m_pInstrumentListForm)
2331                m_pInstrumentListForm->refreshInstruments();
2332            if (m_pDeviceForm)
2333                m_pDeviceForm->refreshDevices();
2334    
2335      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2336      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2337          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1770  void qsamplerMainForm::stopClient (void) Line 2366  void qsamplerMainForm::stopClient (void)
2366      // channels from the back-end server.      // channels from the back-end server.
2367      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2368      closeSession(false);      closeSession(false);
2369        
2370      // Close us as a client...      // Close us as a client...
2371      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2372        ::lscp_client_destroy(m_pClient);
2373      m_pClient = NULL;      m_pClient = NULL;
2374    
2375            // Hard-notify instrumnet and device configuration forms,
2376            // if visible, that we're running out...
2377            if (m_pInstrumentListForm)
2378                m_pInstrumentListForm->refreshInstruments();
2379            if (m_pDeviceForm)
2380                m_pDeviceForm->refreshDevices();
2381    
2382      // Log final here.      // Log final here.
2383      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2384    

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

  ViewVC Help
Powered by ViewVC