/[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 267 by capela, Wed Oct 6 15:42:59 2004 UTC revision 995 by capela, Thu Dec 21 13:58:52 2006 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
# Line 40  Line 41 
41  #include "qsamplerMessages.h"  #include "qsamplerMessages.h"
42    
43  #include "qsamplerChannelStrip.h"  #include "qsamplerChannelStrip.h"
44    #include "qsamplerInstrumentList.h"
45    
46    #include "qsamplerInstrumentListForm.h"
47    #include "qsamplerDeviceForm.h"
48  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
49    
50  #include "config.h"  #ifdef HAVE_SIGNAL_H
51    #include <signal.h>
52    #endif
53    
54    #ifdef CONFIG_LIBGIG
55    #include <gig.h>
56    #endif
57    
58  // Timer constant stuff.  // Timer constant stuff.
59  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
# Line 94  private: Line 104  private:
104  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
105  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
106    
107    // Kind of singleton reference.
108    qsamplerMainForm *qsamplerMainForm::g_pMainForm = NULL;
109    
110    
111  // Kind of constructor.  // Kind of constructor.
112  void qsamplerMainForm::init (void)  void qsamplerMainForm::init (void)
113  {  {
114            // Pseudo-singleton reference setup.
115            g_pMainForm = this;
116    
117      // Initialize some pointer references.      // Initialize some pointer references.
118      m_pOptions = NULL;      m_pOptions = NULL;
119    
120      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
121      m_pMessages = NULL;      m_pMessages = NULL;
122        m_pInstrumentListForm = NULL;
123        m_pDeviceForm = NULL;
124    
125      // We'll start clean.      // We'll start clean.
126      m_iUntitled = 0;      m_iUntitled   = 0;
127      m_iDirtyCount = 0;      m_iDirtyCount = 0;
128    
129      m_pServer = NULL;      m_pServer = NULL;
# Line 115  void qsamplerMainForm::init (void) Line 134  void qsamplerMainForm::init (void)
134    
135      m_iTimerSlot = 0;      m_iTimerSlot = 0;
136    
137    #ifdef HAVE_SIGNAL_H
138            // Set to ignore any fatal "Broken pipe" signals.
139            ::signal(SIGPIPE, SIG_IGN);
140    #endif
141    
142      // Make it an MDI workspace.      // Make it an MDI workspace.
143      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
144      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
# Line 129  void qsamplerMainForm::init (void) Line 153  void qsamplerMainForm::init (void)
153      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
154      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
155      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
156      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
157      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
158      // Server address.      // Server address.
159      pLabel = new QLabel(this);      pLabel = new QLabel(this);
160      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
161      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
162      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
163      // Channel title.      // Channel title.
164      pLabel = new QLabel(this);      pLabel = new QLabel(this);
165      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
166      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
167      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
168      // Session modification status.      // Session modification status.
169      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
170      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
171      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
172      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
173      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
174    
175      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 164  void qsamplerMainForm::destroy (void) Line 188  void qsamplerMainForm::destroy (void)
188  {  {
189      // Do final processing anyway.      // Do final processing anyway.
190      processServerExit();      processServerExit();
191        
192      // Delete recentfiles menu.  #if defined(WIN32)
193      if (m_pRecentFilesMenu)      WSACleanup();
194          delete m_pRecentFilesMenu;  #endif
     // Delete status item labels one by one.  
     if (m_status[QSAMPLER_STATUS_CLIENT])  
         delete m_status[QSAMPLER_STATUS_CLIENT];  
     if (m_status[QSAMPLER_STATUS_SERVER])  
         delete m_status[QSAMPLER_STATUS_SERVER];  
     if (m_status[QSAMPLER_STATUS_CHANNEL])  
         delete m_status[QSAMPLER_STATUS_CHANNEL];  
     if (m_status[QSAMPLER_STATUS_SESSION])  
         delete m_status[QSAMPLER_STATUS_SESSION];  
195    
196      // Finally drop any widgets around...      // Finally drop any widgets around...
197        if (m_pDeviceForm)
198            delete m_pDeviceForm;
199        if (m_pInstrumentListForm)
200            delete m_pInstrumentListForm;
201      if (m_pMessages)      if (m_pMessages)
202          delete m_pMessages;          delete m_pMessages;
203      if (m_pWorkspace)      if (m_pWorkspace)
204          delete m_pWorkspace;          delete m_pWorkspace;
205    
206  #if defined(WIN32)      // Delete status item labels one by one.
207      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
208  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
209        if (m_statusItem[QSAMPLER_STATUS_SERVER])
210            delete m_statusItem[QSAMPLER_STATUS_SERVER];
211        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
212            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
213        if (m_statusItem[QSAMPLER_STATUS_SESSION])
214            delete m_statusItem[QSAMPLER_STATUS_SESSION];
215    
216        // Delete recentfiles menu.
217        if (m_pRecentFilesMenu)
218            delete m_pRecentFilesMenu;
219    
220            // Pseudo-singleton reference shut-down.
221            g_pMainForm = NULL;
222  }  }
223    
224    
# Line 196  void qsamplerMainForm::setup ( qsamplerO Line 228  void qsamplerMainForm::setup ( qsamplerO
228      // We got options?      // We got options?
229      m_pOptions = pOptions;      m_pOptions = pOptions;
230    
231        // What style do we create these forms?
232            Qt::WFlags wflags = Qt::WStyle_Customize
233                    | Qt::WStyle_NormalBorder
234                    | Qt::WStyle_Title
235                    | Qt::WStyle_SysMenu
236                    | Qt::WStyle_MinMax
237                    | Qt::WType_TopLevel;
238        if (m_pOptions->bKeepOnTop)
239            wflags |= Qt::WStyle_Tool;
240      // Some child forms are to be created right now.      // Some child forms are to be created right now.
241      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
242        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
243    #ifdef CONFIG_MIDI_INSTRUMENT
244        m_pInstrumentListForm = new qsamplerInstrumentListForm(this, 0, wflags);
245            QObject::connect(m_pInstrumentListForm->InstrumentList,
246                    SIGNAL(instrumentsChanged()),
247                    SLOT(sessionDirty()));
248    #else
249            viewInstrumentsAction->setEnabled(false);
250    #endif
251      // Set message defaults...      // Set message defaults...
252      updateMessagesFont();      updateMessagesFont();
253      updateMessagesLimit();      updateMessagesLimit();
254      updateMessagesCapture();      updateMessagesCapture();
255      // Set the visibility signal.      // Set the visibility signal.
256      QObject::connect(m_pMessages, SIGNAL(visibilityChanged(bool)), this, SLOT(stabilizeForm()));      QObject::connect(m_pMessages,
257                    SIGNAL(visibilityChanged(bool)),
258                    SLOT(stabilizeForm()));
259    
260      // Initial decorations toggle state.      // Initial decorations toggle state.
261      viewMenubarAction->setOn(m_pOptions->bMenubar);      viewMenubarAction->setOn(m_pOptions->bMenubar);
# Line 226  void qsamplerMainForm::setup ( qsamplerO Line 278  void qsamplerMainForm::setup ( qsamplerO
278          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
279          istr >> *this;          istr >> *this;
280      }      }
281      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
282      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
283        m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
284        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
285    
286      // Final startup stabilization...      // Final startup stabilization...
287      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 265  bool qsamplerMainForm::queryClose (void) Line 319  bool qsamplerMainForm::queryClose (void)
319              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
320              ostr << *this;              ostr << *this;
321              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
322              // And the main windows state.              // And the children, and the main windows state,.
323              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
324                            m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
325                            m_pOptions->saveWidgetGeometry(this);
326                            // Close popup widgets.
327                            if (m_pInstrumentListForm)
328                                    m_pInstrumentListForm->close();
329                            if (m_pDeviceForm)
330                                    m_pDeviceForm->close();
331              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
332              stopServer();              stopServer();
333          }          }
# Line 285  void qsamplerMainForm::closeEvent ( QClo Line 346  void qsamplerMainForm::closeEvent ( QClo
346  }  }
347    
348    
349  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
350  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
351  {  {
352      bool bAccept = false;      bool bDecode = false;
353    
354      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
355          QString sUrl;          QString sText;
356          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
357              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
358                files = QStringList::split('\n', sText);
359                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
360                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
361            }
362      }      }
363    
364      pDragEnterEvent->accept(bAccept);      return bDecode;
365    }
366    
367    
368    // Window drag-n-drop event handlers.
369    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
370    {
371            QStringList files;
372            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
373  }  }
374    
375    
376  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
377  {  {
378      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
379          QString sUrl;  
380          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
381              loadSessionFile(QUrl(sUrl).path());          return;
382      }  
383            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
384                    const QString& sPath = *iter;
385                    if (qsamplerChannel::isInstrumentFile(sPath)) {
386                            // Try to create a new channel from instrument file...
387                            qsamplerChannel *pChannel = new qsamplerChannel();
388                            if (pChannel == NULL)
389                                    return;
390                            // Start setting the instrument filename...
391                            pChannel->setInstrument(sPath, 0);
392                            // Before we show it up, may be we'll
393                            // better ask for some initial values?
394                            if (!pChannel->channelSetup(this)) {
395                                    delete pChannel;
396                                    return;
397                            }
398                            // Finally, give it to a new channel strip...
399                            if (!createChannelStrip(pChannel)) {
400                                    delete pChannel;
401                                    return;
402                            }
403                            // Make that an overall update.
404                            m_iDirtyCount++;
405                            stabilizeForm();
406                    }   // Otherwise, load an usual session file (LSCP script)...
407                    else if (closeSession(true)) {
408                            loadSessionFile(sPath);
409                            break;
410                    }
411                    // Make it look responsive...:)
412                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
413            }
414  }  }
415    
416    
# Line 316  void qsamplerMainForm::customEvent ( QCu Line 420  void qsamplerMainForm::customEvent ( QCu
420      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
421      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
422          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
423          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
424              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
425              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
426                            if (pChannelStrip)
427                                    channelStripChanged(pChannelStrip);
428                    } else {
429                            appendMessagesColor(tr("Notify event: %1 data: %2")
430                                    .arg(::lscp_event_to_text(pEvent->event()))
431                                    .arg(pEvent->data()), "#996699");
432                    }
433      }      }
434  }  }
435    
# Line 327  void qsamplerMainForm::customEvent ( QCu Line 438  void qsamplerMainForm::customEvent ( QCu
438  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
439  {  {
440      stabilizeForm();      stabilizeForm();
441        
442      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
443  }  }
444    
# Line 341  qsamplerOptions *qsamplerMainForm::optio Line 452  qsamplerOptions *qsamplerMainForm::optio
452      return m_pOptions;      return m_pOptions;
453  }  }
454    
455    
456  // The LSCP client descriptor property.  // The LSCP client descriptor property.
457  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
458  {  {
# Line 348  lscp_client_t *qsamplerMainForm::client Line 460  lscp_client_t *qsamplerMainForm::client
460  }  }
461    
462    
463    // The pseudo-singleton instance accessor.
464    qsamplerMainForm *qsamplerMainForm::getInstance (void)
465    {
466            return g_pMainForm;
467    }
468    
469    
470  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
471  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
472    
# Line 371  bool qsamplerMainForm::newSession (void) Line 490  bool qsamplerMainForm::newSession (void)
490      if (!closeSession(true))      if (!closeSession(true))
491          return false;          return false;
492    
493            // Give us what the server has, right now...
494            updateSession();
495    
496      // Ok increment untitled count.      // Ok increment untitled count.
497      m_iUntitled++;      m_iUntitled++;
498    
# Line 392  bool qsamplerMainForm::openSession (void Line 514  bool qsamplerMainForm::openSession (void
514    
515      // Ask for the filename to open...      // Ask for the filename to open...
516      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
517              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
518              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
519              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
520              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
521      );      );
522    
523      // Have we cancelled?      // Have we cancelled?
# Line 426  bool qsamplerMainForm::saveSession ( boo Line 548  bool qsamplerMainForm::saveSession ( boo
548              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
549          // Prompt the guy...          // Prompt the guy...
550          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
551                  sFilename,                              // Start here.                          sFilename,                              // Start here.
552                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
553                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
554                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
555          );          );
556          // Have we cancelled it?          // Have we cancelled it?
557          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 439  bool qsamplerMainForm::saveSession ( boo Line 561  bool qsamplerMainForm::saveSession ( boo
561              sFilename += ".lscp";              sFilename += ".lscp";
562          // Check if already exists...          // Check if already exists...
563          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
564              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
565                                    QSAMPLER_TITLE ": " + tr("Warning"),
566                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
567                     "\"%1\"\n\n"                     "\"%1\"\n\n"
568                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 461  bool qsamplerMainForm::closeSession ( bo Line 584  bool qsamplerMainForm::closeSession ( bo
584    
585      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
586      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
587          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
588                            QSAMPLER_TITLE ": " + tr("Warning"),
589              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
590              "\"%1\"\n\n"              "\"%1\"\n\n"
591              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 487  bool qsamplerMainForm::closeSession ( bo Line 611  bool qsamplerMainForm::closeSession ( bo
611              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
612              if (pChannelStrip) {              if (pChannelStrip) {
613                  qsamplerChannel *pChannel = pChannelStrip->channel();                  qsamplerChannel *pChannel = pChannelStrip->channel();
614                  if (bForce && pChannel && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)                  if (bForce && pChannel)
615                      appendMessagesClient("lscp_remove_channel");                      pChannel->removeChannel();
616                  delete pChannelStrip;                  delete pChannelStrip;
617              }              }
618          }          }
# Line 514  bool qsamplerMainForm::loadSessionFile ( Line 638  bool qsamplerMainForm::loadSessionFile (
638          return false;          return false;
639      }      }
640    
641            // Tell the world we'll take some time...
642            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
643    
644      // Read the file.      // Read the file.
645            int iLine = 0;
646      int iErrors = 0;      int iErrors = 0;
647      QTextStream ts(&file);      QTextStream ts(&file);
648      while (!ts.atEnd()) {      while (!ts.atEnd()) {
649          // Read the line.          // Read the line.
650          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
651                    iLine++;
652          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
653          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
             appendMessagesColor(sCommand, "#996633");  
654              // Remember that, no matter what,              // Remember that, no matter what,
655              // all LSCP commands are CR/LF terminated.              // all LSCP commands are CR/LF terminated.
656              sCommand += "\r\n";              sCommand += "\r\n";
657              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
658                                    appendMessagesColor(QString("%1(%2): %3")
659                                            .arg(QFileInfo(sFilename).fileName()).arg(iLine)
660                                            .arg(sCommand.simplifyWhiteSpace()), "#996633");
661                  appendMessagesClient("lscp_client_query");                  appendMessagesClient("lscp_client_query");
662                  iErrors++;                  iErrors++;
663              }              }
# Line 538  bool qsamplerMainForm::loadSessionFile ( Line 669  bool qsamplerMainForm::loadSessionFile (
669      // Ok. we've read it.      // Ok. we've read it.
670      file.close();      file.close();
671    
672      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
673      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
674    
675      // Now we'll try to create the whole GUI session.          // We're fornerly done.
676      int iChannels = ::lscp_get_channels(m_pClient);          QApplication::restoreOverrideCursor();
677      if (iChannels < 0) {  
678          appendMessagesClient("lscp_get_channels");          // Have we any errors?
679          appendMessagesError(tr("Could not get current number of channels.\n\nSorry."));          if (iErrors > 0)
680      }                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
       
     // Try to (re)create each channel.  
     m_pWorkspace->setUpdatesEnabled(false);  
     for (int iChannelID = 0; iChannelID < iChannels; iChannelID++) {  
         createChannel(iChannelID, false);  
         QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);  
     }  
     m_pWorkspace->setUpdatesEnabled(true);  
681    
682      // Save as default session directory.      // Save as default session directory.
683      if (m_pOptions)      if (m_pOptions)
684          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
685      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
686      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
687      // Stabilize form...      // Stabilize form...
688      m_sFilename = sFilename;      m_sFilename = sFilename;
689      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
690      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
691    
692        // Make that an overall update.
693      stabilizeForm();      stabilizeForm();
694      return true;      return true;
695  }  }
# Line 574  bool qsamplerMainForm::loadSessionFile ( Line 698  bool qsamplerMainForm::loadSessionFile (
698  // Save current session to specific file path.  // Save current session to specific file path.
699  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
700  {  {
701            if (m_pClient == NULL)
702                    return false;
703    
704            // Check whether server is apparently OK...
705            if (::lscp_get_channels(m_pClient) < 0) {
706                    appendMessagesClient("lscp_get_channels");
707                    return false;
708            }
709    
710      // Open and write into real file.      // Open and write into real file.
711      QFile file(sFilename);      QFile file(sFilename);
712      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 581  bool qsamplerMainForm::saveSessionFile ( Line 714  bool qsamplerMainForm::saveSessionFile (
714          return false;          return false;
715      }      }
716    
717            // Tell the world we'll take some time...
718            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
719    
720      // Write the file.      // Write the file.
721      int iErrors = 0;      int  iErrors = 0;
722      QTextStream ts(&file);      QTextStream ts(&file);
723      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
724      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 593  bool qsamplerMainForm::saveSessionFile ( Line 729  bool qsamplerMainForm::saveSessionFile (
729      ts << "# " << tr("File")      ts << "# " << tr("File")
730         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
731      ts << "# " << tr("Date")      ts << "# " << tr("Date")
732         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
733         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
734      ts << "#"  << endl;      ts << "#"  << endl;
735      ts << endl;      ts << endl;
736    
737            // It is assumed that this new kind of device+session file
738            // will be loaded from a complete initialized server...
739            int *piDeviceIDs;
740            int  iDevice;
741            ts << "RESET" << endl;
742    
743            // Audio device mapping.
744            QMap<int, int> audioDeviceMap;
745            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
746            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
747                    ts << endl;
748                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
749                    // Audio device specification...
750                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
751                            << " " << tr("Device") << " " << iDevice << endl;
752                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
753                    qsamplerDeviceParamMap::ConstIterator deviceParam;
754                    for (deviceParam = device.params().begin();
755                                    deviceParam != device.params().end();
756                                            ++deviceParam) {
757                            const qsamplerDeviceParam& param = deviceParam.data();
758                            if (param.value.isEmpty()) ts << "# ";
759                            ts << " " << deviceParam.key() << "='" << param.value << "'";
760                    }
761                    ts << endl;
762                    // Audio channel parameters...
763                    int iPort = 0;
764                    for (qsamplerDevicePort *pPort = device.ports().first();
765                                    pPort;
766                                            pPort = device.ports().next(), ++iPort) {
767                            qsamplerDeviceParamMap::ConstIterator portParam;
768                            for (portParam = pPort->params().begin();
769                                            portParam != pPort->params().end();
770                                                    ++portParam) {
771                                    const qsamplerDeviceParam& param = portParam.data();
772                                    if (param.fix || param.value.isEmpty()) ts << "# ";
773                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
774                                            << " " << iPort << " " << portParam.key()
775                                            << "='" << param.value << "'" << endl;
776                            }
777                    }
778                    // Audio device index/id mapping.
779                    audioDeviceMap[device.deviceID()] = iDevice;
780                    // Try to keep it snappy :)
781                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
782            }
783    
784            // MIDI device mapping.
785            QMap<int, int> midiDeviceMap;
786            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
787            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
788                    ts << endl;
789                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
790                    // MIDI device specification...
791                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
792                            << " " << tr("Device") << " " << iDevice << endl;
793                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
794                    qsamplerDeviceParamMap::ConstIterator deviceParam;
795                    for (deviceParam = device.params().begin();
796                                    deviceParam != device.params().end();
797                                            ++deviceParam) {
798                            const qsamplerDeviceParam& param = deviceParam.data();
799                            if (param.value.isEmpty()) ts << "# ";
800                            ts << " " << deviceParam.key() << "='" << param.value << "'";
801                    }
802                    ts << endl;
803                    // MIDI port parameters...
804                    int iPort = 0;
805                    for (qsamplerDevicePort *pPort = device.ports().first();
806                                    pPort;
807                                            pPort = device.ports().next(), ++iPort) {
808                            qsamplerDeviceParamMap::ConstIterator portParam;
809                            for (portParam = pPort->params().begin();
810                                            portParam != pPort->params().end();
811                                                    ++portParam) {
812                                    const qsamplerDeviceParam& param = portParam.data();
813                                    if (param.fix || param.value.isEmpty()) ts << "# ";
814                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
815                                       << " " << iPort << " " << portParam.key()
816                                       << "='" << param.value << "'" << endl;
817                            }
818                    }
819                    // MIDI device index/id mapping.
820                    midiDeviceMap[device.deviceID()] = iDevice;
821                    // Try to keep it snappy :)
822                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
823            }
824            ts << endl;
825    
826    #ifdef CONFIG_MIDI_INSTRUMENT
827            // MIDI instrument mapping...
828            QMap<int, int> midiInstrumentMap;
829            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
830            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
831                    int iMidiMap = piMaps[iMap];
832                    const char *pszMapName
833                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
834                    ts << "# " << tr("MIDI instrument map") << " " << iMap;
835                    if (pszMapName)
836                            ts << " - " << pszMapName;
837                    ts << endl;
838                    ts << "ADD MIDI_INSTRUMENT_MAP";
839                    if (pszMapName)
840                            ts << " '" << pszMapName << "'";
841                    ts << endl;
842                    // MIDI instrument mapping...
843                    lscp_midi_instrument_t *pInstrs
844                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
845                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
846                            lscp_midi_instrument_info_t *pInstrInfo
847                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
848                            if (pInstrInfo) {
849                                    ts << "MAP MIDI_INSTRUMENT "
850                                            << iMap                        << " "
851                                            << pInstrs[iInstr].bank        << " "
852                                            << pInstrs[iInstr].prog        << " "
853                                            << pInstrInfo->engine_name     << " '"
854                                            << pInstrInfo->instrument_file << "' "
855                                            << pInstrInfo->instrument_nr   << " "
856                                            << pInstrInfo->volume          << " ";
857                                    switch (pInstrInfo->load_mode) {
858                                            case LSCP_LOAD_PERSISTENT:
859                                                    ts << "PERSISTENT";
860                                                    break;
861                                            case LSCP_LOAD_ON_DEMAND_HOLD:
862                                                    ts << "ON_DEMAND_HOLD";
863                                                    break;
864                                            case LSCP_LOAD_ON_DEMAND:
865                                            case LSCP_LOAD_DEFAULT:
866                                            default:
867                                                    ts << "ON_DEMAND";
868                                                    break;
869                                    }
870                                    if (pInstrInfo->name)
871                                            ts << " '" << pInstrInfo->name << "'";
872                                    ts << endl;
873                            }       // Check for errors...
874                            else if (::lscp_client_get_errno(m_pClient)) {
875                                    appendMessagesClient("lscp_get_midi_instrument_info");
876                                    iErrors++;
877                            }
878                            // MIDI device index/id mapping.
879                            midiInstrumentMap[iMidiMap] = iMap;
880                            // Try to keep it snappy :)
881                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
882                    }
883                    // Check for errors...
884                    if (pInstrs)
885                            ts << endl;
886                    else if (::lscp_client_get_errno(m_pClient)) {
887                            appendMessagesClient("lscp_list_midi_instruments");
888                            iErrors++;
889                    }
890            }
891            // Check for errors...
892            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
893                    appendMessagesClient("lscp_list_midi_instrument_maps");
894                    iErrors++;
895            }
896    #endif  // CONFIG_MIDI_INSTRUMENT
897    
898            // Sampler channel mapping.
899      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
900      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
901          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
902          if (pChannelStrip) {          if (pChannelStrip) {
903              qsamplerChannel *pChannel = pChannelStrip->channel();              qsamplerChannel *pChannel = pChannelStrip->channel();
904              if (pChannel) {              if (pChannel) {
905                  int iChannelID = pChannel->channelID();                  ts << "# " << tr("Channel") << " " << iChannel << endl;
                 ts << "# " << pChannelStrip->caption() << endl;  
906                  ts << "ADD CHANNEL" << endl;                  ts << "ADD CHANNEL" << endl;
907                  ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                                  if (audioDeviceMap.isEmpty()) {
908                  ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
909                  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                                  << " " << pChannel->audioDriver() << endl;
910                  ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " ";                                  } else {
911                  if (pChannel->midiChannel() > 0)                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
912                      ts << pChannel->midiChannel();                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
913                   else                                  }
914                                    if (midiDeviceMap.isEmpty()) {
915                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
916                                                    << " " << pChannel->midiDriver() << endl;
917                                    } else {
918                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
919                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
920                                    }
921                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
922                                            << " " << pChannel->midiPort() << endl;
923                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
924                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
925                      ts << "ALL";                      ts << "ALL";
926                    else
927                        ts << pChannel->midiChannel();
928                  ts << endl;                  ts << endl;
929                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                  ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
930                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  if (pChannel->instrumentStatus() < 100) ts << "# ";
931                  ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                  ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
932                                            << pChannel->instrumentNr() << " " << iChannel << endl;
933                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
934                                    for (audioRoute = pChannel->audioRouting().begin();
935                                                    audioRoute != pChannel->audioRouting().end();
936                                                            ++audioRoute) {
937                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
938                                                    << " " << audioRoute.key()
939                                                    << " " << audioRoute.data() << endl;
940                                    }
941                                    ts << "SET CHANNEL VOLUME " << iChannel
942                                            << " " << pChannel->volume() << endl;
943                                    if (pChannel->channelMute())
944                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
945                                    if (pChannel->channelSolo())
946                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
947    #ifdef CONFIG_MIDI_INSTRUMENT
948                                    if (pChannel->midiMap() >= 0) {
949                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
950                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
951                                    }
952    #endif
953                  ts << endl;                  ts << endl;
954              }              }
955          }          }
# Line 628  bool qsamplerMainForm::saveSessionFile ( Line 960  bool qsamplerMainForm::saveSessionFile (
960      // Ok. we've wrote it.      // Ok. we've wrote it.
961      file.close();      file.close();
962    
963            // We're fornerly done.
964            QApplication::restoreOverrideCursor();
965    
966      // Have we any errors?      // Have we any errors?
967      if (iErrors > 0)      if (iErrors > 0)
968          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 646  bool qsamplerMainForm::saveSessionFile ( Line 981  bool qsamplerMainForm::saveSessionFile (
981  }  }
982    
983    
984    // Session change receiver slot.
985    void qsamplerMainForm::sessionDirty (void)
986    {
987        // Just mark the dirty form.
988        m_iDirtyCount++;
989        // and update the form status...
990        stabilizeForm();
991    }
992    
993    
994  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
995  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
996    
# Line 699  void qsamplerMainForm::fileReset (void) Line 1044  void qsamplerMainForm::fileReset (void)
1044          return;          return;
1045    
1046      // Ask user whether he/she want's an internal sampler reset...      // Ask user whether he/she want's an internal sampler reset...
1047      if (QMessageBox::warning(this, tr("Warning"),      if (QMessageBox::warning(this,
1048                    QSAMPLER_TITLE ": " + tr("Warning"),
1049          tr("Resetting the sampler instance will close\n"          tr("Resetting the sampler instance will close\n"
1050             "all device and channel configurations.\n\n"             "all device and channel configurations.\n\n"
1051             "Please note that this operation may cause\n"             "Please note that this operation may cause\n"
1052             "temporary MIDI and Audio disruption\n\n"             "temporary MIDI and Audio disruption.\n\n"
1053             "Do you want to reset the sampler engine now?"),             "Do you want to reset the sampler engine now?"),
1054          tr("Reset"), tr("Cancel")) > 0)          tr("Reset"), tr("Cancel")) > 0)
1055          return;          return;
1056    
1057      // Just do the reset, after closing down current session...      // Just do the reset, after closing down current session...
1058      if (closeSession(true) && ::lscp_reset_sampler(m_pClient) != LSCP_OK) {      if (closeSession(true)) {
1059          appendMessagesClient("lscp_reset_sampler");  #ifdef CONFIG_MIDI_INSTRUMENT
1060          appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));                  // Reset all MIDI instrument mapping, if any.
1061          return;                  int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
1062                    for (int iMap = 0; piMaps && piMaps[iMap] >= 0; ++iMap) {
1063                            int iMidiMap = piMaps[iMap];
1064                            if (::lscp_clear_midi_instruments(m_pClient, iMidiMap) != LSCP_OK)
1065                                    appendMessagesClient("lscp_clear_midi_instruments");
1066                            if (::lscp_remove_midi_instrument_map(m_pClient, iMidiMap) != LSCP_OK)
1067                                    appendMessagesClient("lscp_remove_midi_instrument_map");
1068                    }
1069                    // Check for errors...
1070                    if (piMaps == NULL && ::lscp_client_get_errno(m_pClient))
1071                            appendMessagesClient("lscp_list_midi_instrument_maps");
1072    #endif  // CONFIG_MIDI_INSTRUMENT
1073                    // actually do the sampler reset...
1074                    if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1075                            appendMessagesClient("lscp_reset_sampler");
1076                            appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
1077                            return;
1078                    }
1079      }      }
1080    
1081      // Log this.      // Log this.
1082      appendMessages(tr("Sampler reset."));      appendMessages(tr("Sampler reset."));
1083    
1084            // Make it a new session...
1085            newSession();
1086  }  }
1087    
1088    
# Line 725  void qsamplerMainForm::fileRestart (void Line 1091  void qsamplerMainForm::fileRestart (void
1091  {  {
1092      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1093          return;          return;
1094            
1095      bool bRestart = true;      bool bRestart = true;
1096        
1097      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1098      // (if we're currently up and running)      // (if we're currently up and running)
1099      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1100          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1101                            QSAMPLER_TITLE ": " + tr("Warning"),
1102              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1103                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1104                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1105                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1106                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1107              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1108      }      }
# Line 767  void qsamplerMainForm::editAddChannel (v Line 1134  void qsamplerMainForm::editAddChannel (v
1134      if (m_pClient == NULL)      if (m_pClient == NULL)
1135          return;          return;
1136    
1137      // Create the new sampler channel.      // Just create the channel instance...
1138      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel();
1139      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
1140          return;          return;
     }  
