/[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 391 by capela, Fri Feb 18 10:28:45 2005 UTC revision 1372 by capela, Wed Oct 3 11:34:30 2007 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004-2005, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 32  Line 32 
32  #include <qfile.h>  #include <qfile.h>
33  #include <qtextstream.h>  #include <qtextstream.h>
34  #include <qstatusbar.h>  #include <qstatusbar.h>
35    #include <qslider.h>
36    #include <qspinbox.h>
37  #include <qlabel.h>  #include <qlabel.h>
38  #include <qtimer.h>  #include <qtimer.h>
39    #include <qtooltip.h>
40    
41  #include "qsamplerAbout.h"  #include "qsamplerAbout.h"
42  #include "qsamplerOptions.h"  #include "qsamplerOptions.h"
# Line 41  Line 44 
44  #include "qsamplerMessages.h"  #include "qsamplerMessages.h"
45    
46  #include "qsamplerChannelStrip.h"  #include "qsamplerChannelStrip.h"
47  #include "qsamplerOptionsForm.h"  #include "qsamplerInstrumentList.h"
48    
49  #include "config.h"  #include "qsamplerInstrumentListForm.h"
50    #include "qsamplerDeviceForm.h"
51    #include "qsamplerOptionsForm.h"
52    
53  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
54  #include <signal.h>  #include <signal.h>
55  #endif  #endif
56    
57    #ifdef CONFIG_LIBGIG
58    #include <gig.h>
59    #endif
60    
61    // Needed for lroundf()
62    #include <math.h>
63    
64    #ifndef CONFIG_ROUND
65    static inline long lroundf ( float x )
66    {
67            if (x >= 0.0f)
68                    return long(x + 0.5f);
69            else
70                    return long(x - 0.5f);
71    }
72    #endif
73    
74  // Timer constant stuff.  // Timer constant stuff.
75  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
76    
# Line 98  private: Line 120  private:
120  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
121  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
122    
123    // Kind of singleton reference.
124    qsamplerMainForm *qsamplerMainForm::g_pMainForm = NULL;
125    
126    
127  // Kind of constructor.  // Kind of constructor.
128  void qsamplerMainForm::init (void)  void qsamplerMainForm::init (void)
129  {  {
130            // Pseudo-singleton reference setup.
131            g_pMainForm = this;
132    
133      // Initialize some pointer references.      // Initialize some pointer references.
134      m_pOptions = NULL;      m_pOptions = NULL;
135    
136      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
137      m_pMessages = NULL;      m_pMessages = NULL;
138        m_pInstrumentListForm = NULL;
139        m_pDeviceForm = NULL;
140    
141      // We'll start clean.      // We'll start clean.
142      m_iUntitled    = 0;      m_iUntitled   = 0;
143      m_iDirtyCount  = 0;      m_iDirtyCount = 0;
     m_iChangeCount = 0;  
144    
145      m_pServer = NULL;      m_pServer = NULL;
146      m_pClient = NULL;      m_pClient = NULL;
# Line 125  void qsamplerMainForm::init (void) Line 155  void qsamplerMainForm::init (void)
155          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
156  #endif  #endif
157    
158    #ifdef CONFIG_VOLUME
159        // Make some extras into the toolbar...
160            const QString& sVolumeText = tr("Master volume");
161            m_iVolumeChanging = 0;
162            // Volume slider...
163            channelsToolbar->addSeparator();
164            m_pVolumeSlider = new QSlider(Qt::Horizontal, channelsToolbar);
165            m_pVolumeSlider->setTickmarks(QSlider::Below);
166            m_pVolumeSlider->setTickInterval(10);
167            m_pVolumeSlider->setPageStep(10);
168            m_pVolumeSlider->setRange(0, 100);
169            m_pVolumeSlider->setMaximumHeight(22);
170            m_pVolumeSlider->setMinimumWidth(160);
171            QToolTip::add(m_pVolumeSlider, sVolumeText);
172            QObject::connect(m_pVolumeSlider,
173                    SIGNAL(valueChanged(int)),
174                    SLOT(volumeChanged(int)));
175            channelsToolbar->setHorizontallyStretchable(true);
176            channelsToolbar->setStretchableWidget(m_pVolumeSlider);
177            // Volume spin-box
178            channelsToolbar->addSeparator();
179            m_pVolumeSpinBox = new QSpinBox(channelsToolbar);
180            m_pVolumeSpinBox->setSuffix(" %");
181            m_pVolumeSpinBox->setRange(0, 100);
182            QToolTip::add(m_pVolumeSpinBox, sVolumeText);
183            QObject::connect(m_pVolumeSpinBox,
184                    SIGNAL(valueChanged(int)),
185                    SLOT(volumeChanged(int)));
186    #endif
187    
188      // Make it an MDI workspace.      // Make it an MDI workspace.
189      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
190      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
191      // Set the activation connection.          // Set the activation connection.
192      QObject::connect(m_pWorkspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(stabilizeForm()));          QObject::connect(m_pWorkspace,
193                    SIGNAL(windowActivated(QWidget *)),
194                    SLOT(stabilizeForm()));
195      // Make it shine :-)      // Make it shine :-)
196      setCentralWidget(m_pWorkspace);      setCentralWidget(m_pWorkspace);
197    
# Line 139  void qsamplerMainForm::init (void) Line 201  void qsamplerMainForm::init (void)
201      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
202      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
203      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
204      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
205      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
206      // Server address.      // Server address.
207      pLabel = new QLabel(this);      pLabel = new QLabel(this);
208      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
209      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
210      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
211      // Channel title.      // Channel title.
212      pLabel = new QLabel(this);      pLabel = new QLabel(this);
213      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
214      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
215      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
216      // Session modification status.      // Session modification status.
217      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
218      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
219      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
220      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
221      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
222    
223      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 174  void qsamplerMainForm::destroy (void) Line 236  void qsamplerMainForm::destroy (void)
236  {  {
237      // Do final processing anyway.      // Do final processing anyway.
238      processServerExit();      processServerExit();
239        
240      // Delete recentfiles menu.  #if defined(WIN32)
241      if (m_pRecentFilesMenu)      WSACleanup();
242          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];  
243    
244      // Finally drop any widgets around...      // Finally drop any widgets around...
245        if (m_pDeviceForm)
246            delete m_pDeviceForm;
247        if (m_pInstrumentListForm)
248            delete m_pInstrumentListForm;
249      if (m_pMessages)      if (m_pMessages)
250          delete m_pMessages;          delete m_pMessages;
251      if (m_pWorkspace)      if (m_pWorkspace)
252          delete m_pWorkspace;          delete m_pWorkspace;
253    
254  #if defined(WIN32)      // Delete status item labels one by one.
255      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
256            delete m_statusItem[QSAMPLER_STATUS_CLIENT];
257        if (m_statusItem[QSAMPLER_STATUS_SERVER])
258            delete m_statusItem[QSAMPLER_STATUS_SERVER];
259        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
260            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
261        if (m_statusItem[QSAMPLER_STATUS_SESSION])
262            delete m_statusItem[QSAMPLER_STATUS_SESSION];
263    
264    #ifdef CONFIG_VOLUME
265            delete m_pVolumeSpinBox;
266            delete m_pVolumeSlider;
267  #endif  #endif
268    
269        // Delete recentfiles menu.
270        if (m_pRecentFilesMenu)
271            delete m_pRecentFilesMenu;
272    
273            // Pseudo-singleton reference shut-down.
274            g_pMainForm = NULL;
275  }  }
276    
277    
# Line 206  void qsamplerMainForm::setup ( qsamplerO Line 281  void qsamplerMainForm::setup ( qsamplerO
281      // We got options?      // We got options?
282      m_pOptions = pOptions;      m_pOptions = pOptions;
283    
284        // What style do we create these forms?
285            Qt::WFlags wflags = Qt::WStyle_Customize
286                    | Qt::WStyle_NormalBorder
287                    | Qt::WStyle_Title
288                    | Qt::WStyle_SysMenu
289                    | Qt::WStyle_MinMax
290                    | Qt::WType_TopLevel;
291        if (m_pOptions->bKeepOnTop)
292            wflags |= Qt::WStyle_Tool;
293      // Some child forms are to be created right now.      // Some child forms are to be created right now.
294      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
295        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
296    #ifdef CONFIG_MIDI_INSTRUMENT
297        m_pInstrumentListForm = new qsamplerInstrumentListForm(this, 0, wflags);
298            QObject::connect(m_pInstrumentListForm->InstrumentList,
299                    SIGNAL(instrumentsChanged()),
300                    SLOT(sessionDirty()));
301    #else
302            viewInstrumentsAction->setEnabled(false);
303    #endif
304      // Set message defaults...      // Set message defaults...
305      updateMessagesFont();      updateMessagesFont();
306      updateMessagesLimit();      updateMessagesLimit();
307      updateMessagesCapture();      updateMessagesCapture();
308      // Set the visibility signal.      // Set the visibility signal.
309      QObject::connect(m_pMessages, SIGNAL(visibilityChanged(bool)), this, SLOT(stabilizeForm()));          QObject::connect(m_pMessages,
310                    SIGNAL(visibilityChanged(bool)),
311                    SLOT(stabilizeForm()));
312    
313      // Initial decorations toggle state.      // Initial decorations toggle state.
314      viewMenubarAction->setOn(m_pOptions->bMenubar);      viewMenubarAction->setOn(m_pOptions->bMenubar);
# Line 236  void qsamplerMainForm::setup ( qsamplerO Line 331  void qsamplerMainForm::setup ( qsamplerO
331          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
332          istr >> *this;          istr >> *this;
333      }      }
334      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
335      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
336        m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
337        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
338    
339      // Final startup stabilization...      // Final startup stabilization...
340        updateMaxVolume();
341      updateRecentFilesMenu();      updateRecentFilesMenu();
342      stabilizeForm();      stabilizeForm();
343    
# Line 275  bool qsamplerMainForm::queryClose (void) Line 373  bool qsamplerMainForm::queryClose (void)
373              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
374              ostr << *this;              ostr << *this;
375              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
376              // And the main windows state.              // And the children, and the main windows state,.
377              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
378                            m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
379                            m_pOptions->saveWidgetGeometry(this);
380                            // Close popup widgets.
381                            if (m_pInstrumentListForm)
382                                    m_pInstrumentListForm->close();
383                            if (m_pDeviceForm)
384                                    m_pDeviceForm->close();
385              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
386              stopServer();              stopServer();
387          }          }
# Line 306  bool qsamplerMainForm::decodeDragFiles ( Line 411  bool qsamplerMainForm::decodeDragFiles (
411          if (bDecode) {          if (bDecode) {
412              files = QStringList::split('\n', sText);              files = QStringList::split('\n', sText);
413              for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)              for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
414                  *iter = (*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null);                  *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
415          }          }
416      }      }
417    
# Line 317  bool qsamplerMainForm::decodeDragFiles ( Line 422  bool qsamplerMainForm::decodeDragFiles (
422  // Window drag-n-drop event handlers.  // Window drag-n-drop event handlers.
423  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
424  {  {
425      QStringList files;          QStringList files;
426            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
     pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));  
