/[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 176 by capela, Tue Jul 6 10:54:45 2004 UTC revision 1013 by capela, Mon Jan 8 16:52:48 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, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
# Line 36  Line 37 
37    
38  #include "qsamplerAbout.h"  #include "qsamplerAbout.h"
39  #include "qsamplerOptions.h"  #include "qsamplerOptions.h"
40    #include "qsamplerChannel.h"
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 93  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 114  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 128  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 163  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 195  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 225  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 264  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 284  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 315  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 326  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 340  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 347  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 370  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 391  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 425  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 438  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 460  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 483  bool qsamplerMainForm::closeSession ( bo Line 608  bool qsamplerMainForm::closeSession ( bo
608          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
609          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
610          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
611              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
612              if (bForce && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)              if (pChannelStrip) {
613                  appendMessagesClient("lscp_remove_channel");                  qsamplerChannel *pChannel = pChannelStrip->channel();
614              delete pChannel;                  if (bForce && pChannel)
615                        pChannel->removeChannel();
616                    delete pChannelStrip;
617                }
618          }          }
619          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
620          // We're now clean, for sure.          // We're now clean, for sure.
# Line 510  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] != '#') {
654              appendMessagesColor(sCommand, "#996633");                          // Remember that, no matter what,
655              // Remember that, no matter what,                          // all LSCP commands are CR/LF terminated.
656              // all LSCP commands are CR/LF terminated.                          sCommand += "\r\n";
657              sCommand += "\r\n";                          if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
658              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {                                  appendMessagesColor(QString("%1(%2): %3")
659                  appendMessagesClient("lscp_client_query");                                          .arg(QFileInfo(sFilename).fileName()).arg(iLine)
660                  iErrors++;                                          .arg(sCommand.simplifyWhiteSpace()), "#996633");
661              }                                  appendMessagesClient("lscp_client_query");
662                                    iErrors++;
663                            }
664          }          }
665          // Try to make it snappy :)          // Try to make it snappy :)
666          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
# Line 534  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 570  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 577  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 589  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                            // Try to keep it snappy :)
879                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
880                    }
881                    ts << endl;
882                    // Check for errors...
883                    if (pInstrs == NULL && ::lscp_client_get_errno(m_pClient)) {
884                            appendMessagesClient("lscp_list_midi_instruments");
885                            iErrors++;
886                    }
887                    // MIDI strument index/id mapping.
888                    midiInstrumentMap[iMidiMap] = iMap;
889            }
890            // Check for errors...
891            if (piMaps == NULL && ::lscp_client_get_errno(m_pClient)) {
892                    appendMessagesClient("lscp_list_midi_instrument_maps");
893                    iErrors++;
894            }
895    #endif  // CONFIG_MIDI_INSTRUMENT
896    
897            // Sampler channel mapping.
898      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
899      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
900          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
901          int iChannelID = pChannel->channelID();          if (pChannelStrip) {
902          ts << "# " << pChannel->caption() << endl;              qsamplerChannel *pChannel = pChannelStrip->channel();
903          ts << "ADD CHANNEL" << endl;              if (pChannel) {
904          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                  ts << "# " << tr("Channel") << " " << iChannel << endl;
905          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                  ts << "ADD CHANNEL" << endl;
906          ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                  if (audioDeviceMap.isEmpty()) {
907          ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " " << pChannel->midiChannel() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
908          ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                                                  << " " << pChannel->audioDriver() << endl;
909          ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  } else {
910          ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
911          ts << endl;                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
912                                    }
913                                    if (midiDeviceMap.isEmpty()) {
914                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
915                                                    << " " << pChannel->midiDriver() << endl;
916                                    } else {
917                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
918                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
919                                    }
920                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
921                                            << " " << pChannel->midiPort() << endl;
922                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
923                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
924                        ts << "ALL";
925                    else
926                        ts << pChannel->midiChannel();
927                    ts << endl;
928                    ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
929                                    if (pChannel->instrumentStatus() < 100) ts << "# ";
930                                    ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
931                                            << pChannel->instrumentNr() << " " << iChannel << endl;
932                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
933                                    for (audioRoute = pChannel->audioRouting().begin();
934                                                    audioRoute != pChannel->audioRouting().end();
935                                                            ++audioRoute) {
936                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
937                                                    << " " << audioRoute.key()
938                                                    << " " << audioRoute.data() << endl;
939                                    }
940                                    ts << "SET CHANNEL VOLUME " << iChannel
941                                            << " " << pChannel->volume() << endl;
942                                    if (pChannel->channelMute())
943                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
944                                    if (pChannel->channelSolo())
945                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
946    #ifdef CONFIG_MIDI_INSTRUMENT
947                                    if (pChannel->midiMap() >= 0) {
948                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
949                                                    << " " << midiInstrumentMap[pChannel->midiMap()] << endl;
950                                    }
951    #endif
952                    ts << endl;
953                }
954            }
955          // Try to keep it snappy :)          // Try to keep it snappy :)
956          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
957      }      }
# Line 614  bool qsamplerMainForm::saveSessionFile ( Line 959  bool qsamplerMainForm::saveSessionFile (
959      // Ok. we've wrote it.      // Ok. we've wrote it.
960      file.close();      file.close();
961    
962            // We're fornerly done.
963            QApplication::restoreOverrideCursor();
964    
965      // Have we any errors?      // Have we any errors?
966      if (iErrors > 0)      if (iErrors > 0)
967          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 632  bool qsamplerMainForm::saveSessionFile ( Line 980  bool qsamplerMainForm::saveSessionFile (
980  }  }
981    
982    
983    // Session change receiver slot.
984    void qsamplerMainForm::sessionDirty (void)
985    {
986        // Just mark the dirty form.
987        m_iDirtyCount++;
988        // and update the form status...
989        stabilizeForm();
990    }
991    
992    
993  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
994  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
995    
# Line 678  void qsamplerMainForm::fileSaveAs (void) Line 1036  void qsamplerMainForm::fileSaveAs (void)
1036  }  }
1037    
1038    
1039    // Reset the sampler instance.
1040    void qsamplerMainForm::fileReset (void)
1041    {
1042        if (m_pClient == NULL)
1043            return;
1044    
1045        // Ask user whether he/she want's an internal sampler reset...
1046        if (QMessageBox::warning(this,
1047                    QSAMPLER_TITLE ": " + tr("Warning"),
1048            tr("Resetting the sampler instance will close\n"
1049               "all device and channel configurations.\n\n"
1050               "Please note that this operation may cause\n"
1051               "temporary MIDI and Audio disruption.\n\n"
1052               "Do you want to reset the sampler engine now?"),
1053            tr("Reset"), tr("Cancel")) > 0)
1054            return;
1055    
1056            // Trye closing the current session, first...
1057            if (!closeSession(true))
1058                    return;
1059    
1060        // Just do the reset, after closing down current session...
1061            // Do the actual sampler reset...
1062            if (::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1063                    appendMessagesClient("lscp_reset_sampler");
1064                    appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
1065                    return;
1066            }
1067    
1068        // Log this.
1069        appendMessages(tr("Sampler reset."));
1070    
1071            // Make it a new session...
1072            newSession();
1073    }
1074    
1075    
1076  // Restart the client/server instance.  // Restart the client/server instance.
1077  void qsamplerMainForm::fileRestart (void)  void qsamplerMainForm::fileRestart (void)
1078  {  {
1079      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1080          return;          return;
1081            
1082      bool bRestart = true;      bool bRestart = true;
1083        
1084      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1085      // (if we're currently up and running)      // (if we're currently up and running)
1086      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1087          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1088                            QSAMPLER_TITLE ": " + tr("Warning"),
1089              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1090                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1091                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1092                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1093                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1094              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1095      }      }
# Line 725  void qsamplerMainForm::editAddChannel (v Line 1121  void qsamplerMainForm::editAddChannel (v
1121      if (m_pClient == NULL)      if (m_pClient == NULL)
1122          return;          return;
1123    
1124      // Create the new sampler channel.      // Just create the channel instance...
1125      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel();
1126      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
1127          return;          return;
     }  