1141    
1142      // Log this happening.      // Before we show it up, may be we'll
1143      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
1144        if (!pChannel->channelSetup(this)) {
1145            delete pChannel;
1146            return;
1147        }
1148    
1149      // Just create the channel strip with given id.      // And give it to the strip (will own the channel instance, if successful).
1150      createChannel(iChannelID, true);      if (!createChannelStrip(pChannel)) {
1151            delete pChannel;
1152            return;
1153        }
1154    
1155      // We'll be dirty, for sure...      // Make that an overall update.
1156      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
1157      stabilizeForm();      stabilizeForm();
1158  }  }
1159    
# Line 797  void qsamplerMainForm::editRemoveChannel Line 1167  void qsamplerMainForm::editRemoveChannel
1167      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1168      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1169          return;          return;
1170            
1171      qsamplerChannel *pChannel = pChannelStrip->channel();      qsamplerChannel *pChannel = pChannelStrip->channel();
1172      if (pChannel == NULL)      if (pChannel == NULL)
1173          return;          return;
1174    
1175      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1176      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1177          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1178                            QSAMPLER_TITLE ": " + tr("Warning"),
1179              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1180                 "%1\n\n"                 "%1\n\n"
1181                 "Are you sure?")                 "Are you sure?")
# Line 814  void qsamplerMainForm::editRemoveChannel Line 1185  void qsamplerMainForm::editRemoveChannel
1185      }      }
1186    
1187      // Remove the existing sampler channel.      // Remove the existing sampler channel.
1188      if (::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      if (!pChannel->removeChannel())
         appendMessagesClient("lscp_remove_channel");  
         appendMessagesError(tr("Could not remove channel.\n\nSorry."));  
1189          return;          return;
     }  
