/[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 957 by capela, Wed Nov 29 11:48:26 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"
 #include "qsamplerOptionsForm.h"  
44    
45  #include "config.h"  #include "qsamplerDeviceForm.h"
46    #include "qsamplerOptionsForm.h"
47    
48  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
49  #include <signal.h>  #include <signal.h>
50  #endif  #endif
51    
52    #ifdef CONFIG_LIBGIG
53    #include <gig.h>
54    #endif
55    
56  // Timer constant stuff.  // Timer constant stuff.
57  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
58    
# Line 104  void qsamplerMainForm::init (void) Line 109  void qsamplerMainForm::init (void)
109      m_pOptions = NULL;      m_pOptions = NULL;
110    
111      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
112      m_pMessages = NULL;      m_pMessages   = NULL;
113        m_pDeviceForm = NULL;
114    
115      // We'll start clean.      // We'll start clean.
116      m_iUntitled    = 0;      m_iUntitled   = 0;
117      m_iDirtyCount  = 0;      m_iDirtyCount = 0;
     m_iChangeCount = 0;  
118    
119      m_pServer = NULL;      m_pServer = NULL;
120      m_pClient = NULL;      m_pClient = NULL;
# Line 138  void qsamplerMainForm::init (void) Line 143  void qsamplerMainForm::init (void)
143      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
144      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
145      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
146      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
147      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
148      // Server address.      // Server address.
149      pLabel = new QLabel(this);      pLabel = new QLabel(this);
150      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
151      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
152      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
153      // Channel title.      // Channel title.
154      pLabel = new QLabel(this);      pLabel = new QLabel(this);
155      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
156      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
157      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
158      // Session modification status.      // Session modification status.
159      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
160      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
161      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
162      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
163      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
164    
165      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 173  void qsamplerMainForm::destroy (void) Line 178  void qsamplerMainForm::destroy (void)
178  {  {
179      // Do final processing anyway.      // Do final processing anyway.
180      processServerExit();      processServerExit();
181        
182      // Delete recentfiles menu.  #if defined(WIN32)
183      if (m_pRecentFilesMenu)      WSACleanup();
184          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];  
185    
186      // Finally drop any widgets around...      // Finally drop any widgets around...
187        if (m_pDeviceForm)
188            delete m_pDeviceForm;
189      if (m_pMessages)      if (m_pMessages)
190          delete m_pMessages;          delete m_pMessages;
191      if (m_pWorkspace)      if (m_pWorkspace)
192          delete m_pWorkspace;          delete m_pWorkspace;
193    
194  #if defined(WIN32)      // Delete status item labels one by one.
195      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
196  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
197        if (m_statusItem[QSAMPLER_STATUS_SERVER])
198            delete m_statusItem[QSAMPLER_STATUS_SERVER];
199        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
200            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
201        if (m_statusItem[QSAMPLER_STATUS_SESSION])
202            delete m_statusItem[QSAMPLER_STATUS_SESSION];
203    
204        // Delete recentfiles menu.
205        if (m_pRecentFilesMenu)
206            delete m_pRecentFilesMenu;
207  }  }
208    
209    
# Line 205  void qsamplerMainForm::setup ( qsamplerO Line 213  void qsamplerMainForm::setup ( qsamplerO
213      // We got options?      // We got options?
214      m_pOptions = pOptions;      m_pOptions = pOptions;
215    
216          // Set initial instrument name display mode.      // What style do we create these forms?
217      qsamplerChannel::setInstrumentNames(m_pOptions->bInstrumentNames);      WFlags wflags = Qt::WType_TopLevel;
218        if (m_pOptions->bKeepOnTop)
219            wflags |= Qt::WStyle_Tool;
220      // Some child forms are to be created right now.      // Some child forms are to be created right now.
221      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
222        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
223        m_pDeviceForm->setMainForm(this); // An important life immutable!
224      // Set message defaults...      // Set message defaults...
225      updateMessagesFont();      updateMessagesFont();
226      updateMessagesLimit();      updateMessagesLimit();
# Line 238  void qsamplerMainForm::setup ( qsamplerO Line 249  void qsamplerMainForm::setup ( qsamplerO
249          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
250          istr >> *this;          istr >> *this;
251      }      }
252      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
253      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
254        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
255    
256      // Final startup stabilization...      // Final startup stabilization...
257      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 277  bool qsamplerMainForm::queryClose (void) Line 289  bool qsamplerMainForm::queryClose (void)
289              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
290              ostr << *this;              ostr << *this;
291              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
292              // And the main windows state.              // And the children, and the main windows state,.
293              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
294                            m_pOptions->saveWidgetGeometry(this);
295                            // Close popup widgets.
296                            if (m_pDeviceForm)
297                                    m_pDeviceForm->close();
298              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
299              stopServer();              stopServer();
300          }          }
# Line 297  void qsamplerMainForm::closeEvent ( QClo Line 313  void qsamplerMainForm::closeEvent ( QClo
313  }  }
314    
315    
316  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
317  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
318  {  {
319      bool bAccept = false;      bool bDecode = false;
320    
321      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
322          QString sUrl;          QString sText;
323          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
324              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
325                files = QStringList::split('\n', sText);
326                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
327                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
328            }
329      }      }
330    
331      pDragEnterEvent->accept(bAccept);      return bDecode;
332    }
333    
334    
335    // Window drag-n-drop event handlers.
336    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
337    {
338            QStringList files;
339            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
340  }  }
341    
342    
343  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
344  {  {
345      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
346          QString sUrl;  
347          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
348              loadSessionFile(QUrl(sUrl).path());          return;
349      }  
350            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
351                    const QString& sPath = *iter;
352                    if (qsamplerChannel::isInstrumentFile(sPath)) {
353                            // Try to create a new channel from instrument file...
354                            qsamplerChannel *pChannel = new qsamplerChannel(this);
355                            if (pChannel == NULL)
356                                    return;
357                            // Start setting the instrument filename...
358                            pChannel->setInstrument(sPath, 0);
359                            // Before we show it up, may be we'll
360                            // better ask for some initial values?
361                            if (!pChannel->channelSetup(this)) {
362                                    delete pChannel;
363                                    return;
364                            }
365                            // Finally, give it to a new channel strip...
366                            if (!createChannelStrip(pChannel)) {
367                                    delete pChannel;
368                                    return;
369                            }
370                            // Make that an overall update.
371                            m_iDirtyCount++;
372                            stabilizeForm();
373                    }   // Otherwise, load an usual session file (LSCP script)...
374                    else if (closeSession(true))
375                            loadSessionFile(sPath);
376                    // Make it look responsive...:)
377                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
378            }
379  }  }
380    
381    
# Line 328  void qsamplerMainForm::customEvent ( QCu Line 385  void qsamplerMainForm::customEvent ( QCu
385      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
386      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
387          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
388          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
389              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
390              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
391                            if (pChannelStrip)
392                                    channelStripChanged(pChannelStrip);
393                    } else {
394                            appendMessagesColor(tr("Notify event: %1 data: %2")
395                                    .arg(::lscp_event_to_text(pEvent->event()))
396                                    .arg(pEvent->data()), "#996699");
397                    }
398      }      }
399  }  }
400    
# Line 339  void qsamplerMainForm::customEvent ( QCu Line 403  void qsamplerMainForm::customEvent ( QCu
403  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
404  {  {
405      stabilizeForm();      stabilizeForm();
406        
407      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
408  }  }
409    
# Line 383  bool qsamplerMainForm::newSession (void) Line 447  bool qsamplerMainForm::newSession (void)
447      if (!closeSession(true))      if (!closeSession(true))
448          return false;          return false;
449    
450            // Give us what the server has, right now...
451            updateSession();
452    
453      // Ok increment untitled count.      // Ok increment untitled count.
454      m_iUntitled++;      m_iUntitled++;
455    
# Line 404  bool qsamplerMainForm::openSession (void Line 471  bool qsamplerMainForm::openSession (void
471    
472      // Ask for the filename to open...      // Ask for the filename to open...
473      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
474              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
475              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
476              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
477              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
478      );      );
479    
480      // Have we cancelled?      // Have we cancelled?
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 505  bool qsamplerMainForm::saveSession ( boo
505              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
506          // Prompt the guy...          // Prompt the guy...
507          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
508                  sFilename,                              // Start here.                          sFilename,                              // Start here.
509                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
510                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
511                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
512          );          );
513          // Have we cancelled it?          // Have we cancelled it?
514          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 451  bool qsamplerMainForm::saveSession ( boo Line 518  bool qsamplerMainForm::saveSession ( boo
518              sFilename += ".lscp";              sFilename += ".lscp";
519          // Check if already exists...          // Check if already exists...
520          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
521              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
522                                    QSAMPLER_TITLE ": " + tr("Warning"),
523                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
524                     "\"%1\"\n\n"                     "\"%1\"\n\n"
525                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 473  bool qsamplerMainForm::closeSession ( bo Line 541  bool qsamplerMainForm::closeSession ( bo
541    
542      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
543      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
544          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
545                            QSAMPLER_TITLE ": " + tr("Warning"),
546              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
547              "\"%1\"\n\n"              "\"%1\"\n\n"
548              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 531  bool qsamplerMainForm::loadSessionFile ( Line 600  bool qsamplerMainForm::loadSessionFile (
600      QTextStream ts(&file);      QTextStream ts(&file);
601      while (!ts.atEnd()) {      while (!ts.atEnd()) {
602          // Read the line.          // Read the line.
603          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
604          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
605          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
606              appendMessagesColor(sCommand, "#996633");              appendMessagesColor(sCommand, "#996633");
# Line 550  bool qsamplerMainForm::loadSessionFile ( Line 619  bool qsamplerMainForm::loadSessionFile (
619      // Ok. we've read it.      // Ok. we've read it.
620      file.close();      file.close();
621    
622      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
623      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
624    
625      // Now we'll try to create the whole GUI session.          // Have we any errors?
626      int *piChannelIDs = ::lscp_list_channels(m_pClient);          if (iErrors > 0)
627      if (piChannelIDs == NULL) {                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
         appendMessagesClient("lscp_list_channels");  
         appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));  
     }  
       
     // Try to (re)create each channel.  
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {  
         createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));  
         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
628    
629      // Save as default session directory.      // Save as default session directory.
630      if (m_pOptions)      if (m_pOptions)
631          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
632      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
633      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
634      // Stabilize form...      // Stabilize form...
635      m_sFilename = sFilename;      m_sFilename = sFilename;
636      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
637      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
638        
639      // Make that an overall update.      // Make that an overall update.
     m_iChangeCount++;  
640      stabilizeForm();      stabilizeForm();
641      return true;      return true;
642  }  }
# Line 597  bool qsamplerMainForm::saveSessionFile ( Line 653  bool qsamplerMainForm::saveSessionFile (
653      }      }
654    
655      // Write the file.      // Write the file.
656      int iErrors = 0;      int  iErrors = 0;
657      QTextStream ts(&file);      QTextStream ts(&file);
658      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
659      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 608  bool qsamplerMainForm::saveSessionFile ( Line 664  bool qsamplerMainForm::saveSessionFile (
664      ts << "# " << tr("File")      ts << "# " << tr("File")
665         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
666      ts << "# " << tr("Date")      ts << "# " << tr("Date")
667         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
668         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
669      ts << "#"  << endl;      ts << "#"  << endl;
670      ts << endl;      ts << endl;
671            // It is assumed that this new kind of device+session file
672            // will be loaded from a complete
673            int *piDeviceIDs;
674            int  iDevice;
675            ts << "RESET" << endl;
676            // Audio device mapping.
677            QMap<int, int> audioDeviceMap;
678            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
679            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
680                    ts << endl;
681                    qsamplerDevice device(this, qsamplerDevice::Audio, piDeviceIDs[iDevice]);
682                    // Audio device specification...
683                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
684                            << " " << tr("Device") << " " << iDevice << endl;
685                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
686                    qsamplerDeviceParamMap::ConstIterator deviceParam;
687                    for (deviceParam = device.params().begin();
688                                    deviceParam != device.params().end();
689                                            ++deviceParam) {
690                            const qsamplerDeviceParam& param = deviceParam.data();
691                            if (param.value.isEmpty()) ts << "# ";
692                            ts << " " << deviceParam.key() << "='" << param.value << "'";
693                    }
694                    ts << endl;
695                    // Audio channel parameters...
696                    int iPort = 0;
697                    for (qsamplerDevicePort *pPort = device.ports().first();
698                                    pPort;
699                                            pPort = device.ports().next(), ++iPort) {
700                            qsamplerDeviceParamMap::ConstIterator portParam;
701                            for (portParam = pPort->params().begin();
702                                            portParam != pPort->params().end();
703                                                    ++portParam) {
704                                    const qsamplerDeviceParam& param = portParam.data();
705                                    if (param.fix || param.value.isEmpty()) ts << "# ";
706                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
707                                            << " " << iPort << " " << portParam.key()
708                                            << "='" << param.value << "'" << endl;
709                            }
710                    }
711                    // Audio device index/id mapping.
712                    audioDeviceMap[device.deviceID()] = iDevice;
713            // Try to keep it snappy :)
714            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
715            }
716            // MIDI device mapping.
717            QMap<int, int> midiDeviceMap;
718            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
719            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
720                    ts << endl;
721                    qsamplerDevice device(this, qsamplerDevice::Midi, piDeviceIDs[iDevice]);
722                    // MIDI device specification...
723                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
724                            << " " << tr("Device") << " " << iDevice << endl;
725                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
726                    qsamplerDeviceParamMap::ConstIterator deviceParam;
727                    for (deviceParam = device.params().begin();
728                                    deviceParam != device.params().end();
729                                            ++deviceParam) {
730                            const qsamplerDeviceParam& param = deviceParam.data();
731                            if (param.value.isEmpty()) ts << "# ";
732                            ts << " " << deviceParam.key() << "='" << param.value << "'";
733                    }
734                    ts << endl;
735                    // MIDI port parameters...
736                    int iPort = 0;
737                    for (qsamplerDevicePort *pPort = device.ports().first();
738                                    pPort;
739                                            pPort = device.ports().next(), ++iPort) {
740                            qsamplerDeviceParamMap::ConstIterator portParam;
741                            for (portParam = pPort->params().begin();
742                                            portParam != pPort->params().end();
743                                                    ++portParam) {
744                                    const qsamplerDeviceParam& param = portParam.data();
745                                    if (param.fix || param.value.isEmpty()) ts << "# ";
746                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
747                                       << " " << iPort << " " << portParam.key()
748                                       << "='" << param.value << "'" << endl;
749                            }
750                    }
751                    // MIDI device index/id mapping.
752                    midiDeviceMap[device.deviceID()] = iDevice;
753            // Try to keep it snappy :)
754            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
755            }
756            ts << endl;
757            // Sampler channel mapping.
758      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
759      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
760          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
761          if (pChannelStrip) {          if (pChannelStrip) {
762              qsamplerChannel *pChannel = pChannelStrip->channel();              qsamplerChannel *pChannel = pChannelStrip->channel();
763              if (pChannel) {              if (pChannel) {
764                  int iChannelID = pChannel->channelID();                  ts << "# " << tr("Channel") << " " << iChannel << endl;
                 ts << "# " << pChannelStrip->caption() << endl;  
765                  ts << "ADD CHANNEL" << endl;                  ts << "ADD CHANNEL" << endl;
766                  ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                                  if (audioDeviceMap.isEmpty()) {
767                  ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
768                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                                  << " " << pChannel->audioDriver() << endl;
769                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  } else {
770                                            ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
771                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
772                                    }
773                                    if (midiDeviceMap.isEmpty()) {
774                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
775                                                    << " " << pChannel->midiDriver() << endl;
776                                    } else {
777                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
778                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
779                                    }
780                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
781                                            << " " << pChannel->midiPort() << endl;
782                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
783                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
784                      ts << "ALL";                      ts << "ALL";
785                  else                  else
786                      ts << pChannel->midiChannel();                      ts << pChannel->midiChannel();
787                  ts << endl;                  ts << endl;
788                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
789                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannel << endl;
790                  ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;
791                                    for (audioRoute = pChannel->audioRouting().begin();
792                                                    audioRoute != pChannel->audioRouting().end();
793                                                            ++audioRoute) {
794                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
795                                                    << " " << audioRoute.key()
796                                                    << " " << audioRoute.data() << endl;
797                                    }
798                    ts << "SET CHANNEL VOLUME " << iChannel << " " << pChannel->volume() << endl;
799                                    if (pChannel->channelMute())
800                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
801                                    if (pChannel->channelSolo())
802                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
803                  ts << endl;                  ts << endl;
804              }              }
805          }          }
# Line 640  bool qsamplerMainForm::saveSessionFile ( Line 807  bool qsamplerMainForm::saveSessionFile (
807          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
808      }      }
809    
810    #ifdef CONFIG_MIDI_INSTRUMENT
811            // MIDI instrument mapping...
812            lscp_midi_instrument_t *pInstrs = ::lscp_list_midi_instruments(m_pClient);
813            if (pInstrs)
814            ts << "# " << tr("MIDI instrument mapping") << endl;
815            for (int iInstr = 0; pInstrs && pInstrs[iInstr].program >= 0; iInstr++) {
816                    lscp_midi_instrument_info_t *pInstrInfo
817                            = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
818                    if (pInstrInfo) {
819                            ts << "MAP MIDI_INSTRUMENT "
820                                    << pInstrs[iInstr].bank_msb    << " "
821                                    << pInstrs[iInstr].bank_lsb    << " "
822                                    << pInstrs[iInstr].program     << " "
823                                    << pInstrInfo->engine_name     << " '"
824                                    << pInstrInfo->instrument_file << "' "
825                                    << pInstrInfo->instrument_nr   << " "
826                                    << pInstrInfo->volume          << " ";
827                            switch (pInstrInfo->load_mode) {
828                                    case LSCP_LOAD_PERSISTENT:
829                                            ts << "PERSISTENT";
830                                            break;
831                                    case LSCP_LOAD_ON_DEMAND_HOLD:
832                                            ts << "ON_DEMAND_HOLD";
833                                            break;
834                                    case LSCP_LOAD_ON_DEMAND:
835                                    case LSCP_LOAD_DEFAULT:
836                                    default:
837                                            ts << "ON_DEMAND";
838                                            break;
839                            }
840                            if (pInstrInfo->name)
841                                    ts << " '" << pInstrInfo->name << "'";
842                            ts << endl;
843                    }
844                    ts << endl;
845            // Try to keep it snappy :)
846            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
847            }
848    #endif //  CONFIG_MIDI_INSTRUMENT
849    
850      // Ok. we've wrote it.      // Ok. we've wrote it.
851      file.close();      file.close();
852    
# Line 661  bool qsamplerMainForm::saveSessionFile ( Line 868  bool qsamplerMainForm::saveSessionFile (
868  }  }
869    
870    
871    // Session change receiver slot.
872    void qsamplerMainForm::sessionDirty (void)
873    {
874        // Just mark the dirty form.
875        m_iDirtyCount++;
876        // and update the form status...
877        stabilizeForm();
878    }
879    
880    
881  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
882  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
883    
# Line 714  void qsamplerMainForm::fileReset (void) Line 931  void qsamplerMainForm::fileReset (void)
931          return;          return;
932    
933      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
934      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
935                    QSAMPLER_TITLE ": " + tr("Warning"),
936          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
937             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
938             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
939             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
940             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
941          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
942          return;          return;
# Line 732  void qsamplerMainForm::fileReset (void) Line 950  void qsamplerMainForm::fileReset (void)
950    
951      // Log this.      // Log this.
952      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
953    
954            // Make it a new session...
955            newSession();
956  }  }
957    
958    
# Line 740  void qsamplerMainForm::fileRestart (void Line 961  void qsamplerMainForm::fileRestart (void
961  {  {
962      if (m_pOptions == NULL)      if (m_pOptions == NULL)
963          return;          return;
964            
965      bool bRestart = true;      bool bRestart = true;
966        
967      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
968      // (if we're currently up and running)      // (if we're currently up and running)
969      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
970          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
971                            QSAMPLER_TITLE ": " + tr("Warning"),
972              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
973                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
974                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
975                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
976                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
977              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
978      }      }
# Line 793  void qsamplerMainForm::editAddChannel (v Line 1015  void qsamplerMainForm::editAddChannel (v
1015          delete pChannel;          delete pChannel;
1016          return;          return;
1017      }      }
1018        
1019      // 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).
1020      if (!createChannelStrip(pChannel)) {      if (!createChannelStrip(pChannel)) {
1021          delete pChannel;          delete pChannel;
# Line 802  void qsamplerMainForm::editAddChannel (v Line 1024  void qsamplerMainForm::editAddChannel (v
1024    
1025      // Make that an overall update.      // Make that an overall update.
1026      m_iDirtyCount++;      m_iDirtyCount++;
     m_iChangeCount++;  
1027      stabilizeForm();      stabilizeForm();
1028  }  }
1029    
# Line 816  void qsamplerMainForm::editRemoveChannel Line 1037  void qsamplerMainForm::editRemoveChannel
1037      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1038      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1039          return;          return;
1040            
1041      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
1042      if (pChannel == NULL)      if (pChannel == NULL)
1043          return;          return;
1044    
1045      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1046      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1047          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1048                            QSAMPLER_TITLE ": " + tr("Warning"),
1049              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1050                 "%1\n\n"                 "%1\n\n"
1051                 "Are you sure?")                 "Are you sure?")
# Line 838  void qsamplerMainForm::editRemoveChannel Line 1060  void qsamplerMainForm::editRemoveChannel
1060    
1061      // Just delete the channel strip.      // Just delete the channel strip.
1062      delete pChannelStrip;      delete pChannelStrip;
1063        
1064      // Do we auto-arrange?      // Do we auto-arrange?
1065      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1066          channelsArrange();          channelsArrange();
# Line 874  void qsamplerMainForm::editResetChannel Line 1096  void qsamplerMainForm::editResetChannel
1096      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1097          return;          return;
1098    
1099      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1100      if (pChannel == NULL)      pChannelStrip->channelReset();
1101          return;  }
1102    
     // Reset the existing sampler channel.  
     pChannel->resetChannel();  
