/[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 122 by capela, Sat Jun 12 13:21:35 2004 UTC revision 462 by capela, Tue Mar 15 11:39:12 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  // Timer constant stuff.  // Timer constant stuff.
55  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
# Line 54  Line 61 
61  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
62    
63    
64    // All winsock apps needs this.
65  #if defined(WIN32)  #if defined(WIN32)
66  static WSADATA _wsaData;  static WSADATA _wsaData;
67  #endif  #endif
68    
69    
70    //-------------------------------------------------------------------------
71    // qsamplerCustomEvent -- specialty for callback comunication.
72    
73    #define QSAMPLER_CUSTOM_EVENT   1000
74    
75    class qsamplerCustomEvent : public QCustomEvent
76    {
77    public:
78    
79        // Constructor.
80        qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)
81            : QCustomEvent(QSAMPLER_CUSTOM_EVENT)
82        {
83            m_event = event;
84            m_data.setLatin1(pchData, cchData);
85        }
86    
87        // Accessors.
88        lscp_event_t event() { return m_event; }
89        QString&     data()  { return m_data;  }
90    
91    private:
92    
93        // The proper event type.
94        lscp_event_t m_event;
95        // The event data as a string.
96        QString      m_data;
97    };
98    
99    
100  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
101  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
102    
# Line 68  void qsamplerMainForm::init (void) Line 107  void qsamplerMainForm::init (void)
107      m_pOptions = NULL;      m_pOptions = NULL;
108    
109      // All child forms are to be created later, not earlier than setup.      // All child forms are to be created later, not earlier than setup.
110      m_pMessages = NULL;      m_pMessages   = NULL;
111        m_pDeviceForm = NULL;
112    
113      // We'll start clean.      // We'll start clean.
114      m_iUntitled = 0;      m_iUntitled   = 0;
115      m_iDirtyCount = 0;      m_iDirtyCount = 0;
116    
117      m_pServer = NULL;      m_pServer = NULL;
# Line 82  void qsamplerMainForm::init (void) Line 122  void qsamplerMainForm::init (void)
122    
123      m_iTimerSlot = 0;      m_iTimerSlot = 0;
124    
125    #ifdef HAVE_SIGNAL_H
126            // Set to ignore any fatal "Broken pipe" signals.
127            ::signal(SIGPIPE, SIG_IGN);
128    #endif
129    
130      // Make it an MDI workspace.      // Make it an MDI workspace.
131      m_pWorkspace = new QWorkspace(this);      m_pWorkspace = new QWorkspace(this);
132      m_pWorkspace->setScrollBarsEnabled(true);      m_pWorkspace->setScrollBarsEnabled(true);
# Line 96  void qsamplerMainForm::init (void) Line 141  void qsamplerMainForm::init (void)
141      pLabel = new QLabel(tr("Connected"), this);      pLabel = new QLabel(tr("Connected"), this);
142      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
143      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
144      m_status[QSAMPLER_STATUS_CLIENT] = pLabel;      m_statusItem[QSAMPLER_STATUS_CLIENT] = pLabel;
145      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
146      // Server address.      // Server address.
147      pLabel = new QLabel(this);      pLabel = new QLabel(this);
148      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
149      m_status[QSAMPLER_STATUS_SERVER] = pLabel;      m_statusItem[QSAMPLER_STATUS_SERVER] = pLabel;
150      statusBar()->addWidget(pLabel, 1);      statusBar()->addWidget(pLabel, 1);
151      // Channel title.      // Channel title.
152      pLabel = new QLabel(this);      pLabel = new QLabel(this);
153      pLabel->setAlignment(Qt::AlignLeft);      pLabel->setAlignment(Qt::AlignLeft);
154      m_status[QSAMPLER_STATUS_CHANNEL] = pLabel;      m_statusItem[QSAMPLER_STATUS_CHANNEL] = pLabel;
155      statusBar()->addWidget(pLabel, 2);      statusBar()->addWidget(pLabel, 2);
156      // Session modification status.      // Session modification status.
157      pLabel = new QLabel(tr("MOD"), this);      pLabel = new QLabel(tr("MOD"), this);
158      pLabel->setAlignment(Qt::AlignHCenter);      pLabel->setAlignment(Qt::AlignHCenter);
159      pLabel->setMinimumSize(pLabel->sizeHint());      pLabel->setMinimumSize(pLabel->sizeHint());
160      m_status[QSAMPLER_STATUS_SESSION] = pLabel;      m_statusItem[QSAMPLER_STATUS_SESSION] = pLabel;
161      statusBar()->addWidget(pLabel);      statusBar()->addWidget(pLabel);
162    
163      // Create the recent files sub-menu.      // Create the recent files sub-menu.
# Line 131  void qsamplerMainForm::destroy (void) Line 176  void qsamplerMainForm::destroy (void)
176  {  {
177      // Do final processing anyway.      // Do final processing anyway.
178      processServerExit();      processServerExit();
179        
180      // Delete recentfiles menu.  #if defined(WIN32)
181      if (m_pRecentFilesMenu)      WSACleanup();
182          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];  
183    
184      // Finally drop any widgets around...      // Finally drop any widgets around...
185        if (m_pDeviceForm)
186            delete m_pDeviceForm;
187      if (m_pMessages)      if (m_pMessages)
188          delete m_pMessages;          delete m_pMessages;
189      if (m_pWorkspace)      if (m_pWorkspace)
190          delete m_pWorkspace;          delete m_pWorkspace;
191    
192  #if defined(WIN32)      // Delete status item labels one by one.
193      WSACleanup();      if (m_statusItem[QSAMPLER_STATUS_CLIENT])
194  #endif          delete m_statusItem[QSAMPLER_STATUS_CLIENT];
195        if (m_statusItem[QSAMPLER_STATUS_SERVER])
196            delete m_statusItem[QSAMPLER_STATUS_SERVER];
197        if (m_statusItem[QSAMPLER_STATUS_CHANNEL])
198            delete m_statusItem[QSAMPLER_STATUS_CHANNEL];
199        if (m_statusItem[QSAMPLER_STATUS_SESSION])
200            delete m_statusItem[QSAMPLER_STATUS_SESSION];
201    
202        // Delete recentfiles menu.
203        if (m_pRecentFilesMenu)
204            delete m_pRecentFilesMenu;
205  }  }
206    
207    
# Line 163  void qsamplerMainForm::setup ( qsamplerO Line 211  void qsamplerMainForm::setup ( qsamplerO
211      // We got options?      // We got options?
212      m_pOptions = pOptions;      m_pOptions = pOptions;
213    
214        // What style do we create these forms?
215        WFlags wflags = Qt::WType_TopLevel;
216        if (m_pOptions->bKeepOnTop)
217            wflags |= Qt::WStyle_Tool;
218      // Some child forms are to be created right now.      // Some child forms are to be created right now.
219      m_pMessages = new qsamplerMessages(this);      m_pMessages = new qsamplerMessages(this);
220        m_pDeviceForm = new qsamplerDeviceForm(this, 0, wflags);
221      // Set message defaults...      // Set message defaults...
222      updateMessagesFont();      updateMessagesFont();
223      updateMessagesLimit();      updateMessagesLimit();
# Line 193  void qsamplerMainForm::setup ( qsamplerO Line 246  void qsamplerMainForm::setup ( qsamplerO
246          QTextIStream istr(&sDockables);          QTextIStream istr(&sDockables);
247          istr >> *this;          istr >> *this;
248      }      }
249      // Try to restore old window positioning.      // Try to restore old window positioning and initial visibility.
250      m_pOptions->loadWidgetGeometry(this);      m_pOptions->loadWidgetGeometry(this);
251        m_pOptions->loadWidgetGeometry(m_pDeviceForm);
252    
253      // Final startup stabilization...      // Final startup stabilization...
254      updateRecentFilesMenu();      updateRecentFilesMenu();
# Line 232  bool qsamplerMainForm::queryClose (void) Line 286  bool qsamplerMainForm::queryClose (void)
286              QTextOStream ostr(&sDockables);              QTextOStream ostr(&sDockables);
287              ostr << *this;              ostr << *this;
288              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);              m_pOptions->settings().writeEntry("/Layout/DockWindows", sDockables);
289              // And the main windows state.              // And the children, and the main windows state,.
290                    m_pOptions->saveWidgetGeometry(m_pDeviceForm);
291              m_pOptions->saveWidgetGeometry(this);              m_pOptions->saveWidgetGeometry(this);
292                    // Close popup widgets.
293                    if (m_pDeviceForm)
294                        m_pDeviceForm->close();
295              // Stop client and/or server, gracefully.              // Stop client and/or server, gracefully.
296              stopServer();              stopServer();
297          }          }
# Line 252  void qsamplerMainForm::closeEvent ( QClo Line 310  void qsamplerMainForm::closeEvent ( QClo
310  }  }
311    
312    
313  void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )  // Drag'n'drop file handler.
314    bool qsamplerMainForm::decodeDragFiles ( const QMimeSource *pEvent, QStringList& files )
315  {  {
316      bool bAccept = false;      bool bDecode = false;
317    
318      if (QTextDrag::canDecode(pDragEnterEvent)) {      if (QTextDrag::canDecode(pEvent)) {
319          QString sUrl;          QString sText;
320          if (QTextDrag::decode(pDragEnterEvent, sUrl) && m_pClient)          bDecode = QTextDrag::decode(pEvent, sText);
321              bAccept = QFileInfo(QUrl(sUrl).path()).exists();          if (bDecode) {
322                files = QStringList::split('\n', sText);
323                for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++)
324                    *iter = QUrl((*iter).stripWhiteSpace().replace(QRegExp("^file:"), QString::null)).path();
325            }
326      }      }
327    
328      pDragEnterEvent->accept(bAccept);      return bDecode;
329    }
330    
331    
332    // Window drag-n-drop event handlers.
333    void qsamplerMainForm::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
334    {
335            QStringList files;
336            pDragEnterEvent->accept(decodeDragFiles(pDragEnterEvent, files));
337  }  }
338    
339    
340  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )  void qsamplerMainForm::dropEvent ( QDropEvent* pDropEvent )
341  {  {
342      if (QTextDrag::canDecode(pDropEvent)) {      QStringList files;
343          QString sUrl;  
344          if (QTextDrag::decode(pDropEvent, sUrl) && closeSession(true))      if (!decodeDragFiles(pDropEvent, files))
345              loadSessionFile(QUrl(sUrl).path());          return;
346    
347        for (QStringList::Iterator iter = files.begin(); iter != files.end(); iter++) {
348                    const QString& sPath = *iter;
349                    if (qsamplerChannel::isInstrumentFile(sPath)) {
350                            // Try to create a new channel from instrument file...
351                        qsamplerChannel *pChannel = new qsamplerChannel(this);
352                        if (pChannel == NULL)
353                            return;
354                            // Start setting the instrument filename...
355                            pChannel->setInstrument(sPath, 0);
356                        // Before we show it up, may be we'll
357                        // better ask for some initial values?
358                        if (!pChannel->channelSetup(this)) {
359                            delete pChannel;
360                            return;
361                        }
362                        // Finally, give it to a new channel strip...
363                            if (!createChannelStrip(pChannel)) {
364                            delete pChannel;
365                            return;
366                            }
367                        // Make that an overall update.
368                        m_iDirtyCount++;
369                        stabilizeForm();
370                    }   // Otherwise, load an usual session file (LSCP script)...
371                    else if (closeSession(true))
372                            loadSessionFile(sPath);
373                    // Make it look responsive...:)
374                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
375            }
376    }
377    
378    
379    // Custome event handler.
380    void qsamplerMainForm::customEvent ( QCustomEvent *pCustomEvent )
381    {
382        // For the time being, just pump it to messages.
383        if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
384            qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;
385            appendMessagesColor(tr("Notify event: %1 data: %2")
386                .arg(::lscp_event_to_text(pEvent->event()))
387                .arg(pEvent->data()), "#996699");
388      }      }
389  }  }
390    
391    
392    // Context menu event handler.
393    void qsamplerMainForm::contextMenuEvent( QContextMenuEvent *pEvent )
394    {
395        stabilizeForm();
396        
397        editMenu->exec(pEvent->globalPos());
398    }
399    
400    
401  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
402  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
403    
# Line 315  bool qsamplerMainForm::newSession (void) Line 437  bool qsamplerMainForm::newSession (void)
437      if (!closeSession(true))      if (!closeSession(true))
438          return false;          return false;
439    
440            // Give us what the server has, right now...
441            updateSession();
442    
443      // Ok increment untitled count.      // Ok increment untitled count.
444      m_iUntitled++;      m_iUntitled++;
445    
# Line 428  bool qsamplerMainForm::closeSession ( bo Line 553  bool qsamplerMainForm::closeSession ( bo
553          m_pWorkspace->setUpdatesEnabled(false);          m_pWorkspace->setUpdatesEnabled(false);
554          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
555          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
556              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
557              if (bForce && ::lscp_remove_channel(m_pClient, pChannel->channelID()) != LSCP_OK)              if (pChannelStrip) {
558                  appendMessagesClient("lscp_remove_channel");                  qsamplerChannel *pChannel = pChannelStrip->channel();
559              delete pChannel;                  if (bForce && pChannel)
560                        pChannel->removeChannel();
561                    delete pChannelStrip;
562                }
563          }          }
564          m_pWorkspace->setUpdatesEnabled(true);          m_pWorkspace->setUpdatesEnabled(true);
565          // We're now clean, for sure.          // We're now clean, for sure.
# Line 470  bool qsamplerMainForm::loadSessionFile ( Line 598  bool qsamplerMainForm::loadSessionFile (
598              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {              if (::lscp_client_query(m_pClient, sCommand.latin1()) != LSCP_OK) {
599                  appendMessagesClient("lscp_client_query");                  appendMessagesClient("lscp_client_query");
600                  iErrors++;                  iErrors++;
601                    break;
602              }              }
603          }          }
604          // Try to make it snappy :)          // Try to make it snappy :)
# Line 481  bool qsamplerMainForm::loadSessionFile ( Line 610  bool qsamplerMainForm::loadSessionFile (
610    
611      // Have we any errors?      // Have we any errors?
612      if (iErrors > 0)      if (iErrors > 0)
613          appendMessagesError(tr("Some setttings could not be loaded\nfrom \"%1\" session file.\n\nSorry.").arg(sFilename));          appendMessagesError(tr("Session could not be loaded\nfrom \"%1\".\n\nSorry.").arg(sFilename));
614    
615      // Now we'll try to create the whole GUI session.          // Now we'll try to create (update) the whole GUI session.
616      int iChannels = ::lscp_get_channels(m_pClient);          updateSession();
     if (iChannels < 0) {  
         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);  