1190    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
1191      // Just delete the channel strip.      // Just delete the channel strip.
1192      delete pChannelStrip;      delete pChannelStrip;
1193        
1194      // Do we auto-arrange?      // Do we auto-arrange?
1195      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1196          channelsArrange();          channelsArrange();
# Line 847  void qsamplerMainForm::editSetupChannel Line 1212  void qsamplerMainForm::editSetupChannel
1212          return;          return;
1213    
1214      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
1215      pChannelStrip->showChannelSetup(false);      pChannelStrip->channelSetup();
1216  }  }
1217    
1218    
# Line 861  void qsamplerMainForm::editResetChannel Line 1226  void qsamplerMainForm::editResetChannel
1226      if (pChannelStrip == NULL)      if (pChannelStrip == NULL)
1227          return;          return;
1228    
1229      qsamplerChannel *pChannel = pChannelStrip->channel();      // Just invoque the channel strip procedure.
1230      if (pChannel == NULL)      pChannelStrip->channelReset();
1231          return;  }
   
     // Remove the existing sampler channel.  
     if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {  
         appendMessagesClient("lscp_reset_channel");  
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
1232    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
1233    
1234      // Refresh channel strip info.  // Reset all sampler channels.
1235      pChannelStrip->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
1236    {
1237            if (m_pClient == NULL)
1238                    return;
1239    
1240            // Invoque the channel strip procedure,
1241            // for all channels out there...
1242            m_pWorkspace->setUpdatesEnabled(false);
1243            QWidgetList wlist = m_pWorkspace->windowList();
1244            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1245                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1246                    if (pChannelStrip)
1247                            pChannelStrip->channelReset();
1248            }
1249            m_pWorkspace->setUpdatesEnabled(true);
1250  }  }
1251    
1252    
# Line 928  void qsamplerMainForm::viewMessages ( bo Line 1298  void qsamplerMainForm::viewMessages ( bo
1298  }  }
1299    
1300    
1301    // Show/hide the MIDI instrument list-view form.
1302    void qsamplerMainForm::viewInstruments (void)
1303    {
1304            if (m_pOptions == NULL)
1305                    return;
1306    
1307            if (m_pInstrumentListForm) {
1308                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1309                    if (m_pInstrumentListForm->isVisible()) {
1310                            m_pInstrumentListForm->hide();
1311                    } else {
1312                            m_pInstrumentListForm->show();
1313                            m_pInstrumentListForm->raise();
1314                            m_pInstrumentListForm->setActiveWindow();
1315                    }
1316            }
1317    }
1318    
1319    
1320    // Show/hide the device configurator form.
1321    void qsamplerMainForm::viewDevices (void)
1322    {
1323            if (m_pOptions == NULL)
1324                    return;
1325    
1326            if (m_pDeviceForm) {
1327                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1328                    if (m_pDeviceForm->isVisible()) {
1329                            m_pDeviceForm->hide();
1330                    } else {
1331                            m_pDeviceForm->show();
1332                            m_pDeviceForm->raise();
1333                            m_pDeviceForm->setActiveWindow();
1334                    }
1335            }
1336    }
1337    
1338    
1339  // Show options dialog.  // Show options dialog.
1340  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1341  {  {
# Line 952  void qsamplerMainForm::viewOptions (void Line 1360  void qsamplerMainForm::viewOptions (void
1360          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;          bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1361          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1362          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1363            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1364          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1365          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1366          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1367          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1368            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1369          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1370          // Load the current setup settings.          // Load the current setup settings.
1371          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 963  void qsamplerMainForm::viewOptions (void Line 1373  void qsamplerMainForm::viewOptions (void
1373          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1374              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1375              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1376                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1377                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1378                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1379                    QMessageBox::information(this,
1380                                            QSAMPLER_TITLE ": " + tr("Information"),
1381                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1382                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1383                  updateMessagesCapture();                  updateMessagesCapture();
# Line 974  void qsamplerMainForm::viewOptions (void Line 1387  void qsamplerMainForm::viewOptions (void
1387                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1388                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1389                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1390                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1391                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1392                    updateInstrumentNames();
1393              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||              if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1394                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))                  (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1395                  updateDisplayEffect();                  updateDisplayEffect();
# Line 1035  void qsamplerMainForm::channelsArrange ( Line 1451  void qsamplerMainForm::channelsArrange (
1451          y += iHeight;          y += iHeight;
1452      }      }
1453      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1454        
1455      stabilizeForm();      stabilizeForm();
1456  }  }
1457    
# Line 1084  void qsamplerMainForm::helpAbout (void) Line 1500  void qsamplerMainForm::helpAbout (void)
1500      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1501      sText += "</font></small><br />";      sText += "</font></small><br />";
1502  #endif  #endif
1503    #ifndef CONFIG_INSTRUMENT_NAME
1504        sText += "<small><font color=\"red\">";
1505        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1506        sText += "</font></small><br />";
1507    #endif
1508    #ifndef CONFIG_MUTE_SOLO
1509        sText += "<small><font color=\"red\">";
1510        sText += tr("Sampler channel Mute/Solo support disabled.");
1511        sText += "</font></small><br />";
1512    #endif
1513    #ifndef CONFIG_MIDI_INSTRUMENT
1514        sText += "<small><font color=\"red\">";
1515        sText += tr("MIDI instrument mapping support disabled.");
1516        sText += "</font></small><br />";
1517    #endif
1518      sText += "<br />\n";      sText += "<br />\n";
1519      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1520      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1521      sText += " ";      sText += " ";
1522      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1523    #ifdef CONFIG_LIBGIG
1524        sText += ", ";
1525        sText += gig::libraryName().c_str();
1526        sText += " ";
1527        sText += gig::libraryVersion().c_str();
1528    #endif
1529      sText += "<br />\n";      sText += "<br />\n";
1530      sText += "<br />\n";      sText += "<br />\n";
1531      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 1111  void qsamplerMainForm::helpAbout (void) Line 1548  void qsamplerMainForm::helpAbout (void)
1548  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1549  {  {
1550      // Update the main application caption...      // Update the main application caption...
1551      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1552      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1553          sSessioName += '*';          sSessionName += " *";
1554      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1555    
1556      // Update the main menu state...      // Update the main menu state...
1557      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
# Line 1130  void qsamplerMainForm::stabilizeForm (vo Line 1567  void qsamplerMainForm::stabilizeForm (vo
1567      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1568      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1569      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1570      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1571      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1572    #ifdef CONFIG_MIDI_INSTRUMENT
1573            viewInstrumentsAction->setOn(m_pInstrumentListForm
1574                    && m_pInstrumentListForm->isVisible());
1575            viewInstrumentsAction->setEnabled(bHasClient);
1576    #endif
1577            viewDevicesAction->setOn(m_pDeviceForm
1578                    && m_pDeviceForm->isVisible());
1579        viewDevicesAction->setEnabled(bHasClient);
1580        channelsArrangeAction->setEnabled(bHasChannel);
1581    
1582      // Client/Server status...      // Client/Server status...
1583      if (bHasClient) {      if (bHasClient) {
1584          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1585          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));
1586      } else {      } else {
1587          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1588          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1589      }      }
1590      // Channel status...      // Channel status...
1591      if (bHasChannel)      if (bHasChannel)
1592          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1593      else      else
1594          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1595      // Session status...      // Session status...
1596      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1597          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1598      else      else
1599          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1600    
1601      // Recent files menu.      // Recent files menu.
1602      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1162  void qsamplerMainForm::stabilizeForm (vo Line 1608  void qsamplerMainForm::stabilizeForm (vo
1608    
1609    
1610  // Channel change receiver slot.  // Channel change receiver slot.
1611  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1612  {  {
1613            // Add this strip to the changed list...
1614            if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1615                    m_changedStrips.append(pChannelStrip);
1616                    pChannelStrip->resetErrorCount();
1617            }
1618    
1619      // Just mark the dirty form.      // Just mark the dirty form.
1620      m_iDirtyCount++;      m_iDirtyCount++;
1621      // and update the form status...      // and update the form status...
# Line 1171  void qsamplerMainForm::channelStripChang Line 1623  void qsamplerMainForm::channelStripChang
1623  }  }
1624    
1625    
1626    // Grab and restore current sampler channels session.
1627    void qsamplerMainForm::updateSession (void)
1628    {
1629    #ifdef CONFIG_MIDI_INSTRUMENT
1630            // FIXME Make some room for default instrument maps...
1631            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1632            if (iMaps < 0)
1633                    appendMessagesClient("lscp_get_midi_instrument_maps");
1634            else if (iMaps < 1) {
1635                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1636                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1637            }
1638    #endif
1639    
1640            // Retrieve the current channel list.
1641            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1642            if (piChannelIDs == NULL) {
1643                    if (::lscp_client_get_errno(m_pClient)) {
1644                            appendMessagesClient("lscp_list_channels");
1645                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1646                    }
1647            } else {
1648                    // Try to (re)create each channel.
1649                    m_pWorkspace->setUpdatesEnabled(false);
1650                    for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1651                            // Check if theres already a channel strip for this one...
1652                            if (!channelStrip(piChannelIDs[iChannel]))
1653                                    createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1654                    }
1655                    m_pWorkspace->setUpdatesEnabled(true);
1656            }
1657    
1658        // Do we auto-arrange?
1659        if (m_pOptions && m_pOptions->bAutoArrange)
1660            channelsArrange();
1661    
1662            // Remember to refresh devices and instruments...
1663            if (m_pInstrumentListForm)
1664                m_pInstrumentListForm->refreshInstruments();
1665            if (m_pDeviceForm)
1666                m_pDeviceForm->refreshDevices();
1667    }
1668    
1669    
1670  // Update the recent files list and menu.  // Update the recent files list and menu.
1671  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1672  {  {
# Line 1215  void qsamplerMainForm::updateRecentFiles Line 1711  void qsamplerMainForm::updateRecentFiles
1711  }  }
1712    
1713    
1714    // Force update of the channels instrument names mode.
1715    void qsamplerMainForm::updateInstrumentNames (void)
1716    {
1717        // Full channel list update...
1718        QWidgetList wlist = m_pWorkspace->windowList();
1719        if (wlist.isEmpty())
1720            return;
1721    
1722        m_pWorkspace->setUpdatesEnabled(false);
1723        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1724            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1725            if (pChannelStrip)
1726                pChannelStrip->updateInstrumentName(true);
1727        }
1728        m_pWorkspace->setUpdatesEnabled(true);
1729    }
1730    
1731    
1732  // Force update of the channels display font.  // Force update of the channels display font.
1733  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1734  {  {
# Line 1320  void qsamplerMainForm::appendMessagesErr Line 1834  void qsamplerMainForm::appendMessagesErr
1834    
1835      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1836    
1837      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));          // Make it look responsive...:)
1838            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1839    
1840        QMessageBox::critical(this,
1841                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1842  }  }
1843    
1844    
# Line 1333  void qsamplerMainForm::appendMessagesCli Line 1851  void qsamplerMainForm::appendMessagesCli
1851      appendMessagesColor(s + QString(": %1 (errno=%2)")      appendMessagesColor(s + QString(": %1 (errno=%2)")
1852          .arg(::lscp_client_get_result(m_pClient))          .arg(::lscp_client_get_result(m_pClient))
1853          .arg(::lscp_client_get_errno(m_pClient)), "#996666");          .arg(::lscp_client_get_errno(m_pClient)), "#996666");
1854    
1855            // Make it look responsive...:)
1856            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1857  }  }
1858    
1859    
# Line 1360  void qsamplerMainForm::updateMessagesLim Line 1881  void qsamplerMainForm::updateMessagesLim
1881          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1882              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1883          else          else
1884              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1885      }      }
1886  }  }
1887    
# Line 1380  void qsamplerMainForm::updateMessagesCap Line 1901  void qsamplerMainForm::updateMessagesCap
1901  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
1902    
1903  // The channel strip creation executive.  // The channel strip creation executive.
1904  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
1905  {  {
1906      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
1907          return;          return NULL;
1908    
1909      // Prepare for auto-arrange?      // Prepare for auto-arrange?
1910      qsamplerChannelStrip *pChannelStrip = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
# Line 1392  void qsamplerMainForm::createChannel ( i Line 1913  void qsamplerMainForm::createChannel ( i
1913          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1914          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1915              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1916          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1917              y += pChannelStrip->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1918                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1919                            }
1920          }          }
1921      }      }
1922    
1923      // Add a new channel itema...      // Add a new channel itema...
1924      WFlags wflags = Qt::WStyle_Customize | Qt::WStyle_Tool | Qt::WStyle_Title | Qt::WStyle_NoBorder;      WFlags wflags = Qt::WStyle_Customize | Qt::WStyle_Tool | Qt::WStyle_Title | Qt::WStyle_NoBorder;
1925      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1926        if (pChannelStrip == NULL)
1927            return NULL;
1928    
1929        // Actual channel strip setup...
1930        pChannelStrip->setup(pChannel);
1931        QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
1932      // Set some initial aesthetic options...      // Set some initial aesthetic options...
1933      if (m_pOptions) {      if (m_pOptions) {
1934          // Background display effect...          // Background display effect...
# Line 1411  void qsamplerMainForm::createChannel ( i Line 1940  void qsamplerMainForm::createChannel ( i
1940          // Maximum allowed volume setting.          // Maximum allowed volume setting.
1941          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);          pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1942      }      }
1943      // Actual channel setup.  
     pChannelStrip->setup(this, iChannelID);  
     QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));  
     // Before we show it up, may be we'll  
     // better ask for some initial values?  
     if (bPrompt)  
         pChannelStrip->showChannelSetup(true);  