427  }  }
428    
429    
# Line 330  void qsamplerMainForm::dropEvent ( QDrop Line 434  void qsamplerMainForm::dropEvent ( QDrop
434      if (!decodeDragFiles(pDropEvent, files))      if (!decodeDragFiles(pDropEvent, files))
435          return;          return;
436    
437      for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {          for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
438                  const QString& sPath = QUrl(*iter).path();                  const QString& sPath = *iter;
439                  if (qsamplerChannel::isInstrumentFile(sPath)) {                  if (qsamplerChannel::isInstrumentFile(sPath)) {
440                          // Try to create a new channel from instrument file...                          // Try to create a new channel from instrument file...
441                      qsamplerChannel *pChannel = new qsamplerChannel(this);                          qsamplerChannel *pChannel = new qsamplerChannel();
442                      if (pChannel == NULL)                          if (pChannel == NULL)
443                          return;                                  return;
444                          // Start setting the instrument filename...                          // Start setting the instrument filename...
445                          pChannel->setInstrument(sPath, 0);                          pChannel->setInstrument(sPath, 0);
446                      // Before we show it up, may be we'll                          // Before we show it up, may be we'll
447                      // better ask for some initial values?                          // better ask for some initial values?
448                      if (!pChannel->channelSetup(this)) {                          if (!pChannel->channelSetup(this)) {
449                          delete pChannel;                                  delete pChannel;
450                          return;                                  return;
451                      }                          }
452                      // Finally, give it to a new channel strip...                          // Finally, give it to a new channel strip...
453                          if (!createChannelStrip(pChannel)) {                          if (!createChannelStrip(pChannel)) {
454                          delete pChannel;                                  delete pChannel;
455                          return;                                  return;
456                          }                          }
457                      // Make that an overall update.                          // Make that an overall update.
458                      m_iDirtyCount++;                          m_iDirtyCount++;
459                      m_iChangeCount++;                          stabilizeForm();
                     stabilizeForm();  
460                  }   // Otherwise, load an usual session file (LSCP script)...                  }   // Otherwise, load an usual session file (LSCP script)...
461                  else if (closeSession(true))                  else if (closeSession(true)) {
462                          loadSessionFile(sPath);                          loadSessionFile(sPath);
463                            break;
464                    }
465                  // Make it look responsive...:)                  // Make it look responsive...:)
466                  QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);                  QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
467          }          }
# Line 369  void qsamplerMainForm::customEvent ( QCu Line 474  void qsamplerMainForm::customEvent ( QCu
474      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
475      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
476          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
477          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
478              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
479              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
480                            if (pChannelStrip)
481                                    channelStripChanged(pChannelStrip);
482                    } else {
483                            appendMessagesColor(tr("Notify event: %1 data: %2")
484                                    .arg(::lscp_event_to_text(pEvent->event()))
485                                    .arg(pEvent->data()), "#996699");
486                    }
487      }      }
488  }  }
489    
# Line 380  void qsamplerMainForm::customEvent ( QCu Line 492  void qsamplerMainForm::customEvent ( QCu
492  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
493  {  {
494      stabilizeForm();      stabilizeForm();
495        
496      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
497  }  }
498    
# Line 394  qsamplerOptions *qsamplerMainForm::optio Line 506  qsamplerOptions *qsamplerMainForm::optio
506      return m_pOptions;      return m_pOptions;
507  }  }
508    
509    
510  // The LSCP client descriptor property.  // The LSCP client descriptor property.
511  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
512  {  {
# Line 401  lscp_client_t *qsamplerMainForm::client Line 514  lscp_client_t *qsamplerMainForm::client
514  }  }
515    
516    
517    // The pseudo-singleton instance accessor.
518    qsamplerMainForm *qsamplerMainForm::getInstance (void)
519    {
520            return g_pMainForm;
521    }
522    
523    
524  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
525  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
526    
# Line 424  bool qsamplerMainForm::newSession (void) Line 544  bool qsamplerMainForm::newSession (void)
544      if (!closeSession(true))      if (!closeSession(true))
545          return false;          return false;
546    
547            // Give us what the server has, right now...
548            updateSession();
549    
550      // Ok increment untitled count.      // Ok increment untitled count.
551      m_iUntitled++;      m_iUntitled++;
552    
# Line 445  bool qsamplerMainForm::openSession (void Line 568  bool qsamplerMainForm::openSession (void
568    
569      // Ask for the filename to open...      // Ask for the filename to open...
570      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
571              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
572              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
573              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
574              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
575      );      );
576    
577      // Have we cancelled?      // Have we cancelled?
# Line 479  bool qsamplerMainForm::saveSession ( boo Line 602  bool qsamplerMainForm::saveSession ( boo
602              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
603          // Prompt the guy...          // Prompt the guy...
604          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
605                  sFilename,                              // Start here.                          sFilename,                              // Start here.
606                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
607                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
608                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
609          );          );
610          // Have we cancelled it?          // Have we cancelled it?
611          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 492  bool qsamplerMainForm::saveSession ( boo Line 615  bool qsamplerMainForm::saveSession ( boo
615              sFilename += ".lscp";              sFilename += ".lscp";
616          // Check if already exists...          // Check if already exists...
617          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
618              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
619                                    QSAMPLER_TITLE ": " + tr("Warning"),
620                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
621                     "\"%1\"\n\n"                     "\"%1\"\n\n"
622                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 514  bool qsamplerMainForm::closeSession ( bo Line 638  bool qsamplerMainForm::closeSession ( bo
638    
639      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
640      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
641          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
642                            QSAMPLER_TITLE ": " + tr("Warning"),
643              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
644              "\"%1\"\n\n"              "\"%1\"\n\n"
645              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 567  bool qsamplerMainForm::loadSessionFile ( Line 692  bool qsamplerMainForm::loadSessionFile (
692          return false;          return false;
693      }      }
694    
695            // Tell the world we'll take some time...
696            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
697    
698      // Read the file.      // Read the file.
699            int iLine = 0;
700      int iErrors = 0;      int iErrors = 0;
701      QTextStream ts(&file);      QTextStream ts(&file);
702      while (!ts.atEnd()) {      while (!ts.atEnd()) {
703          // Read the line.          // Read the line.
704          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
705                    iLine++;
706          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
707          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
708              appendMessagesColor(sCommand, "#996633");                          // Remember that, no matter what,
709              // Remember that, no matter what,                          // all LSCP commands are CR/LF terminated.
710              // all LSCP commands are CR/LF terminated.                          sCommand += "\r\n";
711              sCommand += "\r\n";                          if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
712              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {                                  appendMessagesColor(QString("%1(%2): %3")
713                  appendMessagesClient("lscp_client_query");                                          .arg(QFileInfo(sFilename).fileName()).arg(iLine)
714                  iErrors++;                                          .arg(sCommand.simplifyWhiteSpace()), "#996633");
715                  break;                                  appendMessagesClient("lscp_client_query");
716              }                                  iErrors++;
717                            }
718          }          }
719          // Try to make it snappy :)          // Try to make it snappy :)
720          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
# Line 592  bool qsamplerMainForm::loadSessionFile ( Line 723  bool qsamplerMainForm::loadSessionFile (
723      // Ok. we've read it.      // Ok. we've read it.
724      file.close();      file.close();
725    
726      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
727      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Session could not be loaded\nfrom \"%1\".\n\nSorry.").arg(sFilename));  
728    
729      // Now we'll try to create the whole GUI session.          // We're fornerly done.
730      int *piChannelIDs = ::lscp_list_channels(m_pClient);          QApplication::restoreOverrideCursor();
731      if (piChannelIDs == NULL) {  
732          appendMessagesClient("lscp_list_channels");          // Have we any errors?
733          appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));          if (iErrors > 0)
734      } else {                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
                 // Try to (re)create each channel.  
                 m_pWorkspace->setUpdatesEnabled(false);  
                 for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {  
                         createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));  
                         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
                 }  
                 m_pWorkspace->setUpdatesEnabled(true);  
         }  