617    
618      // Save as default session directory.      // Save as default session directory.
619      if (m_pOptions)      if (m_pOptions)
# Line 507  bool qsamplerMainForm::loadSessionFile ( Line 624  bool qsamplerMainForm::loadSessionFile (
624      m_sFilename = sFilename;      m_sFilename = sFilename;
625      updateRecentFiles(sFilename);      updateRecentFiles(sFilename);
626      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));      appendMessages(tr("Open session: \"%1\".").arg(sessionName(m_sFilename)));
627        
628        // Make that an overall update.
629      stabilizeForm();      stabilizeForm();
630      return true;      return true;
631  }  }
# Line 523  bool qsamplerMainForm::saveSessionFile ( Line 642  bool qsamplerMainForm::saveSessionFile (
642      }      }
643    
644      // Write the file.      // Write the file.
645      int iErrors = 0;      int  iErrors = 0;
646      QTextStream ts(&file);      QTextStream ts(&file);
647      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;      ts << "# " << QSAMPLER_TITLE " - " << tr(QSAMPLER_SUBTITLE) << endl;
648      ts << "# " << tr("Version")      ts << "# " << tr("Version")
# Line 534  bool qsamplerMainForm::saveSessionFile ( Line 653  bool qsamplerMainForm::saveSessionFile (
653      ts << "# " << tr("File")      ts << "# " << tr("File")
654         << ": " << QFileInfo(sFilename).fileName() << endl;         << ": " << QFileInfo(sFilename).fileName() << endl;
655      ts << "# " << tr("Date")      ts << "# " << tr("Date")
656         << ": " << QDate::currentDate().toString("MMMM dd yyyy")         << ": " << QDate::currentDate().toString("MMM dd yyyy")
657         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;         << " "  << QTime::currentTime().toString("hh:mm:ss") << endl;
658      ts << "#"  << endl;      ts << "#"  << endl;
659      ts << endl;      ts << endl;
660            // It is assumed that this new kind of device+session file
661            // will be loaded from a complete
662            int *piDeviceIDs;
663            int  iDevice;
664            ts << "RESET" << endl;
665            // Audio device mapping.
666            QMap<int, int> audioDeviceMap;
667            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);
668            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
669                    qsamplerDevice device(m_pClient, qsamplerDevice::Audio, piDeviceIDs[iDevice]);
670                    ts << endl;
671            ts << "# " << device.deviceTypeName() << " " << device.driverName()
672                       << " " << tr("Device") << " " << iDevice << endl;
673                    ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
674                    const qsamplerDeviceParamMap& params = device.params();
675                    qsamplerDeviceParamMap::ConstIterator iter;
676                    for (iter = params.begin(); iter != params.end(); ++iter)
677                            ts << " " << iter.key() << "='" << iter.data().value << "'";
678                    ts << endl;
679                    audioDeviceMap[device.deviceID()] = iDevice;
680            // Try to keep it snappy :)
681            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
682            }
683            // MIDI device mapping.
684            QMap<int, int> midiDeviceMap;
685            piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);
686            for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
687                    qsamplerDevice device(m_pClient, qsamplerDevice::Midi, piDeviceIDs[iDevice]);
688                    ts << endl;
689            ts << "# " << device.deviceTypeName() << " " << device.driverName()
690                       << " " << tr("Device") << " " << iDevice << endl;
691                    ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
692                    const qsamplerDeviceParamMap& params = device.params();
693                    qsamplerDeviceParamMap::ConstIterator iter;
694                    for (iter = params.begin(); iter != params.end(); ++iter)
695                            ts << " " << iter.key() << "='" << iter.data().value << "'";
696                    ts << endl;
697                    midiDeviceMap[device.deviceID()] = iDevice;
698            // Try to keep it snappy :)
699            QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
700            }
701            ts << endl;
702            // Sampler channel mapping.
703      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
704      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
705          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
706          int iChannelID = pChannel->channelID();          if (pChannelStrip) {
707          ts << "# " << pChannel->caption() << endl;              qsamplerChannel *pChannel = pChannelStrip->channel();
708          ts << "ADD CHANNEL" << endl;              if (pChannel) {
709          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannelID << " " << pChannel->audioDriver() << endl;                  ts << "# " << tr("Channel") << " " << iChannel << endl;
710          ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannelID << " " << pChannel->midiDriver() << endl;                  ts << "ADD CHANNEL" << endl;
711      //  ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannelID << " " << pChannel->midiPort() << endl;                  if (audioDeviceMap.isEmpty()) {
712          ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannelID << " " << pChannel->midiChannel() << endl;                          ts << "SET CHANNEL AUDIO_OUTPUT_TYPE " << iChannel
713          ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannelID << endl;                                              << " " << pChannel->audioDriver() << endl;
714          ts << "LOAD INSTRUMENT " << pChannel->instrumentFile() << " " << pChannel->instrumentNr() << " " << iChannelID << endl;                              } else {
715          ts << "SET CHANNEL VOLUME " << iChannelID << " " << pChannel->volume() << endl;                          ts << "SET CHANNEL AUDIO_OUTPUT_DEVICE " << iChannel
716          ts << endl;                                             << " " << audioDeviceMap[pChannel->audioDevice()] << endl;
717                                    }
718                    if (midiDeviceMap.isEmpty()) {
719                            ts << "SET CHANNEL MIDI_INPUT_TYPE " << iChannel
720                                           << " " << pChannel->midiDriver() << endl;
721                                } else {
722                            ts << "SET CHANNEL MIDI_INPUT_DEVICE " << iChannel
723                                               << " " << midiDeviceMap[pChannel->midiDevice()] << endl;
724                                }
725                    ts << "SET CHANNEL MIDI_INPUT_PORT " << iChannel
726                                   << " " << pChannel->midiPort() << endl;
727                    ts << "SET CHANNEL MIDI_INPUT_CHANNEL " << iChannel << " ";
728                    if (pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
729                        ts << "ALL";
730                    else
731                        ts << pChannel->midiChannel();
732                    ts << endl;
733                    ts << "LOAD ENGINE " << pChannel->engineName() << " " << iChannel << endl;
734                    ts << "LOAD INSTRUMENT NON_MODAL '" << pChannel->instrumentFile() << "' " << pChannel->instrumentNr() << " " << iChannel << endl;
735                    ts << "SET CHANNEL VOLUME " << iChannel << " " << pChannel->volume() << endl;
736                    ts << endl;
737                }
738            }
739          // Try to keep it snappy :)          // Try to keep it snappy :)
740          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);          QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
741      }      }
# Line 577  bool qsamplerMainForm::saveSessionFile ( Line 761  bool qsamplerMainForm::saveSessionFile (
761  }  }
762    
763    
764    // Session change receiver slot.
765    void qsamplerMainForm::sessionDirty (void)
766    {
767        // Just mark the dirty form.
768        m_iDirtyCount++;
769        // and update the form status...
770        stabilizeForm();
771    }
772    
773    
774  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
775  // qsamplerMainForm -- File Action slots.  // qsamplerMainForm -- File Action slots.
776    
# Line 623  void qsamplerMainForm::fileSaveAs (void) Line 817  void qsamplerMainForm::fileSaveAs (void)
817  }  }
818    
819    
820    // Reset the sampler instance.
821    void qsamplerMainForm::fileReset (void)
822    {
823        if (m_pClient == NULL)
824            return;
825    
826        // Ask user whether he/she want's an internal sampler reset...
827        if (QMessageBox::warning(this, tr("Warning"),
828            tr("Resetting the sampler instance will close\n"
829               "all device and channel configurations.\n\n"
830               "Please note that this operation may cause\n"
831               "temporary MIDI and Audio disruption\n\n"
832               "Do you want to reset the sampler engine now?"),
833            tr("Reset"), tr("Cancel")) > 0)
834            return;
835    
836        // Just do the reset, after closing down current session...
837        if (closeSession(true) && ::lscp_reset_sampler(m_pClient) != LSCP_OK) {
838            appendMessagesClient("lscp_reset_sampler");
839            appendMessagesError(tr("Could not reset sampler instance.\n\nSorry."));
840            return;
841        }
842    
843        // Log this.
844        appendMessages(tr("Sampler reset."));
845    
846            // Make it a new session...
847            newSession();
848    }
849    
850    
851  // Restart the client/server instance.  // Restart the client/server instance.
852  void qsamplerMainForm::fileRestart (void)  void qsamplerMainForm::fileRestart (void)
853  {  {
# Line 670  void qsamplerMainForm::editAddChannel (v Line 895  void qsamplerMainForm::editAddChannel (v
895      if (m_pClient == NULL)      if (m_pClient == NULL)
896          return;          return;
897    
898      // Create the new sampler channel.      // Just create the channel instance...
899      int iChannelID = ::lscp_add_channel(m_pClient);      qsamplerChannel *pChannel = new qsamplerChannel(this);
900      if (iChannelID < 0) {      if (pChannel == NULL)
         appendMessagesClient("lscp_add_channel");  
         appendMessagesError(tr("Could not create the new channel.\n\nSorry."));  
901          return;          return;
     }  
902    
903      // Log this happening.      // Before we show it up, may be we'll
904      appendMessages(tr("Channel %1 created.").arg(iChannelID));      // better ask for some initial values?
905        if (!pChannel->channelSetup(this)) {
906      // Just create the channel strip with given id.          delete pChannel;
907      createChannel(iChannelID, true);          return;
908        }
909        
910        // And give it to the strip (will own the channel instance, if successful).
911        if (!createChannelStrip(pChannel)) {
912            delete pChannel;
913            return;
914        }
915    
916      // We'll be dirty, for sure...      // Make that an overall update.
917      m_iDirtyCount++;      m_iDirtyCount++;
     // Stabilize form anyway.  
918      stabilizeForm();      stabilizeForm();
919  }  }
920    
# Line 697  void qsamplerMainForm::editRemoveChannel Line 925  void qsamplerMainForm::editRemoveChannel
925      if (m_pClient == NULL)      if (m_pClient == NULL)
926          return;          return;
927    
928      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
929        if (pChannelStrip == NULL)
930            return;
931            
932        qsamplerChannel *pChannel = pChannelStrip->channel();
933      if (pChannel == NULL)      if (pChannel == NULL)
934          return;          return;
935    
# Line 707  void qsamplerMainForm::editRemoveChannel Line 939  void qsamplerMainForm::editRemoveChannel
939              tr("About to remove channel:\n\n"              tr("About to remove channel:\n\n"
940                 "%1\n\n"                 "%1\n\n"
941                 "Are you sure?")                 "Are you sure?")
942                 .arg(pChannel->caption()),                 .arg(pChannelStrip->caption()),
943              tr("OK"), tr("Cancel")) > 0)              tr("OK"), tr("Cancel")) > 0)
944              return;              return;
945      }      }
946    
947      // Remove the existing sampler channel.      // Remove the existing sampler channel.
948      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."));  
949          return;          return;
     }  