1128    
1129      // Log this happening.      // Before we show it up, may be we'll
1130      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
1131        if (!pChannel->channelSetup(this)) {
1132            delete pChannel;
1133            return;
1134        }
1135    
1136      // Just create the channel strip with given id.      // And give it to the strip (will own the channel instance, if successful).
1137      createChannel(iChannelID, true);      if (!createChannelStrip(pChannel)) {
1138            delete pChannel;
1139            return;
1140        }
1141    
1142      // We'll be dirty, for sure...      // Make that an overall update.
1143      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
1144      stabilizeForm();      stabilizeForm();
1145  }  }
1146    
# Line 752  void qsamplerMainForm::editRemoveChannel Line 1151  void qsamplerMainForm::editRemoveChannel
1151      if (m_pClient == NULL)      if (m_pClient == NULL)
1152          return;          return;
1153    
1154      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1155        if (pChannelStrip == NULL)
1156            return;
1157    
1158        qsamplerChannel *pChannel = pChannelStrip->channel();
1159      if (pChannel == NULL)      if (pChannel == NULL)
1160          return;          return;
1161    
1162      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1163      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1164          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1165                            QSAMPLER_TITLE ": " + tr("Warning"),
1166              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1167                 "%1\n\n"                 "%1\n\n"
1168                 "Are you sure?")                 "Are you sure?")
1169                 .arg(pChannel->caption()),                 .arg(pChannelStrip->caption()),
1170              tr("OK"), tr("Cancel")) > 0)              tr("OK"), tr("Cancel")) > 0)
1171              return;              return;
1172      }      }
1173    
1174      // Remove the existing sampler channel.      // Remove the existing sampler channel.
1175      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."));  
1176          return;          return;
     }  
