/[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 304 by capela, Fri Nov 19 11:55:18 2004 UTC revision 757 by capela, Fri Aug 26 23:04:32 2005 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2005, 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 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    
45    #include "qsamplerDeviceForm.h"
46  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
47    
48  #include "config.h"  #ifdef HAVE_SIGNAL_H
49    #include <signal.h>
50    #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
# Line 101  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 116  void qsamplerMainForm::init (void) Line 124  void qsamplerMainForm::init (void)
124    
125      m_iTimerSlot = 0;      m_iTimerSlot = 0;
126    
127    #ifdef HAVE_SIGNAL_H
128            // Set to ignore any fatal "Broken pipe" signals.
129            ::signal(SIGPIPE, SIG_IGN);
130    #endif
131    
132      // Make it an MDI workspace.      // Make it an MDI workspace.
133      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
134      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
# Line 130  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 165  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 197  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        // What style do we create these forms?
217        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 227  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 266  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 286  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 317  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 328  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 372  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 393  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 427  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 440  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 462  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 539  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 586  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 597  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;                  ts << "SET CHANNEL VOLUME " << iChannel << " " << pChannel->volume() << endl;
791                    if (pChannel->channelMute())
792                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
793                    if (pChannel->channelSolo())
794                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
795                  ts << endl;                  ts << endl;
796              }              }
797          }          }
# Line 650  bool qsamplerMainForm::saveSessionFile ( Line 820  bool qsamplerMainForm::saveSessionFile (
820  }  }
821    
822    
823    // Session change receiver slot.
824    void qsamplerMainForm::sessionDirty (void)
825    {
826        // Just mark the dirty form.
827        m_iDirtyCount++;
828        // and update the form status...
829        stabilizeForm();
830    }
831    
832    
833  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
834  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
835    
# Line 703  void qsamplerMainForm::fileReset (void) Line 883  void qsamplerMainForm::fileReset (void)
883          return;          return;
884    
885      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
886      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
887                    QSAMPLER_TITLE ": " + tr("Warning"),
888          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
889             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
890             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
891             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
892             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
893          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
894          return;          return;
# Line 721  void qsamplerMainForm::fileReset (void) Line 902  void qsamplerMainForm::fileReset (void)
902    
903      // Log this.      // Log this.
904      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
905    
906            // Make it a new session...
907            newSession();
908  }  }
909    
910    
# Line 729  void qsamplerMainForm::fileRestart (void Line 913  void qsamplerMainForm::fileRestart (void
913  {  {
914      if (m_pOptions == NULL)      if (m_pOptions == NULL)
915          return;          return;
916            
917      bool bRestart = true;      bool bRestart = true;
918        
919      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
920      // (if we're currently up and running)      // (if we're currently up and running)
921      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
922          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
923                            QSAMPLER_TITLE ": " + tr("Warning"),
924              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
925                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
926                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
927                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
928                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
929              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
930      }      }
# Line 782  void qsamplerMainForm::editAddChannel (v Line 967  void qsamplerMainForm::editAddChannel (v
967          delete pChannel;          delete pChannel;
968          return;          return;
969      }      }
970        
971      // 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).
972      if (!createChannelStrip(pChannel)) {      if (!createChannelStrip(pChannel)) {
973          delete pChannel;          delete pChannel;
# Line 791  void qsamplerMainForm::editAddChannel (v Line 976  void qsamplerMainForm::editAddChannel (v
976    
977      // Make that an overall update.      // Make that an overall update.
978      m_iDirtyCount++;      m_iDirtyCount++;
     m_iChangeCount++;  
979      stabilizeForm();      stabilizeForm();
980  }  }
981    
# Line 805  void qsamplerMainForm::editRemoveChannel Line 989  void qsamplerMainForm::editRemoveChannel
989      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
990      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
991          return;          return;
992            
993      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
994      if (pChannel == NULL)      if (pChannel == NULL)
995          return;          return;
996    
997      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
998      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
999          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1000                            QSAMPLER_TITLE ": " + tr("Warning"),
1001              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1002                 "%1\n\n"                 "%1\n\n"
1003                 "Are you sure?")                 "Are you sure?")
# Line 827  void qsamplerMainForm::editRemoveChannel Line 1012  void qsamplerMainForm::editRemoveChannel
1012    
1013      // Just delete the channel strip.      // Just delete the channel strip.
1014      delete pChannelStrip;      delete pChannelStrip;
1015        
1016      // Do we auto-arrange?      // Do we auto-arrange?
1017      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1018          channelsArrange();          channelsArrange();
# Line 863  void qsamplerMainForm::editResetChannel Line 1048  void qsamplerMainForm::editResetChannel
1048      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1049          return;          return;
1050    
1051      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1052      if (pChannel == NULL)      pChannelStrip->channelReset();
1053          return;  }
1054    
     // Reset the existing sampler channel.  
     pChannel->resetChannel();  
