/[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 980 by capela, Sun Dec 17 22:29:29 2006 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
# Line 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                    // Make it look responsive...:)
410                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
411            }
412  }  }
413    
414    
# Line 315  void qsamplerMainForm::customEvent ( QCu Line 418  void qsamplerMainForm::customEvent ( QCu
418      // For the time being, just pump it to messages.      // For the time being, just pump it to messages.
419      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {      if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
420          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;          qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
421          appendMessagesColor(tr("Notify event: %1 data: %2")                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {
422              .arg(::lscp_event_to_text(pEvent->event()))                          int iChannelID = pEvent->data().toInt();
423              .arg(pEvent->data()), "#996699");                          qsamplerChannelStrip *pChannelStrip = channelStrip(iChannelID);
424                            if (pChannelStrip)
425                                    channelStripChanged(pChannelStrip);
426                    } else {
427                            appendMessagesColor(tr("Notify event: %1 data: %2")
428                                    .arg(::lscp_event_to_text(pEvent->event()))
429                                    .arg(pEvent->data()), "#996699");
430                    }
431      }      }
432  }  }
433    
# Line 326  void qsamplerMainForm::customEvent ( QCu Line 436  void qsamplerMainForm::customEvent ( QCu
436  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
437  {  {
438      stabilizeForm();      stabilizeForm();
439        
440      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
441  }  }
442    
# Line 340  qsamplerOptions *qsamplerMainForm::optio Line 450  qsamplerOptions *qsamplerMainForm::optio
450      return m_pOptions;      return m_pOptions;
451  }  }
452    
453    
454  // The LSCP client descriptor property.  // The LSCP client descriptor property.
455  lscp_client_t *qsamplerMainForm::client (void)  lscp_client_t *qsamplerMainForm::client (void)
456  {  {
# Line 347  lscp_client_t *qsamplerMainForm::client Line 458  lscp_client_t *qsamplerMainForm::client
458  }  }
459    
460    
461    // The pseudo-singleton instance accessor.
462    qsamplerMainForm *qsamplerMainForm::getInstance (void)
463    {
464            return g_pMainForm;
465    }
466    
467    
468  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
469  // qsamplerMainForm -- Session file stuff.  // qsamplerMainForm -- Session file stuff.
470    
# Line 370  bool qsamplerMainForm::newSession (void) Line 488  bool qsamplerMainForm::newSession (void)
488      if (!closeSession(true))      if (!closeSession(true))
489          return false;          return false;
490    
491            // Give us what the server has, right now...
492            updateSession();
493    
494      // Ok increment untitled count.      // Ok increment untitled count.
495      m_iUntitled++;      m_iUntitled++;
496    
# Line 391  bool qsamplerMainForm::openSession (void Line 512  bool qsamplerMainForm::openSession (void
512    
513      // Ask for the filename to open...      // Ask for the filename to open...
514      QString sFilename = QFileDialog::getOpenFileName(      QString sFilename = QFileDialog::getOpenFileName(
515              m_pOptions->sSessionDir,                // Start here.                  m_pOptions->sSessionDir,                // Start here.
516              tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
517              this, 0,                                // Parent and name (none)                  this, 0,                                // Parent and name (none)
518              tr("Open Session")                      // Caption.                  QSAMPLER_TITLE ": " + tr("Open Session")        // Caption.
519      );      );
520    
521      // Have we cancelled?      // Have we cancelled?
# Line 425  bool qsamplerMainForm::saveSession ( boo Line 546  bool qsamplerMainForm::saveSession ( boo
546              sFilename = m_pOptions->sSessionDir;              sFilename = m_pOptions->sSessionDir;
547          // Prompt the guy...          // Prompt the guy...
548          sFilename = QFileDialog::getSaveFileName(          sFilename = QFileDialog::getSaveFileName(
549                  sFilename,                              // Start here.                          sFilename,                              // Start here.
550                  tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)                          tr("LSCP Session files") + " (*.lscp)", // Filter (LSCP files)
551                  this, 0,                                // Parent and name (none)                          this, 0,                                // Parent and name (none)
552                  tr("Save Session")                      // Caption.                          QSAMPLER_TITLE ": " + tr("Save Session")        // Caption.
553          );          );
554          // Have we cancelled it?          // Have we cancelled it?
555          if (sFilename.isEmpty())          if (sFilename.isEmpty())
# Line 438  bool qsamplerMainForm::saveSession ( boo Line 559  bool qsamplerMainForm::saveSession ( boo
559              sFilename += ".lscp";              sFilename += ".lscp";
560          // Check if already exists...          // Check if already exists...
561          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {          if (sFilename != m_sFilename && QFileInfo(sFilename).exists()) {
562              if (QMessageBox::warning(this, tr("Warning"),              if (QMessageBox::warning(this,
563                                    QSAMPLER_TITLE ": " + tr("Warning"),
564                  tr("The file already exists:\n\n"                  tr("The file already exists:\n\n"
565                     "\"%1\"\n\n"                     "\"%1\"\n\n"
566                     "Do you want to replace it?")                     "Do you want to replace it?")
# Line 460  bool qsamplerMainForm::closeSession ( bo Line 582  bool qsamplerMainForm::closeSession ( bo
582    
583      // Are we dirty enough to prompt it?      // Are we dirty enough to prompt it?
584      if (m_iDirtyCount > 0) {      if (m_iDirtyCount > 0) {
585          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
586                            QSAMPLER_TITLE ": " + tr("Warning"),
587              tr("The current session has been changed:\n\n"              tr("The current session has been changed:\n\n"
588              "\"%1\"\n\n"              "\"%1\"\n\n"
589              "Do you want to save the changes?")              "Do you want to save the changes?")
# Line 483  bool qsamplerMainForm::closeSession ( bo Line 606  bool qsamplerMainForm::closeSession ( bo
606          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
607          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
608          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
609              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
610              if (bForce && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)              if (pChannelStrip) {
611                  appendMessagesClient("lscp_remove_channel");                  qsamplerChannel *pChannel = pChannelStrip->channel();
612              delete pChannel;                  if (bForce && pChannel)
613                        pChannel->removeChannel();
614                    delete pChannelStrip;
615                }
616          }          }
617          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
618          // We're now clean, for sure.          // We're now clean, for sure.
# Line 515  bool qsamplerMainForm::loadSessionFile ( Line 641  bool qsamplerMainForm::loadSessionFile (
641      QTextStream ts(&file);      QTextStream ts(&file);
642      while (!ts.atEnd()) {      while (!ts.atEnd()) {
643          // Read the line.          // Read the line.
644          QString sCommand = ts.readLine().simplifyWhiteSpace();          QString sCommand = ts.readLine().stripWhiteSpace();
645          // If not empty, nor a comment, call the server...          // If not empty, nor a comment, call the server...
646          if (!sCommand.isEmpty() && sCommand[0] != '#') {          if (!sCommand.isEmpty() && sCommand[0] != '#') {
647              appendMessagesColor(sCommand, "#996633");              appendMessagesColor(sCommand, "#996633");
# Line 534  bool qsamplerMainForm::loadSessionFile ( Line 660  bool qsamplerMainForm::loadSessionFile (
660      // Ok. we've read it.      // Ok. we've read it.
661      file.close();      file.close();
662    
663      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
664      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
665    
666      // Now we'll try to create the whole GUI session.          // Have we any errors?
667      int iChannels = ::lscp_get_channels(m_pClient);          if (iErrors > 0)
668      if (iChannels < 0) {                  appendMessagesError(tr("Session loaded with errors\nfrom \"%1\".\n\nSorry.").arg(sFilename));
         appendMessagesClient("lscp_get_channels");  
         appendMessagesError(tr("Could not get current number of channels.\n\nSorry."));  
     }  
       
     // 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);  
669    
670      // Save as default session directory.      // Save as default session directory.
671      if (m_pOptions)      if (m_pOptions)
672          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
673      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
674      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
675      // Stabilize form...      // Stabilize form...
676      m_sFilename = sFilename;      m_sFilename = sFilename;
677      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
678      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
679    
680        // Make that an overall update.
681      stabilizeForm();      stabilizeForm();
682      return true;      return true;
683  }  }
# Line 570  bool qsamplerMainForm::loadSessionFile ( Line 686  bool qsamplerMainForm::loadSessionFile (
686  // Save current session to specific file path.  // Save current session to specific file path.
687  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )  bool qsamplerMainForm::saveSessionFile ( const QString& sFilename )
688  {  {
689            if (m_pClient == NULL)
690                    return false;
691    
692            // Check whether server is apparently OK...
693            if (::lscp_get_channels(m_pClient) < 0) {
694                    appendMessagesClient("lscp_get_channels");
695                    return false;
696            }
697    
698      // Open and write into real file.      // Open and write into real file.
699      QFile file(sFilename);      QFile file(sFilename);
700      if (!file.open(IO_WriteOnly | IO_Truncate)) {      if (!file.open(IO_WriteOnly | IO_Truncate)) {
# Line 578  bool qsamplerMainForm::saveSessionFile ( Line 703  bool qsamplerMainForm::saveSessionFile (
703      }      }
704    
705      // Write the file.      // Write the file.
706      int iErrors = 0;      int  iErrors = 0;
707      QTextStream ts(&file);      QTextStream ts(&file);
708      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
709      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 589  bool qsamplerMainForm::saveSessionFile ( Line 714  bool qsamplerMainForm::saveSessionFile (
714      ts << "# " << tr("File")      ts << "# " << tr("File")
715         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
716      ts << "# " << tr("Date")      ts << "# " << tr("Date")
717         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
718         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
719      ts << "#"  << endl;      ts << "#"  << endl;
720      ts << endl;      ts << endl;
721    
722            // It is assumed that this new kind of device+session file
723            // will be loaded from a complete initialized server...
724            int *piDeviceIDs;
725            int  iDevice;
726            ts << "RESET" << endl;
727    
728            // Audio device mapping.
729            QMap<int, int> audioDeviceMap;
730            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
731            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
732                    ts << endl;
733                    qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);
734                    // Audio device specification...
735                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
736                            << " " << tr("Device") << " " << iDevice << endl;
737                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
738                    qsamplerDeviceParamMap::ConstIterator deviceParam;
739                    for (deviceParam = device.params().begin();
740                                    deviceParam != device.params().end();
741                                            ++deviceParam) {
742                            const qsamplerDeviceParam& param = deviceParam.data();
743                            if (param.value.isEmpty()) ts << "# ";
744                            ts << " " << deviceParam.key() << "='" << param.value << "'";
745                    }
746                    ts << endl;
747                    // Audio channel parameters...
748                    int iPort = 0;
749                    for (qsamplerDevicePort *pPort = device.ports().first();
750                                    pPort;
751                                            pPort = device.ports().next(), ++iPort) {
752                            qsamplerDeviceParamMap::ConstIterator portParam;
753                            for (portParam = pPort->params().begin();
754                                            portParam != pPort->params().end();
755                                                    ++portParam) {
756                                    const qsamplerDeviceParam& param = portParam.data();
757                                    if (param.fix || param.value.isEmpty()) ts << "# ";
758                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
759                                            << " " << iPort << " " << portParam.key()
760                                            << "='" << param.value << "'" << endl;
761                            }
762                    }
763                    // Audio device index/id mapping.
764                    audioDeviceMap[device.deviceID()] = iDevice;
765                    // Try to keep it snappy :)
766                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
767            }
768    
769            // MIDI device mapping.
770            QMap<int, int> midiDeviceMap;
771            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
772            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
773                    ts << endl;
774                    qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);
775                    // MIDI device specification...
776                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
777                            << " " << tr("Device") << " " << iDevice << endl;
778                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
779                    qsamplerDeviceParamMap::ConstIterator deviceParam;
780                    for (deviceParam = device.params().begin();
781                                    deviceParam != device.params().end();
782                                            ++deviceParam) {
783                            const qsamplerDeviceParam& param = deviceParam.data();
784                            if (param.value.isEmpty()) ts << "# ";
785                            ts << " " << deviceParam.key() << "='" << param.value << "'";
786                    }
787                    ts << endl;
788                    // MIDI port parameters...
789                    int iPort = 0;
790                    for (qsamplerDevicePort *pPort = device.ports().first();
791                                    pPort;
792                                            pPort = device.ports().next(), ++iPort) {
793                            qsamplerDeviceParamMap::ConstIterator portParam;
794                            for (portParam = pPort->params().begin();
795                                            portParam != pPort->params().end();
796                                                    ++portParam) {
797                                    const qsamplerDeviceParam& param = portParam.data();
798                                    if (param.fix || param.value.isEmpty()) ts << "# ";
799                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
800                                       << " " << iPort << " " << portParam.key()
801                                       << "='" << param.value << "'" << endl;
802                            }
803                    }
804                    // MIDI device index/id mapping.
805                    midiDeviceMap[device.deviceID()] = iDevice;
806                    // Try to keep it snappy :)
807                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
808            }
809            ts << endl;
810    
811    #ifdef CONFIG_MIDI_INSTRUMENT
812            // MIDI instrument mapping...
813            int *piMaps = ::lscp_list_midi_instrument_maps(m_pClient);
814            for (int iMap = 0; piMaps && piMaps[iMap] >= 0; iMap++) {
815                    int iMidiMap = piMaps[iMap];
816                    const char *pszMapName
817                            = ::lscp_get_midi_instrument_map_name(m_pClient, iMidiMap);
818                    ts << "# " << tr("MIDI instrument map") << " " << iMidiMap;
819                    if (pszMapName)
820                            ts << " - " << pszMapName;
821                    ts << endl;
822                    ts << "ADD MIDI_INSTRUMENT_MAP";
823                    if (pszMapName)
824                            ts << " '" << pszMapName << "'";
825                    ts << endl;
826                    // MIDI instrument mapping...
827                    lscp_midi_instrument_t *pInstrs
828                            = ::lscp_list_midi_instruments(m_pClient, iMidiMap);
829                    for (int iInstr = 0; pInstrs && pInstrs[iInstr].map >= 0; iInstr++) {
830                            lscp_midi_instrument_info_t *pInstrInfo
831                                    = ::lscp_get_midi_instrument_info(m_pClient, &pInstrs[iInstr]);
832                            if (pInstrInfo) {
833                                    ts << "MAP MIDI_INSTRUMENT "
834                                            << pInstrs[iInstr].map         << " "
835                                            << pInstrs[iInstr].bank        << " "
836                                            << pInstrs[iInstr].prog        << " "
837                                            << pInstrInfo->engine_name     << " '"
838                                            << pInstrInfo->instrument_file << "' "
839                                            << pInstrInfo->instrument_nr   << " "
840                                            << pInstrInfo->volume          << " ";
841                                    switch (pInstrInfo->load_mode) {
842                                            case LSCP_LOAD_PERSISTENT:
843                                                    ts << "PERSISTENT";
844                                                    break;
845                                            case LSCP_LOAD_ON_DEMAND_HOLD:
846                                                    ts << "ON_DEMAND_HOLD";
847                                                    break;
848                                            case LSCP_LOAD_ON_DEMAND:
849                                            case LSCP_LOAD_DEFAULT:
850                                            default:
851                                                    ts << "ON_DEMAND";
852                                                    break;
853                                    }
854                                    if (pInstrInfo->name)
855                                            ts << " '" << pInstrInfo->name << "'";
856                                    ts << endl;
857                            }
858                            // Try to keep it snappy :)
859                            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
860                    }
861                    if (pInstrs)
862                            ts << endl;
863            }
864    #endif //  CONFIG_MIDI_INSTRUMENT
865    
866            // Sampler channel mapping.
867      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
868      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
869          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
870          int iChannelID = pChannel->channelID();          if (pChannelStrip) {
871          ts << "# " << pChannel->caption() << endl;              qsamplerChannel *pChannel = pChannelStrip->channel();
872          ts << "ADD CHANNEL" << endl;              if (pChannel) {
873          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                  ts << "# " << tr("Channel") << " " << iChannel << endl;
874          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                  ts << "ADD CHANNEL" << endl;
875          ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                  if (audioDeviceMap.isEmpty()) {
876          ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " " << pChannel->midiChannel() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
877          ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                                                  << " " << pChannel->audioDriver() << endl;
878          ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  } else {
879          ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
880          ts << endl;                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
881                                    }
882                                    if (midiDeviceMap.isEmpty()) {
883                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
884                                                    << " " << pChannel->midiDriver() << endl;
885                                    } else {
886                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
887                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
888                                    }
889                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
890                                            << " " << pChannel->midiPort() << endl;
891                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
892                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
893                        ts << "ALL";
894                    else
895                        ts << pChannel->midiChannel();
896                    ts << endl;
897                    ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
898                                    if (pChannel->instrumentStatus() < 100) ts << "# ";
899                                    ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' "
900                                            << pChannel->instrumentNr() << " " << iChannel << endl;
901                                    qsamplerChannelRoutingMap::ConstIterator audioRoute;
902                                    for (audioRoute = pChannel->audioRouting().begin();
903                                                    audioRoute != pChannel->audioRouting().end();
904                                                            ++audioRoute) {
905                                            ts << "SET CHANNEL AUDIO_OUTPUT_CHANNEL " << iChannel
906                                                    << " " << audioRoute.key()
907                                                    << " " << audioRoute.data() << endl;
908                                    }
909                                    ts << "SET CHANNEL VOLUME " << iChannel
910                                            << " " << pChannel->volume() << endl;
911                                    if (pChannel->channelMute())
912                                            ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl;
913                                    if (pChannel->channelSolo())
914                                            ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl;
915    #ifdef CONFIG_MIDI_INSTRUMENT
916                                    if (pChannel->midiMap() >= 0) {
917                                            ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel
918                                                    << " " << pChannel->midiChannel() << endl;
919                                    }
920    #endif
921                    ts << endl;
922                }
923            }
924          // Try to keep it snappy :)          // Try to keep it snappy :)
925          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
926      }      }
# Line 632  bool qsamplerMainForm::saveSessionFile ( Line 946  bool qsamplerMainForm::saveSessionFile (
946  }  }
947    
948    
949    // Session change receiver slot.
950    void qsamplerMainForm::sessionDirty (void)
951    {
952        // Just mark the dirty form.
953        m_iDirtyCount++;
954        // and update the form status...
955        stabilizeForm();
956    }
957    
958    
959  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
960  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
961    
# Line 678  void qsamplerMainForm::fileSaveAs (void) Line 1002  void qsamplerMainForm::fileSaveAs (void)
1002  }  }
1003    
1004    
1005    // Reset the sampler instance.
1006    void qsamplerMainForm::fileReset (void)
1007    {
1008        if (m_pClient == NULL)
1009            return;
1010    
1011        // Ask user whether he/she want's an internal sampler reset...
1012        if (QMessageBox::warning(this,
1013                    QSAMPLER_TITLE ": " + tr("Warning"),
1014            tr("Resetting the sampler instance will close\n"
1015               "all device and channel configurations.\n\n"
1016               "Please note that this operation may cause\n"
1017               "temporary MIDI and Audio disruption.\n\n"
1018               "Do you want to reset the sampler engine now?"),
1019            tr("Reset"), tr("Cancel")) > 0)
1020            return;
1021    
1022        // Just do the reset, after closing down current session...
1023        if (closeSession(true) && ::lscp_reset_sampler(m_pClient) != LSCP_OK) {
1024            appendMessagesClient("lscp_reset_sampler");
1025            appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
1026            return;
1027        }
1028    
1029        // Log this.
1030        appendMessages(tr("Sampler reset."));
1031    
1032            // Make it a new session...
1033            newSession();
1034    }
1035    
1036    
1037  // Restart the client/server instance.  // Restart the client/server instance.
1038  void qsamplerMainForm::fileRestart (void)  void qsamplerMainForm::fileRestart (void)
1039  {  {
1040      if (m_pOptions == NULL)      if (m_pOptions == NULL)
1041          return;          return;
1042            
1043      bool bRestart = true;      bool bRestart = true;
1044        
1045      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
1046      // (if we're currently up and running)      // (if we're currently up and running)
1047      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
1048          bRestart = (QMessageBox::warning(this, tr("Warning"),          bRestart = (QMessageBox::warning(this,
1049                            QSAMPLER_TITLE ": " + tr("Warning"),
1050              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
1051                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
1052                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
1053                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
1054                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
1055              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
1056      }      }
# Line 725  void qsamplerMainForm::editAddChannel (v Line 1082  void qsamplerMainForm::editAddChannel (v
1082      if (m_pClient == NULL)      if (m_pClient == NULL)
1083          return;          return;
1084    
1085      // Create the new sampler channel.      // Just create the channel instance...
1086      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel();
1087      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
1088          return;          return;
     }  
1089    
1090      // Log this happening.      // Before we show it up, may be we'll
1091      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
1092        if (!pChannel->channelSetup(this)) {
1093            delete pChannel;
1094            return;
1095        }
1096    
1097      // Just create the channel strip with given id.      // And give it to the strip (will own the channel instance, if successful).
1098      createChannel(iChannelID, true);      if (!createChannelStrip(pChannel)) {
1099            delete pChannel;
1100            return;
1101        }
1102    
1103      // We'll be dirty, for sure...      // Make that an overall update.
1104      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
1105      stabilizeForm();      stabilizeForm();
1106  }  }
1107    
# Line 752  void qsamplerMainForm::editRemoveChannel Line 1112  void qsamplerMainForm::editRemoveChannel
1112      if (m_pClient == NULL)      if (m_pClient == NULL)
1113          return;          return;
1114    
1115      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1116        if (pChannelStrip == NULL)
1117            return;
1118    
1119        qsamplerChannel *pChannel = pChannelStrip->channel();
1120      if (pChannel == NULL)      if (pChannel == NULL)
1121          return;          return;
1122    
1123      // Prompt user if he/she's sure about this...      // Prompt user if he/she's sure about this...
1124      if (m_pOptions && m_pOptions->bConfirmRemove) {      if (m_pOptions && m_pOptions->bConfirmRemove) {
1125          if (QMessageBox::warning(this, tr("Warning"),          if (QMessageBox::warning(this,
1126                            QSAMPLER_TITLE ": " + tr("Warning"),
1127              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
1128                 "%1\n\n"                 "%1\n\n"
1129                 "Are you sure?")                 "Are you sure?")
1130                 .arg(pChannel->caption()),                 .arg(pChannelStrip->caption()),
1131              tr("OK"), tr("Cancel")) > 0)              tr("OK"), tr("Cancel")) > 0)
1132              return;              return;
1133      }      }
1134    
1135      // Remove the existing sampler channel.      // Remove the existing sampler channel.
1136      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."));  
1137          return;          return;
     }  