1177    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
1178      // Just delete the channel strip.      // Just delete the channel strip.
1179      delete pChannel;      delete pChannelStrip;
1180    
1181      // Do we auto-arrange?      // Do we auto-arrange?
1182      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1183          channelsArrange();          channelsArrange();
# Line 795  void qsamplerMainForm::editSetupChannel Line 1194  void qsamplerMainForm::editSetupChannel
1194      if (m_pClient == NULL)      if (m_pClient == NULL)
1195          return;          return;
1196    
1197      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1198      if (pChannel == NULL)      if (pChannelStrip == NULL)
1199          return;          return;
1200    
1201      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
1202      pChannel->channelSetup(false);      pChannelStrip->channelSetup();
1203  }  }
1204    
1205    
# Line 810  void qsamplerMainForm::editResetChannel Line 1209  void qsamplerMainForm::editResetChannel
1209      if (m_pClient == NULL)      if (m_pClient == NULL)
1210          return;          return;
1211    
1212      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1213      if (pChannel == NULL)      if (pChannelStrip == NULL)
1214          return;          return;
1215    
1216      // Remove the existing sampler channel.      // Just invoque the channel strip procedure.
1217      if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      pChannelStrip->channelReset();
1218          appendMessagesClient("lscp_reset_channel");  }
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
1219    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
1220    
1221      // Refresh channel strip info.  // Reset all sampler channels.
1222      pChannel->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
1223    {
1224            if (m_pClient == NULL)
1225                    return;
1226    
1227            // Invoque the channel strip procedure,
1228            // for all channels out there...
1229            m_pWorkspace->setUpdatesEnabled(false);
1230            QWidgetList wlist = m_pWorkspace->windowList();
1231            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1232                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1233                    if (pChannelStrip)
1234                            pChannelStrip->channelReset();
1235            }
1236            m_pWorkspace->setUpdatesEnabled(true);
1237  }  }
1238    
1239    
# Line 877  void qsamplerMainForm::viewMessages ( bo Line 1285  void qsamplerMainForm::viewMessages ( bo
1285  }  }
1286    
1287    
1288    // Show/hide the MIDI instrument list-view form.
1289    void qsamplerMainForm::viewInstruments (void)
1290    {
1291            if (m_pOptions == NULL)
1292                    return;
1293    
1294            if (m_pInstrumentListForm) {
1295                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1296                    if (m_pInstrumentListForm->isVisible()) {
1297                            m_pInstrumentListForm->hide();
1298                    } else {
1299                            m_pInstrumentListForm->show();
1300                            m_pInstrumentListForm->raise();
1301                            m_pInstrumentListForm->setActiveWindow();
1302                    }
1303            }
1304    }
1305    
1306    
1307    // Show/hide the device configurator form.
1308    void qsamplerMainForm::viewDevices (void)
1309    {
1310            if (m_pOptions == NULL)
1311                    return;
1312    
1313            if (m_pDeviceForm) {
1314                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1315                    if (m_pDeviceForm->isVisible()) {
1316                            m_pDeviceForm->hide();
1317                    } else {
1318                            m_pDeviceForm->show();
1319                            m_pDeviceForm->raise();
1320                            m_pDeviceForm->setActiveWindow();
1321                    }
1322            }
1323    }
1324    
1325    
1326  // Show options dialog.  // Show options dialog.
1327  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1328  {  {
# Line 886  void qsamplerMainForm::viewOptions (void Line 1332  void qsamplerMainForm::viewOptions (void
1332      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);
1333      if (pOptionsForm) {      if (pOptionsForm) {
1334          // Check out some initial nullities(tm)...          // Check out some initial nullities(tm)...
1335          qsamplerChannelStrip *pChannel = activeChannel();          qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1336          if (m_pOptions->sDisplayFont.isEmpty() && pChannel)          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1337              m_pOptions->sDisplayFont = pChannel->displayFont().toString();              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1338          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1339              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1340          // To track down deferred or immediate changes.          // To track down deferred or immediate changes.
# Line 898  void qsamplerMainForm::viewOptions (void Line 1344  void qsamplerMainForm::viewOptions (void
1344          bool    bOldServerStart     = m_pOptions->bServerStart;          bool    bOldServerStart     = m_pOptions->bServerStart;
1345          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1346          QString sOldDisplayFont     = m_pOptions->sDisplayFont;          QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1347            bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1348          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1349          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1350            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1351          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1352          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1353          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1354          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1355            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1356          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1357          // Load the current setup settings.          // Load the current setup settings.
1358          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 911  void qsamplerMainForm::viewOptions (void Line 1360  void qsamplerMainForm::viewOptions (void
1360          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1361              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1362              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1363                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1364                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1365                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1366                    QMessageBox::information(this,
1367                                            QSAMPLER_TITLE ": " + tr("Information"),
1368                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1369                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1370                  updateMessagesCapture();                  updateMessagesCapture();
# Line 922  void qsamplerMainForm::viewOptions (void Line 1374  void qsamplerMainForm::viewOptions (void
1374                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1375                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1376                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1377                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1378                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1379                    updateInstrumentNames();
1380                if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1381                    (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1382                    updateDisplayEffect();
1383              if (sOldDisplayFont != m_pOptions->sDisplayFont)              if (sOldDisplayFont != m_pOptions->sDisplayFont)
1384                  updateDisplayFont();                  updateDisplayFont();
1385              if (iOldMaxVolume != m_pOptions->iMaxVolume)              if (iOldMaxVolume != m_pOptions->iMaxVolume)
# Line 964  void qsamplerMainForm::channelsArrange ( Line 1422  void qsamplerMainForm::channelsArrange (
1422      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1423      int y = 0;      int y = 0;
1424      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1425          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1426      /*  if (pChannel->testWState(WState_Maximized | WState_Minimized)) {      /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1427              // Prevent flicker...              // Prevent flicker...
1428              pChannel->hide();              pChannelStrip->hide();
1429              pChannel->showNormal();              pChannelStrip->showNormal();
1430          }   */          }   */
1431          pChannel->adjustSize();          pChannelStrip->adjustSize();
1432          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1433          if (iWidth < pChannel->width())          if (iWidth < pChannelStrip->width())
1434              iWidth = pChannel->width();              iWidth = pChannelStrip->width();
1435      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1436          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1437          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1438          y += iHeight;          y += iHeight;
1439      }      }
1440      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1441        
1442      stabilizeForm();      stabilizeForm();
1443  }  }
1444    
# Line 1029  void qsamplerMainForm::helpAbout (void) Line 1487  void qsamplerMainForm::helpAbout (void)
1487      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1488      sText += "</font></small><br />";      sText += "</font></small><br />";
1489  #endif  #endif
1490    #ifndef CONFIG_INSTRUMENT_NAME
1491        sText += "<small><font color=\"red\">";
1492        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1493        sText += "</font></small><br />";
1494    #endif
1495    #ifndef CONFIG_MUTE_SOLO
1496        sText += "<small><font color=\"red\">";
1497        sText += tr("Sampler channel Mute/Solo support disabled.");
1498        sText += "</font></small><br />";
1499    #endif
1500    #ifndef CONFIG_MIDI_INSTRUMENT
1501        sText += "<small><font color=\"red\">";
1502        sText += tr("MIDI instrument mapping support disabled.");
1503        sText += "</font></small><br />";
1504    #endif
1505      sText += "<br />\n";      sText += "<br />\n";
1506      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1507      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1508      sText += " ";      sText += " ";
1509      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1510    #ifdef CONFIG_LIBGIG
1511        sText += ", ";
1512        sText += gig::libraryName().c_str();
1513        sText += " ";
1514        sText += gig::libraryVersion().c_str();
1515    #endif
1516      sText += "<br />\n";      sText += "<br />\n";
1517      sText += "<br />\n";      sText += "<br />\n";
1518      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 1056  void qsamplerMainForm::helpAbout (void) Line 1535  void qsamplerMainForm::helpAbout (void)
1535  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1536  {  {
1537      // Update the main application caption...      // Update the main application caption...
1538      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1539      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1540          sSessioName += '*';          sSessionName += " *";
1541      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1542    
1543      // Update the main menu state...      // Update the main menu state...
1544      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1545      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1546      bool bHasChannel = (bHasClient && pChannel != NULL);      bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1547      fileNewAction->setEnabled(bHasClient);      fileNewAction->setEnabled(bHasClient);
1548      fileOpenAction->setEnabled(bHasClient);      fileOpenAction->setEnabled(bHasClient);
1549      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1550      fileSaveAsAction->setEnabled(bHasClient);      fileSaveAsAction->setEnabled(bHasClient);
1551        fileResetAction->setEnabled(bHasClient);
1552      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1553      editAddChannelAction->setEnabled(bHasClient);      editAddChannelAction->setEnabled(bHasClient);
1554      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1555      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1556      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1557      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1558      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1559    #ifdef CONFIG_MIDI_INSTRUMENT
1560            viewInstrumentsAction->setOn(m_pInstrumentListForm
1561                    && m_pInstrumentListForm->isVisible());
1562            viewInstrumentsAction->setEnabled(bHasClient);
1563    #endif
1564            viewDevicesAction->setOn(m_pDeviceForm
1565                    && m_pDeviceForm->isVisible());
1566        viewDevicesAction->setEnabled(bHasClient);
1567        channelsArrangeAction->setEnabled(bHasChannel);
1568    
1569      // Client/Server status...      // Client/Server status...
1570      if (bHasClient) {      if (bHasClient) {
1571          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1572          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));
1573      } else {      } else {
1574          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1575          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1576      }      }
1577      // Channel status...      // Channel status...
1578      if (bHasChannel)      if (bHasChannel)
1579          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannel->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1580      else      else
1581          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1582      // Session status...      // Session status...
1583      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1584          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1585      else      else
1586          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1587    
1588      // Recent files menu.      // Recent files menu.
1589      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1106  void qsamplerMainForm::stabilizeForm (vo Line 1595  void qsamplerMainForm::stabilizeForm (vo
1595    
1596    
1597  // Channel change receiver slot.  // Channel change receiver slot.
1598  void qsamplerMainForm::channelChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1599  {  {
1600            // Add this strip to the changed list...
1601            if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1602                    m_changedStrips.append(pChannelStrip);
1603                    pChannelStrip->resetErrorCount();
1604            }
1605    
1606      // Just mark the dirty form.      // Just mark the dirty form.
1607      m_iDirtyCount++;      m_iDirtyCount++;
1608      // and update the form status...      // and update the form status...
# Line 1115  void qsamplerMainForm::channelChanged( q Line 1610  void qsamplerMainForm::channelChanged( q
1610  }  }
1611    
1612    
1613    // Grab and restore current sampler channels session.
1614    void qsamplerMainForm::updateSession (void)
1615    {
1616    #ifdef CONFIG_MIDI_INSTRUMENT
1617            // FIXME: Make some room for default instrument maps...
1618            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1619            if (iMaps < 0)
1620                    appendMessagesClient("lscp_get_midi_instrument_maps");
1621            else if (iMaps < 1) {
1622                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1623                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1624            }
1625    #endif
1626    
1627            // Retrieve the current channel list.
1628            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1629            if (piChannelIDs == NULL) {
1630                    if (::lscp_client_get_errno(m_pClient)) {
1631                            appendMessagesClient("lscp_list_channels");
1632                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1633                    }
1634            } else {
1635                    // Try to (re)create each channel.
1636                    m_pWorkspace->setUpdatesEnabled(false);
1637                    for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1638                            // Check if theres already a channel strip for this one...
1639                            if (!channelStrip(piChannelIDs[iChannel]))
1640                                    createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1641                    }
1642                    m_pWorkspace->setUpdatesEnabled(true);
1643            }
1644    
1645        // Do we auto-arrange?
1646        if (m_pOptions && m_pOptions->bAutoArrange)
1647            channelsArrange();
1648    
1649            // Remember to refresh devices and instruments...
1650            if (m_pInstrumentListForm)
1651                m_pInstrumentListForm->refreshInstruments();
1652            if (m_pDeviceForm)
1653                m_pDeviceForm->refreshDevices();
1654    }
1655    
1656    
1657  // Update the recent files list and menu.  // Update the recent files list and menu.
1658  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1659  {  {
# Line 1159  void qsamplerMainForm::updateRecentFiles Line 1698  void qsamplerMainForm::updateRecentFiles
1698  }  }
1699    
1700    
1701    // Force update of the channels instrument names mode.
1702    void qsamplerMainForm::updateInstrumentNames (void)
1703    {
1704        // Full channel list update...
1705        QWidgetList wlist = m_pWorkspace->windowList();
1706        if (wlist.isEmpty())
1707            return;
1708    
1709        m_pWorkspace->setUpdatesEnabled(false);
1710        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1711            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1712            if (pChannelStrip)
1713                pChannelStrip->updateInstrumentName(true);
1714        }
1715        m_pWorkspace->setUpdatesEnabled(true);
1716    }
1717    
1718    
1719  // Force update of the channels display font.  // Force update of the channels display font.
1720  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1721  {  {
# Line 1180  void qsamplerMainForm::updateDisplayFont Line 1737  void qsamplerMainForm::updateDisplayFont
1737    
1738      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1739      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1740          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1741          pChannel->setDisplayFont(font);          if (pChannelStrip)
1742                pChannelStrip->setDisplayFont(font);
1743        }
1744        m_pWorkspace->setUpdatesEnabled(true);
1745    }
1746    
1747    
1748    // Update channel strips background effect.
1749    void qsamplerMainForm::updateDisplayEffect (void)
1750    {
1751       QPixmap pm;
1752        if (m_pOptions->bDisplayEffect)
1753            pm = QPixmap::fromMimeSource("displaybg1.png");
1754    
1755        // Full channel list update...
1756        QWidgetList wlist = m_pWorkspace->windowList();
1757        if (wlist.isEmpty())
1758            return;
1759    
1760        m_pWorkspace->setUpdatesEnabled(false);
1761        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1762            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1763            if (pChannelStrip)
1764                pChannelStrip->setDisplayBackground(pm);
1765      }      }
1766      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1767  }  }
# Line 1200  void qsamplerMainForm::updateMaxVolume ( Line 1780  void qsamplerMainForm::updateMaxVolume (
1780    
1781      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1782      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1783          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1784          pChannel->setMaxVolume(m_pOptions->iMaxVolume);          if (pChannelStrip)
1785                pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1786      }      }
1787      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1788  }  }
# Line 1240  void qsamplerMainForm::appendMessagesErr Line 1821  void qsamplerMainForm::appendMessagesErr
1821    
1822      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1823    
1824      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));          // Make it look responsive...:)
1825            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1826    
1827        QMessageBox::critical(this,
1828                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1829  }  }
1830    
1831    
# Line 1253  void qsamplerMainForm::appendMessagesCli Line 1838  void qsamplerMainForm::appendMessagesCli
1838      appendMessagesColor(s + QString(": %1 (errno=%2)")      appendMessagesColor(s + QString(": %1 (errno=%2)")
1839          .arg(::lscp_client_get_result(m_pClient))          .arg(::lscp_client_get_result(m_pClient))
1840          .arg(::lscp_client_get_errno(m_pClient)), "#996666");          .arg(::lscp_client_get_errno(m_pClient)), "#996666");
1841    
1842            // Make it look responsive...:)
1843            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1844  }  }
1845    
1846    
# Line 1280  void qsamplerMainForm::updateMessagesLim Line 1868  void qsamplerMainForm::updateMessagesLim
1868          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1869              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1870          else          else
1871              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1872      }      }
1873  }  }
1874    
# Line 1300  void qsamplerMainForm::updateMessagesCap Line 1888  void qsamplerMainForm::updateMessagesCap
1888  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
1889    
1890  // The channel strip creation executive.  // The channel strip creation executive.
1891  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
1892  {  {
1893      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
1894          return;          return NULL;
1895    
1896      // Prepare for auto-arrange?      // Prepare for auto-arrange?
1897      qsamplerChannelStrip *pChannel = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
1898      int y = 0;      int y = 0;
1899      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1900          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1901          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1902              pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1903          //  y += pChannel->height() + pChannel->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1904              y += pChannel->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1905                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1906                            }
1907          }          }
1908      }      }
1909    
1910      // Add a new channel itema...      // Add a new channel itema...
1911      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;
1912      pChannel = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1913      pChannel->setMaxVolume(m_pOptions->iMaxVolume);      if (pChannelStrip == NULL)
1914      pChannel->setup(this, iChannelID);          return NULL;
1915      // We'll need a display font.  
1916      QFont font;      // Actual channel strip setup...
1917      if (m_pOptions && font.fromString(m_pOptions->sDisplayFont))      pChannelStrip->setup(pChannel);
1918          pChannel->setDisplayFont(font);      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
1919      // Track channel setup changes.      // Set some initial aesthetic options...
1920      QObject::connect(pChannel, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelChanged(qsamplerChannelStrip *)));      if (m_pOptions) {
1921      // Before we show it up, may be we'll          // Background display effect...
1922      // better ask for some initial values?          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
1923      if (bPrompt)          // We'll need a display font.
1924          pChannel->channelSetup(true);          QFont font;
1925            if (font.fromString(m_pOptions->sDisplayFont))
1926                pChannelStrip->setDisplayFont(font);
1927            // Maximum allowed volume setting.
1928            pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1929        }
1930    
1931      // Now we show up us to the world.      // Now we show up us to the world.
1932      pChannel->show();      pChannelStrip->show();
1933      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
1934      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1935          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1936      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();
1937          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1938          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1939      }      }
1940    
1941            // This is pretty new, so we'll watch for it closely.
1942            channelStripChanged(pChannelStrip);
1943    
1944        // Return our successful reference...
1945        return pChannelStrip;
1946  }  }
1947    
1948    
1949  // Retrieve the active channel strip.  // Retrieve the active channel strip.
1950  qsamplerChannelStrip *qsamplerMainForm::activeChannel (void)  qsamplerChannelStrip *qsamplerMainForm::activeChannelStrip (void)
1951  {  {
1952      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();
1953  }  }
1954    
1955    
1956  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
1957  qsamplerChannelStrip *qsamplerMainForm::channelAt ( int iChannel )  qsamplerChannelStrip *qsamplerMainForm::channelStripAt ( int iChannel )
1958  {  {
1959      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1960      if (wlist.isEmpty())      if (wlist.isEmpty())
1961          return 0;          return NULL;
1962    
1963      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1964  }  }
1965    
1966    
1967    // Retrieve a channel strip by sampler channel id.
1968    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1969    {
1970            QWidgetList wlist = m_pWorkspace->windowList();
1971            if (wlist.isEmpty())
1972                    return NULL;
1973    
1974            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1975                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1976                    if (pChannelStrip) {
1977                            qsamplerChannel *pChannel = pChannelStrip->channel();
1978                            if (pChannel && pChannel->channelID() == iChannelID)
1979                                    return pChannelStrip;
1980                    }
1981            }
1982    
1983            // Not found.
1984            return NULL;
1985    }
1986    
1987    
1988  // Construct the windows menu.  // Construct the windows menu.
1989  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1990  {  {
# Line 1373  void qsamplerMainForm::channelsMenuAbout Line 1996  void qsamplerMainForm::channelsMenuAbout
1996      if (!wlist.isEmpty()) {      if (!wlist.isEmpty()) {
1997          channelsMenu->insertSeparator();          channelsMenu->insertSeparator();
1998          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1999              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
2000              int iItemID = channelsMenu->insertItem(pChannel->caption(), this, SLOT(channelsMenuActivated(int)));              if (pChannelStrip) {
2001              channelsMenu->setItemParameter(iItemID, iChannel);                  int iItemID = channelsMenu->insertItem(pChannelStrip->caption(), this, SLOT(channelsMenuActivated(int)));
2002              channelsMenu->setItemChecked(iItemID, activeChannel() == pChannel);                  channelsMenu->setItemParameter(iItemID, iChannel);
2003                    channelsMenu->setItemChecked(iItemID, activeChannelStrip() == pChannelStrip);
2004                }
2005          }          }
2006      }      }
2007  }  }
# Line 1385  void qsamplerMainForm::channelsMenuAbout Line 2010  void qsamplerMainForm::channelsMenuAbout
2010  // Windows menu activation slot  // Windows menu activation slot
2011  void qsamplerMainForm::channelsMenuActivated ( int iChannel )  void qsamplerMainForm::channelsMenuActivated ( int iChannel )
2012  {  {
2013      qsamplerChannelStrip *pChannel = channelAt(iChannel);      qsamplerChannelStrip *pChannelStrip = channelStripAt(iChannel);
2014      if (pChannel)      if (pChannelStrip)
2015          pChannel->showNormal();          pChannelStrip->showNormal();
2016      pChannel->setFocus();      pChannelStrip->setFocus();
2017  }  }
2018    
2019    
# Line 1426  void qsamplerMainForm::timerSlot (void) Line 2051  void qsamplerMainForm::timerSlot (void)
2051              }              }
2052          }          }
2053      }      }
2054        
2055          // Refresh each channel usage, on each period...          if (m_pClient) {
2056      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {                  // Update the channel information for each pending strip...
2057          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2058          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2059              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2060              QWidgetList wlist = m_pWorkspace->windowList();                                  // If successfull, remove from pending list...
2061              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                  if (pChannelStrip->updateChannelInfo())
2062                  qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);                                          m_changedStrips.remove(pChannelStrip);
2063                  if (pChannel->isVisible())                          }
2064                      pChannel->updateChannelUsage();                  }
2065              }                  // Refresh each channel usage, on each period...
2066          }                  if (m_pOptions->bAutoRefresh) {
2067      }                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2068                            if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2069                                    m_iTimerSlot = 0;
2070                                    // Update the channel stream usage for each strip...
2071                                    QWidgetList wlist = m_pWorkspace->windowList();
2072                                    for (int iChannel = 0;
2073                                                    iChannel < (int) wlist.count(); iChannel++) {
2074                                            qsamplerChannelStrip *pChannelStrip
2075                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2076                                            if (pChannelStrip && pChannelStrip->isVisible())
2077                                                    pChannelStrip->updateChannelUsage();
2078                                    }
2079                            }
2080                    }
2081            }
2082    
2083      // Register the next timer slot.      // Register the next timer slot.
2084      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1461  void qsamplerMainForm::startServer (void Line 2100  void qsamplerMainForm::startServer (void
2100    
2101      // Is the server process instance still here?      // Is the server process instance still here?
2102      if (m_pServer) {      if (m_pServer) {
2103          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2104                            QSAMPLER_TITLE ": " + tr("Warning"),
2105              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2106                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2107              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1620  bool qsamplerMainForm::startClient (void Line 2260  bool qsamplerMainForm::startClient (void
2260      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2261      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)));
2262    
2263            // Subscribe to channel info change notifications...
2264            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2265                    appendMessagesClient("lscp_client_subscribe");
2266    
2267      // We may stop scheduling around.      // We may stop scheduling around.
2268      stopSchedule();      stopSchedule();
2269    
# Line 1629  bool qsamplerMainForm::startClient (void Line 2273  bool qsamplerMainForm::startClient (void
2273      // Log success here.      // Log success here.
2274      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2275    
2276            // Hard-notify instrumnet and device configuration forms,
2277            // if visible, that we're ready...
2278            if (m_pInstrumentListForm)
2279                m_pInstrumentListForm->refreshInstruments();
2280            if (m_pDeviceForm)
2281                m_pDeviceForm->refreshDevices();
2282    
2283      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2284      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2285          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1663  void qsamplerMainForm::stopClient (void) Line 2314  void qsamplerMainForm::stopClient (void)
2314      // channels from the back-end server.      // channels from the back-end server.
2315      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2316      closeSession(false);      closeSession(false);
2317        
2318      // Close us as a client...      // Close us as a client...
2319      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2320        ::lscp_client_destroy(m_pClient);
2321      m_pClient = NULL;      m_pClient = NULL;
2322    
2323            // Hard-notify instrumnet and device configuration forms,
2324            // if visible, that we're running out...
2325            if (m_pInstrumentListForm)
2326                m_pInstrumentListForm->refreshInstruments();
2327            if (m_pDeviceForm)
2328                m_pDeviceForm->refreshDevices();
2329    
2330      // Log final here.      // Log final here.
2331      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2332    

Legend:
Removed from v.176  
changed lines
  Added in v.1013

  ViewVC Help
Powered by ViewVC