1944      // Now we show up us to the world.      // Now we show up us to the world.
1945      pChannelStrip->show();      pChannelStrip->show();
1946      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
# Line 1427  void qsamplerMainForm::createChannel ( i Line 1950  void qsamplerMainForm::createChannel ( i
1950          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1951          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1952      }      }
1953    
1954            // This is pretty new, so we'll watch for it closely.
1955            channelStripChanged(pChannelStrip);
1956    
1957        // Return our successful reference...
1958        return pChannelStrip;
1959  }  }
1960    
1961    
# Line 1442  qsamplerChannelStrip *qsamplerMainForm:: Line 1971  qsamplerChannelStrip *qsamplerMainForm::
1971  {  {
1972      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1973      if (wlist.isEmpty())      if (wlist.isEmpty())
1974          return 0;          return NULL;
1975    
1976      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1977  }  }
1978    
1979    
1980    // Retrieve a channel strip by sampler channel id.
1981    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1982    {
1983            QWidgetList wlist = m_pWorkspace->windowList();
1984            if (wlist.isEmpty())
1985                    return NULL;
1986    
1987            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1988                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1989                    if (pChannelStrip) {
1990                            qsamplerChannel *pChannel = pChannelStrip->channel();
1991                            if (pChannel && pChannel->channelID() == iChannelID)
1992                                    return pChannelStrip;
1993                    }
1994            }
1995    
1996            // Not found.
1997            return NULL;
1998    }
1999    
2000    
2001  // Construct the windows menu.  // Construct the windows menu.
2002  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
2003  {  {
# Line 1514  void qsamplerMainForm::timerSlot (void) Line 2064  void qsamplerMainForm::timerSlot (void)
2064              }              }
2065          }          }
2066      }      }
2067        
2068          // Refresh each channel usage, on each period...          if (m_pClient) {
2069      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {                  // Update the channel information for each pending strip...
2070          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2071          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2072              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2073              QWidgetList wlist = m_pWorkspace->windowList();                                  // If successfull, remove from pending list...
2074              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                  if (pChannelStrip->updateChannelInfo())
2075                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);                                          m_changedStrips.remove(pChannelStrip);
2076                  if (pChannelStrip && pChannelStrip->isVisible())                          }
2077                      pChannelStrip->updateChannelUsage();                  }
2078              }                  // Refresh each channel usage, on each period...
2079          }                  if (m_pOptions->bAutoRefresh) {
2080      }                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2081                            if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2082                                    m_iTimerSlot = 0;
2083                                    // Update the channel stream usage for each strip...
2084                                    QWidgetList wlist = m_pWorkspace->windowList();
2085                                    for (int iChannel = 0;
2086                                                    iChannel < (int) wlist.count(); iChannel++) {
2087                                            qsamplerChannelStrip *pChannelStrip
2088                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2089                                            if (pChannelStrip && pChannelStrip->isVisible())
2090                                                    pChannelStrip->updateChannelUsage();
2091                                    }
2092                            }
2093                    }
2094            }
2095    
2096      // Register the next timer slot.      // Register the next timer slot.
2097      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1549  void qsamplerMainForm::startServer (void Line 2113  void qsamplerMainForm::startServer (void
2113    
2114      // Is the server process instance still here?      // Is the server process instance still here?
2115      if (m_pServer) {      if (m_pServer) {
2116          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2117                            QSAMPLER_TITLE ": " + tr("Warning"),
2118              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2119                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2120              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1708  bool qsamplerMainForm::startClient (void Line 2273  bool qsamplerMainForm::startClient (void
2273      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2274      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)));
2275    
2276            // Subscribe to channel info change notifications...
2277            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2278                    appendMessagesClient("lscp_client_subscribe");
2279    
2280      // We may stop scheduling around.      // We may stop scheduling around.
2281      stopSchedule();      stopSchedule();
2282    
# Line 1717  bool qsamplerMainForm::startClient (void Line 2286  bool qsamplerMainForm::startClient (void
2286      // Log success here.      // Log success here.
2287      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2288    
2289            // Hard-notify instrumnet and device configuration forms,
2290            // if visible, that we're ready...
2291            if (m_pInstrumentListForm)
2292                m_pInstrumentListForm->refreshInstruments();
2293            if (m_pDeviceForm)
2294                m_pDeviceForm->refreshDevices();
2295    
2296      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2297      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2298          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1751  void qsamplerMainForm::stopClient (void) Line 2327  void qsamplerMainForm::stopClient (void)
2327      // channels from the back-end server.      // channels from the back-end server.
2328      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2329      closeSession(false);      closeSession(false);
2330        
2331      // Close us as a client...      // Close us as a client...
2332      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2333        ::lscp_client_destroy(m_pClient);
2334      m_pClient = NULL;      m_pClient = NULL;
2335    
2336            // Hard-notify instrumnet and device configuration forms,
2337            // if visible, that we're running out...
2338            if (m_pInstrumentListForm)
2339                m_pInstrumentListForm->refreshInstruments();
2340            if (m_pDeviceForm)
2341                m_pDeviceForm->refreshDevices();
2342    
2343      // Log final here.      // Log final here.
2344      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2345    

Legend:
Removed from v.267  
changed lines
  Added in v.995

  ViewVC Help
Powered by ViewVC