1138    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
1139      // Just delete the channel strip.      // Just delete the channel strip.
1140      delete pChannel;      delete pChannelStrip;
1141    
1142      // Do we auto-arrange?      // Do we auto-arrange?
1143      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1144          channelsArrange();          channelsArrange();
# Line 795  void qsamplerMainForm::editSetupChannel Line 1155  void qsamplerMainForm::editSetupChannel
1155      if (m_pClient == NULL)      if (m_pClient == NULL)
1156          return;          return;
1157    
1158      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1159      if (pChannel == NULL)      if (pChannelStrip == NULL)
1160          return;          return;
1161    
1162      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
1163      pChannel->channelSetup(false);      pChannelStrip->channelSetup();
1164  }  }
1165    
1166    
# Line 810  void qsamplerMainForm::editResetChannel Line 1170  void qsamplerMainForm::editResetChannel
1170      if (m_pClient == NULL)      if (m_pClient == NULL)
1171          return;          return;
1172    
1173      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1174      if (pChannel == NULL)      if (pChannelStrip == NULL)
1175          return;          return;
1176    
1177      // Remove the existing sampler channel.      // Just invoque the channel strip procedure.
1178      if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      pChannelStrip->channelReset();
1179          appendMessagesClient("lscp_reset_channel");  }
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
1180    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
1181    
1182      // Refresh channel strip info.  // Reset all sampler channels.
1183      pChannel->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
1184    {
1185            if (m_pClient == NULL)
1186                    return;
1187    
1188            // Invoque the channel strip procedure,
1189            // for all channels out there...
1190            m_pWorkspace->setUpdatesEnabled(false);
1191            QWidgetList wlist = m_pWorkspace->windowList();
1192            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1193                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1194                    if (pChannelStrip)
1195                            pChannelStrip->channelReset();
1196            }
1197            m_pWorkspace->setUpdatesEnabled(true);
1198  }  }
1199    
1200    
# Line 877  void qsamplerMainForm::viewMessages ( bo Line 1246  void qsamplerMainForm::viewMessages ( bo
1246  }  }
1247    
1248    
1249    // Show/hide the MIDI instrument list-view form.
1250    void qsamplerMainForm::viewInstruments (void)
1251    {
1252            if (m_pOptions == NULL)
1253                    return;
1254    
1255            if (m_pInstrumentListForm) {
1256                    m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
1257                    if (m_pInstrumentListForm->isVisible()) {
1258                            m_pInstrumentListForm->hide();
1259                    } else {
1260                            m_pInstrumentListForm->show();
1261                            m_pInstrumentListForm->raise();
1262                            m_pInstrumentListForm->setActiveWindow();
1263                    }
1264            }
1265    }
1266    
1267    
1268    // Show/hide the device configurator form.
1269    void qsamplerMainForm::viewDevices (void)
1270    {
1271            if (m_pOptions == NULL)
1272                    return;
1273    
1274            if (m_pDeviceForm) {
1275                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1276                    if (m_pDeviceForm->isVisible()) {
1277                            m_pDeviceForm->hide();
1278                    } else {
1279                            m_pDeviceForm->show();
1280                            m_pDeviceForm->raise();
1281                            m_pDeviceForm->setActiveWindow();
1282                    }
1283            }
1284    }
1285    
1286    
1287  // Show options dialog.  // Show options dialog.
1288  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1289  {  {
# Line 886  void qsamplerMainForm::viewOptions (void Line 1293  void qsamplerMainForm::viewOptions (void
1293      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);
1294      if (pOptionsForm) {      if (pOptionsForm) {
1295          // Check out some initial nullities(tm)...          // Check out some initial nullities(tm)...
1296          qsamplerChannelStrip *pChannel = activeChannel();          qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1297          if (m_pOptions->sDisplayFont.isEmpty() && pChannel)          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1298              m_pOptions->sDisplayFont = pChannel->displayFont().toString();              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1299          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1300              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1301          // To track down deferred or immediate changes.          // To track down deferred or immediate changes.
# Line 898  void qsamplerMainForm::viewOptions (void Line 1305  void qsamplerMainForm::viewOptions (void
1305          bool    bOldServerStart     = m_pOptions->bServerStart;          bool    bOldServerStart     = m_pOptions->bServerStart;
1306          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1307          QString sOldDisplayFont     = m_pOptions->sDisplayFont;          QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1308            bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1309          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1310          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1311            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1312          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1313          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1314          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1315          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1316            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1317          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1318          // Load the current setup settings.          // Load the current setup settings.
1319          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 911  void qsamplerMainForm::viewOptions (void Line 1321  void qsamplerMainForm::viewOptions (void
1321          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1322              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1323              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1324                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1325                  QMessageBox::information(this, tr("Information"),                  ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1326                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1327                    QMessageBox::information(this,
1328                                            QSAMPLER_TITLE ": " + tr("Information"),
1329                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1330                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
1331                  updateMessagesCapture();                  updateMessagesCapture();
# Line 922  void qsamplerMainForm::viewOptions (void Line 1335  void qsamplerMainForm::viewOptions (void
1335                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1336                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1337                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1338                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1339                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1340                    updateInstrumentNames();
1341                if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1342                    (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1343                    updateDisplayEffect();
1344              if (sOldDisplayFont != m_pOptions->sDisplayFont)              if (sOldDisplayFont != m_pOptions->sDisplayFont)
1345                  updateDisplayFont();                  updateDisplayFont();
1346              if (iOldMaxVolume != m_pOptions->iMaxVolume)              if (iOldMaxVolume != m_pOptions->iMaxVolume)
# Line 964  void qsamplerMainForm::channelsArrange ( Line 1383  void qsamplerMainForm::channelsArrange (
1383      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1384      int y = 0;      int y = 0;
1385      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1386          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1387      /*  if (pChannel->testWState(WState_Maximized | WState_Minimized)) {      /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1388              // Prevent flicker...              // Prevent flicker...
1389              pChannel->hide();              pChannelStrip->hide();
1390              pChannel->showNormal();              pChannelStrip->showNormal();
1391          }   */          }   */
1392          pChannel->adjustSize();          pChannelStrip->adjustSize();
1393          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1394          if (iWidth < pChannel->width())          if (iWidth < pChannelStrip->width())
1395              iWidth = pChannel->width();              iWidth = pChannelStrip->width();
1396      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1397          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1398          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1399          y += iHeight;          y += iHeight;
1400      }      }
1401      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1402        
1403      stabilizeForm();      stabilizeForm();
1404  }  }
1405    
# Line 1029  void qsamplerMainForm::helpAbout (void) Line 1448  void qsamplerMainForm::helpAbout (void)
1448      sText += tr("GIG (libgig) file support disabled.");      sText += tr("GIG (libgig) file support disabled.");
1449      sText += "</font></small><br />";      sText += "</font></small><br />";
1450  #endif  #endif
1451    #ifndef CONFIG_INSTRUMENT_NAME
1452        sText += "<small><font color=\"red\">";
1453        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1454        sText += "</font></small><br />";
1455    #endif
1456    #ifndef CONFIG_MUTE_SOLO
1457        sText += "<small><font color=\"red\">";
1458        sText += tr("Sampler channel Mute/Solo support disabled.");
1459        sText += "</font></small><br />";
1460    #endif
1461    #ifndef CONFIG_MIDI_INSTRUMENT
1462        sText += "<small><font color=\"red\">";
1463        sText += tr("MIDI instrument mapping support disabled.");
1464        sText += "</font></small><br />";
1465    #endif
1466      sText += "<br />\n";      sText += "<br />\n";
1467      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1468      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1469      sText += " ";      sText += " ";
1470      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1471    #ifdef CONFIG_LIBGIG
1472        sText += ", ";
1473        sText += gig::libraryName().c_str();
1474        sText += " ";
1475        sText += gig::libraryVersion().c_str();
1476    #endif
1477      sText += "<br />\n";      sText += "<br />\n";
1478      sText += "<br />\n";      sText += "<br />\n";
1479      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 1496  void qsamplerMainForm::helpAbout (void)
1496  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1497  {  {
1498      // Update the main application caption...      // Update the main application caption...
1499      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1500      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1501          sSessioName += '*';          sSessionName += " *";
1502      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1503    
1504      // Update the main menu state...      // Update the main menu state...
1505      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1506      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1507      bool bHasChannel = (bHasClient && pChannel != NULL);      bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1508      fileNewAction->setEnabled(bHasClient);      fileNewAction->setEnabled(bHasClient);
1509      fileOpenAction->setEnabled(bHasClient);      fileOpenAction->setEnabled(bHasClient);
1510      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1511      fileSaveAsAction->setEnabled(bHasClient);      fileSaveAsAction->setEnabled(bHasClient);
1512        fileResetAction->setEnabled(bHasClient);
1513      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1514      editAddChannelAction->setEnabled(bHasClient);      editAddChannelAction->setEnabled(bHasClient);
1515      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1516      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1517      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1518      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1519      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1520    #ifdef CONFIG_MIDI_INSTRUMENT
1521            viewInstrumentsAction->setOn(m_pInstrumentListForm
1522                    && m_pInstrumentListForm->isVisible());
1523            viewInstrumentsAction->setEnabled(bHasClient);
1524    #endif
1525            viewDevicesAction->setOn(m_pDeviceForm
1526                    && m_pDeviceForm->isVisible());
1527        viewDevicesAction->setEnabled(bHasClient);
1528        channelsArrangeAction->setEnabled(bHasChannel);
1529    
1530      // Client/Server status...      // Client/Server status...
1531      if (bHasClient) {      if (bHasClient) {
1532          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1533          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));
1534      } else {      } else {
1535          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1536          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1537      }      }
1538      // Channel status...      // Channel status...
1539      if (bHasChannel)      if (bHasChannel)
1540          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannel->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1541      else      else
1542          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1543      // Session status...      // Session status...
1544      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1545          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1546      else      else
1547          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1548    
1549      // Recent files menu.      // Recent files menu.
1550      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 1556  void qsamplerMainForm::stabilizeForm (vo
1556    
1557    
1558  // Channel change receiver slot.  // Channel change receiver slot.
1559  void qsamplerMainForm::channelChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1560  {  {
1561            // Add this strip to the changed list...
1562            if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1563                    m_changedStrips.append(pChannelStrip);
1564                    pChannelStrip->resetErrorCount();
1565            }
1566    
1567      // Just mark the dirty form.      // Just mark the dirty form.
1568      m_iDirtyCount++;      m_iDirtyCount++;
1569      // and update the form status...      // and update the form status...
# Line 1115  void qsamplerMainForm::channelChanged( q Line 1571  void qsamplerMainForm::channelChanged( q
1571  }  }
1572    
1573    
1574    // Grab and restore current sampler channels session.
1575    void qsamplerMainForm::updateSession (void)
1576    {
1577    #ifdef CONFIG_MIDI_INSTRUMENT
1578            // FIXME Make some room for default instrument maps...
1579            int iMaps = ::lscp_get_midi_instrument_maps(m_pClient);
1580            if (iMaps < 0)
1581                    appendMessagesClient("lscp_get_midi_instrument_maps");
1582            else if (iMaps < 1) {
1583                    ::lscp_add_midi_instrument_map(m_pClient, tr("Chromatic").latin1());
1584                    ::lscp_add_midi_instrument_map(m_pClient, tr("Drum Kits").latin1());
1585            }
1586    #endif
1587    
1588            // Retrieve the current channel list.
1589            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1590            if (piChannelIDs == NULL) {
1591                    if (::lscp_client_get_errno(m_pClient)) {
1592                            appendMessagesClient("lscp_list_channels");
1593                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1594                    }
1595                    return;
1596            }
1597    
1598            // Try to (re)create each channel.
1599            m_pWorkspace->setUpdatesEnabled(false);
1600            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1601                    // Check if theres already a channel strip for this one...
1602                    if (!channelStrip(piChannelIDs[iChannel]))
1603                            createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));
1604                    // Make it visibly responsive...
1605                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1606            }
1607            m_pWorkspace->setUpdatesEnabled(true);
1608    
1609            // Remember to refresh devices and instruments...
1610            if (m_pInstrumentListForm)
1611                m_pInstrumentListForm->refreshInstruments();
1612            if (m_pDeviceForm)
1613                m_pDeviceForm->refreshDevices();
1614    }
1615    
1616    
1617  // Update the recent files list and menu.  // Update the recent files list and menu.
1618  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1619  {  {
# Line 1159  void qsamplerMainForm::updateRecentFiles Line 1658  void qsamplerMainForm::updateRecentFiles
1658  }  }
1659    
1660    
1661    // Force update of the channels instrument names mode.
1662    void qsamplerMainForm::updateInstrumentNames (void)
1663    {
1664        // Full channel list update...
1665        QWidgetList wlist = m_pWorkspace->windowList();
1666        if (wlist.isEmpty())
1667            return;
1668    
1669        m_pWorkspace->setUpdatesEnabled(false);
1670        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1671            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1672            if (pChannelStrip)
1673                pChannelStrip->updateInstrumentName(true);
1674        }
1675        m_pWorkspace->setUpdatesEnabled(true);
1676    }
1677    
1678    
1679  // Force update of the channels display font.  // Force update of the channels display font.
1680  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1681  {  {
# Line 1180  void qsamplerMainForm::updateDisplayFont Line 1697  void qsamplerMainForm::updateDisplayFont
1697    
1698      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1699      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1700          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1701          pChannel->setDisplayFont(font);          if (pChannelStrip)
1702                pChannelStrip->setDisplayFont(font);
1703        }
1704        m_pWorkspace->setUpdatesEnabled(true);
1705    }
1706    
1707    
1708    // Update channel strips background effect.
1709    void qsamplerMainForm::updateDisplayEffect (void)
1710    {
1711       QPixmap pm;
1712        if (m_pOptions->bDisplayEffect)
1713            pm = QPixmap::fromMimeSource("displaybg1.png");
1714    
1715        // Full channel list update...
1716        QWidgetList wlist = m_pWorkspace->windowList();
1717        if (wlist.isEmpty())
1718            return;
1719    
1720        m_pWorkspace->setUpdatesEnabled(false);
1721        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1722            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1723            if (pChannelStrip)
1724                pChannelStrip->setDisplayBackground(pm);
1725      }      }
1726      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1727  }  }
# Line 1200  void qsamplerMainForm::updateMaxVolume ( Line 1740  void qsamplerMainForm::updateMaxVolume (
1740    
1741      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1742      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1743          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1744          pChannel->setMaxVolume(m_pOptions->iMaxVolume);          if (pChannelStrip)
1745                pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1746      }      }
1747      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1748  }  }
# Line 1240  void qsamplerMainForm::appendMessagesErr Line 1781  void qsamplerMainForm::appendMessagesErr
1781    
1782      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");      appendMessagesColor(s.simplifyWhiteSpace(), "#ff0000");
1783    
1784      QMessageBox::critical(this, tr("Error"), s, tr("Cancel"));      QMessageBox::critical(this,
1785                    QSAMPLER_TITLE ": " + tr("Error"), s, tr("Cancel"));
1786  }  }
1787    
1788    
# Line 1280  void qsamplerMainForm::updateMessagesLim Line 1822  void qsamplerMainForm::updateMessagesLim
1822          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1823              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1824          else          else
1825              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1826      }      }
1827  }  }
1828    
# Line 1300  void qsamplerMainForm::updateMessagesCap Line 1842  void qsamplerMainForm::updateMessagesCap
1842  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
1843    
1844  // The channel strip creation executive.  // The channel strip creation executive.
1845  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
1846  {  {
1847      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
1848          return;          return NULL;
1849    
1850      // Prepare for auto-arrange?      // Prepare for auto-arrange?
1851      qsamplerChannelStrip *pChannel = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
1852      int y = 0;      int y = 0;
1853      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1854          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1855          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1856              pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1857          //  y += pChannel->height() + pChannel->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1858              y += pChannel->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1859                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1860                            }
1861          }          }
1862      }      }
1863    
1864      // Add a new channel itema...      // Add a new channel itema...
1865      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;
1866      pChannel = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1867      pChannel->setMaxVolume(m_pOptions->iMaxVolume);      if (pChannelStrip == NULL)
1868      pChannel->setup(this, iChannelID);          return NULL;
1869      // We'll need a display font.  
1870      QFont font;      // Actual channel strip setup...
1871      if (m_pOptions && font.fromString(m_pOptions->sDisplayFont))      pChannelStrip->setup(pChannel);
1872          pChannel->setDisplayFont(font);      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
1873      // Track channel setup changes.      // Set some initial aesthetic options...
1874      QObject::connect(pChannel, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelChanged(qsamplerChannelStrip *)));      if (m_pOptions) {
1875      // Before we show it up, may be we'll          // Background display effect...
1876      // better ask for some initial values?          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
1877      if (bPrompt)          // We'll need a display font.
1878          pChannel->channelSetup(true);          QFont font;
1879            if (font.fromString(m_pOptions->sDisplayFont))
1880                pChannelStrip->setDisplayFont(font);
1881            // Maximum allowed volume setting.
1882            pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1883        }
1884    
1885      // Now we show up us to the world.      // Now we show up us to the world.
1886      pChannel->show();      pChannelStrip->show();
1887      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
1888      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1889          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1890      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();
1891          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1892          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1893      }      }
1894    
1895            // This is pretty new, so we'll watch for it closely.
1896            channelStripChanged(pChannelStrip);
1897    
1898        // Return our successful reference...
1899        return pChannelStrip;
1900  }  }
1901    
1902    
1903  // Retrieve the active channel strip.  // Retrieve the active channel strip.
1904  qsamplerChannelStrip *qsamplerMainForm::activeChannel (void)  qsamplerChannelStrip *qsamplerMainForm::activeChannelStrip (void)
1905  {  {
1906      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();
1907  }  }
1908    
1909    
1910  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
1911  qsamplerChannelStrip *qsamplerMainForm::channelAt ( int iChannel )  qsamplerChannelStrip *qsamplerMainForm::channelStripAt ( int iChannel )
1912  {  {
1913      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1914      if (wlist.isEmpty())      if (wlist.isEmpty())
1915          return 0;          return NULL;
1916    
1917      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1918  }  }
1919    
1920    
1921    // Retrieve a channel strip by sampler channel id.
1922    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1923    {
1924            QWidgetList wlist = m_pWorkspace->windowList();
1925            if (wlist.isEmpty())
1926                    return NULL;
1927    
1928            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1929                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1930                    if (pChannelStrip) {
1931                            qsamplerChannel *pChannel = pChannelStrip->channel();
1932                            if (pChannel && pChannel->channelID() == iChannelID)
1933                                    return pChannelStrip;
1934                    }
1935            }
1936    
1937            // Not found.
1938            return NULL;
1939    }
1940    
1941    
1942  // Construct the windows menu.  // Construct the windows menu.
1943  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1944  {  {
# Line 1373  void qsamplerMainForm::channelsMenuAbout Line 1950  void qsamplerMainForm::channelsMenuAbout
1950      if (!wlist.isEmpty()) {      if (!wlist.isEmpty()) {
1951          channelsMenu->insertSeparator();          channelsMenu->insertSeparator();
1952          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1953              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1954              int iItemID = channelsMenu->insertItem(pChannel->caption(), this, SLOT(channelsMenuActivated(int)));              if (pChannelStrip) {
1955              channelsMenu->setItemParameter(iItemID, iChannel);                  int iItemID = channelsMenu->insertItem(pChannelStrip->caption(), this, SLOT(channelsMenuActivated(int)));
1956              channelsMenu->setItemChecked(iItemID, activeChannel() == pChannel);                  channelsMenu->setItemParameter(iItemID, iChannel);
1957                    channelsMenu->setItemChecked(iItemID, activeChannelStrip() == pChannelStrip);
1958                }
1959          }          }
1960      }      }
1961  }  }
# Line 1385  void qsamplerMainForm::channelsMenuAbout Line 1964  void qsamplerMainForm::channelsMenuAbout
1964  // Windows menu activation slot  // Windows menu activation slot
1965  void qsamplerMainForm::channelsMenuActivated ( int iChannel )  void qsamplerMainForm::channelsMenuActivated ( int iChannel )
1966  {  {
1967      qsamplerChannelStrip *pChannel = channelAt(iChannel);      qsamplerChannelStrip *pChannelStrip = channelStripAt(iChannel);
1968      if (pChannel)      if (pChannelStrip)
1969          pChannel->showNormal();          pChannelStrip->showNormal();
1970      pChannel->setFocus();      pChannelStrip->setFocus();
1971  }  }
1972    
1973    
# Line 1426  void qsamplerMainForm::timerSlot (void) Line 2005  void qsamplerMainForm::timerSlot (void)
2005              }              }
2006          }          }
2007      }      }
2008        
2009          // Refresh each channel usage, on each period...          if (m_pClient) {
2010      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {                  // Update the channel information for each pending strip...
2011          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  if (m_changedStrips.count() > 0) {
2012          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
2013              m_iTimerSlot = 0;                                          pChannelStrip; pChannelStrip = m_changedStrips.next()) {
2014              QWidgetList wlist = m_pWorkspace->windowList();                                  // If successfull, remove from pending list...
2015              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                                  if (pChannelStrip->updateChannelInfo())
2016                  qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);                                          m_changedStrips.remove(pChannelStrip);
2017                  if (pChannel->isVisible())                          }
2018                      pChannel->updateChannelUsage();                  }
2019              }                  // Refresh each channel usage, on each period...
2020          }                  if (m_pOptions->bAutoRefresh) {
2021      }                          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
2022                            if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {
2023                                    m_iTimerSlot = 0;
2024                                    // Update the channel stream usage for each strip...
2025                                    QWidgetList wlist = m_pWorkspace->windowList();
2026                                    for (int iChannel = 0;
2027                                                    iChannel < (int) wlist.count(); iChannel++) {
2028                                            qsamplerChannelStrip *pChannelStrip
2029                                                    = (qsamplerChannelStrip *) wlist.at(iChannel);
2030                                            if (pChannelStrip && pChannelStrip->isVisible())
2031                                                    pChannelStrip->updateChannelUsage();
2032                                    }
2033                            }
2034                    }
2035            }
2036    
2037      // Register the next timer slot.      // Register the next timer slot.
2038      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1461  void qsamplerMainForm::startServer (void Line 2054  void qsamplerMainForm::startServer (void
2054    
2055      // Is the server process instance still here?      // Is the server process instance still here?
2056      if (m_pServer) {      if (m_pServer) {
2057          switch (QMessageBox::warning(this, tr("Warning"),          switch (QMessageBox::warning(this,
2058                            QSAMPLER_TITLE ": " + tr("Warning"),
2059              tr("Could not start the LinuxSampler server.\n\n"              tr("Could not start the LinuxSampler server.\n\n"
2060                 "Maybe it ss already started."),                 "Maybe it ss already started."),
2061              tr("Stop"), tr("Kill"), tr("Cancel"))) {              tr("Stop"), tr("Kill"), tr("Cancel"))) {
# Line 1620  bool qsamplerMainForm::startClient (void Line 2214  bool qsamplerMainForm::startClient (void
2214      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);      ::lscp_client_set_timeout(m_pClient, m_pOptions->iServerTimeout);
2215      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)));
2216    
2217            // Subscribe to channel info change notifications...
2218            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2219                    appendMessagesClient("lscp_client_subscribe");
2220    
2221      // We may stop scheduling around.      // We may stop scheduling around.
2222      stopSchedule();      stopSchedule();
2223    
# Line 1629  bool qsamplerMainForm::startClient (void Line 2227  bool qsamplerMainForm::startClient (void
2227      // Log success here.      // Log success here.
2228      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2229    
2230            // Hard-notify instrumnet and device configuration forms,
2231            // if visible, that we're ready...
2232            if (m_pInstrumentListForm)
2233                m_pInstrumentListForm->refreshInstruments();
2234            if (m_pDeviceForm)
2235                m_pDeviceForm->refreshDevices();
2236    
2237      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2238      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2239          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1663  void qsamplerMainForm::stopClient (void) Line 2268  void qsamplerMainForm::stopClient (void)
2268      // channels from the back-end server.      // channels from the back-end server.
2269      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2270      closeSession(false);      closeSession(false);
2271        
2272      // Close us as a client...      // Close us as a client...
2273      lscp_client_destroy(m_pClient);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2274        ::lscp_client_destroy(m_pClient);
2275      m_pClient = NULL;      m_pClient = NULL;
2276    
2277            // Hard-notify instrumnet and device configuration forms,
2278            // if visible, that we're running out...
2279            if (m_pInstrumentListForm)
2280                m_pInstrumentListForm->refreshInstruments();
2281            if (m_pDeviceForm)
2282                m_pDeviceForm->refreshDevices();
2283    
2284      // Log final here.      // Log final here.
2285      appendMessages(tr("Client disconnected."));      appendMessages(tr("Client disconnected."));
2286    

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

  ViewVC Help
Powered by ViewVC