1103    
1104      // And force a deferred update.  // Reset all sampler channels.
1105      m_iChangeCount++;  void qsamplerMainForm::editResetAllChannels (void)
1106    {
1107            if (m_pClient == NULL)
1108                    return;
1109    
1110            // Invoque the channel strip procedure,
1111            // for all channels out there...
1112            m_pWorkspace->setUpdatesEnabled(false);
1113            QWidgetList wlist = m_pWorkspace->windowList();
1114            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1115                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1116                    if (pChannelStrip)
1117                            pChannelStrip->channelReset();
1118            }
1119            m_pWorkspace->setUpdatesEnabled(true);
1120  }  }
1121    
1122    
# Line 934  void qsamplerMainForm::viewMessages ( bo Line 1168  void qsamplerMainForm::viewMessages ( bo
1168  }  }
1169    
1170    
1171    // Show/hide the device configurator form.
1172    void qsamplerMainForm::viewDevices (void)
1173    {
1174            if (m_pOptions == NULL)
1175                    return;
1176    
1177            if (m_pDeviceForm) {
1178                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1179                    m_pDeviceForm->setClient(m_pClient);
1180                    if (m_pDeviceForm->isVisible()) {
1181                            m_pDeviceForm->hide();
1182                    } else {
1183                            m_pDeviceForm->show();
1184                            m_pDeviceForm->raise();
1185                            m_pDeviceForm->setActiveWindow();
1186                    }
1187            }
1188    }
1189    
1190    
1191  // Show options dialog.  // Show options dialog.
1192  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1193  {  {
# Line 958  void qsamplerMainForm::viewOptions (void Line 1212  void qsamplerMainForm::viewOptions (void
1212          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1213          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1214          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1215            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1216          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1217          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1218          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1219          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
         int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;  
1220          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;          bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1221            int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1222          // Load the current setup settings.          // Load the current setup settings.
1223          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
1224          // Show the setup dialog...          // Show the setup dialog...
1225          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1226              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1227              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1228                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1229                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1230                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1231                    QMessageBox::information(this,
1232                                            QSAMPLER_TITLE ": " + tr("Information"),
1233                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1234                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1235                  updateMessagesCapture();                  updateMessagesCapture();
1236              }              }
1237              // 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);  
1238              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||              if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1239                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1240                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1241                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1242                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1243                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1244                    updateInstrumentNames();
1245              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1246                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1247                  updateDisplayEffect();                  updateDisplayEffect();
# Line 1045  void qsamplerMainForm::channelsArrange ( Line 1303  void qsamplerMainForm::channelsArrange (
1303          y += iHeight;          y += iHeight;
1304      }      }
1305      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1306        
1307      stabilizeForm();      stabilizeForm();
1308  }  }
1309    
# Line 1094  void qsamplerMainForm::helpAbout (void) Line 1352  void qsamplerMainForm::helpAbout (void)
1352      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1353      sText += "</font></small><br />";      sText += "</font></small><br />";
1354  #endif  #endif
1355    #ifndef CONFIG_INSTRUMENT_NAME
1356        sText += "<small><font color=\"red\">";
1357        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1358        sText += "</font></small><br />";
1359    #endif
1360    #ifndef CONFIG_MUTE_SOLO
1361        sText += "<small><font color=\"red\">";
1362        sText += tr("Sampler channel Mute/Solo support disabled.");
1363        sText += "</font></small><br />";
1364    #endif
1365      sText += "<br />\n";      sText += "<br />\n";
1366      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1367      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1368      sText += " ";      sText += " ";
1369      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1370    #ifdef CONFIG_LIBGIG
1371        sText += ", ";
1372        sText += gig::libraryName().c_str();
1373        sText += " ";
1374        sText += gig::libraryVersion().c_str();
1375    #endif
1376      sText += "<br />\n";      sText += "<br />\n";
1377      sText += "<br />\n";      sText += "<br />\n";
1378      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 1395  void qsamplerMainForm::helpAbout (void)
1395  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1396  {  {
1397      // Update the main application caption...      // Update the main application caption...
1398      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1399      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1400          sSessioName += '*';          sSessionName += " *";
1401      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1402    
1403      // Update the main menu state...      // Update the main menu state...
1404      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1140  void qsamplerMainForm::stabilizeForm (vo Line 1414  void qsamplerMainForm::stabilizeForm (vo
1414      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1415      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1416      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1417      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1418      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1419        viewDevicesAction->setOn(m_pDeviceForm && m_pDeviceForm->isVisible());
1420        viewDevicesAction->setEnabled(bHasClient);
1421        channelsArrangeAction->setEnabled(bHasChannel);
1422    
1423      // Client/Server status...      // Client/Server status...
1424      if (bHasClient) {      if (bHasClient) {
1425          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1426          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));
1427      } else {      } else {
1428          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1429          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1430      }      }
1431      // Channel status...      // Channel status...
1432      if (bHasChannel)      if (bHasChannel)
1433          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1434      else      else
1435          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1436      // Session status...      // Session status...
1437      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1438          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1439      else      else
1440          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1441    
1442      // Recent files menu.      // Recent files menu.
1443      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 1449  void qsamplerMainForm::stabilizeForm (vo
1449    
1450    
1451  // Channel change receiver slot.  // Channel change receiver slot.
1452  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1453  {  {
1454      // Flag that we're update those channel strips.          // Add this strip to the changed list...
1455      m_iChangeCount++;          if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1456                    m_changedStrips.append(pChannelStrip);
1457                    pChannelStrip->resetErrorCount();
1458            }
1459    
1460      // Just mark the dirty form.      // Just mark the dirty form.
1461      m_iDirtyCount++;      m_iDirtyCount++;
1462      // and update the form status...      // and update the form status...
# Line 1183  void qsamplerMainForm::channelStripChang Line 1464  void qsamplerMainForm::channelStripChang
1464  }  }
1465    
1466    
1467    // Grab and restore current sampler channels session.
1468    void qsamplerMainForm::updateSession (void)
1469    {
1470            // Retrieve the current channel list.
1471            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1472            if (piChannelIDs == NULL) {
1473                    if (::lscp_client_get_errno(m_pClient)) {
1474                            appendMessagesClient("lscp_list_channels");
1475                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1476                    }
1477                    return;
1478            }
1479    
1480            // Try to (re)create each channel.
1481            m_pWorkspace->setUpdatesEnabled(false);
1482            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1483                    // Check if theres already a channel strip for this one...
1484                    if (!channelStrip(piChannelIDs[iChannel]))
1485                            createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));
1486                    // Make it visibly responsive...
1487                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1488            }
1489            m_pWorkspace->setUpdatesEnabled(true);
1490            
1491            // Remember to refresh devices
1492            if (m_pDeviceForm)
1493                m_pDeviceForm->refreshDevices();
1494    }
1495    
1496    
1497  // Update the recent files list and menu.  // Update the recent files list and menu.
1498  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1499  {  {
# Line 1227  void qsamplerMainForm::updateRecentFiles Line 1538  void qsamplerMainForm::updateRecentFiles
1538  }  }
1539    
1540    
1541    // Force update of the channels instrument names mode.
1542    void qsamplerMainForm::updateInstrumentNames (void)
1543    {
1544        // Full channel list update...
1545        QWidgetList wlist = m_pWorkspace->windowList();
1546        if (wlist.isEmpty())
1547            return;
1548    
1549        m_pWorkspace->setUpdatesEnabled(false);
1550        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1551            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1552            if (pChannelStrip)
1553                pChannelStrip->updateInstrumentName(true);
1554        }
1555        m_pWorkspace->setUpdatesEnabled(true);
1556    }
1557    
1558    
1559  // Force update of the channels display font.  // Force update of the channels display font.
1560  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1561  {  {
# Line 1332  void qsamplerMainForm::appendMessagesErr Line 1661  void qsamplerMainForm::appendMessagesErr
1661    
1662      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1663    
1664      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));      QMessageBox::critical(this,
1665                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1666  }  }
1667    
1668    
# Line 1372  void qsamplerMainForm::updateMessagesLim Line 1702  void qsamplerMainForm::updateMessagesLim
1702          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1703              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1704          else          else
1705              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1706      }      }
1707  }  }
1708    
# Line 1404  qsamplerChannelStrip *qsamplerMainForm:: Line 1734  qsamplerChannelStrip *qsamplerMainForm::
1734          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1735          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1736              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1737          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1738              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1739                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1740                            }
1741          }          }
1742      }      }
1743    
# Line 1414  qsamplerChannelStrip *qsamplerMainForm:: Line 1746  qsamplerChannelStrip *qsamplerMainForm::
1746      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1747      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1748          return NULL;          return NULL;
1749            
1750      // Actual channel strip setup...      // Actual channel strip setup...
1751      pChannelStrip->setup(pChannel);      pChannelStrip->setup(pChannel);
1752      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 1771  qsamplerChannelStrip *qsamplerMainForm::
1771          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1772          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1773      }      }
1774        
1775            // This is pretty new, so we'll watch for it closely.
1776            channelStripChanged(pChannelStrip);
1777    
1778      // Return our successful reference...      // Return our successful reference...
1779      return pChannelStrip;      return pChannelStrip;
1780  }  }
# Line 1457  qsamplerChannelStrip *qsamplerMainForm:: Line 1792  qsamplerChannelStrip *qsamplerMainForm::
1792  {  {
1793      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1794      if (wlist.isEmpty())      if (wlist.isEmpty())
1795          return 0;          return NULL;
1796    
1797      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1798  }  }
1799    
1800    
1801    // Retrieve a channel strip by sampler channel id.
1802    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1803    {
1804            QWidgetList wlist = m_pWorkspace->windowList();
1805            if (wlist.isEmpty())
1806                    return NULL;
1807    
1808            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1809                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1810                    if (pChannelStrip) {
1811                            qsamplerChannel *pChannel = pChannelStrip->channel();
1812                            if (pChannel && pChannel->channelID() == iChannelID)
1813                                    return pChannelStrip;
1814                    }
1815            }
1816    
1817            // Not found.
1818            return NULL;
1819    }
1820    
1821    
1822  // Construct the windows menu.  // Construct the windows menu.
1823  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1824  {  {
# Line 1529  void qsamplerMainForm::timerSlot (void) Line 1885  void qsamplerMainForm::timerSlot (void)
1885              }              }
1886          }          }
1887      }      }
1888        
1889          // Refresh each channel usage, on each period...          if (m_pClient) {
1890      if (m_pClient && (m_iChangeCount > 0 || m_pOptions->bAutoRefresh)) {                  // Update the channel information for each pending strip...
1891          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
1892          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
1893              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
1894              m_iChangeCount = 0;                                  // If successfull, remove from pending list...
1895              QWidgetList wlist = m_pWorkspace->windowList();                                  if (pChannelStrip->updateChannelInfo())
1896              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                          m_changedStrips.remove(pChannelStrip);
1897                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                          }
1898                  if (pChannelStrip && pChannelStrip->isVisible()) {                  }
1899                      // If we can't make it clean, try next time.                  // Refresh each channel usage, on each period...
1900                      if (!pChannelStrip->updateChannelUsage())                  if (m_pOptions->bAutoRefresh) {
1901                          m_iChangeCount++;                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
1902                  }                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
1903              }                                  m_iTimerSlot = 0;
1904          }                                  // Update the channel stream usage for each strip...
1905      }                                  QWidgetList wlist = m_pWorkspace->windowList();
1906                                    for (int iChannel = 0;
1907                                                    iChannel < (int) wlist.count(); iChannel++) {
1908                                            qsamplerChannelStrip *pChannelStrip
1909                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
1910                                            if (pChannelStrip && pChannelStrip->isVisible())
1911                                                    pChannelStrip->updateChannelUsage();
1912                                    }
1913                            }
1914                    }
1915            }
1916    
1917      // Register the next timer slot.      // Register the next timer slot.
1918      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1568  void qsamplerMainForm::startServer (void Line 1934  void qsamplerMainForm::startServer (void
1934    
1935      // Is the server process instance still here?      // Is the server process instance still here?
1936      if (m_pServer) {      if (m_pServer) {
1937          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
1938                            QSAMPLER_TITLE ": " + tr("Warning"),
1939              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
1940                 "Maybe it ss already started."),                 "Maybe it ss already started."),
1941              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1727  bool qsamplerMainForm::startClient (void Line 2094  bool qsamplerMainForm::startClient (void
2094      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2095      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)));
2096    
2097            // Subscribe to channel info change notifications...
2098            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2099                    appendMessagesClient("lscp_client_subscribe");
2100    
2101      // We may stop scheduling around.      // We may stop scheduling around.
2102      stopSchedule();      stopSchedule();
2103    
# Line 1736  bool qsamplerMainForm::startClient (void Line 2107  bool qsamplerMainForm::startClient (void
2107      // Log success here.      // Log success here.
2108      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2109    
2110            // Hard-notify device configuration form,
2111            // if visible, that we're ready...
2112            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2113                m_pDeviceForm->setClient(m_pClient);
2114    
2115      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2116      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2117          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1756  void qsamplerMainForm::stopClient (void) Line 2132  void qsamplerMainForm::stopClient (void)
2132      if (m_pClient == NULL)      if (m_pClient == NULL)
2133          return;          return;
2134    
2135            // Hard-notify device configuration form,
2136            // if visible, that we're running out...
2137            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2138                m_pDeviceForm->setClient(NULL);
2139    
2140      // Log prepare here.      // Log prepare here.
2141      appendMessages(tr("Client disconnecting..."));      appendMessages(tr("Client disconnecting..."));
2142    
# Line 1770  void qsamplerMainForm::stopClient (void) Line 2151  void qsamplerMainForm::stopClient (void)
2151      // channels from the back-end server.      // channels from the back-end server.
2152      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2153      closeSession(false);      closeSession(false);
2154        
2155      // Close us as a client...      // Close us as a client...
2156      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2157        ::lscp_client_destroy(m_pClient);
2158      m_pClient = NULL;      m_pClient = NULL;
2159    
2160      // Log final here.      // Log final here.

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

  ViewVC Help
Powered by ViewVC