950    
     // Log this happening.  
     appendMessages(tr("Channel %1 removed.").arg(pChannel->channelID()));  
       
951      // Just delete the channel strip.      // Just delete the channel strip.
952      delete pChannel;      delete pChannelStrip;
953        
954      // Do we auto-arrange?      // Do we auto-arrange?
955      if (m_pOptions && m_pOptions->bAutoArrange)      if (m_pOptions && m_pOptions->bAutoArrange)
956          channelsArrange();          channelsArrange();
# Line 740  void qsamplerMainForm::editSetupChannel Line 967  void qsamplerMainForm::editSetupChannel
967      if (m_pClient == NULL)      if (m_pClient == NULL)
968          return;          return;
969    
970      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
971      if (pChannel == NULL)      if (pChannelStrip == NULL)
972          return;          return;
973    
974      // Just invoque the channel strip procedure.      // Just invoque the channel strip procedure.
975      pChannel->channelSetup();      pChannelStrip->channelSetup();
976  }  }
977    
978    
# Line 755  void qsamplerMainForm::editResetChannel Line 982  void qsamplerMainForm::editResetChannel
982      if (m_pClient == NULL)      if (m_pClient == NULL)
983          return;          return;
984    
985      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
986      if (pChannel == NULL)      if (pChannelStrip == NULL)
987          return;          return;
988    
989      // Remove the existing sampler channel.      // Just invoque the channel strip procedure.
990      if (::lscp_reset_channel(m_pClient, pChannel->channelID()) != LSCP_OK) {      pChannelStrip->channelReset();
991          appendMessagesClient("lscp_reset_channel");  }
         appendMessagesError(tr("Could not reset channel.\n\nSorry."));  
         return;  
     }  
