/[svn]/qsampler/trunk/src/qsamplerDevice.cpp
ViewVC logotype

Diff of /qsampler/trunk/src/qsamplerDevice.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1477 by schoenebeck, Mon Nov 12 01:33:13 2007 UTC revision 2059 by capela, Wed Feb 17 19:50:04 2010 UTC
# Line 1  Line 1 
1  // qsamplerDevice.cpp  // qsamplerDevice.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2010, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, Christian Schoenebeck     Copyright (C) 2007, 2008 Christian Schoenebeck
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 "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
27  #include "qsamplerDeviceForm.h"  #include "qsamplerDeviceForm.h"
28    
29  #include <qspinbox.h>  #include <QCheckBox>
30  #include <qlineedit.h>  #include <QSpinBox>
31    #include <QLineEdit>
32    
33  using namespace QSampler;  
34    namespace QSampler {
35    
36  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
37  // qsamplerDeviceParam - MIDI/Audio Device parameter structure.  // QSampler::DeviceParam - MIDI/Audio Device parameter structure.
38  //  //
39    
40  // Constructors.  // Constructors.
41  qsamplerDeviceParam::qsamplerDeviceParam ( lscp_param_info_t *pParamInfo,  DeviceParam::DeviceParam ( lscp_param_info_t *pParamInfo,
42          const char *pszValue )          const char *pszValue )
43  {  {
44          setParam(pParamInfo, pszValue);          setParam(pParamInfo, pszValue);
# Line 44  qsamplerDeviceParam::qsamplerDeviceParam Line 46  qsamplerDeviceParam::qsamplerDeviceParam
46    
47    
48  // Default destructor.  // Default destructor.
49  qsamplerDeviceParam::~qsamplerDeviceParam (void)  DeviceParam::~DeviceParam (void)
50  {  {
51  }  }
52    
53    
54  // Initializer.  // Initializer.
55  void qsamplerDeviceParam::setParam ( lscp_param_info_t *pParamInfo,  void DeviceParam::setParam ( lscp_param_info_t *pParamInfo,
56          const char *pszValue )          const char *pszValue )
57  {  {
58          if (pParamInfo == NULL)          if (pParamInfo == NULL)
# Line 101  void qsamplerDeviceParam::setParam ( lsc Line 103  void qsamplerDeviceParam::setParam ( lsc
103    
104    
105  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
106  // qsamplerDevice - MIDI/Audio Device structure.  // QSampler::Device - MIDI/Audio Device structure.
107  //  //
108    
109  // Constructor.  // Constructor.
110  qsamplerDevice::qsamplerDevice ( qsamplerDeviceType deviceType, int iDeviceID )  Device::Device ( DeviceType deviceType, int iDeviceID )
111  {  {
112          m_ports.setAutoDelete(true);  //      m_ports.setAutoDelete(true);
113    
114          setDevice(deviceType, iDeviceID);          setDevice(deviceType, iDeviceID);
115  }  }
116    
117  // Default destructor.  // Default destructor.
118  qsamplerDevice::~qsamplerDevice (void)  Device::~Device (void)
119  {  {
120            qDeleteAll(m_ports);
121            m_ports.clear();
122  }  }
123    
124  // Copy constructor.  // Copy constructor.
125  qsamplerDevice::qsamplerDevice ( const qsamplerDevice& device )  Device::Device ( const Device& device )
126          : m_params(device.m_params), m_ports(m_ports)          : m_params(device.m_params), m_ports(device.m_ports)
127  {  {
128          m_iDeviceID   = device.m_iDeviceID;          m_iDeviceID   = device.m_iDeviceID;
129          m_deviceType  = device.m_deviceType;          m_deviceType  = device.m_deviceType;
# Line 130  qsamplerDevice::qsamplerDevice ( const q Line 134  qsamplerDevice::qsamplerDevice ( const q
134    
135    
136  // Initializer.  // Initializer.
137  void qsamplerDevice::setDevice ( qsamplerDeviceType deviceType, int iDeviceID )  void Device::setDevice ( DeviceType deviceType, int iDeviceID )
138  {  {
139          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
140          if (pMainForm == NULL)          if (pMainForm == NULL)
# Line 144  void qsamplerDevice::setDevice ( qsample Line 148  void qsamplerDevice::setDevice ( qsample
148    
149          // Reset device parameters and ports anyway.          // Reset device parameters and ports anyway.
150          m_params.clear();          m_params.clear();
151            qDeleteAll(m_ports);
152          m_ports.clear();          m_ports.clear();
153    
154          // Retrieve device info, if any.          // Retrieve device info, if any.
155          lscp_device_info_t *pDeviceInfo = NULL;          lscp_device_info_t *pDeviceInfo = NULL;
156          switch (deviceType) {          switch (deviceType) {
157          case qsamplerDevice::Audio:          case Device::Audio:
158                  m_sDeviceType = QObject::tr("Audio");                  m_sDeviceType = QObject::tr("Audio");
159                  if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_audio_device_info(                  if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_audio_device_info(
160                                  pMainForm->client(), m_iDeviceID)) == NULL)                                  pMainForm->client(), m_iDeviceID)) == NULL)
161                          appendMessagesClient("lscp_get_audio_device_info");                          appendMessagesClient("lscp_get_audio_device_info");
162                  break;                  break;
163          case qsamplerDevice::Midi:          case Device::Midi:
164                  m_sDeviceType = QObject::tr("MIDI");                  m_sDeviceType = QObject::tr("MIDI");
165                  if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_midi_device_info(                  if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_midi_device_info(
166                                  pMainForm->client(), m_iDeviceID)) == NULL)                                  pMainForm->client(), m_iDeviceID)) == NULL)
167                          appendMessagesClient("lscp_get_midi_device_info");                          appendMessagesClient("lscp_get_midi_device_info");
168                  break;                  break;
169          case qsamplerDevice::None:          case Device::None:
170                  m_sDeviceType = QString::null;                  m_sDeviceType = QString::null;
171                  break;                  break;
172          }          }
# Line 182  void qsamplerDevice::setDevice ( qsample Line 187  void qsamplerDevice::setDevice ( qsample
187                  const QString sParam = pDeviceInfo->params[i].key;                  const QString sParam = pDeviceInfo->params[i].key;
188                  lscp_param_info_t *pParamInfo = NULL;                  lscp_param_info_t *pParamInfo = NULL;
189                  switch (deviceType) {                  switch (deviceType) {
190                  case qsamplerDevice::Audio:                  case Device::Audio:
191                          if ((pParamInfo = ::lscp_get_audio_driver_param_info(pMainForm->client(),                          if ((pParamInfo = ::lscp_get_audio_driver_param_info(
192                                          m_sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)                                          pMainForm->client(), m_sDriverName.toUtf8().constData(),
193                                            sParam.toUtf8().constData(), NULL)) == NULL)
194                                  appendMessagesClient("lscp_get_audio_driver_param_info");                                  appendMessagesClient("lscp_get_audio_driver_param_info");
195                          break;                          break;
196                  case qsamplerDevice::Midi:                  case Device::Midi:
197                          if ((pParamInfo = ::lscp_get_midi_driver_param_info(pMainForm->client(),                          if ((pParamInfo = ::lscp_get_midi_driver_param_info(
198                                          m_sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)                                          pMainForm->client(), m_sDriverName.toUtf8().constData(),
199                                            sParam.toUtf8().constData(), NULL)) == NULL)
200                                  appendMessagesClient("lscp_get_midi_driver_param_info");                                  appendMessagesClient("lscp_get_midi_driver_param_info");
201                          break;                          break;
202                  case qsamplerDevice::None:                  case Device::None:
203                          break;                          break;
204                  }                  }
205                  if (pParamInfo) {                  if (pParamInfo) {
206                          m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,                          m_params[sParam.toUpper()] = DeviceParam(pParamInfo,
207                                  pDeviceInfo->params[i].value);                                  pDeviceInfo->params[i].value);
208                  }                  }
209          }          }
# Line 209  void qsamplerDevice::setDevice ( qsample Line 216  void qsamplerDevice::setDevice ( qsample
216    
217    
218  // Driver name initializer/settler.  // Driver name initializer/settler.
219  void qsamplerDevice::setDriver ( const QString& sDriverName )  void Device::setDriver ( const QString& sDriverName )
220  {  {
221          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
222          if (pMainForm == NULL)          if (pMainForm == NULL)
# Line 223  void qsamplerDevice::setDriver ( const Q Line 230  void qsamplerDevice::setDriver ( const Q
230    
231          // Reset device parameters and ports anyway.          // Reset device parameters and ports anyway.
232          m_params.clear();          m_params.clear();
233            qDeleteAll(m_ports);
234          m_ports.clear();          m_ports.clear();
235    
236          // Retrieve driver info, if any.          // Retrieve driver info, if any.
237          lscp_driver_info_t *pDriverInfo = NULL;          lscp_driver_info_t *pDriverInfo = NULL;
238          switch (m_deviceType) {          switch (m_deviceType) {
239          case qsamplerDevice::Audio:          case Device::Audio:
240                  if ((pDriverInfo = ::lscp_get_audio_driver_info(pMainForm->client(),                  if ((pDriverInfo = ::lscp_get_audio_driver_info(pMainForm->client(),
241                                  sDriverName.latin1())) == NULL)                                  sDriverName.toUtf8().constData())) == NULL)
242                          appendMessagesClient("lscp_get_audio_driver_info");                          appendMessagesClient("lscp_get_audio_driver_info");
243                  break;                  break;
244          case qsamplerDevice::Midi:          case Device::Midi:
245                  if ((pDriverInfo = ::lscp_get_midi_driver_info(pMainForm->client(),                  if ((pDriverInfo = ::lscp_get_midi_driver_info(pMainForm->client(),
246                                  sDriverName.latin1())) == NULL)                                  sDriverName.toUtf8().constData())) == NULL)
247                          appendMessagesClient("lscp_get_midi_driver_info");                          appendMessagesClient("lscp_get_midi_driver_info");
248                  break;                  break;
249          case qsamplerDevice::None:          case Device::None:
250                  break;                  break;
251          }          }
252    
# Line 254  void qsamplerDevice::setDriver ( const Q Line 262  void qsamplerDevice::setDriver ( const Q
262                  const QString sParam = pDriverInfo->parameters[i];                  const QString sParam = pDriverInfo->parameters[i];
263                  lscp_param_info_t *pParamInfo = NULL;                  lscp_param_info_t *pParamInfo = NULL;
264                  switch (m_deviceType) {                  switch (m_deviceType) {
265                  case qsamplerDevice::Audio:                  case Device::Audio:
266                          if ((pParamInfo = ::lscp_get_audio_driver_param_info(pMainForm->client(),                          if ((pParamInfo = ::lscp_get_audio_driver_param_info(
267                                          sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)                                          pMainForm->client(), sDriverName.toUtf8().constData(),
268                                            sParam.toUtf8().constData(), NULL)) == NULL)
269                                  appendMessagesClient("lscp_get_audio_driver_param_info");                                  appendMessagesClient("lscp_get_audio_driver_param_info");
270                          break;                          break;
271                  case qsamplerDevice::Midi:                  case Device::Midi:
272                          if ((pParamInfo = ::lscp_get_midi_driver_param_info(pMainForm->client(),                          if ((pParamInfo = ::lscp_get_midi_driver_param_info(
273                                          sDriverName.latin1(), sParam.latin1(), NULL)) == NULL)                                          pMainForm->client(), sDriverName.toUtf8().constData(),
274                                            sParam.toUtf8().constData(), NULL)) == NULL)
275                                  appendMessagesClient("lscp_get_midi_driver_param_info");                                  appendMessagesClient("lscp_get_midi_driver_param_info");
276                          break;                          break;
277                  case qsamplerDevice::None:                  case Device::None:
278                          break;                          break;
279                  }                  }
280                  if (pParamInfo) {                  if (pParamInfo) {
281                          m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,                          m_params[sParam.toUpper()] = DeviceParam(pParamInfo,
282                                  pParamInfo->defaultv);                                  pParamInfo->defaultv);
283                  }                  }
284          }          }
# Line 281  void qsamplerDevice::setDriver ( const Q Line 291  void qsamplerDevice::setDriver ( const Q
291    
292    
293  // Device property accessors.  // Device property accessors.
294  int qsamplerDevice::deviceID (void) const  int Device::deviceID (void) const
295  {  {
296          return m_iDeviceID;          return m_iDeviceID;
297  }  }
298    
299  qsamplerDevice::qsamplerDeviceType qsamplerDevice::deviceType (void) const  Device::DeviceType Device::deviceType (void) const
300  {  {
301          return m_deviceType;          return m_deviceType;
302  }  }
303    
304  const QString& qsamplerDevice::deviceTypeName (void) const  const QString& Device::deviceTypeName (void) const
305  {  {
306          return m_sDeviceType;          return m_sDeviceType;
307  }  }
308    
309  const QString& qsamplerDevice::driverName (void) const  const QString& Device::driverName (void) const
310  {  {
311          return m_sDriverName;          return m_sDriverName;
312  }  }
313    
314  // Special device name formatter.  // Special device name formatter.
315  QString qsamplerDevice::deviceName (void) const  QString Device::deviceName (void) const
316  {  {
317          QString sPrefix;          QString sPrefix;
318          if (m_iDeviceID >= 0)          if (m_iDeviceID >= 0)
319              sPrefix += m_sDeviceType + ' ';                  sPrefix += m_sDeviceType + ' ';
320          return sPrefix + m_sDeviceName;          return sPrefix + m_sDeviceName;
321  }  }
322    
323    
324  // Set the proper device parameter value.  // Set the proper device parameter value.
325  bool qsamplerDevice::setParam ( const QString& sParam,  bool Device::setParam ( const QString& sParam,
326          const QString& sValue )          const QString& sValue )
327  {  {
328          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
# Line 322  bool qsamplerDevice::setParam ( const QS Line 332  bool qsamplerDevice::setParam ( const QS
332                  return false;                  return false;
333    
334          // Set proper device parameter.          // Set proper device parameter.
335          m_params[sParam.upper()].value = sValue;          m_params[sParam.toUpper()].value = sValue;
336    
337          // If the device already exists, things get immediate...          // If the device already exists, things get immediate...
338          int iRefresh = 0;          int iRefresh = 0;
339          if (m_iDeviceID >= 0) {          if (m_iDeviceID >= 0 && sValue != QString::null) {
340    
341                    // we need temporary byte arrrays with the final strings, because
342                    // i.e. QString::toUtf8() only returns a temporary object and the
343                    // C-style char* pointers for liblscp would immediately be invalidated
344                    QByteArray finalParamKey = sParam.toUtf8();
345                    QByteArray finalParamVal = sValue.toUtf8();
346    
347                  // Prepare parameter struct.                  // Prepare parameter struct.
348                  lscp_param_t param;                  lscp_param_t param;
349                  param.key   = (char *) sParam.latin1();                  param.key   = (char *) finalParamKey.constData();
350                  param.value = (char *) sValue.latin1();                  param.value = (char *) finalParamVal.constData();
351                  // Now it depends on the device type...                  // Now it depends on the device type...
352                  lscp_status_t ret = LSCP_FAILED;                  lscp_status_t ret = LSCP_FAILED;
353                  switch (m_deviceType) {                  switch (m_deviceType) {
354                  case qsamplerDevice::Audio:                  case Device::Audio:
355                      if (sParam == "CHANNELS") iRefresh++;                          if (sParam == "CHANNELS") iRefresh++;
356                          if ((ret = ::lscp_set_audio_device_param(pMainForm->client(),                          if ((ret = ::lscp_set_audio_device_param(pMainForm->client(),
357                                          m_iDeviceID, &param)) != LSCP_OK)                                          m_iDeviceID, &param)) != LSCP_OK)
358                                  appendMessagesClient("lscp_set_audio_device_param");                                  appendMessagesClient("lscp_set_audio_device_param");
359                          break;                          break;
360                  case qsamplerDevice::Midi:                  case Device::Midi:
361                      if (sParam == "PORTS") iRefresh++;                          if (sParam == "PORTS") iRefresh++;
362                          if ((ret = ::lscp_set_midi_device_param(pMainForm->client(),                          if ((ret = ::lscp_set_midi_device_param(pMainForm->client(),
363                                          m_iDeviceID, &param)) != LSCP_OK)                                          m_iDeviceID, &param)) != LSCP_OK)
364                                  appendMessagesClient("lscp_set_midi_device_param");                                  appendMessagesClient("lscp_set_midi_device_param");
365                          break;                          break;
366                  case qsamplerDevice::None:                  case Device::None:
367                          break;                          break;
368                  }                  }
369                  // Show result.                  // Show result.
# Line 369  bool qsamplerDevice::setParam ( const QS Line 386  bool qsamplerDevice::setParam ( const QS
386    
387    
388  // Device parameter accessor.  // Device parameter accessor.
389  const qsamplerDeviceParamMap& qsamplerDevice::params (void) const  const DeviceParamMap& Device::params (void) const
390  {  {
391          return m_params;          return m_params;
392  }  }
393    
394    
395  // Device port/channel list accessor.  // Device port/channel list accessor.
396  qsamplerDevicePortList& qsamplerDevice::ports (void)  DevicePortList& Device::ports (void)
397  {  {
398          return m_ports;          return m_ports;
399  }  }
400    
401    
402  // Create a new device, as a copy of this current one.  // Create a new device, as a copy of this current one.
403  bool qsamplerDevice::createDevice (void)  bool Device::createDevice (void)
404  {  {
405          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
406          if (pMainForm == NULL)          if (pMainForm == NULL)
# Line 391  bool qsamplerDevice::createDevice (void) Line 408  bool qsamplerDevice::createDevice (void)
408          if (pMainForm->client() == NULL)          if (pMainForm->client() == NULL)
409                  return false;                  return false;
410    
411          // Build the parameter list...          // we need temporary lists with the final strings, because i.e.
412          lscp_param_t *pParams = new lscp_param_t [m_params.count() + 1];          // QString::toUtf8() only returns a temporary object and the
413          int iParam = 0;          // C-style char* pointers for liblscp would immediately be invalidated
414          qsamplerDeviceParamMap::ConstIterator iter;          QList<QByteArray> finalKeys;
415            QList<QByteArray> finalVals;
416    
417            DeviceParamMap::ConstIterator iter;
418          for (iter = m_params.begin(); iter != m_params.end(); ++iter) {          for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
419                  pParams[iParam].key   = (char *) iter.key().latin1();                  if (iter.value().value == QString::null) continue;
420                  pParams[iParam].value = (char *) iter.data().value.latin1();                  finalKeys.push_back(iter.key().toUtf8());
421                  ++iParam;                  finalVals.push_back(iter.value().value.toUtf8());
422            }
423    
424            // yeah, we DO HAVE to do the two loops separately !
425    
426            // Build the parameter list...
427            lscp_param_t *pParams = new lscp_param_t [finalKeys.count() + 1];
428            int iParam;
429            for (iParam = 0; iParam < finalKeys.count(); iParam++) {
430                    pParams[iParam].key   = (char *) finalKeys[iParam].constData();
431                    pParams[iParam].value = (char *) finalVals[iParam].constData();
432          }          }
433          // Null terminated.          // Null terminated.
434          pParams[iParam].key   = NULL;          pParams[iParam].key   = NULL;
# Line 406  bool qsamplerDevice::createDevice (void) Line 436  bool qsamplerDevice::createDevice (void)
436    
437          // Now it depends on the device type...          // Now it depends on the device type...
438          switch (m_deviceType) {          switch (m_deviceType) {
439          case qsamplerDevice::Audio:          case Device::Audio:
440                  if ((m_iDeviceID = ::lscp_create_audio_device(pMainForm->client(),                  if ((m_iDeviceID = ::lscp_create_audio_device(pMainForm->client(),
441                                  m_sDriverName.latin1(), pParams)) < 0)                                  m_sDriverName.toUtf8().constData(), pParams)) < 0)
442                          appendMessagesClient("lscp_create_audio_device");                          appendMessagesClient("lscp_create_audio_device");
443                  break;                  break;
444          case qsamplerDevice::Midi:          case Device::Midi:
445                  if ((m_iDeviceID = ::lscp_create_midi_device(pMainForm->client(),                  if ((m_iDeviceID = ::lscp_create_midi_device(pMainForm->client(),
446                                  m_sDriverName.latin1(), pParams)) < 0)                                  m_sDriverName.toUtf8().constData(), pParams)) < 0)
447                          appendMessagesClient("lscp_create_midi_device");                          appendMessagesClient("lscp_create_midi_device");
448                  break;                  break;
449          case qsamplerDevice::None:          case Device::None:
450                  break;                  break;
451          }          }
452    
# Line 438  bool qsamplerDevice::createDevice (void) Line 468  bool qsamplerDevice::createDevice (void)
468    
469    
470  // Destroy existing device.  // Destroy existing device.
471  bool qsamplerDevice::deleteDevice (void)  bool Device::deleteDevice (void)
472  {  {
473          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
474          if (pMainForm == NULL)          if (pMainForm == NULL)
# Line 449  bool qsamplerDevice::deleteDevice (void) Line 479  bool qsamplerDevice::deleteDevice (void)
479          // Now it depends on the device type...          // Now it depends on the device type...
480          lscp_status_t ret = LSCP_FAILED;          lscp_status_t ret = LSCP_FAILED;
481          switch (m_deviceType) {          switch (m_deviceType) {
482          case qsamplerDevice::Audio:          case Device::Audio:
483                  if ((ret = ::lscp_destroy_audio_device(pMainForm->client(),                  if ((ret = ::lscp_destroy_audio_device(pMainForm->client(),
484                                  m_iDeviceID)) != LSCP_OK)                                  m_iDeviceID)) != LSCP_OK)
485                          appendMessagesClient("lscp_destroy_audio_device");                          appendMessagesClient("lscp_destroy_audio_device");
486                  break;                  break;
487          case qsamplerDevice::Midi:          case Device::Midi:
488                  if ((ret = ::lscp_destroy_midi_device(pMainForm->client(),                  if ((ret = ::lscp_destroy_midi_device(pMainForm->client(),
489                                  m_iDeviceID)) != LSCP_OK)                                  m_iDeviceID)) != LSCP_OK)
490                          appendMessagesClient("lscp_destroy_midi_device");                          appendMessagesClient("lscp_destroy_midi_device");
491                  break;                  break;
492          case qsamplerDevice::None:          case Device::None:
493                  break;                  break;
494          }          }
495    
# Line 477  bool qsamplerDevice::deleteDevice (void) Line 507  bool qsamplerDevice::deleteDevice (void)
507    
508    
509  // Device parameter dependencies refreshner.  // Device parameter dependencies refreshner.
510  int qsamplerDevice::refreshParams (void)  int Device::refreshParams (void)
511  {  {
512          // This should only make sense for scratch devices...          // This should only make sense for scratch devices...
513          if (m_iDeviceID >= 0)          if (m_iDeviceID >= 0)
514              return 0;                  return 0;
515          // Refresh all parameters that have dependencies...          // Refresh all parameters that have dependencies...
516          int iParams = 0;          int iParams = 0;
517          qsamplerDeviceParamMap::ConstIterator iter;          DeviceParamMap::ConstIterator iter;
518          for (iter = m_params.begin(); iter != m_params.end(); ++iter)          for (iter = m_params.begin(); iter != m_params.end(); ++iter)
519                  iParams += refreshParam(iter.key());                  iParams += refreshParam(iter.key());
520          // Return how many parameters have been refreshed...          // Return how many parameters have been refreshed...
# Line 493  int qsamplerDevice::refreshParams (void) Line 523  int qsamplerDevice::refreshParams (void)
523    
524    
525  // Device port/channel list refreshner.  // Device port/channel list refreshner.
526  int qsamplerDevice::refreshPorts (void)  int Device::refreshPorts (void)
527  {  {
528          // This should only make sense for actual devices...          // This should only make sense for actual devices...
529          if (m_iDeviceID < 0)          if (m_iDeviceID < 0)
530              return 0;                  return 0;
531          // Port/channel count determination...          // Port/channel count determination...
532          int iPorts = 0;          int iPorts = 0;
533          switch (m_deviceType) {          switch (m_deviceType) {
534          case qsamplerDevice::Audio:          case Device::Audio:
535                  iPorts = m_params["CHANNELS"].value.toInt();                  iPorts = m_params["CHANNELS"].value.toInt();
536                  break;                  break;
537          case qsamplerDevice::Midi:          case Device::Midi:
538                  iPorts = m_params["PORTS"].value.toInt();                  iPorts = m_params["PORTS"].value.toInt();
539                  break;                  break;
540          case qsamplerDevice::None:          case Device::None:
541                  break;                  break;
542          }          }
543          // Retrieve port/channel information...          // Retrieve port/channel information...
544            qDeleteAll(m_ports);
545          m_ports.clear();          m_ports.clear();
546          for (int iPort = 0; iPort < iPorts; iPort++)          for (int iPort = 0; iPort < iPorts; iPort++)
547                  m_ports.append(new qsamplerDevicePort(*this, iPort));                  m_ports.append(new DevicePort(*this, iPort));
548          // Return how many ports have been refreshed...          // Return how many ports have been refreshed...
549          return iPorts;          return iPorts;
550  }  }
551    
552    
553  // Refresh/set dependencies given that some parameter has changed.  // Refresh/set dependencies given that some parameter has changed.
554  int qsamplerDevice::refreshDepends ( const QString& sParam )  int Device::refreshDepends ( const QString& sParam )
555  {  {
556          // This should only make sense for scratch devices...          // This should only make sense for scratch devices...
557          if (m_iDeviceID >= 0)          if (m_iDeviceID >= 0)
558              return 0;                  return 0;
559          // Refresh all parameters that depend on this one...          // Refresh all parameters that depend on this one...
560          int iDepends = 0;          int iDepends = 0;
561          qsamplerDeviceParamMap::ConstIterator iter;          DeviceParamMap::ConstIterator iter;
562          for (iter = m_params.begin(); iter != m_params.end(); ++iter) {          for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
563                  const QStringList& depends = iter.data().depends;                  const QStringList& depends = iter.value().depends;
564                  if (depends.find(sParam) != depends.end())                  if (depends.indexOf(sParam) >= 0)
565                          iDepends += refreshParam(iter.key());                          iDepends += refreshParam(iter.key());
566          }          }
567          // Return how many dependencies have been refreshed...          // Return how many dependencies have been refreshed...
# Line 539  int qsamplerDevice::refreshDepends ( con Line 570  int qsamplerDevice::refreshDepends ( con
570    
571    
572  // Refresh/set given parameter based on driver supplied dependencies.  // Refresh/set given parameter based on driver supplied dependencies.
573  int qsamplerDevice::refreshParam ( const QString& sParam )  int Device::refreshParam ( const QString& sParam )
574  {  {
575          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
576          if (pMainForm == NULL)          if (pMainForm == NULL)
# Line 548  int qsamplerDevice::refreshParam ( const Line 579  int qsamplerDevice::refreshParam ( const
579                  return 0;                  return 0;
580    
581          // Check if we have dependencies...          // Check if we have dependencies...
582          qsamplerDeviceParam& param = m_params[sParam.upper()];          DeviceParam& param = m_params[sParam.toUpper()];
583          if (param.depends.isEmpty())          if (param.depends.isEmpty())
584                  return 0;                  return 0;
585    
# Line 557  int qsamplerDevice::refreshParam ( const Line 588  int qsamplerDevice::refreshParam ( const
588          // Build dependency list...          // Build dependency list...
589          lscp_param_t *pDepends = new lscp_param_t [param.depends.count() + 1];          lscp_param_t *pDepends = new lscp_param_t [param.depends.count() + 1];
590          int iDepend = 0;          int iDepend = 0;
591          QStringList::ConstIterator iter;  
592          for (iter = param.depends.begin(); iter != param.depends.end(); ++iter) {          // we need temporary lists with the final strings, because i.e.
593                  const QString& sDepend = *iter;          // QString::toUtf8() only returns a temporary object and the
594                  pDepends[iDepend].key   = (char *) sDepend.latin1();          // C-style char* pointers for liblscp would immediately be invalidated
595                  pDepends[iDepend].value = (char *) m_params[sDepend.upper()].value.latin1();          QList<QByteArray> finalKeys;
596            QList<QByteArray> finalVals;
597            for (int i = 0; i < param.depends.count(); i++) {
598                    const QString& sDepend = param.depends[i];
599                    finalKeys.push_back(sDepend.toUtf8());
600                    finalVals.push_back(m_params[sDepend.toUpper()].value.toUtf8());
601            }
602            // yeah, we DO HAVE to do those two loops separately !
603            for (int i = 0; i < param.depends.count(); i++) {
604                    pDepends[iDepend].key   = (char *) finalKeys[i].constData();
605                    pDepends[iDepend].value = (char *) finalVals[i].constData();
606                  ++iDepend;                  ++iDepend;
607          }          }
608          // Null terminated.          // Null terminated.
# Line 576  int qsamplerDevice::refreshParam ( const Line 617  int qsamplerDevice::refreshParam ( const
617          // Retrieve some modern parameters...          // Retrieve some modern parameters...
618          lscp_param_info_t *pParamInfo = NULL;          lscp_param_info_t *pParamInfo = NULL;
619          switch (m_deviceType) {          switch (m_deviceType) {
620          case qsamplerDevice::Audio:          case Device::Audio:
621                  if ((pParamInfo = ::lscp_get_audio_driver_param_info(pMainForm->client(),                  if ((pParamInfo = ::lscp_get_audio_driver_param_info(
622                                  m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)                                  pMainForm->client(), m_sDriverName.toUtf8().constData(),
623                                    sParam.toUtf8().constData(), pDepends)) == NULL)
624                          appendMessagesClient("lscp_get_audio_driver_param_info");                          appendMessagesClient("lscp_get_audio_driver_param_info");
625                  break;                  break;
626          case qsamplerDevice::Midi:          case Device::Midi:
627                  if ((pParamInfo = ::lscp_get_midi_driver_param_info(pMainForm->client(),                  if ((pParamInfo = ::lscp_get_midi_driver_param_info(
628                                  m_sDriverName.latin1(), sParam.latin1(), pDepends)) == NULL)                                  pMainForm->client(), m_sDriverName.toUtf8().constData(),
629                                    sParam.toUtf8().constData(), pDepends)) == NULL)
630                          appendMessagesClient("lscp_get_midi_driver_param_info");                          appendMessagesClient("lscp_get_midi_driver_param_info");
631                  break;                  break;
632          case qsamplerDevice::None:          case Device::None:
633                  break;                  break;
634          }          }
635          if (pParamInfo) {          if (pParamInfo) {
636                  param = qsamplerDeviceParam(pParamInfo, QString(param.value));                  param = DeviceParam(pParamInfo,
637                            param.value.isEmpty() ? NULL : param.value.toUtf8().constData());
638                  iRefresh++;                  iRefresh++;
639          }          }
640    
# Line 603  int qsamplerDevice::refreshParam ( const Line 647  int qsamplerDevice::refreshParam ( const
647    
648    
649  // Redirected messages output methods.  // Redirected messages output methods.
650  void qsamplerDevice::appendMessages( const QString& s ) const  void Device::appendMessages( const QString& s ) const
651  {  {
652          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
653          if (pMainForm)          if (pMainForm)
654                  pMainForm->appendMessages(deviceName() + ' ' + s);                  pMainForm->appendMessages(deviceName() + ' ' + s);
655  }  }
656    
657  void qsamplerDevice::appendMessagesColor( const QString& s,  void Device::appendMessagesColor( const QString& s,
658          const QString& c ) const          const QString& c ) const
659  {  {
660          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
# Line 618  void qsamplerDevice::appendMessagesColor Line 662  void qsamplerDevice::appendMessagesColor
662                  pMainForm->appendMessagesColor(deviceName() + ' ' + s, c);                  pMainForm->appendMessagesColor(deviceName() + ' ' + s, c);
663  }  }
664    
665  void qsamplerDevice::appendMessagesText( const QString& s ) const  void Device::appendMessagesText( const QString& s ) const
666  {  {
667          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
668          if (pMainForm)          if (pMainForm)
669                  pMainForm->appendMessagesText(deviceName() + ' ' + s);                  pMainForm->appendMessagesText(deviceName() + ' ' + s);
670  }  }
671    
672  void qsamplerDevice::appendMessagesError( const QString& s ) const  void Device::appendMessagesError( const QString& s ) const
673  {  {
674          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
675          if (pMainForm)          if (pMainForm)
676                  pMainForm->appendMessagesError(deviceName() + "\n\n" + s);                  pMainForm->appendMessagesError(deviceName() + "\n\n" + s);
677  }  }
678    
679  void qsamplerDevice::appendMessagesClient( const QString& s ) const  void Device::appendMessagesClient( const QString& s ) const
680  {  {
681          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
682          if (pMainForm)          if (pMainForm)
# Line 641  void qsamplerDevice::appendMessagesClien Line 685  void qsamplerDevice::appendMessagesClien
685    
686    
687  // Device ids enumerator.  // Device ids enumerator.
688  int *qsamplerDevice::getDevices ( lscp_client_t *pClient,  int *Device::getDevices ( lscp_client_t *pClient,
689          qsamplerDeviceType deviceType )          DeviceType deviceType )
690  {  {
691          int *piDeviceIDs = NULL;          int *piDeviceIDs = NULL;
692          switch (deviceType) {          switch (deviceType) {
693          case qsamplerDevice::Audio:          case Device::Audio:
694                  piDeviceIDs = ::lscp_list_audio_devices(pClient);                  piDeviceIDs = ::lscp_list_audio_devices(pClient);
695                  break;                  break;
696          case qsamplerDevice::Midi:          case Device::Midi:
697                  piDeviceIDs = ::lscp_list_midi_devices(pClient);                  piDeviceIDs = ::lscp_list_midi_devices(pClient);
698                  break;                  break;
699          case qsamplerDevice::None:          case Device::None:
700                  break;                  break;
701          }          }
702          return piDeviceIDs;          return piDeviceIDs;
703  }  }
704    
705    std::set<int> Device::getDeviceIDs(lscp_client_t *pClient,
706            DeviceType deviceType)
707    {
708            std::set<int> result;
709            int* piDeviceIDs = getDevices(pClient, deviceType);
710            if (!piDeviceIDs) return result;
711            for (int i = 0; piDeviceIDs[i] != -1; ++i)
712                    result.insert(piDeviceIDs[i]);
713            return result;
714    }
715    
716    
717  // Driver names enumerator.  // Driver names enumerator.
718  QStringList qsamplerDevice::getDrivers ( lscp_client_t *pClient,  QStringList Device::getDrivers ( lscp_client_t *pClient,
719          qsamplerDeviceType deviceType )          DeviceType deviceType )
720  {  {
721          QStringList drivers;          QStringList drivers;
722    
723          const char **ppszDrivers = NULL;          const char **ppszDrivers = NULL;
724          switch (deviceType) {          switch (deviceType) {
725          case qsamplerDevice::Audio:          case Device::Audio:
726                  ppszDrivers = ::lscp_list_available_audio_drivers(pClient);                  ppszDrivers = ::lscp_list_available_audio_drivers(pClient);
727                  break;                  break;
728          case qsamplerDevice::Midi:          case Device::Midi:
729                  ppszDrivers = ::lscp_list_available_midi_drivers(pClient);                  ppszDrivers = ::lscp_list_available_midi_drivers(pClient);
730                  break;                  break;
731          case qsamplerDevice::None:          case Device::None:
732                  break;                  break;
733          }          }
734    
# Line 685  QStringList qsamplerDevice::getDrivers ( Line 740  QStringList qsamplerDevice::getDrivers (
740    
741    
742  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
743  // qsamplerDevicePort - MIDI/Audio Device port/channel structure.  // QSampler::DevicePort - MIDI/Audio Device port/channel structure.
744  //  //
745    
746  // Constructor.  // Constructor.
747  qsamplerDevicePort::qsamplerDevicePort ( qsamplerDevice& device,  DevicePort::DevicePort ( Device& device,
748          int iPortID ) : m_device(device)          int iPortID ) : m_device(device)
749  {  {
750          setDevicePort(iPortID);          setDevicePort(iPortID);
751  }  }
752    
753  // Default destructor.  // Default destructor.
754  qsamplerDevicePort::~qsamplerDevicePort (void)  DevicePort::~DevicePort (void)
755  {  {
756  }  }
757    
758    
759  // Initializer.  // Initializer.
760  void qsamplerDevicePort::setDevicePort ( int iPortID )  void DevicePort::setDevicePort ( int iPortID )
761  {  {
762          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
763          if (pMainForm == NULL)          if (pMainForm == NULL)
# Line 719  void qsamplerDevicePort::setDevicePort ( Line 774  void qsamplerDevicePort::setDevicePort (
774          // Retrieve device port/channel info, if any.          // Retrieve device port/channel info, if any.
775          lscp_device_port_info_t *pPortInfo = NULL;          lscp_device_port_info_t *pPortInfo = NULL;
776          switch (m_device.deviceType()) {          switch (m_device.deviceType()) {
777          case qsamplerDevice::Audio:          case Device::Audio:
778                  if ((pPortInfo = ::lscp_get_audio_channel_info(pMainForm->client(),                  if ((pPortInfo = ::lscp_get_audio_channel_info(pMainForm->client(),
779                                  m_device.deviceID(), m_iPortID)) == NULL)                                  m_device.deviceID(), m_iPortID)) == NULL)
780                          m_device.appendMessagesClient("lscp_get_audio_channel_info");                          m_device.appendMessagesClient("lscp_get_audio_channel_info");
781                  break;                  break;
782          case qsamplerDevice::Midi:          case Device::Midi:
783                  if ((pPortInfo = ::lscp_get_midi_port_info(pMainForm->client(),                  if ((pPortInfo = ::lscp_get_midi_port_info(pMainForm->client(),
784                                  m_device.deviceID(), m_iPortID)) == NULL)                                  m_device.deviceID(), m_iPortID)) == NULL)
785                          m_device.appendMessagesClient("lscp_get_midi_port_info");                          m_device.appendMessagesClient("lscp_get_midi_port_info");
786                  break;                  break;
787          case qsamplerDevice::None:          case Device::None:
788                  break;                  break;
789          }          }
790    
# Line 748  void qsamplerDevicePort::setDevicePort ( Line 803  void qsamplerDevicePort::setDevicePort (
803                  const QString sParam = pPortInfo->params[i].key;                  const QString sParam = pPortInfo->params[i].key;
804                  lscp_param_info_t *pParamInfo = NULL;                  lscp_param_info_t *pParamInfo = NULL;
805                  switch (m_device.deviceType()) {                  switch (m_device.deviceType()) {
806                  case qsamplerDevice::Audio:                  case Device::Audio:
807                          if ((pParamInfo = ::lscp_get_audio_channel_param_info(                          if ((pParamInfo = ::lscp_get_audio_channel_param_info(
808                                          pMainForm->client(), m_device.deviceID(),                                          pMainForm->client(), m_device.deviceID(),
809                                          m_iPortID, sParam.latin1())) == NULL)                                          m_iPortID, sParam.toUtf8().constData())) == NULL)
810                                  m_device.appendMessagesClient("lscp_get_audio_channel_param_info");                                  m_device.appendMessagesClient("lscp_get_audio_channel_param_info");
811                          break;                          break;
812                  case qsamplerDevice::Midi:                  case Device::Midi:
813                          if ((pParamInfo = ::lscp_get_midi_port_param_info(                          if ((pParamInfo = ::lscp_get_midi_port_param_info(
814                                          pMainForm->client(), m_device.deviceID(),                                          pMainForm->client(), m_device.deviceID(),
815                                          m_iPortID, sParam.latin1())) == NULL)                                          m_iPortID, sParam.toUtf8().constData())) == NULL)
816                                  m_device.appendMessagesClient("lscp_get_midi_port_param_info");                                  m_device.appendMessagesClient("lscp_get_midi_port_param_info");
817                          break;                          break;
818                  case qsamplerDevice::None:                  case Device::None:
819                          break;                          break;
820                  }                  }
821                  if (pParamInfo) {                  if (pParamInfo) {
822                          m_params[sParam.upper()] = qsamplerDeviceParam(pParamInfo,                          m_params[sParam.toUpper()] = DeviceParam(pParamInfo,
823                                  pPortInfo->params[i].value);                                  pPortInfo->params[i].value);
824                  }                  }
825          }          }
# Line 772  void qsamplerDevicePort::setDevicePort ( Line 827  void qsamplerDevicePort::setDevicePort (
827    
828    
829  // Device port/channel property accessors.  // Device port/channel property accessors.
830  int qsamplerDevicePort::portID (void) const  int DevicePort::portID (void) const
831  {  {
832          return m_iPortID;          return m_iPortID;
833  }  }
834    
835  const QString& qsamplerDevicePort::portName (void) const  const QString& DevicePort::portName (void) const
836  {  {
837          return m_sPortName;          return m_sPortName;
838  }  }
839    
840  // Device port/channel parameter accessor.  // Device port/channel parameter accessor.
841  const qsamplerDeviceParamMap& qsamplerDevicePort::params (void) const  const DeviceParamMap& DevicePort::params (void) const
842  {  {
843          return m_params;          return m_params;
844  }  }
845    
846    
847  // Set the proper device port/channel parameter value.  // Set the proper device port/channel parameter value.
848  bool qsamplerDevicePort::setParam ( const QString& sParam,  bool DevicePort::setParam ( const QString& sParam,
849          const QString& sValue )          const QString& sValue )
850  {  {
851          MainForm *pMainForm = MainForm::getInstance();          MainForm *pMainForm = MainForm::getInstance();
# Line 800  bool qsamplerDevicePort::setParam ( cons Line 855  bool qsamplerDevicePort::setParam ( cons
855                  return false;                  return false;
856    
857          // Set proper port/channel parameter.          // Set proper port/channel parameter.
858          m_params[sParam.upper()].value = sValue;          m_params[sParam.toUpper()].value = sValue;
859    
860          // If the device already exists, things get immediate...          // If the device already exists, things get immediate...
861          int iRefresh = 0;          int iRefresh = 0;
862          if (m_device.deviceID() >= 0 && m_iPortID >= 0) {          if (m_device.deviceID() >= 0 && m_iPortID >= 0) {
863    
864                    // we need temporary byte arrrays with the final strings, because
865                    // i.e. QString::toUtf8() only returns a temporary object and the
866                    // C-style char* pointers for liblscp would immediately be invalidated
867                    QByteArray finalParamKey = sParam.toUtf8();
868                    QByteArray finalParamVal = sValue.toUtf8();
869    
870                  // Prepare parameter struct.                  // Prepare parameter struct.
871                  lscp_param_t param;                  lscp_param_t param;
872                  param.key   = (char *) sParam.latin1();                  param.key   = (char *) finalParamKey.constData();
873                  param.value = (char *) sValue.latin1();                  param.value = (char *) finalParamVal.constData();
874                  // Now it depends on the device type...                  // Now it depends on the device type...
875                  lscp_status_t ret = LSCP_FAILED;                  lscp_status_t ret = LSCP_FAILED;
876                  switch (m_device.deviceType()) {                  switch (m_device.deviceType()) {
877                  case qsamplerDevice::Audio:                  case Device::Audio:
878                          if ((ret = ::lscp_set_audio_channel_param(pMainForm->client(),                          if ((ret = ::lscp_set_audio_channel_param(pMainForm->client(),
879                                          m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)                                          m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
880                                  m_device.appendMessagesClient("lscp_set_audio_channel_param");                                  m_device.appendMessagesClient("lscp_set_audio_channel_param");
881                          break;                          break;
882                  case qsamplerDevice::Midi:                  case Device::Midi:
883                          if ((ret = ::lscp_set_midi_port_param(pMainForm->client(),                          if ((ret = ::lscp_set_midi_port_param(pMainForm->client(),
884                                          m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)                                          m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
885                                  m_device.appendMessagesClient("lscp_set_midi_port_param");                                  m_device.appendMessagesClient("lscp_set_midi_port_param");
886                          break;                          break;
887                  case qsamplerDevice::None:                  case Device::None:
888                          break;                          break;
889                  }                  }
890                  // Show result.                  // Show result.
# Line 843  bool qsamplerDevicePort::setParam ( cons Line 905  bool qsamplerDevicePort::setParam ( cons
905    
906    
907  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
908  // qsamplerDeviceItem - QTreeWidget device item.  // QSampler::DeviceItem - QTreeWidget device item.
909  //  //
910    
911  // Constructors.  // Constructors.
912  qsamplerDeviceItem::qsamplerDeviceItem ( QTreeWidget* pTreeWidget,  DeviceItem::DeviceItem ( QTreeWidget* pTreeWidget,
913          qsamplerDevice::qsamplerDeviceType deviceType )          Device::DeviceType deviceType )
914          : QTreeWidgetItem(pTreeWidget, QSAMPLER_DEVICE_ITEM),          : QTreeWidgetItem(pTreeWidget, QSAMPLER_DEVICE_ITEM),
915        m_device(deviceType)                  m_device(deviceType)
916  {  {
917          switch(m_device.deviceType()) {          switch(m_device.deviceType()) {
918          case qsamplerDevice::Audio:          case Device::Audio:
919                  setIcon(0, QPixmap(":/icons/audio1.png"));                  setIcon(0, QPixmap(":/icons/audio1.png"));
920                  setText(0, QObject::tr("Audio Devices"));                  setText(0, QObject::tr("Audio Devices"));
921                  break;                  break;
922          case qsamplerDevice::Midi:          case Device::Midi:
923                  setIcon(0, QPixmap(":/icons/midi1.png"));                  setIcon(0, QPixmap(":/icons/midi1.png"));
924                  setText(0, QObject::tr("MIDI Devices"));                  setText(0, QObject::tr("MIDI Devices"));
925                  break;                  break;
926          case qsamplerDevice::None:          case Device::None:
927                  break;                  break;
928          }          }
929    
930            // Root items are not selectable...
931            setFlags(flags() & ~Qt::ItemIsSelectable);
932  }  }
933    
934  qsamplerDeviceItem::qsamplerDeviceItem ( QTreeWidgetItem* pItem,  DeviceItem::DeviceItem ( QTreeWidgetItem* pItem,
935          qsamplerDevice::qsamplerDeviceType deviceType,          Device::DeviceType deviceType,
936          int iDeviceID )          int iDeviceID )
937          : QTreeWidgetItem(pItem, QSAMPLER_DEVICE_ITEM),          : QTreeWidgetItem(pItem, QSAMPLER_DEVICE_ITEM),
938        m_device(deviceType, iDeviceID)                  m_device(deviceType, iDeviceID)
939  {  {
940          switch(m_device.deviceType()) {          switch(m_device.deviceType()) {
941          case qsamplerDevice::Audio:          case Device::Audio:
942                  setIcon(0, QPixmap(":/icons/audio2.png"));                  setIcon(0, QPixmap(":/icons/audio2.png"));
943                  break;                  break;
944          case qsamplerDevice::Midi:          case Device::Midi:
945                  setIcon(0, QPixmap(":/icons/midi2.png"));                  setIcon(0, QPixmap(":/icons/midi2.png"));
946                  break;                  break;
947          case qsamplerDevice::None:          case Device::None:
948                  break;                  break;
949          }          }
950    
951          setText(1, m_device.deviceName());          setText(0, m_device.deviceName());
952  }  }
953    
954  // Default destructor.  // Default destructor.
955  qsamplerDeviceItem::~qsamplerDeviceItem ()  DeviceItem::~DeviceItem ()
956  {  {
957  }  }
958    
959  // Instance accessors.  // Instance accessors.
960  qsamplerDevice& qsamplerDeviceItem::device ()  Device& DeviceItem::device ()
961  {  {
962          return m_device;          return m_device;
963  }  }
964    
965    
   
966  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
967  // qsamplerDeviceParamTable - Device parameter view table.  // QSampler::AbstractDeviceParamModel - data model base class for device parameters
968  //  //
 #if 0  
 // Constructor.  
 qsamplerDeviceParamTable::qsamplerDeviceParamTable ( QWidget *pParent,  
         const char *pszName )  
         : QTable(pParent, pszName)  
 {  
         // Set fixed number of columns.  
         QTable::setNumCols(3);  
         QTable::setShowGrid(false);  
         QTable::setSorting(false);  
         QTable::setFocusStyle(QTable::FollowStyle);  
         QTable::setSelectionMode(QTable::NoSelection);  
         // No vertical header.  
         QTable::verticalHeader()->hide();  
         QTable::setLeftMargin(0);  
         // Initialize the fixed table column headings.  
         QHeader *pHeader = QTable::horizontalHeader();  
         pHeader->setLabel(0, tr("Parameter"));  
         pHeader->setLabel(1, tr("Description"));  
         pHeader->setLabel(2, tr("Value"));  
         // Set read-onlyness of each column  
         QTable::setColumnReadOnly(0, true);  
         QTable::setColumnReadOnly(1, true);  
 //  QTable::setColumnReadOnly(2, false); -- of course not.  
         QTable::setColumnStretchable(1, true);  
 }  
969    
970  // Default destructor.  AbstractDeviceParamModel::AbstractDeviceParamModel ( QObject* pParent )
971  qsamplerDeviceParamTable::~qsamplerDeviceParamTable (void)          : QAbstractTableModel(pParent), m_bEditable(false)
972  {  {
973            m_pParams = NULL;
974  }  }
975    
976    
977  // Common parameter table renderer.  int AbstractDeviceParamModel::rowCount ( const QModelIndex& /*parent*/) const
978  void qsamplerDeviceParamTable::refresh ( const qsamplerDeviceParamMap& params,  {
979          bool bEditable )          //std::cout << "model size=" << params.size() << "\n" << std::flush;
980  {          return (m_pParams ? m_pParams->size() : 0);
981          // Always (re)start it empty.  }
         QTable::setUpdatesEnabled(false);  
         QTable::setNumRows(0);  
   
         // Fill the parameter table...  
         QTable::insertRows(0, params.count());  
         int iRow = 0;  
         qsamplerDeviceParamMap::ConstIterator iter;  
         for (iter = params.begin(); iter != params.end(); ++iter) {  
                 const qsamplerDeviceParam& param = iter.data();  
                 bool bEnabled = (bEditable || !param.fix);  
                 QTable::setText(iRow, 0, iter.key());  
                 QTable::setText(iRow, 1, param.description);  
                 if (param.type == LSCP_TYPE_BOOL) {  
                         QStringList opts;  
                         opts.append(tr("false"));  
                         opts.append(tr("true"));  
                         QComboTableItem *pComboItem = new QComboTableItem(this, opts);  
                         pComboItem->setCurrentItem(param.value.lower() == "true" ? 1 : 0);  
                         pComboItem->setEnabled(bEnabled);  
                         QTable::setItem(iRow, 2, pComboItem);  
                 } else if (param.possibilities.count() > 0 && bEnabled) {  
                         QStringList opts = param.possibilities;  
                         if (param.multiplicity)  
                                 opts.prepend(tr("(none)"));  
                         QComboTableItem *pComboItem = new QComboTableItem(this, opts);  
                         if (param.value.isEmpty())  
                                 pComboItem->setCurrentItem(0);  
                         else  
                                 pComboItem->setCurrentItem(param.value);  
                         pComboItem->setEnabled(bEnabled);  
                         QTable::setItem(iRow, 2, pComboItem);  
                 } else if (param.type == LSCP_TYPE_INT && bEnabled  
                                 && !param.range_min.isEmpty()  
                                 && !param.range_max.isEmpty()) {  
                         qsamplerDeviceParamTableSpinBox *pSpinItem =  
                                 new qsamplerDeviceParamTableSpinBox(this,  
                                         bEnabled ? QTableItem::OnTyping : QTableItem::Never,  
                                         param.value);  
                         pSpinItem->setMinValue(param.range_min.toInt());  
                         pSpinItem->setMaxValue(param.range_max.toInt());  
                         QTable::setItem(iRow, 2, pSpinItem);  
                 } else {  
                         qsamplerDeviceParamTableEditBox *pEditItem =  
                                 new qsamplerDeviceParamTableEditBox(this,  
                                         bEnabled ? QTableItem::OnTyping : QTableItem::Never,  
                                         param.value);  
                         QTable::setItem(iRow, 2, pEditItem);  
                 }  
                 ++iRow;  
         }  
982    
         // Adjust optimal column widths.  
         QTable::adjustColumn(0);  
         QTable::adjustColumn(2);  
983    
984          QTable::setUpdatesEnabled(true);  int AbstractDeviceParamModel::columnCount ( const QModelIndex& /*parent*/) const
985          QTable::updateContents();  {
986            return 3;
987  }  }
 #endif  
988    
 DeviceParamModel::DeviceParamModel(QObject* parent) : QAbstractTableModel(parent), bEditable(false) {  
 }  
989    
990  int DeviceParamModel::rowCount(const QModelIndex& /*parent*/) const {  Qt::ItemFlags AbstractDeviceParamModel::flags ( const QModelIndex& /*index*/) const
991      return params.size();  {
992            return Qt::ItemIsEditable | Qt::ItemIsEnabled;
993  }  }
994    
 int DeviceParamModel::columnCount(const QModelIndex& /*parent*/) const {  
     return 3;  
 }  
995    
996  QVariant DeviceParamModel::data(const QModelIndex &index, int role) const {  QVariant AbstractDeviceParamModel::headerData (
997      if (!index.isValid())          int section, Qt::Orientation orientation, int role) const
998          return QVariant();  {
999      if (role != Qt::DisplayRole)          if (role != Qt::DisplayRole)
1000          return QVariant();                  return QVariant();
1001    
1002      DeviceParameterRow item;          if (orientation == Qt::Horizontal) {
1003      item.name  = params.keys()[index.row()];                  switch (section) {
1004      item.param = params[item.name];                          case 0:  return tr("Parameter");
1005                            case 1:  return tr("Value");
1006                            case 2:  return tr("Description");
1007                            default: return QVariant();
1008                    }
1009            }
1010    
1011      return QVariant::fromValue(item);          return QVariant();
1012  }  }
1013    
 QVariant DeviceParamModel::headerData(int section, Qt::Orientation orientation, int role) const {  
     if (role != Qt::DisplayRole) return QVariant();  
   
     if (orientation == Qt::Horizontal) {  
         switch (section) {  
             case 0:  return tr("Parameter");  
             case 1:  return tr("Value");  
             case 2:  return tr("Description");  
             default: return QVariant();  
         }  
     }  
1014    
1015      return QVariant();  void AbstractDeviceParamModel::refresh (
1016            const DeviceParamMap* pParams, bool bEditable )
1017    {
1018            m_pParams   = pParams;
1019            m_bEditable = bEditable;
1020            // inform the outer world (QTableView) that our data changed
1021            QAbstractTableModel::reset();
1022  }  }
1023    
1024  void DeviceParamModel::refresh(const qsamplerDeviceParamMap& params, bool bEditable)  
1025    void AbstractDeviceParamModel::clear (void)
1026  {  {
1027      this->params    = params;          m_pParams = NULL;
1028      this->bEditable = bEditable;          // inform the outer world (QTableView) that our data changed
1029            QAbstractTableModel::reset();
1030  }  }
1031    
 void DeviceParamModel::clear() {  
     params.clear();  
 }  
1032    
1033    //-------------------------------------------------------------------------
1034    // QSampler::DeviceParamModel - data model for device parameters
1035    //                              (used for QTableView)
1036    
1037  DeviceParamDelegate::DeviceParamDelegate(QObject *parent) : QItemDelegate(parent) {  DeviceParamModel::DeviceParamModel ( QObject *pParent )
1038            : AbstractDeviceParamModel(pParent)
1039    {
1040            m_pDevice = NULL;
1041  }  }
1042    
1043  QWidget* DeviceParamDelegate::createEditor(QWidget *parent,  QVariant DeviceParamModel::data (
1044          const QStyleOptionViewItem &/* option */,          const QModelIndex &index, int role) const
         const QModelIndex& index) const  
1045  {  {
1046      DeviceParameterRow r = index.model()->data(index, Qt::DisplayRole).value<DeviceParameterRow>();          if (!index.isValid())
1047                    return QVariant();
1048    
1049      const bool bEnabled = (/*index.model()->bEditable ||*/ !r.param.fix);          if (role != Qt::DisplayRole)
1050                    return QVariant();
1051    
1052      switch (index.column()) {          DeviceParameterRow item;
1053          case 0:          item.name  = m_pParams->keys()[index.row()];
1054              return new QLabel(r.name, parent);          item.param = (*m_pParams)[item.name];
1055          case 1: {          item.alive = (m_pDevice && m_pDevice->deviceID() >= 0);
             if (r.param.type == LSCP_TYPE_BOOL) {  
                 QCheckBox* pCheckBox = new QCheckBox(parent);  
                 pCheckBox->setChecked(r.param.value.lower() == "true");  
                 pCheckBox->setEnabled(bEnabled);  
                 return pCheckBox;  
             } else if (r.param.possibilities.count() > 0 && bEnabled) {  
                 QStringList opts = r.param.possibilities;  
                 if (r.param.multiplicity)  
                     opts.prepend(tr("(none)"));  
                 QComboBox* pComboBox = new QComboBox(parent);  
                 pComboBox->addItems(opts);  
                 if (r.param.value.isEmpty())  
                     pComboBox->setCurrentIndex(0);  
                 else  
                     pComboBox->setCurrentIndex(pComboBox->findText(r.param.value));  
                 pComboBox->setEnabled(bEnabled);  
                 return pComboBox;  
             } else if (r.param.type == LSCP_TYPE_INT && bEnabled  
                        && !r.param.range_min.isEmpty()  
                        && !r.param.range_max.isEmpty()) {  
                 QSpinBox* pSpinBox = new QSpinBox(parent);  
                 pSpinBox->setValue(r.param.value.toInt());  
                 pSpinBox->setMinimum(r.param.range_min.toInt());  
                 pSpinBox->setMaximum(r.param.range_max.toInt());  
                 return pSpinBox;  
             } else {  
                 QLineEdit* pLineEdit = new QLineEdit(r.param.value, parent);  
                 return pLineEdit;  
             }  
         }  
         case 2:  
             return new QLabel(r.param.description, parent);  
         default:  
             return NULL;  
     }  
 }  
1056    
1057  void DeviceParamDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {          return QVariant::fromValue(item);
 /*  
     ChannelRoutingItem item = index.model()->data(index, Qt::DisplayRole).value<ChannelRoutingItem>();  
     QComboBox* comboBox = static_cast<QComboBox*>(editor);  
     comboBox->setCurrentIndex(item.selection);  
 */  
1058  }  }
1059    
1060  void DeviceParamDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {  
1061  /*  bool DeviceParamModel::setData (
1062      QComboBox* comboBox = static_cast<QComboBox*>(editor);          const QModelIndex& index, const QVariant& value, int /*role*/)
1063      model->setData(index, comboBox->currentIndex());  {
1064  */          if (!index.isValid())
1065                    return false;
1066    
1067            QString key = m_pParams->keys()[index.row()];
1068            //m_pParams[key].value = value.toString();
1069            m_pDevice->setParam(key, value.toString());
1070            emit dataChanged(index, index);
1071            return true;
1072  }  }
1073    
1074  void DeviceParamDelegate::updateEditorGeometry(QWidget* editor,  
1075          const QStyleOptionViewItem &option, const QModelIndex &/* index */) const  void DeviceParamModel::refresh ( Device* pDevice, bool bEditable )
1076  {  {
1077      if (editor) editor->setGeometry(option.rect);          m_pDevice = pDevice;
1078            AbstractDeviceParamModel::refresh(&pDevice->params(), bEditable);
1079  }  }
1080    
 //-------------------------------------------------------------------------  
 // qsamplerDeviceParamTableSpinBox - Custom spin box for parameter table.  
 //  
1081    
1082  #if 0  void DeviceParamModel::clear (void)
 // Constructor.  
 qsamplerDeviceParamTableSpinBox::qsamplerDeviceParamTableSpinBox (  
         QTable *pTable, EditType editType, const QString& sText )  
         : QTableItem(pTable, editType, sText)  
1083  {  {
1084          m_iValue = sText.toInt();          AbstractDeviceParamModel::clear();
1085          m_iMinValue = m_iMaxValue = 0;          m_pDevice = NULL;
1086  }  }
1087    
1088  // Public accessors.  
1089  void qsamplerDeviceParamTableSpinBox::setValue ( int iValue )  //-------------------------------------------------------------------------
1090    // QSampler::PortParamModel - data model for port parameters
1091    //                            (used for QTableView)
1092    
1093    PortParamModel::PortParamModel ( QObject *pParent)
1094            : AbstractDeviceParamModel(pParent)
1095  {  {
1096          m_iValue = iValue;          m_pPort = NULL;
         QTableItem::setText(QString::number(m_iValue));  
1097  }  }
1098    
1099  void qsamplerDeviceParamTableSpinBox::setMinValue ( int iMinValue )  QVariant PortParamModel::data ( const QModelIndex &index, int role ) const
1100  {  {
1101          m_iMinValue = iMinValue;          if (!index.isValid())
1102                    return QVariant();
1103    
1104            if (role != Qt::DisplayRole)
1105                    return QVariant();
1106    
1107            DeviceParameterRow item;
1108            item.name  = m_pParams->keys()[index.row()];
1109            item.param = (*m_pParams)[item.name];
1110            item.alive = (m_pPort && m_pPort->portID() >= 0);
1111    
1112            return QVariant::fromValue(item);
1113  }  }
1114    
1115  void qsamplerDeviceParamTableSpinBox::setMaxValue ( int iMaxValue )  
1116    bool PortParamModel::setData (
1117            const QModelIndex& index, const QVariant& value, int /*role*/)
1118  {  {
1119          m_iMaxValue = iMaxValue;          if (!index.isValid())
1120                    return false;
1121    
1122            QString key = m_pParams->keys()[index.row()];
1123            //params[key].value = value.toString();
1124            m_pPort->setParam(key, value.toString());
1125            emit dataChanged(index, index);
1126            return true;
1127  }  }
1128    
1129  // Virtual implemetations.  
1130  QWidget *qsamplerDeviceParamTableSpinBox::createEditor (void) const  void PortParamModel::refresh ( DevicePort* pPort, bool bEditable )
1131  {  {
1132          QSpinBox *pSpinBox = new QSpinBox(QTableItem::table()->viewport());          m_pPort = pPort;
1133          QObject::connect(pSpinBox, SIGNAL(valueChanged(int)),          AbstractDeviceParamModel::refresh(&pPort->params(), bEditable);
                 QTableItem::table(), SLOT(doValueChanged()));  
         if (m_iValue >= m_iMinValue && m_iMaxValue >= m_iValue) {  
                 pSpinBox->setMinValue(m_iMinValue);  
                 pSpinBox->setMaxValue(m_iMaxValue);  
         }  
         pSpinBox->setValue(m_iValue);  
         return pSpinBox;  
1134  }  }
1135    
1136  void qsamplerDeviceParamTableSpinBox::setContentFromEditor ( QWidget *pWidget )  
1137    void PortParamModel::clear (void)
1138  {  {
1139          if (pWidget->inherits("QSpinBox"))          AbstractDeviceParamModel::clear();
1140                  QTableItem::setText(QString::number(((QSpinBox *) pWidget)->value()));          m_pPort = NULL;
         else  
                 QTableItem::setContentFromEditor(pWidget);  
1141  }  }
1142    
1143    
1144  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1145  // qsamplerDeviceParamTableEditBox - Custom edit box for parameter table.  // QSampler::DeviceParamDelegate - table cell renderer for device/port parameters
1146  //  //
1147    
1148  // Constructor.  DeviceParamDelegate::DeviceParamDelegate ( QObject *pParent)
1149  qsamplerDeviceParamTableEditBox::qsamplerDeviceParamTableEditBox (          : QItemDelegate(pParent)
         QTable *pTable, EditType editType, const QString& sText )  
         : QTableItem(pTable, editType, sText)  
1150  {  {
1151  }  }
1152    
1153  // Virtual implemetations.  
1154  QWidget *qsamplerDeviceParamTableEditBox::createEditor (void) const  QWidget* DeviceParamDelegate::createEditor ( QWidget *pParent,
1155            const QStyleOptionViewItem& /* option */, const QModelIndex& index ) const
1156  {  {
1157          QLineEdit *pEditBox = new QLineEdit(QTableItem::table()->viewport());          if (!index.isValid())
1158          QObject::connect(pEditBox, SIGNAL(returnPressed()),                  return NULL;
1159                  QTableItem::table(), SLOT(doValueChanged()));  
1160          pEditBox->setText(QTableItem::text());          DeviceParameterRow r = index.model()->data(index,
1161          return pEditBox;                  Qt::DisplayRole).value<DeviceParameterRow>();
1162    
1163            const bool bEnabled = (r.alive) ? !r.param.fix : true;
1164    
1165            QString val = (r.alive) ? r.param.value : r.param.defaultv;
1166    
1167            switch (index.column()) {
1168                    case 0:
1169                            return new QLabel(r.name, pParent);
1170                    case 1: {
1171                            if (r.param.type == LSCP_TYPE_BOOL) {
1172                                    QCheckBox *pCheckBox = new QCheckBox(pParent);
1173                                    if (val != QString::null)
1174                                            pCheckBox->setChecked(val.toLower() == "true");
1175                                    pCheckBox->setEnabled(bEnabled);
1176                                    return pCheckBox;
1177                            } else if (r.param.possibilities.count() > 0) {
1178                                    QStringList opts = r.param.possibilities;
1179                                    if (r.param.multiplicity)
1180                                            opts.prepend(tr("(none)"));
1181                                    QComboBox *pComboBox = new QComboBox(pParent);
1182                                    pComboBox->addItems(opts);
1183                                    if (r.param.value.isEmpty())
1184                                            pComboBox->setCurrentIndex(0);
1185                                    else
1186                                            pComboBox->setCurrentIndex(pComboBox->findText(val));
1187                                    pComboBox->setEnabled(bEnabled);
1188                                    return pComboBox;
1189                            } else if (r.param.type == LSCP_TYPE_INT && bEnabled) {
1190                                    QSpinBox *pSpinBox = new QSpinBox(pParent);
1191                                    pSpinBox->setMinimum(
1192                                            (!r.param.range_min.isEmpty()) ?
1193                                                    r.param.range_min.toInt() : 0 // or better a negative default min value ?
1194                                    );
1195                                    pSpinBox->setMaximum(
1196                                            (!r.param.range_max.isEmpty()) ?
1197                                                    r.param.range_max.toInt() : (1 << 24) // or better a higher default max value ?
1198                                    );
1199                                    pSpinBox->setValue(val.toInt());
1200                                    return pSpinBox;
1201                            } else if (bEnabled) {
1202                                    QLineEdit *pLineEdit = new QLineEdit(val, pParent);
1203                                    return pLineEdit;
1204                            } else {
1205                                    QLabel *pLabel = new QLabel(val, pParent);
1206                                    return pLabel;
1207                            }
1208                    }
1209                    case 2:
1210                            return new QLabel(r.param.description, pParent);
1211                    default:
1212                            return NULL;
1213            }
1214  }  }
1215    
1216  void qsamplerDeviceParamTableEditBox::setContentFromEditor ( QWidget *pWidget )  
1217    void DeviceParamDelegate::setEditorData (
1218            QWidget* /*pEditor*/, const QModelIndex& /*index*/) const
1219    {
1220            // Unused, since we set the editor data already in createEditor()
1221    }
1222    
1223    
1224    void DeviceParamDelegate::setModelData ( QWidget *pEditor,
1225            QAbstractItemModel *pModel, const QModelIndex& index ) const
1226    {
1227            if (index.column() == 1) {
1228                    DeviceParameterRow r = index.model()->data(index,
1229                            Qt::DisplayRole).value<DeviceParameterRow> ();
1230                    if (pEditor->metaObject()->className() == QString("QCheckBox")) {
1231                            QCheckBox *pCheckBox = static_cast<QCheckBox *> (pEditor);
1232                            pModel->setData(index, QVariant(pCheckBox->checkState() == Qt::Checked));
1233                    } else if (pEditor->metaObject()->className() == QString("QComboBox")) {
1234                            QComboBox *pComboBox = static_cast<QComboBox *> (pEditor);
1235                            pModel->setData(index, pComboBox->currentText());
1236                    } else if (pEditor->metaObject()->className() == QString("QSpinBox")) {
1237                            QSpinBox *pSpinBox = static_cast<QSpinBox *> (pEditor);
1238                            pModel->setData(index, pSpinBox->value());
1239                    } else if (pEditor->metaObject()->className() == QString("QLineEdit")) {
1240                            QLineEdit *pLineEdit = static_cast<QLineEdit *> (pEditor);
1241                            pModel->setData(index, pLineEdit->text());
1242                    } else if (pEditor->metaObject()->className() == QString("QLabel")) {
1243                            QLabel *pLabel = static_cast<QLabel *> (pEditor);
1244                            pModel->setData(index, pLabel->text());
1245                    }
1246            }
1247    }
1248    
1249    void DeviceParamDelegate::updateEditorGeometry ( QWidget *pEditor,
1250            const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
1251  {  {
1252          if (pWidget->inherits("QLineEdit"))          if (pEditor)
1253                  QTableItem::setText(((QLineEdit *) pWidget)->text());                  pEditor->setGeometry(option.rect);
         else  
                 QTableItem::setContentFromEditor(pWidget);  
1254  }  }
 #endif  
1255    
1256    } // namespace QSampler
1257    
1258  // end of qsamplerDevice.cpp  // end of qsamplerDevice.cpp

Legend:
Removed from v.1477  
changed lines
  Added in v.2059

  ViewVC Help
Powered by ViewVC