735    
736      // Save as default session directory.      // Save as default session directory.
737      if (m_pOptions)      if (m_pOptions)
738          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
739      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
740      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
741      // Stabilize form...      // Stabilize form...
742      m_sFilename = sFilename;      m_sFilename = sFilename;
743      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
744      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
745        
746      // Make that an overall update.      // Make that an overall update.
     m_iChangeCount++;  
747      stabilizeForm();      stabilizeForm();
748      return true;      return true;
749  }  }
# Line 631  bool qsamplerMainForm::loadSessionFile ( Line 752  bool qsamplerMainForm::loadSessionFile (
752  // Save current session to specific file path.  // Save current session to specific file path.
753  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
754  {  {
755            if (m_pClient == NULL)
756                    return false;
757    
758            // Check whether server is apparently OK...
759            if (::lscp_get_channels(m_pClient) < 0) {
760                    appendMessagesClient("lscp_get_channels");
761                    return false;
762            }
763    
764      // Open and write into real file.      // Open and write into real file.
765      QFile file(sFilename);      QFile file(sFilename);
766      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 638  bool qsamplerMainForm::saveSessionFile ( Line 768  bool qsamplerMainForm::saveSessionFile (
768          return false;          return false;
769      }      }
770    
771            // Tell the world we'll take some time...
772            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
773    
774      // Write the file.      // Write the file.
775      int iErrors = 0;      int  iErrors = 0;
776      QTextStream ts(&file);      QTextStream ts(&file);
777      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
778      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 650  bool qsamplerMainForm::saveSessionFile ( Line 783  bool qsamplerMainForm::saveSessionFile (
783      ts << "# " << tr("File")      ts << "# " << tr("File")
784         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
785      ts << "# " << tr("Date")      ts << "# " << tr("Date")
786         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
787         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
788      ts << "#"  << endl;      ts << "#"  << endl;
789      ts << endl;      ts << endl;
790    
791            // It is assumed that this new kind of device+session file
792            // will be loaded from a complete initialized server...
793            int *piDeviceIDs;
794            int  iDevice;
795            ts << "RESET" << endl;
796    
797            // Audio device mapping.
798            QMap<int, int> audioDeviceMap;
799            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
800            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
801                    ts << endl;
802                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
803                    // Audio device specification...
804                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
805                            << " " << tr("Device") << " " << iDevice << endl;
806                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
807                    qsamplerDeviceParamMap::ConstIterator deviceParam;
808                    for (deviceParam = device.params().begin();
809                                    deviceParam != device.params().end();
810                                            ++deviceParam) {
811                            const qsamplerDeviceParam& param = deviceParam.data();
812                            if (param.value.isEmpty()) ts << "# ";
813                            ts << " " << deviceParam.key() << "='" << param.value << "'";
814                    }
815                    ts << endl;
816                    // Audio channel parameters...
817                    int iPort = 0;
818                    for (qsamplerDevicePort *pPort = device.ports().first();
819                                    pPort;
820                                            pPort = device.ports().next(), ++iPort) {
821                            qsamplerDeviceParamMap::ConstIterator portParam;
822                            for (portParam = pPort->params().begin();
823                                            portParam != pPort->params().end();
824                                                    ++portParam) {
825                                    const qsamplerDeviceParam& param = portParam.data();
826                                    if (param.fix || param.value.isEmpty()) ts << "# ";
827                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
828                                            << " " << iPort << " " << portParam.key()
829                                            << "='" << param.value << "'" << endl;
830                            }
831                    }
832                    // Audio device index/id mapping.
833                    audioDeviceMap[device.deviceID()] = iDevice;
834                    // Try to keep it snappy :)
835                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
836            }
837    
838            // MIDI device mapping.
839            QMap<int, int> midiDeviceMap;
840            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
841            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
842                    ts << endl;
843                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
844                    // MIDI device specification...
845                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
846                            << " " << tr("Device") << " " << iDevice << endl;
847                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
848                    qsamplerDeviceParamMap::ConstIterator deviceParam;
849                    for (deviceParam = device.params().begin();
850                                    deviceParam != device.params().end();
851                                            ++deviceParam) {
852                            const qsamplerDeviceParam& param = deviceParam.data();
853                            if (param.value.isEmpty()) ts << "# ";
854                            ts << " " << deviceParam.key() << "='" << param.value << "'";
855                    }
856                    ts << endl;
857                    // MIDI port parameters...
858                    int iPort = 0;
859                    for (qsamplerDevicePort *pPort = device.ports().first();
860                                    pPort;
861                                            pPort = device.ports().next(), ++iPort) {
862                            qsamplerDeviceParamMap::ConstIterator portParam;
863                            for (portParam = pPort->params().begin();
864                                            portParam != pPort->params().end();
865                                                    ++portParam) {
866                                    const qsamplerDeviceParam& param = portParam.data();
867                                    if (param.fix || param.value.isEmpty()) ts << "# ";
868                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
869                                       << " " << iPort << " " << portParam.key()
870                                       << "='" << param.value << "'" << endl;
871                            }
872                    }
873                    // MIDI device index/id mapping.
874                    midiDeviceMap[device.deviceID()] = iDevice;
875                    // Try to keep it snappy :)
876                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
877            }
878            ts << endl;
879    
880    #ifdef CONFIG_MIDI_INSTRUMENT
881            // MIDI instrument mapping...
882            QMap<int, int> midiInstrumentMap;
883            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
884            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
885                    int iMidiMap = piMaps[iMap];
886                    const char *pszMapName
887                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
888                    ts << "# " << tr("MIDI instrument map") << " " << iMap;
889                    if (pszMapName)
890                            ts << " - " << pszMapName;
891                    ts << endl;
892                    ts << "ADD MIDI_INSTRUMENT_MAP";
893                    if (pszMapName)
894                            ts << " '" << pszMapName << "'";
895                    ts << endl;
896                    // MIDI instrument mapping...
897                    lscp_midi_instrument_t *pInstrs
898                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
899                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
900                            lscp_midi_instrument_info_t *pInstrInfo
901                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
902                            if (pInstrInfo) {
903                                    ts << "MAP MIDI_INSTRUMENT "
904                                            << iMap                        << " "
905                                            << pInstrs[iInstr].bank        << " "
906                                            << pInstrs[iInstr].prog        << " "
907                                            << pInstrInfo->engine_name     << " '"
908                                            << pInstrInfo->instrument_file << "' "
909                                            << pInstrInfo->instrument_nr   << " "
910                                            << pInstrInfo->volume          << " ";
911                                    switch (pInstrInfo->load_mode) {
912                                            case LSCP_LOAD_PERSISTENT:
913                                                    ts << "PERSISTENT";
914                                                    break;
915                                            case LSCP_LOAD_ON_DEMAND_HOLD:
916                                                    ts << "ON_DEMAND_HOLD";
917                                                    break;
918                                            case LSCP_LOAD_ON_DEMAND:
919                                            case LSCP_LOAD_DEFAULT:
920                                            default:
921                                                    ts << "ON_DEMAND";
922                                                    break;
923                                    }
924                                    if (pInstrInfo->name)
925                                            ts << " '" << pInstrInfo->name << "'";
926                                    ts << endl;
927                            }       // Check for errors...
928                            else if (::lscp_client_get_errno(m_pClient)) {
929                                    appendMessagesClient("lscp_get_midi_instrument_info");
930                                    iErrors++;
931                            }
932                            // Try to keep it snappy :)
933                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
934                    }
935                    ts << endl;
936                    // Check for errors...
937                    if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {
938                            appendMessagesClient("lscp_list_midi_instruments");
939                            iErrors++;
940                    }
941                    // MIDI strument index/id mapping.
942                    midiInstrumentMap[iMidiMap] = iMap;
943            }
944            // Check for errors...
945            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
946                    appendMessagesClient("lscp_list_midi_instrument_maps");
947                    iErrors++;
948            }
949    #endif  // CONFIG_MIDI_INSTRUMENT
950    
951            // Sampler channel mapping.
952      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
953      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
954          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip
955                            = static_cast<qsamplerChannelStrip *> (wlist.at(iChannel));
956          if (pChannelStrip) {          if (pChannelStrip) {
957              qsamplerChannel *pChannel = pChannelStrip->channel();              qsamplerChannel *pChannel = pChannelStrip->channel();
958              if (pChannel) {              if (pChannel) {
959                  int iChannelID = pChannel->channelID();                  ts << "# " << tr("Channel") << " " << iChannel << endl;
                 ts << "# " << pChannelStrip->caption() << endl;  
960                  ts << "ADD CHANNEL" << endl;                  ts << "ADD CHANNEL" << endl;
961                  ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                                  if (audioDeviceMap.isEmpty()) {
962                  ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
963                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                                  << " " << pChannel->audioDriver() << endl;
964                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  } else {
965                                            ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
966                                                    << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
967                                    }
968                                    if (midiDeviceMap.isEmpty()) {
969                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
970                                                    << " " << pChannel->midiDriver() << endl;
971                                    } else {
972                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
973                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
974                                    }
975                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
976                                            << " " << pChannel->midiPort() << endl;
977                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
978                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)                  if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
979                      ts << "ALL";                      ts << "ALL";
980                  else                  else
981                      ts << pChannel->midiChannel();                      ts << pChannel->midiChannel();
982                  ts << endl;                  ts << endl;
983                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
984                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
985                  ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
986                                            << pChannel->instrumentNr() << " " << iChannel << endl;
987                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
988                                    for (audioRoute = pChannel->audioRouting().begin();
989                                                    audioRoute != pChannel->audioRouting().end();
990                                                            ++audioRoute) {
991                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
992                                                    << " " << audioRoute.key()
993                                                    << " " << audioRoute.data() << endl;
994                                    }
995                                    ts << "SET CHANNEL VOLUME " << iChannel
996                                            << " " << pChannel->volume() << endl;
997                                    if (pChannel->channelMute())
998                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
999                                    if (pChannel->channelSolo())
1000                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
1001    #ifdef CONFIG_MIDI_INSTRUMENT
1002                                    if (pChannel->midiMap() >= 0) {
1003                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
1004                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
1005                                    }
1006    #endif
1007    #ifdef CONFIG_FXSEND
1008                                    int iChannelID = pChannel->channelID();
1009                                    int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID);
1010                                    for (int iFxSend = 0;
1011                                                    piFxSends && piFxSends[iFxSend] >= 0;
1012                                                            iFxSend++) {
1013                                            lscp_fxsend_info_t *pFxSendInfo = ::lscp_get_fxsend_info(
1014                                                    m_pClient, iChannelID, piFxSends[iFxSend]);
1015                                            if (pFxSendInfo) {
1016                                                    ts << "CREATE FX_SEND " << iChannel
1017                                                            << " " << pFxSendInfo->midi_controller;
1018                                                    if (pFxSendInfo->name)
1019                                                            ts << " '" << pFxSendInfo->name << "'";
1020                                                    ts << endl;
1021                                                    int *piRouting = pFxSendInfo->audio_routing;
1022                                                    for (int iAudioSrc = 0;
1023                                                                    piRouting && piRouting[iAudioSrc] >= 0;
1024                                                                            iAudioSrc++) {
1025                                                            ts << "SET FX_SEND AUDIO_OUTPUT_CHANNEL "
1026                                                                    << iChannel
1027                                                                    << " " << iFxSend
1028                                                                    << " " << iAudioSrc
1029                                                                    << " " << piRouting[iAudioSrc] << endl;
1030                                                    }
1031    #ifdef CONFIG_FXSEND_LEVEL
1032                                                    ts << "SET FX_SEND LEVEL " << iChannel
1033                                                            << " " << iFxSend
1034                                                            << " " << pFxSendInfo->level << endl;                                                  
1035    #endif
1036                                            }       // Check for errors...
1037                                            else if (::lscp_client_get_errno(m_pClient)) {
1038                                                    appendMessagesClient("lscp_get_fxsend_info");
1039                                                    iErrors++;
1040                                            }
1041                                    }
1042    #endif
1043                  ts << endl;                  ts << endl;
1044              }              }
1045          }          }
# Line 682  bool qsamplerMainForm::saveSessionFile ( Line 1047  bool qsamplerMainForm::saveSessionFile (
1047          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1048      }      }
1049    
1050    #ifdef CONFIG_VOLUME
1051            ts << "# " << tr("Global volume level") << endl;
1052            ts << "SET VOLUME " << ::lscp_get_volume(m_pClient) << endl;
1053            ts << endl;
1054    #endif
1055    
1056      // Ok. we've wrote it.      // Ok. we've wrote it.
1057      file.close();      file.close();
1058    
1059            // We're fornerly done.
1060            QApplication::restoreOverrideCursor();
1061    
1062      // Have we any errors?      // Have we any errors?
1063      if (iErrors > 0)      if (iErrors > 0)
1064          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));          appendMessagesError(tr("Some settings could not be saved\nto \"%1\" session file.\n\nSorry.").arg(sFilename));
# Line 703  bool qsamplerMainForm::saveSessionFile ( Line 1077  bool qsamplerMainForm::saveSessionFile (
1077  }  }
1078    
1079    
1080    // Session change receiver slot.
1081    void qsamplerMainForm::sessionDirty (void)
1082    {
1083        // Just mark the dirty form.
1084        m_iDirtyCount++;
1085        // and update the form status...
1086        stabilizeForm();
1087    }
1088    
1089    
1090  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1091  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
1092    
# Line 756  void qsamplerMainForm::fileReset (void) Line 1140  void qsamplerMainForm::fileReset (void)
1140          return;          return;
1141    
1142      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
1143      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
1144                    QSAMPLER_TITLE ": " + tr("Warning"),
1145          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
1146             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
1147             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
1148             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
1149             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
1150          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
1151          return;          return;
1152    
1153            // Trye closing the current session, first...
1154            if (!closeSession(true))
1155                    return;
1156    
1157      // Just do the reset, after closing down current session...      // Just do the reset, after closing down current session...
1158      if (closeSession(true) && ::lscp_reset_sampler(m_pClient) != LSCP_OK) {          // Do the actual sampler reset...
1159          appendMessagesClient("lscp_reset_sampler");          if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1160          appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));                  appendMessagesClient("lscp_reset_sampler");
1161          return;                  appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
1162      }                  return;
1163            }
1164    
1165      // Log this.      // Log this.
1166      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
1167    
1168            // Make it a new session...
1169            newSession();
1170  }  }
1171    
1172    
# Line 782  void qsamplerMainForm::fileRestart (void Line 1175  void qsamplerMainForm::fileRestart (void
1175  {  {
1176      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1177          return;          return;
1178            
1179      bool bRestart = true;      bool bRestart = true;
1180        
1181      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1182      // (if we're currently up and running)      // (if we're currently up and running)
1183      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1184          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1185                            QSAMPLER_TITLE ": " + tr("Warning"),
1186              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1187                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1188                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1189                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1190                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1191              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1192      }      }
# Line 825  void qsamplerMainForm::editAddChannel (v Line 1219  void qsamplerMainForm::editAddChannel (v
1219          return;          return;
1220    
1221      // Just create the channel instance...      // Just create the channel instance...
1222      qsamplerChannel *pChannel = new qsamplerChannel(this);      qsamplerChannel *pChannel = new qsamplerChannel();
1223      if (pChannel == NULL)      if (pChannel == NULL)
1224          return;          return;
1225    
# Line 835  void qsamplerMainForm::editAddChannel (v Line 1229  void qsamplerMainForm::editAddChannel (v
1229          delete pChannel;          delete pChannel;
1230          return;          return;
1231      }      }
1232        
1233      // 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).
1234      if (!createChannelStrip(pChannel)) {      if (!createChannelStrip(pChannel)) {
1235          delete pChannel;          delete pChannel;
# Line 844  void qsamplerMainForm::editAddChannel (v Line 1238  void qsamplerMainForm::editAddChannel (v
1238    
1239      // Make that an overall update.      // Make that an overall update.
1240      m_iDirtyCount++;      m_iDirtyCount++;
     m_iChangeCount++;  
1241      stabilizeForm();      stabilizeForm();
1242  }  }
1243    
# Line 858  void qsamplerMainForm::editRemoveChannel Line 1251  void qsamplerMainForm::editRemoveChannel
1251      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1252      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1253          return;          return;
1254            
1255      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
1256      if (pChannel == NULL)      if (pChannel == NULL)
1257          return;          return;
1258    
1259      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1260      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1261          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1262                            QSAMPLER_TITLE ": " + tr("Warning"),
1263              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1264                 "%1\n\n"                 "%1\n\n"
1265                 "Are you sure?")                 "Are you sure?")
# Line 880  void qsamplerMainForm::editRemoveChannel Line 1274  void qsamplerMainForm::editRemoveChannel
1274    
1275      // Just delete the channel strip.      // Just delete the channel strip.
1276      delete pChannelStrip;      delete pChannelStrip;
1277        
1278      // Do we auto-arrange?      // Do we auto-arrange?
1279      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1280          channelsArrange();          channelsArrange();
# Line 906  void qsamplerMainForm::editSetupChannel Line 1300  void qsamplerMainForm::editSetupChannel
1300  }  }
1301    
1302    
1303    // Edit current sampler channel.
1304    void qsamplerMainForm::editEditChannel (void)
1305    {
1306        if (m_pClient == NULL)
1307            return;
1308    
1309        qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1310        if (pChannelStrip == NULL)
1311            return;
1312    
1313        // Just invoque the channel strip procedure.
1314        pChannelStrip->channelEdit();
1315    }
1316    
1317    
1318  // Reset current sampler channel.  // Reset current sampler channel.
1319  void qsamplerMainForm::editResetChannel (void)  void qsamplerMainForm::editResetChannel (void)
1320  {  {
# Line 916  void qsamplerMainForm::editResetChannel Line 1325  void qsamplerMainForm::editResetChannel
1325      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1326          return;          return;
1327    
1328      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1329      if (pChannel == NULL)      pChannelStrip->channelReset();
1330          return;  }
1331    
1332    
1333      // Reset the existing sampler channel.  // Reset all sampler channels.
1334      pChannel->resetChannel();  void qsamplerMainForm::editResetAllChannels (void)
1335    {
1336            if (m_pClient == NULL)
1337                    return;
1338    
1339      // And force a deferred update.          // Invoque the channel strip procedure,
1340      m_iChangeCount++;          // for all channels out there...
1341            m_pWorkspace->setUpdatesEnabled(false);
1342            QWidgetList wlist = m_pWorkspace->windowList();
1343            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1344                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1345                    if (pChannelStrip)
1346                            pChannelStrip->channelReset();
1347            }
1348            m_pWorkspace->setUpdatesEnabled(true);
1349  }  }
1350    
1351    
# Line 976  void qsamplerMainForm::viewMessages ( bo Line 1397  void qsamplerMainForm::viewMessages ( bo
1397  }  }
1398    
1399    
1400    // Show/hide the MIDI instrument list-view form.
1401    void qsamplerMainForm::viewInstruments (void)
1402    {
1403            if (m_pOptions == NULL)
1404                    return;
1405    
1406            if (m_pInstrumentListForm) {
1407                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1408                    if (m_pInstrumentListForm->isVisible()) {
1409                            m_pInstrumentListForm->hide();
1410                    } else {
1411                            m_pInstrumentListForm->show();
1412                            m_pInstrumentListForm->raise();
1413                            m_pInstrumentListForm->setActiveWindow();
1414                    }
1415            }
1416    }
1417    
1418    
1419    // Show/hide the device configurator form.
1420    void qsamplerMainForm::viewDevices (void)
1421    {
1422            if (m_pOptions == NULL)
1423                    return;
1424    
1425            if (m_pDeviceForm) {
1426                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1427                    if (m_pDeviceForm->isVisible()) {
1428                            m_pDeviceForm->hide();
1429                    } else {
1430                            m_pDeviceForm->show();
1431                            m_pDeviceForm->raise();
1432                            m_pDeviceForm->setActiveWindow();
1433                    }
1434            }
1435    }
1436    
1437    
1438  // Show options dialog.  // Show options dialog.
1439  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1440  {  {
# Line 1000  void qsamplerMainForm::viewOptions (void Line 1459  void qsamplerMainForm::viewOptions (void
1459          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1460          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1461          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1462            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1463          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1464          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1465          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
# Line 1012  void qsamplerMainForm::viewOptions (void Line 1472  void qsamplerMainForm::viewOptions (void
1472          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1473              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1474              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1475                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1476                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1477                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1478                    QMessageBox::information(this,
1479                                            QSAMPLER_TITLE ": " + tr("Information"),
1480                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1481                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1482                  updateMessagesCapture();                  updateMessagesCapture();
# Line 1087  void qsamplerMainForm::channelsArrange ( Line 1550  void qsamplerMainForm::channelsArrange (
1550          y += iHeight;          y += iHeight;
1551      }      }
1552      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1553        
1554      stabilizeForm();      stabilizeForm();
1555  }  }
1556    
# Line 1141  void qsamplerMainForm::helpAbout (void) Line 1604  void qsamplerMainForm::helpAbout (void)
1604      sText += tr("LSCP (liblscp) instrument_name support disabled.");      sText += tr("LSCP (liblscp) instrument_name support disabled.");
1605      sText += "</font></small><br />";      sText += "</font></small><br />";
1606  #endif  #endif
1607    #ifndef CONFIG_MUTE_SOLO
1608        sText += "<small><font color=\"red\">";
1609        sText += tr("Sampler channel Mute/Solo support disabled.");
1610        sText += "</font></small><br />";
1611    #endif
1612    #ifndef CONFIG_AUDIO_ROUTING
1613        sText += "<small><font color=\"red\">";
1614        sText += tr("LSCP (liblscp) audio_routing support disabled.");
1615        sText += "</font></small><br />";
1616    #endif
1617    #ifndef CONFIG_FXSEND
1618        sText += "<small><font color=\"red\">";
1619        sText += tr("Sampler channel Effect Sends support disabled.");
1620        sText += "</font></small><br />";
1621    #endif
1622    #ifndef CONFIG_VOLUME
1623        sText += "<small><font color=\"red\">";
1624        sText += tr("Global volume support disabled.");
1625        sText += "</font></small><br />";
1626    #endif
1627    #ifndef CONFIG_MIDI_INSTRUMENT
1628        sText += "<small><font color=\"red\">";
1629        sText += tr("MIDI instrument mapping support disabled.");
1630        sText += "</font></small><br />";
1631    #endif
1632    #ifndef CONFIG_EDIT_INSTRUMENT
1633        sText += "<small><font color=\"red\">";
1634        sText += tr("Instrument editing support disabled.");
1635        sText += "</font></small><br />";
1636    #endif
1637      sText += "<br />\n";      sText += "<br />\n";
1638      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1639      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1640      sText += " ";      sText += " ";
1641      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1642    #ifdef CONFIG_LIBGIG
1643        sText += ", ";
1644        sText += gig::libraryName().c_str();
1645        sText += " ";
1646        sText += gig::libraryVersion().c_str();
1647    #endif
1648      sText += "<br />\n";      sText += "<br />\n";
1649      sText += "<br />\n";      sText += "<br />\n";
1650      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 1168  void qsamplerMainForm::helpAbout (void) Line 1667  void qsamplerMainForm::helpAbout (void)
1667  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1668  {  {
1669      // Update the main application caption...      // Update the main application caption...
1670      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1671      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1672          sSessioName += '*';          sSessionName += " *";
1673      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1674    
1675      // Update the main menu state...      // Update the main menu state...
1676      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1186  void qsamplerMainForm::stabilizeForm (vo Line 1685  void qsamplerMainForm::stabilizeForm (vo
1685      editAddChannelAction->setEnabled(bHasClient);      editAddChannelAction->setEnabled(bHasClient);
1686      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1687      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1688    #ifdef CONFIG_EDIT_INSTRUMENT
1689        editEditChannelAction->setEnabled(bHasChannel);
1690    #else
1691        editEditChannelAction->setEnabled(false);
1692    #endif
1693      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1694      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1695      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1696    #ifdef CONFIG_MIDI_INSTRUMENT
1697            viewInstrumentsAction->setOn(m_pInstrumentListForm
1698                    && m_pInstrumentListForm->isVisible());
1699            viewInstrumentsAction->setEnabled(bHasClient);
1700    #else
1701            viewInstrumentsAction->setEnabled(false);
1702    #endif
1703            viewDevicesAction->setOn(m_pDeviceForm
1704                    && m_pDeviceForm->isVisible());
1705        viewDevicesAction->setEnabled(bHasClient);
1706        channelsArrangeAction->setEnabled(bHasChannel);
1707    
1708    #ifdef CONFIG_VOLUME
1709            // Toolbar widgets are also affected...
1710        m_pVolumeSlider->setEnabled(bHasClient);
1711        m_pVolumeSpinBox->setEnabled(bHasClient);
1712    #endif
1713    
1714      // Client/Server status...      // Client/Server status...
1715      if (bHasClient) {      if (bHasClient) {
1716          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1717          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));
1718      } else {      } else {
1719          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1720          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1721      }      }
1722      // Channel status...      // Channel status...
1723      if (bHasChannel)      if (bHasChannel)
1724          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1725      else      else
1726          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1727      // Session status...      // Session status...
1728      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1729          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1730      else      else
1731          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1732    
1733      // Recent files menu.      // Recent files menu.
1734      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1218  void qsamplerMainForm::stabilizeForm (vo Line 1739  void qsamplerMainForm::stabilizeForm (vo
1739  }  }
1740    
1741    
1742    // Global volume change receiver slot.
1743    void qsamplerMainForm::volumeChanged ( int iVolume )
1744    {
1745    #ifdef CONFIG_VOLUME
1746    
1747            if (m_iVolumeChanging > 0)
1748                    return;
1749            
1750            m_iVolumeChanging++;
1751    
1752            // Update the toolbar widgets...
1753            if (m_pVolumeSlider->value()  != iVolume)
1754                    m_pVolumeSlider->setValue(iVolume);
1755            if (m_pVolumeSpinBox->value() != iVolume)
1756                    m_pVolumeSpinBox->setValue(iVolume);
1757    
1758            // Do it as commanded...
1759            float fVolume = 0.01f * float(iVolume);
1760            if (::lscp_set_volume(m_pClient, fVolume) == LSCP_OK)
1761                    appendMessages(QObject::tr("Volume: %1.").arg(fVolume));
1762            else
1763                    appendMessagesClient("lscp_set_volume");
1764    
1765            m_iVolumeChanging--;
1766    
1767            m_iDirtyCount++;
1768            stabilizeForm();
1769    
1770    #endif
1771    }
1772    
1773    
1774  // Channel change receiver slot.  // Channel change receiver slot.
1775  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1776  {  {
1777      // Flag that we're update those channel strips.          // Add this strip to the changed list...
1778      m_iChangeCount++;          if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1779                    m_changedStrips.append(pChannelStrip);
1780                    pChannelStrip->resetErrorCount();
1781            }
1782    
1783      // Just mark the dirty form.      // Just mark the dirty form.
1784      m_iDirtyCount++;      m_iDirtyCount++;
1785      // and update the form status...      // and update the form status...
# Line 1230  void qsamplerMainForm::channelStripChang Line 1787  void qsamplerMainForm::channelStripChang
1787  }  }
1788    
1789    
1790    // Grab and restore current sampler channels session.
1791    void qsamplerMainForm::updateSession (void)
1792    {
1793    #ifdef CONFIG_VOLUME
1794            int iVolume = ::lroundf(100.0f * ::lscp_get_volume(m_pClient));
1795            m_iVolumeChanging++;
1796            m_pVolumeSlider->setValue(iVolume);
1797            m_pVolumeSpinBox->setValue(iVolume);
1798            m_iVolumeChanging--;
1799    #endif
1800    #ifdef CONFIG_MIDI_INSTRUMENT
1801            // FIXME: Make some room for default instrument maps...
1802            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1803            if (iMaps < 0)
1804                    appendMessagesClient("lscp_get_midi_instrument_maps");
1805            else if (iMaps < 1) {
1806                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1807                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1808            }
1809    #endif
1810    
1811            // Retrieve the current channel list.
1812            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1813            if (piChannelIDs == NULL) {
1814                    if (::lscp_client_get_errno(m_pClient)) {
1815                            appendMessagesClient("lscp_list_channels");
1816                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1817                    }
1818            } else {
1819                    // Try to (re)create each channel.
1820                    m_pWorkspace->setUpdatesEnabled(false);
1821                    for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1822                            // Check if theres already a channel strip for this one...
1823                            if (!channelStrip(piChannelIDs[iChannel]))
1824                                    createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1825                    }
1826                    m_pWorkspace->setUpdatesEnabled(true);
1827            }
1828    
1829        // Do we auto-arrange?
1830        if (m_pOptions && m_pOptions->bAutoArrange)
1831            channelsArrange();
1832    
1833            // Remember to refresh devices and instruments...
1834            if (m_pInstrumentListForm)
1835                m_pInstrumentListForm->refreshInstruments();
1836            if (m_pDeviceForm)
1837                m_pDeviceForm->refreshDevices();
1838    }
1839    
1840    
1841  // Update the recent files list and menu.  // Update the recent files list and menu.
1842  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1843  {  {
# Line 1349  void qsamplerMainForm::updateMaxVolume ( Line 1957  void qsamplerMainForm::updateMaxVolume (
1957      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1958          return;          return;
1959    
1960    #ifdef CONFIG_VOLUME
1961            m_iVolumeChanging++;
1962            m_pVolumeSlider->setMaxValue(m_pOptions->iMaxVolume);
1963            m_pVolumeSpinBox->setMaxValue(m_pOptions->iMaxVolume);
1964            m_iVolumeChanging--;
1965    #endif
1966    
1967      // Full channel list update...      // Full channel list update...
1968      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1969      if (wlist.isEmpty())      if (wlist.isEmpty())
# Line 1397  void qsamplerMainForm::appendMessagesErr Line 2012  void qsamplerMainForm::appendMessagesErr
2012    
2013      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
2014    
2015      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));          // Make it look responsive...:)
2016            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
2017    
2018        QMessageBox::critical(this,
2019                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
2020  }  }
2021    
2022    
# Line 1410  void qsamplerMainForm::appendMessagesCli Line 2029  void qsamplerMainForm::appendMessagesCli
2029      appendMessagesColor(s + QString(": %1 (errno=%2)")      appendMessagesColor(s + QString(": %1 (errno=%2)")
2030          .arg(::lscp_client_get_result(m_pClient))          .arg(::lscp_client_get_result(m_pClient))
2031          .arg(::lscp_client_get_errno(m_pClient)), "#996666");          .arg(::lscp_client_get_errno(m_pClient)), "#996666");
2032    
2033            // Make it look responsive...:)
2034            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
2035  }  }
2036    
2037    
# Line 1437  void qsamplerMainForm::updateMessagesLim Line 2059  void qsamplerMainForm::updateMessagesLim
2059          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
2060              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
2061          else          else
2062              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
2063      }      }
2064  }  }
2065    
# Line 1469  qsamplerChannelStrip *qsamplerMainForm:: Line 2091  qsamplerChannelStrip *qsamplerMainForm::
2091          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2092          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2093              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2094          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
2095              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
2096                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
2097                            }
2098          }          }
2099      }      }
2100    
# Line 1479  qsamplerChannelStrip *qsamplerMainForm:: Line 2103  qsamplerChannelStrip *qsamplerMainForm::
2103      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
2104      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
2105          return NULL;          return NULL;
2106            
2107      // Actual channel strip setup...      // Actual channel strip setup...
2108      pChannelStrip->setup(pChannel);      pChannelStrip->setup(pChannel);
2109      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));          QObject::connect(pChannelStrip,
2110                    SIGNAL(channelChanged(qsamplerChannelStrip *)),
2111                    SLOT(channelStripChanged(qsamplerChannelStrip *)));
2112      // Set some initial aesthetic options...      // Set some initial aesthetic options...
2113      if (m_pOptions) {      if (m_pOptions) {
2114          // Background display effect...          // Background display effect...
# Line 1504  qsamplerChannelStrip *qsamplerMainForm:: Line 2130  qsamplerChannelStrip *qsamplerMainForm::
2130          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
2131          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
2132      }      }
2133        
2134            // This is pretty new, so we'll watch for it closely.
2135            channelStripChanged(pChannelStrip);
2136    
2137      // Return our successful reference...      // Return our successful reference...
2138      return pChannelStrip;      return pChannelStrip;
2139  }  }
# Line 1522  qsamplerChannelStrip *qsamplerMainForm:: Line 2151  qsamplerChannelStrip *qsamplerMainForm::
2151  {  {
2152      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
2153      if (wlist.isEmpty())      if (wlist.isEmpty())
2154          return 0;          return NULL;
2155    
2156      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
2157  }  }
2158    
2159    
2160    // Retrieve a channel strip by sampler channel id.
2161    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
2162    {
2163            QWidgetList wlist = m_pWorkspace->windowList();
2164            if (wlist.isEmpty())
2165                    return NULL;
2166    
2167            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
2168                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2169                    if (pChannelStrip) {
2170                            qsamplerChannel *pChannel = pChannelStrip->channel();
2171                            if (pChannel && pChannel->channelID() == iChannelID)
2172                                    return pChannelStrip;
2173                    }
2174            }
2175    
2176            // Not found.
2177            return NULL;
2178    }
2179    
2180    
2181  // Construct the windows menu.  // Construct the windows menu.
2182  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
2183  {  {
# Line 1594  void qsamplerMainForm::timerSlot (void) Line 2244  void qsamplerMainForm::timerSlot (void)
2244              }              }
2245          }          }
2246      }      }
2247        
2248          // Refresh each channel usage, on each period...          if (m_pClient) {
2249      if (m_pClient && (m_iChangeCount > 0 || m_pOptions->bAutoRefresh)) {                  // Update the channel information for each pending strip...
2250          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2251          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2252              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2253              m_iChangeCount = 0;                                  // If successfull, remove from pending list...
2254              QWidgetList wlist = m_pWorkspace->windowList();                                  if (pChannelStrip->updateChannelInfo())
2255              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                          m_changedStrips.remove(pChannelStrip);
2256                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                          }
2257                  if (pChannelStrip && pChannelStrip->isVisible()) {                  }
2258                      // If we can't make it clean, try next time.                  // Refresh each channel usage, on each period...
2259                      if (!pChannelStrip->updateChannelUsage())                  if (m_pOptions->bAutoRefresh) {
2260                          m_iChangeCount++;                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2261                  }                          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2262              }                                  m_iTimerSlot = 0;
2263          }                                  // Update the channel stream usage for each strip...
2264      }                                  QWidgetList wlist = m_pWorkspace->windowList();
2265                                    for (int iChannel = 0;
2266                                                    iChannel < (int) wlist.count(); iChannel++) {
2267                                            qsamplerChannelStrip *pChannelStrip
2268                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2269                                            if (pChannelStrip && pChannelStrip->isVisible())
2270                                                    pChannelStrip->updateChannelUsage();
2271                                    }
2272                            }
2273                    }
2274            }
2275    
2276      // Register the next timer slot.      // Register the next timer slot.
2277      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1633  void qsamplerMainForm::startServer (void Line 2293  void qsamplerMainForm::startServer (void
2293    
2294      // Is the server process instance still here?      // Is the server process instance still here?
2295      if (m_pServer) {      if (m_pServer) {
2296          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2297                            QSAMPLER_TITLE ": " + tr("Warning"),
2298              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2299                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2300              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1654  void qsamplerMainForm::startServer (void Line 2315  void qsamplerMainForm::startServer (void
2315      m_pServer = new QProcess(this);      m_pServer = new QProcess(this);
2316    
2317      // Setup stdout/stderr capture...      // Setup stdout/stderr capture...
2318      //if (m_pOptions->bStdoutCapture) {          //      if (m_pOptions->bStdoutCapture) {
2319          m_pServer->setCommunication(QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);                  m_pServer->setCommunication(
2320          QObject::connect(m_pServer, SIGNAL(readyReadStdout()), this, SLOT(readServerStdout()));                          QProcess::Stdout | QProcess::Stderr | QProcess::DupStderr);
2321          QObject::connect(m_pServer, SIGNAL(readyReadStderr()), this, SLOT(readServerStdout()));                  QObject::connect(m_pServer,
2322      //}                          SIGNAL(readyReadStdout()),
2323      // The unforgiveable signal communication...                          SLOT(readServerStdout()));
2324      QObject::connect(m_pServer, SIGNAL(processExited()), this, SLOT(processServerExit()));                  QObject::connect(m_pServer,
2325                            SIGNAL(readyReadStderr()),
2326                            SLOT(readServerStdout()));
2327            //      }
2328            // The unforgiveable signal communication...
2329            QObject::connect(m_pServer,
2330                    SIGNAL(processExited()),
2331                    SLOT(processServerExit()));
2332    
2333      // Build process arguments...      // Build process arguments...
2334      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));      m_pServer->setArguments(QStringList::split(' ', m_pOptions->sServerCmdLine));
# Line 1792  bool qsamplerMainForm::startClient (void Line 2460  bool qsamplerMainForm::startClient (void
2460      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2461      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)));
2462    
2463            // Subscribe to channel info change notifications...
2464            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2465                    appendMessagesClient("lscp_client_subscribe");
2466    
2467      // We may stop scheduling around.      // We may stop scheduling around.
2468      stopSchedule();      stopSchedule();
2469    
# Line 1801  bool qsamplerMainForm::startClient (void Line 2473  bool qsamplerMainForm::startClient (void
2473      // Log success here.      // Log success here.
2474      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2475    
2476            // Hard-notify instrumnet and device configuration forms,
2477            // if visible, that we're ready...
2478            if (m_pInstrumentListForm)
2479                m_pInstrumentListForm->refreshInstruments();
2480            if (m_pDeviceForm)
2481                m_pDeviceForm->refreshDevices();
2482    
2483      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2484      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2485          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1835  void qsamplerMainForm::stopClient (void) Line 2514  void qsamplerMainForm::stopClient (void)
2514      // channels from the back-end server.      // channels from the back-end server.
2515      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2516      closeSession(false);      closeSession(false);
2517        
2518      // Close us as a client...      // Close us as a client...
2519      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2520        ::lscp_client_destroy(m_pClient);
2521      m_pClient = NULL;      m_pClient = NULL;
2522    
2523            // Hard-notify instrumnet and device configuration forms,
2524            // if visible, that we're running out...
2525            if (m_pInstrumentListForm)
2526                m_pInstrumentListForm->refreshInstruments();
2527            if (m_pDeviceForm)
2528                m_pDeviceForm->refreshDevices();
2529    
2530      // Log final here.      // Log final here.
2531      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2532    

Legend:
Removed from v.391  
changed lines
  Added in v.1372

  ViewVC Help
Powered by ViewVC