992    
     // Log this.  
     appendMessages(tr("Channel %1 reset.").arg(pChannel->channelID()));  
993    
994      // Refresh channel strip info.  // Reset all sampler channels.
995      pChannel->updateChannelInfo();  void qsamplerMainForm::editResetAllChannels (void)
996    {
997        if (m_pClient == NULL)
998            return;
999    
1000        // Invoque the channel strip procedure,
1001            // for all channels out there...
1002        m_pWorkspace->setUpdatesEnabled(false);
1003        QWidgetList wlist = m_pWorkspace->windowList();
1004        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1005            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1006            if (pChannelStrip)
1007                    pChannelStrip->channelReset();
1008        }
1009        m_pWorkspace->setUpdatesEnabled(true);
1010  }  }
1011    
1012    
# Line 822  void qsamplerMainForm::viewMessages ( bo Line 1058  void qsamplerMainForm::viewMessages ( bo
1058  }  }
1059    
1060    
1061    // Show/hide the device configurator form.
1062    void qsamplerMainForm::viewDevices (void)
1063    {
1064        if (m_pOptions == NULL)
1065            return;
1066    
1067        if (m_pDeviceForm) {
1068            m_pOptions->saveWidgetGeometry(m_pDeviceForm);
1069                    m_pDeviceForm->setClient(m_pClient);
1070            if (m_pDeviceForm->isVisible()) {
1071                m_pDeviceForm->hide();
1072            } else {
1073                m_pDeviceForm->show();
1074                m_pDeviceForm->raise();
1075                m_pDeviceForm->setActiveWindow();
1076            }
1077        }
1078    }
1079    
1080    
1081  // Show options dialog.  // Show options dialog.
1082  void qsamplerMainForm::viewOptions (void)  void qsamplerMainForm::viewOptions (void)
1083  {  {
# Line 831  void qsamplerMainForm::viewOptions (void Line 1087  void qsamplerMainForm::viewOptions (void
1087      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);      qsamplerOptionsForm *pOptionsForm = new qsamplerOptionsForm(this);
1088      if (pOptionsForm) {      if (pOptionsForm) {
1089          // Check out some initial nullities(tm)...          // Check out some initial nullities(tm)...
1090          qsamplerChannelStrip *pChannel = activeChannel();          qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1091          if (m_pOptions->sDisplayFont.isEmpty() && pChannel)          if (m_pOptions->sDisplayFont.isEmpty() && pChannelStrip)
1092              m_pOptions->sDisplayFont = pChannel->displayFont().toString();              m_pOptions->sDisplayFont = pChannelStrip->displayFont().toString();
1093          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)          if (m_pOptions->sMessagesFont.isEmpty() && m_pMessages)
1094              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();              m_pOptions->sMessagesFont = m_pMessages->messagesFont().toString();
1095          // To track down deferred or immediate changes.          // To track down deferred or immediate changes.
# Line 843  void qsamplerMainForm::viewOptions (void Line 1099  void qsamplerMainForm::viewOptions (void
1099          bool    bOldServerStart     = m_pOptions->bServerStart;          bool    bOldServerStart     = m_pOptions->bServerStart;
1100          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;          QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1101          QString sOldDisplayFont     = m_pOptions->sDisplayFont;          QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1102            bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1103          int     iOldMaxVolume       = m_pOptions->iMaxVolume;          int     iOldMaxVolume       = m_pOptions->iMaxVolume;
1104          QString sOldMessagesFont    = m_pOptions->sMessagesFont;          QString sOldMessagesFont    = m_pOptions->sMessagesFont;
1105            bool    bOldKeepOnTop       = m_pOptions->bKeepOnTop;
1106          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;          bool    bOldStdoutCapture   = m_pOptions->bStdoutCapture;
1107          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;          int     bOldMessagesLimit   = m_pOptions->bMessagesLimit;
1108          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;          int     iOldMessagesLimitLines = m_pOptions->iMessagesLimitLines;
1109          bool    bOldCompletePath    = m_pOptions->bCompletePath;          bool    bOldCompletePath    = m_pOptions->bCompletePath;
1110            bool    bOldInstrumentNames = m_pOptions->bInstrumentNames;
1111          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;          int     iOldMaxRecentFiles  = m_pOptions->iMaxRecentFiles;
1112          // Load the current setup settings.          // Load the current setup settings.
1113          pOptionsForm->setup(m_pOptions);          pOptionsForm->setup(m_pOptions);
# Line 856  void qsamplerMainForm::viewOptions (void Line 1115  void qsamplerMainForm::viewOptions (void
1115          if (pOptionsForm->exec()) {          if (pOptionsForm->exec()) {
1116              // Warn if something will be only effective on next run.              // Warn if something will be only effective on next run.
1117              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||              if (( bOldStdoutCapture && !m_pOptions->bStdoutCapture) ||
1118                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture)) {                  (!bOldStdoutCapture &&  m_pOptions->bStdoutCapture) ||
1119                    ( bOldKeepOnTop     && !m_pOptions->bKeepOnTop)     ||
1120                    (!bOldKeepOnTop     &&  m_pOptions->bKeepOnTop)) {
1121                  QMessageBox::information(this, tr("Information"),                  QMessageBox::information(this, tr("Information"),
1122                      tr("Some settings may be only effective\n"                      tr("Some settings may be only effective\n"
1123                         "next time you start this program."), tr("OK"));                         "next time you start this program."), tr("OK"));
# Line 867  void qsamplerMainForm::viewOptions (void Line 1128  void qsamplerMainForm::viewOptions (void
1128                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1129                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
1130                  updateRecentFilesMenu();                  updateRecentFilesMenu();
1131                if (( bOldInstrumentNames && !m_pOptions->bInstrumentNames) ||
1132                    (!bOldInstrumentNames &&  m_pOptions->bInstrumentNames))
1133                    updateInstrumentNames();
1134                if (( bOldDisplayEffect && !m_pOptions->bDisplayEffect) ||
1135                    (!bOldDisplayEffect &&  m_pOptions->bDisplayEffect))
1136                    updateDisplayEffect();
1137              if (sOldDisplayFont != m_pOptions->sDisplayFont)              if (sOldDisplayFont != m_pOptions->sDisplayFont)
1138                  updateDisplayFont();                  updateDisplayFont();
1139              if (iOldMaxVolume != m_pOptions->iMaxVolume)              if (iOldMaxVolume != m_pOptions->iMaxVolume)
# Line 909  void qsamplerMainForm::channelsArrange ( Line 1176  void qsamplerMainForm::channelsArrange (
1176      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1177      int y = 0;      int y = 0;
1178      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1179          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1180      /*  if (pChannel->testWState(WState_Maximized | WState_Minimized)) {      /*  if (pChannelStrip->testWState(WState_Maximized | WState_Minimized)) {
1181              // Prevent flicker...              // Prevent flicker...
1182              pChannel->hide();              pChannelStrip->hide();
1183              pChannel->showNormal();              pChannelStrip->showNormal();
1184          }   */          }   */
1185          pChannel->adjustSize();          pChannelStrip->adjustSize();
1186          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1187          if (iWidth < pChannel->width())          if (iWidth < pChannelStrip->width())
1188              iWidth = pChannel->width();              iWidth = pChannelStrip->width();
1189      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1190          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1191          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1192          y += iHeight;          y += iHeight;
1193      }      }
1194      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
# Line 969  void qsamplerMainForm::helpAbout (void) Line 1236  void qsamplerMainForm::helpAbout (void)
1236      sText += tr("Debugging option enabled.");      sText += tr("Debugging option enabled.");
1237      sText += "</font></small><br />";      sText += "</font></small><br />";
1238  #endif  #endif
1239    #ifndef CONFIG_LIBGIG
1240        sText += "<small><font color=\"red\">";
1241        sText += tr("GIG (libgig) file support disabled.");
1242        sText += "</font></small><br />";
1243    #endif
1244    #ifndef CONFIG_INSTRUMENT_NAME
1245        sText += "<small><font color=\"red\">";
1246        sText += tr("LSCP (liblscp) instrument_name support disabled.");
1247        sText += "</font></small><br />";
1248    #endif
1249      sText += "<br />\n";      sText += "<br />\n";
1250      sText += tr("Using") + ": ";      sText += tr("Using") + ": ";
1251      sText += ::lscp_client_package();      sText += ::lscp_client_package();
# Line 996  void qsamplerMainForm::helpAbout (void) Line 1273  void qsamplerMainForm::helpAbout (void)
1273  void qsamplerMainForm::stabilizeForm (void)  void qsamplerMainForm::stabilizeForm (void)
1274  {  {
1275      // Update the main application caption...      // Update the main application caption...
1276      QString sSessioName = sessionName(m_sFilename);      QString sSessionName = sessionName(m_sFilename);
1277      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1278          sSessioName += '*';          sSessionName += '*';
1279      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessioName));      setCaption(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1280    
1281      // Update the main menu state...      // Update the main menu state...
1282      qsamplerChannelStrip *pChannel = activeChannel();      qsamplerChannelStrip *pChannelStrip = activeChannelStrip();
1283      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);      bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);
1284      bool bHasChannel = (bHasClient && pChannel != NULL);      bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1285      fileNewAction->setEnabled(bHasClient);      fileNewAction->setEnabled(bHasClient);
1286      fileOpenAction->setEnabled(bHasClient);      fileOpenAction->setEnabled(bHasClient);
1287      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);      fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
1288      fileSaveAsAction->setEnabled(bHasClient);      fileSaveAsAction->setEnabled(bHasClient);
1289        fileResetAction->setEnabled(bHasClient);
1290      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);      fileRestartAction->setEnabled(bHasClient || m_pServer == NULL);
1291      editAddChannelAction->setEnabled(bHasClient);      editAddChannelAction->setEnabled(bHasClient);
1292      editRemoveChannelAction->setEnabled(bHasChannel);      editRemoveChannelAction->setEnabled(bHasChannel);
1293      editSetupChannelAction->setEnabled(bHasChannel);      editSetupChannelAction->setEnabled(bHasChannel);
1294      editResetChannelAction->setEnabled(bHasChannel);      editResetChannelAction->setEnabled(bHasChannel);
1295      channelsArrangeAction->setEnabled(bHasChannel);      editResetAllChannelsAction->setEnabled(bHasChannel);
1296      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());      viewMessagesAction->setOn(m_pMessages && m_pMessages->isVisible());
1297        viewDevicesAction->setOn(m_pDeviceForm && m_pDeviceForm->isVisible());
1298        viewDevicesAction->setEnabled(bHasClient);
1299        channelsArrangeAction->setEnabled(bHasChannel);
1300    
1301      // Client/Server status...      // Client/Server status...
1302      if (bHasClient) {      if (bHasClient) {
1303          m_status[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));          m_statusItem[QSAMPLER_STATUS_CLIENT]->setText(tr("Connected"));
1304          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));
1305      } else {      } else {
1306          m_status[QSAMPLER_STATUS_CLIENT]->clear();          m_statusItem[QSAMPLER_STATUS_CLIENT]->clear();
1307          m_status[QSAMPLER_STATUS_SERVER]->clear();          m_statusItem[QSAMPLER_STATUS_SERVER]->clear();
1308      }      }
1309      // Channel status...      // Channel status...
1310      if (bHasChannel)      if (bHasChannel)
1311          m_status[QSAMPLER_STATUS_CHANNEL]->setText(pChannel->caption());          m_statusItem[QSAMPLER_STATUS_CHANNEL]->setText(pChannelStrip->caption());
1312      else      else
1313          m_status[QSAMPLER_STATUS_CHANNEL]->clear();          m_statusItem[QSAMPLER_STATUS_CHANNEL]->clear();
1314      // Session status...      // Session status...
1315      if (m_iDirtyCount > 0)      if (m_iDirtyCount > 0)
1316          m_status[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));          m_statusItem[QSAMPLER_STATUS_SESSION]->setText(tr("MOD"));
1317      else      else
1318          m_status[QSAMPLER_STATUS_SESSION]->clear();          m_statusItem[QSAMPLER_STATUS_SESSION]->clear();
1319    
1320      // Recent files menu.      // Recent files menu.
1321      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);      m_pRecentFilesMenu->setEnabled(bHasClient && m_pOptions->recentFiles.count() > 0);
# Line 1046  void qsamplerMainForm::stabilizeForm (vo Line 1327  void qsamplerMainForm::stabilizeForm (vo
1327    
1328    
1329  // Channel change receiver slot.  // Channel change receiver slot.
1330  void qsamplerMainForm::channelChanged( qsamplerChannelStrip * )  void qsamplerMainForm::channelStripChanged( qsamplerChannelStrip *pChannelStrip )
1331  {  {
1332            // Add this strip to the changed list...
1333            if (m_changedStrips.containsRef(pChannelStrip) == 0)
1334                    m_changedStrips.append(pChannelStrip);
1335    
1336      // Just mark the dirty form.      // Just mark the dirty form.
1337      m_iDirtyCount++;      m_iDirtyCount++;
1338      // and update the form status...      // and update the form status...
# Line 1055  void qsamplerMainForm::channelChanged( q Line 1340  void qsamplerMainForm::channelChanged( q
1340  }  }
1341    
1342    
1343    // Grab and restore current sampler channels session.
1344    void qsamplerMainForm::updateSession (void)
1345    {
1346            // Retrieve the current channel list.
1347            int *piChannelIDs = ::lscp_list_channels(m_pClient);
1348            if (piChannelIDs == NULL) {
1349                    if (::lscp_client_get_errno(m_pClient)) {
1350                            appendMessagesClient("lscp_list_channels");
1351                            appendMessagesError(tr("Could not get current list of channels.\n\nSorry."));
1352                    }
1353                    return;
1354            }
1355    
1356            // Try to (re)create each channel.
1357            m_pWorkspace->setUpdatesEnabled(false);
1358            for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1359                    // Check if theres already a channel strip for this one...
1360                    if (!channelStrip(piChannelIDs[iChannel]))
1361                            createChannelStrip(new qsamplerChannel(this, piChannelIDs[iChannel]));
1362                    // Make it visibly responsive...
1363                    QApplication::eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
1364            }
1365            m_pWorkspace->setUpdatesEnabled(true);
1366    }
1367    
1368    
1369  // Update the recent files list and menu.  // Update the recent files list and menu.
1370  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )  void qsamplerMainForm::updateRecentFiles ( const QString& sFilename )
1371  {  {
# Line 1099  void qsamplerMainForm::updateRecentFiles Line 1410  void qsamplerMainForm::updateRecentFiles
1410  }  }
1411    
1412    
1413    // Force update of the channels instrument names mode.
1414    void qsamplerMainForm::updateInstrumentNames (void)
1415    {
1416        // Full channel list update...
1417        QWidgetList wlist = m_pWorkspace->windowList();
1418        if (wlist.isEmpty())
1419            return;
1420    
1421        m_pWorkspace->setUpdatesEnabled(false);
1422        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1423            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1424            if (pChannelStrip)
1425                pChannelStrip->updateInstrumentName(true);
1426        }
1427        m_pWorkspace->setUpdatesEnabled(true);
1428    }
1429    
1430    
1431  // Force update of the channels display font.  // Force update of the channels display font.
1432  void qsamplerMainForm::updateDisplayFont (void)  void qsamplerMainForm::updateDisplayFont (void)
1433  {  {
# Line 1120  void qsamplerMainForm::updateDisplayFont Line 1449  void qsamplerMainForm::updateDisplayFont
1449    
1450      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1451      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1452          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1453          pChannel->setDisplayFont(font);          if (pChannelStrip)
1454                pChannelStrip->setDisplayFont(font);
1455        }
1456        m_pWorkspace->setUpdatesEnabled(true);
1457    }
1458    
1459    
1460    // Update channel strips background effect.
1461    void qsamplerMainForm::updateDisplayEffect (void)
1462    {
1463       QPixmap pm;
1464        if (m_pOptions->bDisplayEffect)
1465            pm = QPixmap::fromMimeSource("displaybg1.png");
1466    
1467        // Full channel list update...
1468        QWidgetList wlist = m_pWorkspace->windowList();
1469        if (wlist.isEmpty())
1470            return;
1471    
1472        m_pWorkspace->setUpdatesEnabled(false);
1473        for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1474            qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1475            if (pChannelStrip)
1476                pChannelStrip->setDisplayBackground(pm);
1477      }      }
1478      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1479  }  }
# Line 1140  void qsamplerMainForm::updateMaxVolume ( Line 1492  void qsamplerMainForm::updateMaxVolume (
1492    
1493      m_pWorkspace->setUpdatesEnabled(false);      m_pWorkspace->setUpdatesEnabled(false);
1494      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {      for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1495          qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);          qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1496          pChannel->setMaxVolume(m_pOptions->iMaxVolume);          if (pChannelStrip)
1497                pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1498      }      }
1499      m_pWorkspace->setUpdatesEnabled(true);      m_pWorkspace->setUpdatesEnabled(true);
1500  }  }
# Line 1240  void qsamplerMainForm::updateMessagesCap Line 1593  void qsamplerMainForm::updateMessagesCap
1593  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
1594    
1595  // The channel strip creation executive.  // The channel strip creation executive.
1596  void qsamplerMainForm::createChannel ( int iChannelID, bool bPrompt )  qsamplerChannelStrip *qsamplerMainForm::createChannelStrip ( qsamplerChannel *pChannel )
1597  {  {
1598      if (m_pClient == NULL)      if (m_pClient == NULL || pChannel == NULL)
1599          return;          return NULL;
1600    
1601      // Prepare for auto-arrange?      // Prepare for auto-arrange?
1602      qsamplerChannelStrip *pChannel = NULL;      qsamplerChannelStrip *pChannelStrip = NULL;
1603      int y = 0;      int y = 0;
1604      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1605          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
1606          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1607              pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1608          //  y += pChannel->height() + pChannel->parentWidget()->baseSize().height();                          if (pChannelStrip) {
1609              y += pChannel->parentWidget()->frameGeometry().height();                          //  y += pChannelStrip->height() + pChannelStrip->parentWidget()->baseSize().height();
1610                                    y += pChannelStrip->parentWidget()->frameGeometry().height();
1611                            }
1612          }          }
1613      }      }
1614    
1615      // Add a new channel itema...      // Add a new channel itema...
1616      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;
1617      pChannel = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);      pChannelStrip = new qsamplerChannelStrip(m_pWorkspace, 0, wflags);
1618      pChannel->setMaxVolume(m_pOptions->iMaxVolume);      if (pChannelStrip == NULL)
1619      pChannel->setup(this, iChannelID);          return NULL;
1620      // We'll need a display font.          
1621      QFont font;      // Actual channel strip setup...
1622      if (m_pOptions && font.fromString(m_pOptions->sDisplayFont))      pChannelStrip->setup(pChannel);
1623          pChannel->setDisplayFont(font);      QObject::connect(pChannelStrip, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelStripChanged(qsamplerChannelStrip *)));
1624      // Track channel setup changes.      // Set some initial aesthetic options...
1625      QObject::connect(pChannel, SIGNAL(channelChanged(qsamplerChannelStrip *)), this, SLOT(channelChanged(qsamplerChannelStrip *)));      if (m_pOptions) {
1626      // Before we show it up, may be we'll          // Background display effect...
1627      // better ask for some initial values?          pChannelStrip->setDisplayEffect(m_pOptions->bDisplayEffect);
1628      if (bPrompt)          // We'll need a display font.
1629          pChannel->channelSetup();                QFont font;
1630            if (font.fromString(m_pOptions->sDisplayFont))
1631                pChannelStrip->setDisplayFont(font);
1632            // Maximum allowed volume setting.
1633            pChannelStrip->setMaxVolume(m_pOptions->iMaxVolume);
1634        }
1635    
1636      // Now we show up us to the world.      // Now we show up us to the world.
1637      pChannel->show();      pChannelStrip->show();
1638      // Only then, we'll auto-arrange...      // Only then, we'll auto-arrange...
1639      if (m_pOptions && m_pOptions->bAutoArrange) {      if (m_pOptions && m_pOptions->bAutoArrange) {
1640          int iWidth  = m_pWorkspace->width();          int iWidth  = m_pWorkspace->width();
1641      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();      //  int iHeight = pChannel->height() + pChannel->parentWidget()->baseSize().height();
1642          int iHeight = pChannel->parentWidget()->frameGeometry().height();          int iHeight = pChannelStrip->parentWidget()->frameGeometry().height();
1643          pChannel->parentWidget()->setGeometry(0, y, iWidth, iHeight);          pChannelStrip->parentWidget()->setGeometry(0, y, iWidth, iHeight);
1644      }      }
1645    
1646            // This is pretty new, so we'll watch for it closely.
1647            channelStripChanged(pChannelStrip);
1648    
1649        // Return our successful reference...
1650        return pChannelStrip;
1651  }  }
1652    
1653    
1654  // Retrieve the active channel strip.  // Retrieve the active channel strip.
1655  qsamplerChannelStrip *qsamplerMainForm::activeChannel (void)  qsamplerChannelStrip *qsamplerMainForm::activeChannelStrip (void)
1656  {  {
1657      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();      return (qsamplerChannelStrip *) m_pWorkspace->activeWindow();
1658  }  }
1659    
1660    
1661  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
1662  qsamplerChannelStrip *qsamplerMainForm::channelAt ( int iChannel )  qsamplerChannelStrip *qsamplerMainForm::channelStripAt ( int iChannel )
1663  {  {
1664      QWidgetList wlist = m_pWorkspace->windowList();      QWidgetList wlist = m_pWorkspace->windowList();
1665      if (wlist.isEmpty())      if (wlist.isEmpty())
1666          return 0;          return NULL;
1667    
1668      return (qsamplerChannelStrip *) wlist.at(iChannel);      return (qsamplerChannelStrip *) wlist.at(iChannel);
1669  }  }
1670    
1671    
1672    // Retrieve a channel strip by sampler channel id.
1673    qsamplerChannelStrip *qsamplerMainForm::channelStrip ( int iChannelID )
1674    {
1675            QWidgetList wlist = m_pWorkspace->windowList();
1676            if (wlist.isEmpty())
1677                    return NULL;
1678            
1679            for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1680                    qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1681                    if (pChannelStrip) {
1682                            qsamplerChannel *pChannel = pChannelStrip->channel();
1683                            if (pChannel && pChannel->channelID() == iChannelID)
1684                                    return pChannelStrip;
1685                    }
1686            }
1687    
1688            // Not found.
1689            return NULL;
1690    }
1691    
1692    
1693  // Construct the windows menu.  // Construct the windows menu.
1694  void qsamplerMainForm::channelsMenuAboutToShow (void)  void qsamplerMainForm::channelsMenuAboutToShow (void)
1695  {  {
# Line 1313  void qsamplerMainForm::channelsMenuAbout Line 1701  void qsamplerMainForm::channelsMenuAbout
1701      if (!wlist.isEmpty()) {      if (!wlist.isEmpty()) {
1702          channelsMenu->insertSeparator();          channelsMenu->insertSeparator();
1703          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {          for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1704              qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);              qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1705              int iItemID = channelsMenu->insertItem(pChannel->caption(), this, SLOT(channelsMenuActivated(int)));              if (pChannelStrip) {
1706              channelsMenu->setItemParameter(iItemID, iChannel);                  int iItemID = channelsMenu->insertItem(pChannelStrip->caption(), this, SLOT(channelsMenuActivated(int)));
1707              channelsMenu->setItemChecked(iItemID, activeChannel() == pChannel);                  channelsMenu->setItemParameter(iItemID, iChannel);
1708                    channelsMenu->setItemChecked(iItemID, activeChannelStrip() == pChannelStrip);
1709                }
1710          }          }
1711      }      }
1712  }  }
# Line 1325  void qsamplerMainForm::channelsMenuAbout Line 1715  void qsamplerMainForm::channelsMenuAbout
1715  // Windows menu activation slot  // Windows menu activation slot
1716  void qsamplerMainForm::channelsMenuActivated ( int iChannel )  void qsamplerMainForm::channelsMenuActivated ( int iChannel )
1717  {  {
1718      qsamplerChannelStrip *pChannel = channelAt(iChannel);      qsamplerChannelStrip *pChannelStrip = channelStripAt(iChannel);
1719      if (pChannel)      if (pChannelStrip)
1720          pChannel->showNormal();          pChannelStrip->showNormal();
1721      pChannel->setFocus();      pChannelStrip->setFocus();
1722  }  }
1723    
1724    
# Line 1368  void qsamplerMainForm::timerSlot (void) Line 1758  void qsamplerMainForm::timerSlot (void)
1758      }      }
1759            
1760          // Refresh each channel usage, on each period...          // Refresh each channel usage, on each period...
1761      if (m_pClient && m_pOptions->bAutoRefresh && m_pWorkspace->isUpdatesEnabled()) {      if (m_pClient && (m_changedStrips.count() > 0 || m_pOptions->bAutoRefresh)) {
1762          m_iTimerSlot += QSAMPLER_TIMER_MSECS;          m_iTimerSlot += QSAMPLER_TIMER_MSECS;
1763          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime)  {          if (m_iTimerSlot >= m_pOptions->iAutoRefreshTime && m_pWorkspace->isUpdatesEnabled())  {
1764              m_iTimerSlot = 0;              m_iTimerSlot = 0;
1765                // Update the channel information for each pending strip...
1766                for (qsamplerChannelStrip *pChannelStrip = m_changedStrips.first();
1767                        pChannelStrip;
1768                                                    pChannelStrip = m_changedStrips.next()) {
1769                                    // If successfull, remove from pending list...
1770                                    if (pChannelStrip->updateChannelInfo())
1771                        m_changedStrips.remove(pChannelStrip);
1772                            }
1773                // Update the channel stream usage for each strip...
1774              QWidgetList wlist = m_pWorkspace->windowList();              QWidgetList wlist = m_pWorkspace->windowList();
1775              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {              for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
1776                  qsamplerChannelStrip *pChannel = (qsamplerChannelStrip *) wlist.at(iChannel);                  qsamplerChannelStrip *pChannelStrip = (qsamplerChannelStrip *) wlist.at(iChannel);
1777                  if (pChannel->isVisible())                  if (pChannelStrip && pChannelStrip->isVisible())
1778                      pChannel->updateChannelUsage();                      pChannelStrip->updateChannelUsage();
1779              }              }
1780          }          }
1781      }      }
# Line 1513  void qsamplerMainForm::processServerExit Line 1912  void qsamplerMainForm::processServerExit
1912  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1913  // qsamplerMainForm -- Client stuff.  // qsamplerMainForm -- Client stuff.
1914    
   