1055    
1056      // And force a deferred update.  // Reset all sampler channels.
1057      m_iChangeCount++;  void qsamplerMainForm::editResetAllChannels (void)
1058    {
1059            if (m_pClient == NULL)
1060                    return;
1061    
1062            // Invoque the channel strip procedure,
1063            // for all channels out there...
1064            m_pWorkspace->setUpdatesEnabled(false);
1065            QWidgetList wlist = m_pWorkspace->windowList();
1066            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1067                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1068                    if (pChannelStrip)
1069                            pChannelStrip->channelReset();
1070            }
1071            m_pWorkspace->setUpdatesEnabled(true);
1072  }  }
1073    
1074    
# Line 923  void qsamplerMainForm::viewMessages ( bo Line 1120  void qsamplerMainForm::viewMessages ( bo
1120  }  }
1121    
1122    
1123    // Show/hide the device configurator form.
1124    void qsamplerMainForm::viewDevices (void)
1125    {
1126            if (m_pOptions == NULL)
1127                    return;
1128    
1129            if (m_pDeviceForm) {
1130                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1131                    m_pDeviceForm->setClient(m_pClient);
1132                    if (m_pDeviceForm->isVisible()) {
1133                            m_pDeviceForm->hide();
1134                    } else {
1135                            m_pDeviceForm->show();
1136                            m_pDeviceForm->raise();
1137                            m_pDeviceForm->setActiveWindow();
1138                    }
1139            }
1140    }
1141    
1142    
1143  // Show options dialog.  // Show options dialog.
1144  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1145  {  {
# Line 947  void qsamplerMainForm::viewOptions (void Line 1164  void qsamplerMainForm::viewOptions (void
1164          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1165          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1166          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1167            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1168          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1169          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1170          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1171          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1172            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1173          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1174          // Load the current setup settings.          // Load the current setup settings.
1175          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 958  void qsamplerMainForm::viewOptions (void Line 1177  void qsamplerMainForm::viewOptions (void
1177          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1178              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1179              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1180                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1181                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1182                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1183                    QMessageBox::information(this,
1184                                            QSAMPLER_TITLE ": " + tr("Information"),
1185                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1186                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1187                  updateMessagesCapture();                  updateMessagesCapture();
# Line 969  void qsamplerMainForm::viewOptions (void Line 1191  void qsamplerMainForm::viewOptions (void
1191                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1192                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1193                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1194                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1195                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1196                    updateInstrumentNames();
1197              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1198                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1199                  updateDisplayEffect();                  updateDisplayEffect();
# Line 1030  void qsamplerMainForm::channelsArrange ( Line 1255  void qsamplerMainForm::channelsArrange (
1255          y += iHeight;          y += iHeight;
1256      }      }
1257      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1258        
1259      stabilizeForm();      stabilizeForm();
1260  }  }
1261    
# Line 1079  void qsamplerMainForm::helpAbout (void) Line 1304  void qsamplerMainForm::helpAbout (void)
1304      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1305      sText += "</font></small><br />";      sText += "</font></small><br />";
1306  #endif  #endif
1307    #ifndef CONFIG_INSTRUMENT_NAME
1308        sText += "<small><font color=\"red\">";
1309        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1310        sText += "</font></small><br />";
1311    #endif
1312    #ifndef CONFIG_MUTE_SOLO
1313        sText += "<small><font color=\"red\">";
1314        sText += tr("Sampler channel Mute/Solo support disabled.");
1315        sText += "</font></small><br />";
1316    #endif
1317      sText += "<br />\n";      sText += "<br />\n";
1318      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1319      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1320      sText += " ";      sText += " ";
1321      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1322    #ifdef CONFIG_LIBGIG
1323        sText += ", ";
1324        sText += gig::libraryName().c_str();
1325        sText += " ";
1326        sText += gig::libraryVersion().c_str();
1327    #endif
1328      sText += "<br />\n";      sText += "<br />\n";
1329      sText += "<br />\n";      sText += "<br />\n";
1330      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 1106  void qsamplerMainForm::helpAbout (void) Line 1347  void qsamplerMainForm::helpAbout (void)
1347  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1348  {  {
1349      // Update the main application caption...      // Update the main application caption...
1350      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1351      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1352          sSessioName += '*';          sSessionName += '*';
1353      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1354    
1355      // Update the main menu state...      // Update the main menu state...
1356      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1125  void qsamplerMainForm::stabilizeForm (vo Line 1366  void qsamplerMainForm::stabilizeForm (vo
1366      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1367      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1368      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1369      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1370      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1371        viewDevicesAction->setOn(m_pDeviceForm && m_pDeviceForm->isVisible());
1372        viewDevicesAction->setEnabled(bHasClient);
1373        channelsArrangeAction->setEnabled(bHasChannel);
1374    
1375      // Client/Server status...      // Client/Server status...
1376      if (bHasClient) {      if (bHasClient) {
1377          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1378          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));
1379      } else {      } else {
1380          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1381          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1382      }      }
1383      // Channel status...      // Channel status...
1384      if (bHasChannel)      if (bHasChannel)
1385          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1386      else      else
1387          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1388      // Session status...      // Session status...
1389      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1390          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1391      else      else
1392          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1393    
1394      // Recent files menu.      // Recent files menu.
1395      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1157  void qsamplerMainForm::stabilizeForm (vo Line 1401  void qsamplerMainForm::stabilizeForm (vo
1401    
1402    
1403  // Channel change receiver slot.  // Channel change receiver slot.
1404  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1405  {  {
1406      // Flag that we're update those channel strips.          // Add this strip to the changed list...
1407      m_iChangeCount++;          if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1408                    m_changedStrips.append(pChannelStrip);
1409                    pChannelStrip->resetErrorCount();
1410            }
1411    
1412      // Just mark the dirty form.      // Just mark the dirty form.
1413      m_iDirtyCount++;      m_iDirtyCount++;
1414      // and update the form status...      // and update the form status...
# Line 1168  void qsamplerMainForm::channelStripChang Line 1416  void qsamplerMainForm::channelStripChang
1416  }  }
1417    
1418    
1419    // Grab and restore current sampler channels session.
1420    void qsamplerMainForm::updateSession (void)
1421    {
1422            // Retrieve the current channel list.
1423            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1424            if (piChannelIDs == NULL) {
1425                    if (::lscp_client_get_errno(m_pClient)) {
1426                            appendMessagesClient("lscp_list_channels");
1427                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1428                    }
1429                    return;
1430            }
1431    
1432            // Try to (re)create each channel.
1433            m_pWorkspace->setUpdatesEnabled(false);
1434            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1435                    // Check if theres already a channel strip for this one...
1436                    if (!channelStrip(piChannelIDs[iChannel]))
1437                            createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));
1438                    // Make it visibly responsive...
1439                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1440            }
1441            m_pWorkspace->setUpdatesEnabled(true);
1442            
1443            // Remember to refresh devices
1444            if (m_pDeviceForm)
1445                m_pDeviceForm->refreshDevices();
1446    }
1447    
1448    
1449  // Update the recent files list and menu.  // Update the recent files list and menu.
1450  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1451  {  {
# Line 1212  void qsamplerMainForm::updateRecentFiles Line 1490  void qsamplerMainForm::updateRecentFiles
1490  }  }
1491    
1492    
1493    // Force update of the channels instrument names mode.
1494    void qsamplerMainForm::updateInstrumentNames (void)
1495    {
1496        // Full channel list update...
1497        QWidgetList wlist = m_pWorkspace->windowList();
1498        if (wlist.isEmpty())
1499            return;
1500    
1501        m_pWorkspace->setUpdatesEnabled(false);
1502        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1503            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1504            if (pChannelStrip)
1505                pChannelStrip->updateInstrumentName(true);
1506        }
1507        m_pWorkspace->setUpdatesEnabled(true);
1508    }
1509    
1510    
1511  // Force update of the channels display font.  // Force update of the channels display font.
1512  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1513  {  {
# Line 1317  void qsamplerMainForm::appendMessagesErr Line 1613  void qsamplerMainForm::appendMessagesErr
1613    
1614      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1615    
1616      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));      QMessageBox::critical(this,
1617                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1618  }  }
1619    
1620    
# Line 1357  void qsamplerMainForm::updateMessagesLim Line 1654  void qsamplerMainForm::updateMessagesLim
1654          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1655              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1656          else          else
1657              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1658      }      }
1659  }  }
1660    
# Line 1389  qsamplerChannelStrip *qsamplerMainForm:: Line 1686  qsamplerChannelStrip *qsamplerMainForm::
1686          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1687          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1688              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1689          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1690              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1691                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1692                            }
1693          }          }
1694      }      }
1695    
# Line 1399  qsamplerChannelStrip *qsamplerMainForm:: Line 1698  qsamplerChannelStrip *qsamplerMainForm::
1698      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1699      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1700          return NULL;          return NULL;
1701            
1702      // Actual channel strip setup...      // Actual channel strip setup...
1703      pChannelStrip->setup(pChannel);      pChannelStrip->setup(pChannel);
1704      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
# Line 1424  qsamplerChannelStrip *qsamplerMainForm:: Line 1723  qsamplerChannelStrip *qsamplerMainForm::
1723          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1724          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1725      }      }
1726        
1727            // This is pretty new, so we'll watch for it closely.
1728            channelStripChanged(pChannelStrip);
1729    
1730      // Return our successful reference...      // Return our successful reference...
1731      return pChannelStrip;      return pChannelStrip;
1732  }  }
# Line 1442  qsamplerChannelStrip *qsamplerMainForm:: Line 1744  qsamplerChannelStrip *qsamplerMainForm::
1744  {  {
1745      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1746      if (wlist.isEmpty())      if (wlist.isEmpty())
1747          return 0;          return NULL;
1748    
1749      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1750  }  }
1751    
1752    
1753    // Retrieve a channel strip by sampler channel id.
1754    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1755    {
1756            QWidgetList wlist = m_pWorkspace->windowList();
1757            if (wlist.isEmpty())
1758                    return NULL;
1759    
1760            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1761                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1762                    if (pChannelStrip) {
1763                            qsamplerChannel *pChannel = pChannelStrip->channel();
1764                            if (pChannel && pChannel->channelID() == iChannelID)
1765                                    return pChannelStrip;
1766                    }
1767            }
1768    
1769            // Not found.
1770            return NULL;
1771    }
1772    
1773    
1774  // Construct the windows menu.  // Construct the windows menu.
1775  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1776  {  {
# Line 1514  void qsamplerMainForm::timerSlot (void) Line 1837  void qsamplerMainForm::timerSlot (void)
1837              }              }
1838          }          }
1839      }      }
1840        
1841          // Refresh each channel usage, on each period...          if (m_pClient) {
1842      if (m_pClient && (m_iChangeCount > 0 || m_pOptions->bAutoRefresh)) {                  // Update the channel information for each pending strip...
1843          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
1844          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
1845              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
1846              m_iChangeCount = 0;                                  // If successfull, remove from pending list...
1847              QWidgetList wlist = m_pWorkspace->windowList();                                  if (pChannelStrip->updateChannelInfo())
1848              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                          m_changedStrips.remove(pChannelStrip);
1849                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                          }
1850                  if (pChannelStrip && pChannelStrip->isVisible()) {                  }
1851                      // If we can't make it clean, try next time.                  // Refresh each channel usage, on each period...
1852                      if (!pChannelStrip->updateChannelUsage())                  if (m_pOptions->bAutoRefresh) {
1853                          m_iChangeCount++;                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
1854                  }                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
1855              }                                  m_iTimerSlot = 0;
1856          }                                  // Update the channel stream usage for each strip...
1857      }                                  QWidgetList wlist = m_pWorkspace->windowList();
1858                                    for (int iChannel = 0;
1859                                                    iChannel < (int) wlist.count(); iChannel++) {
1860                                            qsamplerChannelStrip *pChannelStrip
1861                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
1862                                            if (pChannelStrip && pChannelStrip->isVisible())
1863                                                    pChannelStrip->updateChannelUsage();
1864                                    }
1865                            }
1866                    }
1867            }
1868    
1869      // Register the next timer slot.      // Register the next timer slot.
1870      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1553  void qsamplerMainForm::startServer (void Line 1886  void qsamplerMainForm::startServer (void
1886    
1887      // Is the server process instance still here?      // Is the server process instance still here?
1888      if (m_pServer) {      if (m_pServer) {
1889          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
1890                            QSAMPLER_TITLE ": " + tr("Warning"),
1891              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
1892                 "Maybe it ss already started."),                 "Maybe it ss already started."),
1893              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1712  bool qsamplerMainForm::startClient (void Line 2046  bool qsamplerMainForm::startClient (void
2046      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2047      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)));
2048    
2049            // Subscribe to channel info change notifications...
2050            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2051                    appendMessagesClient("lscp_client_subscribe");
2052    
2053      // We may stop scheduling around.      // We may stop scheduling around.
2054      stopSchedule();      stopSchedule();
2055    
# Line 1721  bool qsamplerMainForm::startClient (void Line 2059  bool qsamplerMainForm::startClient (void
2059      // Log success here.      // Log success here.
2060      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2061    
2062            // Hard-notify device configuration form,
2063            // if visible, that we're ready...
2064            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2065                m_pDeviceForm->setClient(m_pClient);
2066    
2067      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2068      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2069          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1741  void qsamplerMainForm::stopClient (void) Line 2084  void qsamplerMainForm::stopClient (void)
2084      if (m_pClient == NULL)      if (m_pClient == NULL)
2085          return;          return;
2086    
2087            // Hard-notify device configuration form,
2088            // if visible, that we're running out...
2089            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2090                m_pDeviceForm->setClient(NULL);
2091    
2092      // Log prepare here.      // Log prepare here.
2093      appendMessages(tr("Client disconnecting..."));      appendMessages(tr("Client disconnecting..."));
2094    
# Line 1755  void qsamplerMainForm::stopClient (void) Line 2103  void qsamplerMainForm::stopClient (void)
2103      // channels from the back-end server.      // channels from the back-end server.
2104      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2105      closeSession(false);      closeSession(false);
2106        
2107      // Close us as a client...      // Close us as a client...
2108      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2109        ::lscp_client_destroy(m_pClient);
2110      m_pClient = NULL;      m_pClient = NULL;
2111    
2112      // Log final here.      // Log final here.

Legend:
Removed from v.304  
changed lines
  Added in v.757

  ViewVC Help
Powered by ViewVC