/[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 149 by capela, Sat Jun 26 14:27:25 2004 UTC revision 661 by capela, Fri Jun 17 22:43:56 2005 UTC
# Line 2  Line 2 
2  //  //
3  // ui.h extension file, included from the uic-generated form implementation.  // ui.h extension file, included from the uic-generated form implementation.
4  /****************************************************************************  /****************************************************************************
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2005, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 26  Line 26 
26  #include <qprocess.h>  #include <qprocess.h>
27  #include <qmessagebox.h>  #include <qmessagebox.h>
28  #include <qdragobject.h>  #include <qdragobject.h>
29    #include <qregexp.h>
30  #include <qfiledialog.h>  #include <qfiledialog.h>
31  #include <qfileinfo.h>  #include <qfileinfo.h>
32  #include <qfile.h>  #include <qfile.h>
# Line 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    
45    #include "qsamplerDeviceForm.h"
46  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
47    
48  #include "config.h"  #include "config.h"
49    
50    #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 100  void qsamplerMainForm::init (void) Line 111  void qsamplerMainForm::init (void)
111      m_pOptions = NULL;      m_pOptions = NULL;
112    
113      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
114      m_pMessages = NULL;      m_pMessages   = NULL;
115        m_pDeviceForm = NULL;
116    
117      // We'll start clean.      // We'll start clean.
118      m_iUntitled = 0;      m_iUntitled   = 0;
119      m_iDirtyCount = 0;      m_iDirtyCount = 0;
120    
121      m_pServer = NULL;      m_pServer = NULL;
# Line 114  void qsamplerMainForm::init (void) Line 126  void qsamplerMainForm::init (void)
126    
127      m_iTimerSlot = 0;      m_iTimerSlot = 0;
128    
129    #ifdef HAVE_SIGNAL_H
130            // Set to ignore any fatal "Broken pipe" signals.
131            ::signal(SIGPIPE, SIG_IGN);
132    #endif
133    
134      // Make it an MDI workspace.      // Make it an MDI workspace.
135      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
136      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
# Line 128  void qsamplerMainForm::init (void) Line 145  void qsamplerMainForm::init (void)
145      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
146      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
147      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
148      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
149      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
150      // Server address.      // Server address.
151      pLabel = new QLabel(this);      pLabel = new QLabel(this);
152      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
153      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
154      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
155      // Channel title.      // Channel title.
156      pLabel = new QLabel(this);      pLabel = new QLabel(this);
157      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
158      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
159      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
160      // Session modification status.      // Session modification status.
161      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
162      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
163      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
164      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
165      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
166    
167      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 163  void qsamplerMainForm::destroy (void) Line 180  void qsamplerMainForm::destroy (void)
180  {  {
181      // Do final processing anyway.      // Do final processing anyway.
182      processServerExit();      processServerExit();
183        
184      // Delete recentfiles menu.  #if defined(WIN32)
185      if (m_pRecentFilesMenu)      WSACleanup();
186          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];  
187    
188      // Finally drop any widgets around...      // Finally drop any widgets around...
189        if (m_pDeviceForm)
190            delete m_pDeviceForm;
191      if (m_pMessages)      if (m_pMessages)
192          delete m_pMessages;          delete m_pMessages;
193      if (m_pWorkspace)      if (m_pWorkspace)
194          delete m_pWorkspace;          delete m_pWorkspace;
195    
196  #if defined(WIN32)      // Delete status item labels one by one.
197      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
198  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
199        if (m_statusItem[QSAMPLER_STATUS_SERVER])
200            delete m_statusItem[QSAMPLER_STATUS_SERVER];
201        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
202            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
203        if (m_statusItem[QSAMPLER_STATUS_SESSION])
204            delete m_statusItem[QSAMPLER_STATUS_SESSION];
205    
206        // Delete recentfiles menu.
207        if (m_pRecentFilesMenu)
208            delete m_pRecentFilesMenu;
209  }  }
210    
211    
# Line 195  void qsamplerMainForm::setup ( qsamplerO Line 215  void qsamplerMainForm::setup ( qsamplerO
215      // We got options?      // We got options?
216      m_pOptions = pOptions;      m_pOptions = pOptions;
217    
218        // What style do we create these forms?
219        WFlags wflags = Qt::WType_TopLevel;
220        if (m_pOptions->bKeepOnTop)
221            wflags |= Qt::WStyle_Tool;
222      // Some child forms are to be created right now.      // Some child forms are to be created right now.
223      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
224        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
225        m_pDeviceForm->setMainForm(this); // An important life immutable!
226      // Set message defaults...      // Set message defaults...
227      updateMessagesFont();      updateMessagesFont();
228      updateMessagesLimit();      updateMessagesLimit();
# Line 225  void qsamplerMainForm::setup ( qsamplerO Line 251  void qsamplerMainForm::setup ( qsamplerO
251          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
252          istr >> *this;          istr >> *this;
253      }      }
254      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
255      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
256        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
257    
258      // Final startup stabilization...      // Final startup stabilization...
259      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 264  bool qsamplerMainForm::queryClose (void) Line 291  bool qsamplerMainForm::queryClose (void)
291              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
292              ostr << *this;              ostr << *this;
293              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
294              // And the main windows state.              // And the children, and the main windows state,.
295              m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
296                            m_pOptions->saveWidgetGeometry(this);
297                            // Close popup widgets.
298                            if (m_pDeviceForm)
299                                    m_pDeviceForm->close();
300              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
301              stopServer();              stopServer();
302          }          }
# Line 284  void qsamplerMainForm::closeEvent ( QClo Line 315  void qsamplerMainForm::closeEvent ( QClo
315  }  }
316    
317    
318  // Window drag-n-drop event handlers.  // Drag'n'drop file handler.
319  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
320  {  {
321      bool bAccept = false;      bool bDecode = false;
322    
323      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
324          QString sUrl;          QString sText;
325          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
326              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
327                files = QStringList::split('\n', sText);
328                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
329                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
330            }
331      }      }
332    
333      pDragEnterEvent->accept(bAccept);      return bDecode;
334    }
335    
336    
337    // Window drag-n-drop event handlers.
338    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
339    {
340            QStringList files;
341            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
342  }  }
343    
344    
345  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
346  {  {
347      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
348          QString sUrl;  
349          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
350              loadSessionFile(QUrl(sUrl).path());          return;
351      }  
352            for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
353                    const QString& sPath = *iter;
354                    if (qsamplerChannel::isInstrumentFile(sPath)) {
355                            // Try to create a new channel from instrument file...
356                            qsamplerChannel *pChannel = new qsamplerChannel(this);
357                            if (pChannel == NULL)
358                                    return;
359                            // Start setting the instrument filename...
360                            pChannel->setInstrument(sPath, 0);
361                            // Before we show it up, may be we'll
362                            // better ask for some initial values?
363                            if (!pChannel->channelSetup(this)) {
364                                    delete pChannel;
365                                    return;
366                            }
367                            // Finally, give it to a new channel strip...
368                            if (!createChannelStrip(pChannel)) {
369                                    delete pChannel;
370                                    return;
371                            }
372                            // Make that an overall update.
373                            m_iDirtyCount++;
374                            stabilizeForm();
375                    }   // Otherwise, load an usual session file (LSCP script)...
376                    else if (closeSession(true))
377                            loadSessionFile(sPath);
378                    // Make it look responsive...:)
379                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
380            }
381  }  }
382    
383    
# Line 326  void qsamplerMainForm::customEvent ( QCu Line 398  void qsamplerMainForm::customEvent ( QCu
398  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
399  {  {
400      stabilizeForm();      stabilizeForm();
401        
402      editMenu->exec(pEvent->globalPos());      editMenu->exec(pEvent->globalPos());
403  }  }
404    
# Line 370  bool qsamplerMainForm::newSession (void) Line 442  bool qsamplerMainForm::newSession (void)
442      if (!closeSession(true))      if (!closeSession(true))
443          return false;          return false;
444    
445            // Give us what the server has, right now...
446            updateSession();
447    
448      // Ok increment untitled count.      // Ok increment untitled count.
449      m_iUntitled++;      m_iUntitled++;
450    
# Line 483  bool qsamplerMainForm::closeSession ( bo Line 558  bool qsamplerMainForm::closeSession ( bo
558          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
559          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
560          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
561              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
562              if (bForce && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)              if (pChannelStrip) {
563                  appendMessagesClient("lscp_remove_channel");                  qsamplerChannel *pChannel = pChannelStrip->channel();
564              delete pChannel;                  if (bForce && pChannel)
565                        pChannel->removeChannel();
566                    delete pChannelStrip;
567                }
568          }          }
569          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
570          // We're now clean, for sure.          // We're now clean, for sure.
# Line 534  bool qsamplerMainForm::loadSessionFile ( Line 612  bool qsamplerMainForm::loadSessionFile (
612      // Ok. we've read it.      // Ok. we've read it.
613      file.close();      file.close();
614    
615      // Have we any errors?          // Now we'll try to create (update) the whole GUI session.
616      if (iErrors > 0)          updateSession();
         appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));  
617    
618      // Now we'll try to create the whole GUI session.          // Have we any errors?
619      int iChannels = ::lscp_get_channels(m_pClient);          if (iErrors > 0)
620      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);  
621    
622      // Save as default session directory.      // Save as default session directory.
623      if (m_pOptions)      if (m_pOptions)
624          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);          m_pOptions->sSessionDir = QFileInfo(sFilename).dirPath(true);
625      // We're not dirty anymore.          // We're not dirty anymore, if loaded without errors,
626      m_iDirtyCount = 0;          m_iDirtyCount = iErrors;
627      // Stabilize form...      // Stabilize form...
628      m_sFilename = sFilename;      m_sFilename = sFilename;
629      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
630      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
631    
632        // Make that an overall update.
633      stabilizeForm();      stabilizeForm();
634      return true;      return true;
635  }  }
# Line 578  bool qsamplerMainForm::saveSessionFile ( Line 646  bool qsamplerMainForm::saveSessionFile (
646      }      }
647    
648      // Write the file.      // Write the file.
649      int iErrors = 0;      int  iErrors = 0;
650      QTextStream ts(&file);      QTextStream ts(&file);
651      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
652      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 589  bool qsamplerMainForm::saveSessionFile ( Line 657  bool qsamplerMainForm::saveSessionFile (
657      ts << "# " << tr("File")      ts << "# " << tr("File")
658         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
659      ts << "# " << tr("Date")      ts << "# " << tr("Date")
660         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
661         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
662      ts << "#"  << endl;      ts << "#"  << endl;
663      ts << endl;      ts << endl;
664            // It is assumed that this new kind of device+session file
665            // will be loaded from a complete
666            int *piDeviceIDs;
667            int  iDevice;
668            ts << "RESET" << endl;
669            // Audio device mapping.
670            QMap<int, int> audioDeviceMap;
671            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
672            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
673                    ts << endl;
674                    qsamplerDevice device(this, qsamplerDevice::Audio, piDeviceIDs[iDevice]);
675                    // Audio device specification...
676                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
677                            << " " << tr("Device") << " " << iDevice << endl;
678                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
679                    qsamplerDeviceParamMap::ConstIterator deviceParam;
680                    for (deviceParam = device.params().begin();
681                                    deviceParam != device.params().end();
682                                            ++deviceParam) {
683                            const qsamplerDeviceParam& param = deviceParam.data();
684                            if (param.value.isEmpty()) ts << "# ";
685                            ts << " " << deviceParam.key() << "='" << param.value << "'";
686                    }
687                    ts << endl;
688                    // Audio channel parameters...
689                    int iPort = 0;
690                    for (qsamplerDevicePort *pPort = device.ports().first();
691                                    pPort;
692                                            pPort = device.ports().next(), ++iPort) {
693                            qsamplerDeviceParamMap::ConstIterator portParam;
694                            for (portParam = pPort->params().begin();
695                                            portParam != pPort->params().end();
696                                                    ++portParam) {
697                                    const qsamplerDeviceParam& param = portParam.data();
698                                    if (param.fix || param.value.isEmpty()) ts << "# ";
699                                    ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
700                                            << " " << iPort << " " << portParam.key()
701                                            << "='" << param.value << "'" << endl;
702                            }
703                    }
704                    // Audio device index/id mapping.
705                    audioDeviceMap[device.deviceID()] = iDevice;
706            // Try to keep it snappy :)
707            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
708            }
709            // MIDI device mapping.
710            QMap<int, int> midiDeviceMap;
711            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
712            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
713                    ts << endl;
714                    qsamplerDevice device(this, qsamplerDevice::Midi, piDeviceIDs[iDevice]);
715                    // MIDI device specification...
716                    ts << "# " << device.deviceTypeName() << " " << device.driverName()
717                            << " " << tr("Device") << " " << iDevice << endl;
718                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
719                    qsamplerDeviceParamMap::ConstIterator deviceParam;
720                    for (deviceParam = device.params().begin();
721                                    deviceParam != device.params().end();
722                                            ++deviceParam) {
723                            const qsamplerDeviceParam& param = deviceParam.data();
724                            if (param.value.isEmpty()) ts << "# ";
725                            ts << " " << deviceParam.key() << "='" << param.value << "'";
726                    }
727                    ts << endl;
728                    // MIDI port parameters...
729                    int iPort = 0;
730                    for (qsamplerDevicePort *pPort = device.ports().first();
731                                    pPort;
732                                            pPort = device.ports().next(), ++iPort) {
733                            qsamplerDeviceParamMap::ConstIterator portParam;
734                            for (portParam = pPort->params().begin();
735                                            portParam != pPort->params().end();
736                                                    ++portParam) {
737                                    const qsamplerDeviceParam& param = portParam.data();
738                                    if (param.fix || param.value.isEmpty()) ts << "# ";
739                                    ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
740                                       << " " << iPort << " " << portParam.key()
741                                       << "='" << param.value << "'" << endl;
742                            }
743                    }
744                    // MIDI device index/id mapping.
745                    midiDeviceMap[device.deviceID()] = iDevice;
746            // Try to keep it snappy :)
747            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
748            }
749            ts << endl;
750            // Sampler channel mapping.
751      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
752      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
753          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
754          int iChannelID = pChannel->channelID();          if (pChannelStrip) {
755          ts << "# " << pChannel->caption() << endl;              qsamplerChannel *pChannel = pChannelStrip->channel();
756          ts << "ADD CHANNEL" << endl;              if (pChannel) {
757          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                  ts << "# " << tr("Channel") << " " << iChannel << endl;
758          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                  ts << "ADD CHANNEL" << endl;
759      //  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                                  if (audioDeviceMap.isEmpty()) {
760          ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " " << pChannel->midiChannel() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
761          ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                                                  << " " << pChannel->audioDriver() << endl;
762          ts << "LOAD INSTRUMENT NON_MODAL " << pChannel->instrumentFile() << " " << pChannel->instrumentNr() << " " << iChannelID << endl;                                  } else {
763          ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
764          ts << endl;                                                  << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
765                                    }
766                                    if (midiDeviceMap.isEmpty()) {
767                                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
768                                                    << " " << pChannel->midiDriver() << endl;
769                                    } else {
770                                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
771                                                    << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
772                                    }
773                                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
774                                            << " " << pChannel->midiPort() << endl;
775                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
776                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
777                        ts << "ALL";
778                    else
779                        ts << pChannel->midiChannel();
780                    ts << endl;
781                    ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
782                    ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannel << endl;
783                    ts << "SET CHANNEL VOLUME " << iChannel << " " << pChannel->volume() << endl;
784                    ts << endl;
785                }
786            }
787          // Try to keep it snappy :)          // Try to keep it snappy :)
788          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
789      }      }
# Line 632  bool qsamplerMainForm::saveSessionFile ( Line 809  bool qsamplerMainForm::saveSessionFile (
809  }  }
810    
811    
812    // Session change receiver slot.
813    void qsamplerMainForm::sessionDirty (void)
814    {
815        // Just mark the dirty form.
816        m_iDirtyCount++;
817        // and update the form status...
818        stabilizeForm();
819    }
820    
821    
822  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
823  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
824    
# Line 678  void qsamplerMainForm::fileSaveAs (void) Line 865  void qsamplerMainForm::fileSaveAs (void)
865  }  }
866    
867    
868    // Reset the sampler instance.
869    void qsamplerMainForm::fileReset (void)
870    {
871        if (m_pClient == NULL)
872            return;
873    
874        // Ask user whether he/she want's an internal sampler reset...
875        if (QMessageBox::warning(this, tr("Warning"),
876            tr("Resetting the sampler instance will close\n"
877               "all device and channel configurations.\n\n"
878               "Please note that this operation may cause\n"
879               "temporary MIDI and Audio disruption.\n\n"
880               "Do you want to reset the sampler engine now?"),
881            tr("Reset"), tr("Cancel")) > 0)
882            return;
883    
884        // Just do the reset, after closing down current session...
885        if (closeSession(true) && ::lscp_reset_sampler(m_pClient) != LSCP_OK) {
886            appendMessagesClient("lscp_reset_sampler");
887            appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
888            return;
889        }
890    
891        // Log this.
892        appendMessages(tr("Sampler reset."));
893    
894            // Make it a new session...
895            newSession();
896    }
897    
898    
899  // Restart the client/server instance.  // Restart the client/server instance.
900  void qsamplerMainForm::fileRestart (void)  void qsamplerMainForm::fileRestart (void)
901  {  {
902      if (m_pOptions == NULL)      if (m_pOptions == NULL)
903          return;          return;
904            
905      bool bRestart = true;      bool bRestart = true;
906        
907      // Ask user whether he/she want's a complete restart...      // Ask user whether he/she want's a complete restart...
908      // (if we're currently up and running)      // (if we're currently up and running)
909      if (bRestart && m_pClient) {      if (bRestart && m_pClient) {
# Line 693  void qsamplerMainForm::fileRestart (void Line 911  void qsamplerMainForm::fileRestart (void
911              tr("New settings will be effective after\n"              tr("New settings will be effective after\n"
912                 "restarting the client/server connection.\n\n"                 "restarting the client/server connection.\n\n"
913                 "Please note that this operation may cause\n"                 "Please note that this operation may cause\n"
914                 "temporary MIDI and Audio disruption\n\n"                 "temporary MIDI and Audio disruption.\n\n"
915                 "Do you want to restart the connection now?"),                 "Do you want to restart the connection now?"),
916              tr("Restart"), tr("Cancel")) == 0);              tr("Restart"), tr("Cancel")) == 0);
917      }      }
# Line 725  void qsamplerMainForm::editAddChannel (v Line 943  void qsamplerMainForm::editAddChannel (v
943      if (m_pClient == NULL)      if (m_pClient == NULL)
944          return;          return;
945    
946      // Create the new sampler channel.      // Just create the channel instance...
947      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel(this);
948      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
949          return;          return;
     }  
950    
951      // Log this happening.      // Before we show it up, may be we'll
952      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
953        if (!pChannel->channelSetup(this)) {
954            delete pChannel;
955            return;
956        }
957    
958      // Just create the channel strip with given id.      // And give it to the strip (will own the channel instance, if successful).
959      createChannel(iChannelID, true);      if (!createChannelStrip(pChannel)) {
960            delete pChannel;
961            return;
962        }
963    
964      // We'll be dirty, for sure...      // Make that an overall update.
965      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
966      stabilizeForm();      stabilizeForm();
967  }  }
968    
# Line 752  void qsamplerMainForm::editRemoveChannel Line 973  void qsamplerMainForm::editRemoveChannel
973      if (m_pClient == NULL)      if (m_pClient == NULL)
974          return;          return;
975    
976      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
977        if (pChannelStrip == NULL)
978            return;
979    
980        qsamplerChannel *pChannel = pChannelStrip->channel();
981      if (pChannel == NULL)      if (pChannel == NULL)
982          return;          return;
983    
# Line 762  void qsamplerMainForm::editRemoveChannel Line 987  void qsamplerMainForm::editRemoveChannel
987              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
988                 "%1\n\n"                 "%1\n\n"
989                 "Are you sure?")                 "Are you sure?")
990                 .arg(pChannel->caption()),                 .arg(pChannelStrip->caption()),
991              tr("OK"), tr("Cancel")) > 0)              tr("OK"), tr("Cancel")) > 0)
992              return;              return;
993      }      }
994    
995      // Remove the existing sampler channel.      // Remove the existing sampler channel.
996      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."));  
997          return;          return;
     }  
998    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
999      // Just delete the channel strip.      // Just delete the channel strip.
1000      delete pChannel;      delete pChannelStrip;
1001    
1002      // Do we auto-arrange?      // Do we auto-arrange?
1003      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
1004          channelsArrange();          channelsArrange();
# Line 795  void qsamplerMainForm::editSetupChannel Line 1015  void qsamplerMainForm::editSetupChannel
1015      if (m_pClient == NULL)      if (m_pClient == NULL)
1016          return;          return;
1017    
1018      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1019      if (pChannel == NULL)      if (pChannelStrip == NULL)
1020          return;          return;
1021    
1022      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
1023      pChannel->channelSetup();      pChannelStrip->channelSetup();
1024  }  }
1025    
1026    
# Line 810  void qsamplerMainForm::editResetChannel Line 1030  void qsamplerMainForm::editResetChannel
1030      if (m_pClient == NULL)      if (m_pClient == NULL)
1031          return;          return;
1032    
1033      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1034      if (pChannel == NULL)      if (pChannelStrip == NULL)
1035          return;          return;
1036    
1037      // Remove the existing sampler channel.      // Just invoque the channel strip procedure.
1038      if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      pChannelStrip->channelReset();
1039          appendMessagesClient("lscp_reset_channel");  }
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
1040    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
1041    
1042      // Refresh channel strip info.  // Reset all sampler channels.
1043      pChannel->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
1044    {
1045            if (m_pClient == NULL)
1046                    return;
1047    
1048            // Invoque the channel strip procedure,
1049            // for all channels out there...
1050            m_pWorkspace->setUpdatesEnabled(false);
1051            QWidgetList wlist = m_pWorkspace->windowList();
1052            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1053                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1054                    if (pChannelStrip)
1055                            pChannelStrip->channelReset();
1056            }
1057            m_pWorkspace->setUpdatesEnabled(true);
1058  }  }
1059    
1060    
# Line 877  void qsamplerMainForm::viewMessages ( bo Line 1106  void qsamplerMainForm::viewMessages ( bo
1106  }  }
1107    
1108    
1109    // Show/hide the device configurator form.
1110    void qsamplerMainForm::viewDevices (void)
1111    {
1112            if (m_pOptions == NULL)
1113                    return;
1114    
1115            if (m_pDeviceForm) {
1116                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1117                    m_pDeviceForm->setClient(m_pClient);
1118                    if (m_pDeviceForm->isVisible()) {
1119                            m_pDeviceForm->hide();
1120                    } else {
1121                            m_pDeviceForm->show();
1122                            m_pDeviceForm->raise();
1123                            m_pDeviceForm->setActiveWindow();
1124                    }
1125            }
1126    }
1127    
1128    
1129  // Show options dialog.  // Show options dialog.
1130  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1131  {  {
# Line 886  void qsamplerMainForm::viewOptions (void Line 1135  void qsamplerMainForm::viewOptions (void
1135      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);
1136      if (pOptionsForm) {      if (pOptionsForm) {
1137          // Check out some initial nullities(tm)...          // Check out some initial nullities(tm)...
1138          qsamplerChannelStrip *pChannel = activeChannel();          qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1139          if (m_pOptions->sDisplayFont.isEmpty() && pChannel)          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1140              m_pOptions->sDisplayFont = pChannel->displayFont().toString();              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1141          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1142              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1143          // To track down deferred or immediate changes.          // To track down deferred or immediate changes.
# Line 898  void qsamplerMainForm::viewOptions (void Line 1147  void qsamplerMainForm::viewOptions (void
1147          bool    bOldServerStart     = m_pOptions->bServerStart;          bool    bOldServerStart     = m_pOptions->bServerStart;
1148          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1149          QString sOldDisplayFont     = m_pOptions->sDisplayFont;          QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1150            bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1151          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1152          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1153            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1154          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1155          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1156          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1157          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1158            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1159          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1160          // Load the current setup settings.          // Load the current setup settings.
1161          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 911  void qsamplerMainForm::viewOptions (void Line 1163  void qsamplerMainForm::viewOptions (void
1163          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1164              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1165              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1166                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1167                    ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1168                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1169                  QMessageBox::information(this, tr("Information"),                  QMessageBox::information(this, tr("Information"),
1170                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1171                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
# Line 922  void qsamplerMainForm::viewOptions (void Line 1176  void qsamplerMainForm::viewOptions (void
1176                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1177                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1178                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1179                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1180                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1181                    updateInstrumentNames();
1182                if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1183                    (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1184                    updateDisplayEffect();
1185              if (sOldDisplayFont != m_pOptions->sDisplayFont)              if (sOldDisplayFont != m_pOptions->sDisplayFont)
1186                  updateDisplayFont();                  updateDisplayFont();
1187              if (iOldMaxVolume != m_pOptions->iMaxVolume)              if (iOldMaxVolume != m_pOptions->iMaxVolume)
# Line 964  void qsamplerMainForm::channelsArrange ( Line 1224  void qsamplerMainForm::channelsArrange (
1224      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1225      int y = 0;      int y = 0;
1226      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1227          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1228      /*  if (pChannel->testWState(WState_Maximized | WState_Minimized)) {      /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1229              // Prevent flicker...              // Prevent flicker...
1230              pChannel->hide();              pChannelStrip->hide();
1231              pChannel->showNormal();              pChannelStrip->showNormal();
1232          }   */          }   */
1233          pChannel->adjustSize();          pChannelStrip->adjustSize();
1234          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1235          if (iWidth < pChannel->width())          if (iWidth < pChannelStrip->width())
1236              iWidth = pChannel->width();              iWidth = pChannelStrip->width();
1237      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1238          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1239          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1240          y += iHeight;          y += iHeight;
1241      }      }
1242      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1243        
1244      stabilizeForm();      stabilizeForm();
1245  }  }
1246    
# Line 1024  void qsamplerMainForm::helpAbout (void) Line 1284  void qsamplerMainForm::helpAbout (void)
1284      sText += tr("Debugging option enabled.");      sText += tr("Debugging option enabled.");
1285      sText += "</font></small><br />";      sText += "</font></small><br />";
1286  #endif  #endif
1287    #ifndef CONFIG_LIBGIG
1288        sText += "<small><font color=\"red\">";
1289        sText += tr("GIG (libgig) file support disabled.");
1290        sText += "</font></small><br />";
1291    #endif
1292    #ifndef CONFIG_INSTRUMENT_NAME
1293        sText += "<small><font color=\"red\">";
1294        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1295        sText += "</font></small><br />";
1296    #endif
1297      sText += "<br />\n";      sText += "<br />\n";
1298      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1299      sText += ::lscp_client_package();      sText += ::lscp_client_package();
1300      sText += " ";      sText += " ";
1301      sText += ::lscp_client_version();      sText += ::lscp_client_version();
1302    #ifdef CONFIG_LIBGIG
1303        sText += ", ";
1304        sText += gig::libraryName();
1305        sText += " ";
1306        sText += gig::libraryVersion();
1307    #endif
1308      sText += "<br />\n";      sText += "<br />\n";
1309      sText += "<br />\n";      sText += "<br />\n";
1310      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 1051  void qsamplerMainForm::helpAbout (void) Line 1327  void qsamplerMainForm::helpAbout (void)
1327  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1328  {  {
1329      // Update the main application caption...      // Update the main application caption...
1330      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1331      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1332          sSessioName += '*';          sSessionName += '*';
1333      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1334    
1335      // Update the main menu state...      // Update the main menu state...
1336      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1337      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1338      bool bHasChannel = (bHasClient && pChannel != NULL);      bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1339      fileNewAction->setEnabled(bHasClient);      fileNewAction->setEnabled(bHasClient);
1340      fileOpenAction->setEnabled(bHasClient);      fileOpenAction->setEnabled(bHasClient);
1341      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1342      fileSaveAsAction->setEnabled(bHasClient);      fileSaveAsAction->setEnabled(bHasClient);
1343        fileResetAction->setEnabled(bHasClient);
1344      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1345      editAddChannelAction->setEnabled(bHasClient);      editAddChannelAction->setEnabled(bHasClient);
1346      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1347      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1348      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1349      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1350      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1351        viewDevicesAction->setOn(m_pDeviceForm && m_pDeviceForm->isVisible());
1352        viewDevicesAction->setEnabled(bHasClient);
1353        channelsArrangeAction->setEnabled(bHasChannel);
1354    
1355      // Client/Server status...      // Client/Server status...
1356      if (bHasClient) {      if (bHasClient) {
1357          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1358          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));
1359      } else {      } else {
1360          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1361          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1362      }      }
1363      // Channel status...      // Channel status...
1364      if (bHasChannel)      if (bHasChannel)
1365          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannel->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1366      else      else
1367          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1368      // Session status...      // Session status...
1369      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1370          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1371      else      else
1372          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1373    
1374      // Recent files menu.      // Recent files menu.
1375      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1101  void qsamplerMainForm::stabilizeForm (vo Line 1381  void qsamplerMainForm::stabilizeForm (vo
1381    
1382    
1383  // Channel change receiver slot.  // Channel change receiver slot.
1384  void qsamplerMainForm::channelChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1385  {  {
1386            // Add this strip to the changed list...
1387            if (m_changedStrips.containsRef(pChannelStrip) == 0) {
1388                    m_changedStrips.append(pChannelStrip);
1389                    pChannelStrip->resetErrorCount();
1390            }
1391    
1392      // Just mark the dirty form.      // Just mark the dirty form.
1393      m_iDirtyCount++;      m_iDirtyCount++;
1394      // and update the form status...      // and update the form status...
# Line 1110  void qsamplerMainForm::channelChanged( q Line 1396  void qsamplerMainForm::channelChanged( q
1396  }  }
1397    
1398    
1399    // Grab and restore current sampler channels session.
1400    void qsamplerMainForm::updateSession (void)
1401    {
1402            // Retrieve the current channel list.
1403            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1404            if (piChannelIDs == NULL) {
1405                    if (::lscp_client_get_errno(m_pClient)) {
1406                            appendMessagesClient("lscp_list_channels");
1407                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1408                    }
1409                    return;
1410            }
1411    
1412            // Try to (re)create each channel.
1413            m_pWorkspace->setUpdatesEnabled(false);
1414            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1415                    // Check if theres already a channel strip for this one...
1416                    if (!channelStrip(piChannelIDs[iChannel]))
1417                            createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));
1418                    // Make it visibly responsive...
1419                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1420            }
1421            m_pWorkspace->setUpdatesEnabled(true);
1422            
1423            // Remember to refresh devices
1424            if (m_pDeviceForm)
1425                m_pDeviceForm->refreshDevices();
1426    }
1427    
1428    
1429  // Update the recent files list and menu.  // Update the recent files list and menu.
1430  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1431  {  {
# Line 1154  void qsamplerMainForm::updateRecentFiles Line 1470  void qsamplerMainForm::updateRecentFiles
1470  }  }
1471    
1472    
1473    // Force update of the channels instrument names mode.
1474    void qsamplerMainForm::updateInstrumentNames (void)
1475    {
1476        // Full channel list update...
1477        QWidgetList wlist = m_pWorkspace->windowList();
1478        if (wlist.isEmpty())
1479            return;
1480    
1481        m_pWorkspace->setUpdatesEnabled(false);
1482        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1483            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1484            if (pChannelStrip)
1485                pChannelStrip->updateInstrumentName(true);
1486        }
1487        m_pWorkspace->setUpdatesEnabled(true);
1488    }
1489    
1490    
1491  // Force update of the channels display font.  // Force update of the channels display font.
1492  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1493  {  {
# Line 1175  void qsamplerMainForm::updateDisplayFont Line 1509  void qsamplerMainForm::updateDisplayFont
1509    
1510      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1511      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1512          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1513          pChannel->setDisplayFont(font);          if (pChannelStrip)
1514                pChannelStrip->setDisplayFont(font);
1515        }
1516        m_pWorkspace->setUpdatesEnabled(true);
1517    }
1518    
1519    
1520    // Update channel strips background effect.
1521    void qsamplerMainForm::updateDisplayEffect (void)
1522    {
1523       QPixmap pm;
1524        if (m_pOptions->bDisplayEffect)
1525            pm = QPixmap::fromMimeSource("displaybg1.png");
1526    
1527        // Full channel list update...
1528        QWidgetList wlist = m_pWorkspace->windowList();
1529        if (wlist.isEmpty())
1530            return;
1531    
1532        m_pWorkspace->setUpdatesEnabled(false);
1533        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1534            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1535            if (pChannelStrip)
1536                pChannelStrip->setDisplayBackground(pm);
1537      }      }
1538      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1539  }  }
# Line 1195  void qsamplerMainForm::updateMaxVolume ( Line 1552  void qsamplerMainForm::updateMaxVolume (
1552    
1553      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1554      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1555          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1556          pChannel->setMaxVolume(m_pOptions->iMaxVolume);          if (pChannelStrip)
1557                pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1558      }      }
1559      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1560  }  }
# Line 1275  void qsamplerMainForm::updateMessagesLim Line 1633  void qsamplerMainForm::updateMessagesLim
1633          if (m_pOptions->bMessagesLimit)          if (m_pOptions->bMessagesLimit)
1634              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);              m_pMessages->setMessagesLimit(m_pOptions->iMessagesLimitLines);
1635          else          else
1636              m_pMessages->setMessagesLimit(0);              m_pMessages->setMessagesLimit(-1);
1637      }      }
1638  }  }
1639    
# Line 1295  void qsamplerMainForm::updateMessagesCap Line 1653  void qsamplerMainForm::updateMessagesCap
1653  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
1654    
1655  // The channel strip creation executive.  // The channel strip creation executive.
1656  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
1657  {  {
1658      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
1659          return;          return NULL;
1660    
1661      // Prepare for auto-arrange?      // Prepare for auto-arrange?
1662      qsamplerChannelStrip *pChannel = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
1663      int y = 0;      int y = 0;
1664      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1665          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1666          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1667              pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1668          //  y += pChannel->height() + pChannel->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1669              y += pChannel->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1670                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1671                            }
1672          }          }
1673      }      }
1674    
1675      // Add a new channel itema...      // Add a new channel itema...
1676      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;
1677      pChannel = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1678      pChannel->setMaxVolume(m_pOptions->iMaxVolume);      if (pChannelStrip == NULL)
1679      pChannel->setup(this, iChannelID);          return NULL;
1680      // We'll need a display font.  
1681      QFont font;      // Actual channel strip setup...
1682      if (m_pOptions && font.fromString(m_pOptions->sDisplayFont))      pChannelStrip->setup(pChannel);
1683          pChannel->setDisplayFont(font);      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
1684      // Track channel setup changes.      // Set some initial aesthetic options...
1685      QObject::connect(pChannel, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelChanged(qsamplerChannelStrip *)));      if (m_pOptions) {
1686      // Before we show it up, may be we'll          // Background display effect...
1687      // better ask for some initial values?          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
1688      if (bPrompt)          // We'll need a display font.
1689          pChannel->channelSetup();                QFont font;
1690            if (font.fromString(m_pOptions->sDisplayFont))
1691                pChannelStrip->setDisplayFont(font);
1692            // Maximum allowed volume setting.
1693            pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1694        }
1695    
1696      // Now we show up us to the world.      // Now we show up us to the world.
1697      pChannel->show();      pChannelStrip->show();
1698      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
1699      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1700          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1701      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();
1702          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1703          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1704      }      }
1705    
1706            // This is pretty new, so we'll watch for it closely.
1707            channelStripChanged(pChannelStrip);
1708    
1709        // Return our successful reference...
1710        return pChannelStrip;
1711  }  }
1712    
1713    
1714  // Retrieve the active channel strip.  // Retrieve the active channel strip.
1715  qsamplerChannelStrip *qsamplerMainForm::activeChannel (void)  qsamplerChannelStrip *qsamplerMainForm::activeChannelStrip (void)
1716  {  {
1717      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();
1718  }  }
1719    
1720    
1721  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
1722  qsamplerChannelStrip *qsamplerMainForm::channelAt ( int iChannel )  qsamplerChannelStrip *qsamplerMainForm::channelStripAt ( int iChannel )
1723  {  {
1724      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1725      if (wlist.isEmpty())      if (wlist.isEmpty())
1726          return 0;          return NULL;
1727    
1728      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1729  }  }
1730    
1731    
1732    // Retrieve a channel strip by sampler channel id.
1733    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1734    {
1735            QWidgetList wlist = m_pWorkspace->windowList();
1736            if (wlist.isEmpty())
1737                    return NULL;
1738    
1739            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1740                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1741                    if (pChannelStrip) {
1742                            qsamplerChannel *pChannel = pChannelStrip->channel();
1743                            if (pChannel && pChannel->channelID() == iChannelID)
1744                                    return pChannelStrip;
1745                    }
1746            }
1747    
1748            // Not found.
1749            return NULL;
1750    }
1751    
1752    
1753  // Construct the windows menu.  // Construct the windows menu.
1754  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1755  {  {
# Line 1368  void qsamplerMainForm::channelsMenuAbout Line 1761  void qsamplerMainForm::channelsMenuAbout
1761      if (!wlist.isEmpty()) {      if (!wlist.isEmpty()) {
1762          channelsMenu->insertSeparator();          channelsMenu->insertSeparator();
1763          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1764              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1765              int iItemID = channelsMenu->insertItem(pChannel->caption(), this, SLOT(channelsMenuActivated(int)));              if (pChannelStrip) {
1766              channelsMenu->setItemParameter(iItemID, iChannel);                  int iItemID = channelsMenu->insertItem(pChannelStrip->caption(), this, SLOT(channelsMenuActivated(int)));
1767              channelsMenu->setItemChecked(iItemID, activeChannel() == pChannel);                  channelsMenu->setItemParameter(iItemID, iChannel);
1768                    channelsMenu->setItemChecked(iItemID, activeChannelStrip() == pChannelStrip);
1769                }
1770          }          }
1771      }      }
1772  }  }
# Line 1380  void qsamplerMainForm::channelsMenuAbout Line 1775  void qsamplerMainForm::channelsMenuAbout
1775  // Windows menu activation slot  // Windows menu activation slot
1776  void qsamplerMainForm::channelsMenuActivated ( int iChannel )  void qsamplerMainForm::channelsMenuActivated ( int iChannel )
1777  {  {
1778      qsamplerChannelStrip *pChannel = channelAt(iChannel);      qsamplerChannelStrip *pChannelStrip = channelStripAt(iChannel);
1779      if (pChannel)      if (pChannelStrip)
1780          pChannel->showNormal();          pChannelStrip->showNormal();
1781      pChannel->setFocus();      pChannelStrip->setFocus();
1782  }  }
1783    
1784    
# Line 1421  void qsamplerMainForm::timerSlot (void) Line 1816  void qsamplerMainForm::timerSlot (void)
1816              }              }
1817          }          }
1818      }      }
1819        
1820          // Refresh each channel usage, on each period...          // Refresh each channel usage, on each period...
1821      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {          if (m_pClient && (m_changedStrips.count() > 0 || m_pOptions->bAutoRefresh)) {
1822          m_iTimerSlot += QSAMPLER_TIMER_MSECS;                  m_iTimerSlot += QSAMPLER_TIMER_MSECS;
1823          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {                  if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {
1824              m_iTimerSlot = 0;                          m_iTimerSlot = 0;
1825              QWidgetList wlist = m_pWorkspace->windowList();                          // Update the channel information for each pending strip...
1826              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                          for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
1827                  qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);                                          pChannelStrip;
1828                  if (pChannel->isVisible())                                                  pChannelStrip = m_changedStrips.next()) {
1829                      pChannel->updateChannelUsage();                                  // If successfull, remove from pending list...
1830              }                                  if (pChannelStrip->updateChannelInfo())
1831          }                                          m_changedStrips.remove(pChannelStrip);
1832      }                          }
1833                            // Update the channel stream usage for each strip...
1834                            QWidgetList wlist = m_pWorkspace->windowList();
1835                            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1836                                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1837                                    if (pChannelStrip && pChannelStrip->isVisible())
1838                                            pChannelStrip->updateChannelUsage();
1839                            }
1840                    }
1841            }
1842    
1843      // Register the next timer slot.      // Register the next timer slot.
1844      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));      QTimer::singleShot(QSAMPLER_TIMER_MSECS, this, SLOT(timerSlot()));
# Line 1624  bool qsamplerMainForm::startClient (void Line 2028  bool qsamplerMainForm::startClient (void
2028      // Log success here.      // Log success here.
2029      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
2030    
2031            // Hard-notify device configuration form,
2032            // if visible, that we're ready...
2033            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2034                m_pDeviceForm->setClient(m_pClient);
2035                
2036      // Is any session pending to be loaded?      // Is any session pending to be loaded?
2037      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
2038          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1644  void qsamplerMainForm::stopClient (void) Line 2053  void qsamplerMainForm::stopClient (void)
2053      if (m_pClient == NULL)      if (m_pClient == NULL)
2054          return;          return;
2055    
2056            // Hard-notify device configuration form,
2057            // if visible, that we're running out...
2058            if (m_pDeviceForm && m_pDeviceForm->isVisible())
2059                m_pDeviceForm->setClient(NULL);
2060    
2061      // Log prepare here.      // Log prepare here.
2062      appendMessages(tr("Client disconnecting..."));      appendMessages(tr("Client disconnecting..."));
2063    
# Line 1658  void qsamplerMainForm::stopClient (void) Line 2072  void qsamplerMainForm::stopClient (void)
2072      // channels from the back-end server.      // channels from the back-end server.
2073      m_iDirtyCount = 0;      m_iDirtyCount = 0;
2074      closeSession(false);      closeSession(false);
2075        
2076      // Close us as a client...      // Close us as a client...
2077      lscp_client_destroy(m_pClient);      lscp_client_destroy(m_pClient);
2078      m_pClient = NULL;      m_pClient = NULL;

Legend:
Removed from v.149  
changed lines
  Added in v.661

  ViewVC Help
Powered by ViewVC