1915  // The LSCP client callback procedure.  // The LSCP client callback procedure.
1916  lscp_status_t qsampler_client_callback ( lscp_client_t *pClient, const char *pchBuffer, int cchBuffer, void *pvData )  lscp_status_t qsampler_client_callback ( lscp_client_t */*pClient*/, lscp_event_t event, const char *pchData, int cchData, void *pvData )
1917  {  {
1918      qsamplerMainForm *pMainForm = (qsamplerMainForm *) pvData;      qsamplerMainForm *pMainForm = (qsamplerMainForm *) pvData;
1919      if (pMainForm == NULL)      if (pMainForm == NULL)
1920          return LSCP_FAILED;          return LSCP_FAILED;
1921    
1922      char *pszBuffer = (char *) malloc(cchBuffer + 1);      // ATTN: DO NOT EVER call any GUI code here,
1923      if (pszBuffer == NULL)      // as this is run under some other thread context.
1924          return LSCP_FAILED;      // A custom event must be posted here...
1925        QApplication::postEvent(pMainForm, new qsamplerCustomEvent(event, pchData, cchData));
     memcpy(pszBuffer, pchBuffer, cchBuffer);  
     pszBuffer[cchBuffer] = (char) 0;  
     pMainForm->appendMessagesColor(pszBuffer, "#996699");  
     free(pszBuffer);  
1926    
1927      return LSCP_OK;      return LSCP_OK;
1928  }  }
# Line 1574  bool qsamplerMainForm::startClient (void Line 1968  bool qsamplerMainForm::startClient (void
1968      // Log success here.      // Log success here.
1969      appendMessages(tr("Client connected."));      appendMessages(tr("Client connected."));
1970    
1971            // Hard-notify device configuration form,
1972            // if visible, that we're ready...
1973            if (m_pDeviceForm && m_pDeviceForm->isVisible())
1974                m_pDeviceForm->setClient(m_pClient);
1975                
1976      // Is any session pending to be loaded?      // Is any session pending to be loaded?
1977      if (!m_pOptions->sSessionFile.isEmpty()) {      if (!m_pOptions->sSessionFile.isEmpty()) {
1978          // Just load the prabably startup session...          // Just load the prabably startup session...
# Line 1594  void qsamplerMainForm::stopClient (void) Line 1993  void qsamplerMainForm::stopClient (void)
1993      if (m_pClient == NULL)      if (m_pClient == NULL)
1994          return;          return;
1995    
1996            // Hard-notify device configuration form,
1997            // if visible, that we're running out...
1998            if (m_pDeviceForm && m_pDeviceForm->isVisible())
1999                m_pDeviceForm->setClient(NULL);
2000    
2001      // Log prepare here.      // Log prepare here.
2002      appendMessages(tr("Client disconnecting..."));      appendMessages(tr("Client disconnecting..."));
2003    

Legend:
Removed from v.122  
changed lines
  Added in v.462

  ViewVC Help
Powered by ViewVC