/[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 442 by capela, Thu Mar 10 15:48:38 2005 UTC revision 1558 by capela, Thu Dec 6 09:35:33 2007 UTC
# Line 1  Line 1 
1  // qsamplerDevice.cpp  // qsamplerDevice.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2005, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5       Copyright (C) 2007, 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 13  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License along
18     along with this program; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
23    #include "qsamplerAbout.h"
24  #include "qsamplerDevice.h"  #include "qsamplerDevice.h"
25    
 #include <qspinbox.h>  
 #include <qlineedit.h>  
   
26  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
27  #include "qsamplerDeviceForm.h"  #include "qsamplerDeviceForm.h"
28    
29  #include "config.h"  #include <QCheckBox>
30    #include <QSpinBox>
31    #include <QLineEdit>
32    
33    
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 43  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)
59                  return;                  return;
60                    
61          // Info structure field members.          // Info structure field members.
62            
63          type = pParamInfo->type;          type = pParamInfo->type;
64            
65          if (pParamInfo->description)          if (pParamInfo->description)
66                  description = pParamInfo->description;                  description = pParamInfo->description;
67          else          else
68                  description = QString::null;                  description = QString::null;
69            
70          mandatory = (bool) pParamInfo->multiplicity;          mandatory = (bool) pParamInfo->mandatory;
71          fix = (bool) pParamInfo->fix;          fix = (bool) pParamInfo->fix;
72          multiplicity = (bool) pParamInfo->multiplicity;          multiplicity = (bool) pParamInfo->multiplicity;
73            
74          depends.clear();          depends.clear();
75          for (int i = 0; pParamInfo->depends && pParamInfo->depends[i]; i++)          for (int i = 0; pParamInfo->depends && pParamInfo->depends[i]; i++)
76                  depends.append(pParamInfo->depends[i]);                  depends.append(pParamInfo->depends[i]);
77            
78          if (pParamInfo->defaultv)          if (pParamInfo->defaultv)
79                  defaultv = pParamInfo->defaultv;                  defaultv = pParamInfo->defaultv;
80          else          else
81                  defaultv = QString::null;                  defaultv = QString::null;
82            
83          if (pParamInfo->range_min)          if (pParamInfo->range_min)
84                  range_min = pParamInfo->range_min;                  range_min = pParamInfo->range_min;
85          else          else
86                  range_min = QString::null;                  range_min = QString::null;
87            
88          if (pParamInfo->range_max)          if (pParamInfo->range_max)
89                  range_max = pParamInfo->range_max;                  range_max = pParamInfo->range_max;
90          else          else
91                  range_max = QString::null;                  range_max = QString::null;
92            
93          possibilities.clear();          possibilities.clear();
94          for (int i = 0; pParamInfo->possibilities && pParamInfo->possibilities[i]; i++)          for (int i = 0; pParamInfo->possibilities && pParamInfo->possibilities[i]; i++)
95                  possibilities.append(pParamInfo->possibilities[i]);                  possibilities.append(pParamInfo->possibilities[i]);
96                    
97          // The current parameter value.          // The current parameter value.
98          if (pszValue)          if (pszValue)
99                  value = pszValue;                  value = pszValue;
# Line 100  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 ( lscp_client_t *pClient,  Device::Device ( DeviceType deviceType, int iDeviceID )
         qsamplerDeviceType deviceType, int iDeviceID )  
111  {  {
112          setDevice(pClient, deviceType, iDeviceID);  //      m_ports.setAutoDelete(true);
113    
114            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.
125    Device::Device ( const Device& device )
126            : m_params(device.m_params), m_ports(device.m_ports)
127    {
128            m_iDeviceID   = device.m_iDeviceID;
129            m_deviceType  = device.m_deviceType;
130            m_sDeviceType = device.m_sDeviceType;
131            m_sDriverName = device.m_sDriverName;
132            m_sDeviceName = device.m_sDeviceName;
133  }  }
134    
135    
136  // Initializer.  // Initializer.
137  void qsamplerDevice::setDevice ( lscp_client_t *pClient,  void Device::setDevice ( DeviceType deviceType, int iDeviceID )
         qsamplerDeviceType deviceType, int iDeviceID )  
138  {  {
139            MainForm *pMainForm = MainForm::getInstance();
140            if (pMainForm == NULL)
141                    return;
142            if (pMainForm->client() == NULL)
143                    return;
144    
145          // Device id and type should be always set.          // Device id and type should be always set.
146          m_iDeviceID   = iDeviceID;          m_iDeviceID  = iDeviceID;
147          m_deviceType  = deviceType;          m_deviceType = deviceType;
148    
149            // Reset device parameters and ports anyway.
150            m_params.clear();
151            qDeleteAll(m_ports);
152            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                  pDeviceInfo = ::lscp_get_audio_device_info(pClient, iDeviceID);                  if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_audio_device_info(
160                                    pMainForm->client(), m_iDeviceID)) == NULL)
161                            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                  pDeviceInfo = ::lscp_get_midi_device_info(pClient, iDeviceID);                  if (m_iDeviceID >= 0 && (pDeviceInfo = ::lscp_get_midi_device_info(
166                                    pMainForm->client(), m_iDeviceID)) == NULL)
167                            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          }          }
   
173          // If we're bogus, bail out...          // If we're bogus, bail out...
174          if (pDeviceInfo == NULL) {          if (pDeviceInfo == NULL) {
175                  m_sDriverName = QString::null;                  m_sDriverName = QString::null;
176                  m_sDeviceName = QObject::tr("New device");                  m_sDeviceName = QObject::tr("New %1 device").arg(m_sDeviceType);
177                  return;                  return;
178          }          }
179    
# Line 153  void qsamplerDevice::setDevice ( lscp_cl Line 183  void qsamplerDevice::setDevice ( lscp_cl
183                  + QObject::tr("Device %1").arg(m_iDeviceID);                  + QObject::tr("Device %1").arg(m_iDeviceID);
184    
185          // Grab device parameters...          // Grab device parameters...
         m_params.clear();  
186          for (int i = 0; pDeviceInfo->params && pDeviceInfo->params[i].key; i++) {          for (int i = 0; pDeviceInfo->params && pDeviceInfo->params[i].key; i++) {
187                  const char *pszParam = 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                          pParamInfo = ::lscp_get_audio_driver_param_info(pClient,                          if ((pParamInfo = ::lscp_get_audio_driver_param_info(
192                                  m_sDriverName.latin1(), pszParam, NULL);                                          pMainForm->client(), m_sDriverName.toUtf8().constData(),
193                          break;                                          sParam.toUtf8().constData(), NULL)) == NULL)
194                  case qsamplerDevice::Midi:                                  appendMessagesClient("lscp_get_audio_driver_param_info");
195                          pParamInfo = ::lscp_get_midi_driver_param_info(pClient,                          break;
196                                  m_sDriverName.latin1(), pszParam, NULL);                  case Device::Midi:
197                            if ((pParamInfo = ::lscp_get_midi_driver_param_info(
198                                            pMainForm->client(), m_sDriverName.toUtf8().constData(),
199                                            sParam.toUtf8().constData(), NULL)) == NULL)
200                                    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[pszParam] = qsamplerDeviceParam(pParamInfo,                          m_params[sParam.toUpper()] = DeviceParam(pParamInfo,
207                                  pDeviceInfo->params[i].value);                                  pDeviceInfo->params[i].value);
208                  }                  }
209          }          }
210    
211            // Refresh parameter dependencies...
212            refreshParams();
213            // Set port/channel list...
214            refreshPorts();
215  }  }
216    
217    
218  // Driver name initializer.  // Driver name initializer/settler.
219  void qsamplerDevice::setDriver ( lscp_client_t *pClient,  void Device::setDriver ( const QString& sDriverName )
         const QString& sDriverName )  
220  {  {
221            MainForm *pMainForm = MainForm::getInstance();
222            if (pMainForm == NULL)
223                    return;
224            if (pMainForm->client() == NULL)
225                    return;
226    
227          // Valid only for scratch devices.          // Valid only for scratch devices.
228          if (m_sDriverName == sDriverName)          if (m_sDriverName == sDriverName)
229                  return;                  return;
230    
231            // Reset device parameters and ports anyway.
232            m_params.clear();
233            qDeleteAll(m_ports);
234            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                  pDriverInfo = ::lscp_get_audio_driver_info(pClient,                  if ((pDriverInfo = ::lscp_get_audio_driver_info(pMainForm->client(),
241                          sDriverName.latin1());                                  sDriverName.toUtf8().constData())) == NULL)
242                  break;                          appendMessagesClient("lscp_get_audio_driver_info");
         case qsamplerDevice::Midi:  
                 pDriverInfo = ::lscp_get_midi_driver_info(pClient,  
                         sDriverName.latin1());  
243                  break;                  break;
244          case qsamplerDevice::None:          case Device::Midi:
245                    if ((pDriverInfo = ::lscp_get_midi_driver_info(pMainForm->client(),
246                                    sDriverName.toUtf8().constData())) == NULL)
247                            appendMessagesClient("lscp_get_midi_driver_info");
248                    break;
249            case Device::None:
250                  break;                  break;
251          }          }
252    
# Line 208  void qsamplerDevice::setDriver ( lscp_cl Line 258  void qsamplerDevice::setDriver ( lscp_cl
258          m_sDriverName = sDriverName;          m_sDriverName = sDriverName;
259    
260          // Grab driver parameters...          // Grab driver parameters...
         m_params.clear();  
261          for (int i = 0; pDriverInfo->parameters && pDriverInfo->parameters[i]; i++) {          for (int i = 0; pDriverInfo->parameters && pDriverInfo->parameters[i]; i++) {
262                  const char *pszParam = 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                          pParamInfo = ::lscp_get_audio_driver_param_info(pClient,                          if ((pParamInfo = ::lscp_get_audio_driver_param_info(
267                                  sDriverName.latin1(), pszParam, NULL);                                          pMainForm->client(), sDriverName.toUtf8().constData(),
268                                            sParam.toUtf8().constData(), NULL)) == NULL)
269                                    appendMessagesClient("lscp_get_audio_driver_param_info");
270                          break;                          break;
271                  case qsamplerDevice::Midi:                  case Device::Midi:
272                          pParamInfo = ::lscp_get_midi_driver_param_info(pClient,                          if ((pParamInfo = ::lscp_get_midi_driver_param_info(
273                                  sDriverName.latin1(), pszParam, NULL);                                          pMainForm->client(), sDriverName.toUtf8().constData(),
274                                            sParam.toUtf8().constData(), NULL)) == NULL)
275                                    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[pszParam] = qsamplerDeviceParam(pParamInfo, pParamInfo->defaultv);                          m_params[sParam.toUpper()] = DeviceParam(pParamInfo,
282                                    pParamInfo->defaultv);
283                    }
284          }          }
285    
286            // Refresh parameter dependencies...
287            refreshParams();
288            // Set port/channel list...
289            refreshPorts();
290  }  }
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  const QString& qsamplerDevice::deviceName (void) const  // Special device name formatter.
315    QString Device::deviceName (void) const
316  {  {
317          return m_sDeviceName;          QString sPrefix;
318            if (m_iDeviceID >= 0)
319                    sPrefix += m_sDeviceType + ' ';
320            return sPrefix + m_sDeviceName;
321  }  }
322    
323    
324    // Set the proper device parameter value.
325    bool Device::setParam ( const QString& sParam,
326            const QString& sValue )
327    {
328            MainForm *pMainForm = MainForm::getInstance();
329            if (pMainForm == NULL)
330                    return false;
331            if (pMainForm->client() == NULL)
332                    return false;
333    
334            // Set proper device parameter.
335            m_params[sParam.toUpper()].value = sValue;
336    
337            // If the device already exists, things get immediate...
338            int iRefresh = 0;
339            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.
348                    lscp_param_t param;
349                    param.key   = (char *) finalParamKey.constData();
350                    param.value = (char *) finalParamVal.constData();
351                    // Now it depends on the device type...
352                    lscp_status_t ret = LSCP_FAILED;
353                    switch (m_deviceType) {
354                    case Device::Audio:
355                            if (sParam == "CHANNELS") iRefresh++;
356                            if ((ret = ::lscp_set_audio_device_param(pMainForm->client(),
357                                            m_iDeviceID, &param)) != LSCP_OK)
358                                    appendMessagesClient("lscp_set_audio_device_param");
359                            break;
360                    case Device::Midi:
361                            if (sParam == "PORTS") iRefresh++;
362                            if ((ret = ::lscp_set_midi_device_param(pMainForm->client(),
363                                            m_iDeviceID, &param)) != LSCP_OK)
364                                    appendMessagesClient("lscp_set_midi_device_param");
365                            break;
366                    case Device::None:
367                            break;
368                    }
369                    // Show result.
370                    if (ret == LSCP_OK) {
371                            appendMessages(QString("%1: %2.").arg(sParam).arg(sValue));
372                            // Special care for specific parameter changes...
373                            if (iRefresh > 0)
374                                    iRefresh += refreshPorts();
375                            iRefresh += refreshDepends(sParam);
376                    } else {
377                            // Oops...
378                            appendMessagesError(
379                                    QObject::tr("Could not set device parameter value.\n\nSorry."));
380                    }
381            }
382    
383            // Return whether we're need a view refresh.
384            return (iRefresh > 0);
385    }
386    
387    
388  // Device parameter accessor.  // Device parameter accessor.
389  qsamplerDeviceParamMap& qsamplerDevice::params (void)  const DeviceParamMap& Device::params (void) const
390  {  {
391          return m_params;          return m_params;
392  }  }
393    
394    
395  // Update/refresh device/driver data.  // Device port/channel list accessor.
396  void qsamplerDevice::refresh (void)  DevicePortList& Device::ports (void)
397  {  {
398            return m_ports;
399  }  }
400    
401    
402    // Create a new device, as a copy of this current one.
403    bool Device::createDevice (void)
404    {
405            MainForm *pMainForm = MainForm::getInstance();
406            if (pMainForm == NULL)
407                    return false;
408            if (pMainForm->client() == NULL)
409                    return false;
410    
411            // we need temporary lists with the final strings, because i.e.
412            // QString::toUtf8() only returns a temporary object and the
413            // C-style char* pointers for liblscp would immediately be invalidated
414            QList<QByteArray> finalKeys;
415            QList<QByteArray> finalVals;
416    
417            DeviceParamMap::ConstIterator iter;
418            for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
419                    if (iter.value().value == QString::null) continue;
420                    finalKeys.push_back(iter.key().toUtf8());
421                    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.
434            pParams[iParam].key   = NULL;
435            pParams[iParam].value = NULL;
436    
437            // Now it depends on the device type...
438            switch (m_deviceType) {
439            case Device::Audio:
440                    if ((m_iDeviceID = ::lscp_create_audio_device(pMainForm->client(),
441                                    m_sDriverName.toUtf8().constData(), pParams)) < 0)
442                            appendMessagesClient("lscp_create_audio_device");
443                    break;
444            case Device::Midi:
445                    if ((m_iDeviceID = ::lscp_create_midi_device(pMainForm->client(),
446                                    m_sDriverName.toUtf8().constData(), pParams)) < 0)
447                            appendMessagesClient("lscp_create_midi_device");
448                    break;
449            case Device::None:
450                    break;
451            }
452    
453            // Free used parameter array.
454            delete pParams;
455    
456            // Show result.
457            if (m_iDeviceID >= 0) {
458                    // Refresh our own stuff...
459                    setDevice(m_deviceType, m_iDeviceID);
460                    appendMessages(QObject::tr("created."));
461            } else {
462                    appendMessagesError(QObject::tr("Could not create device.\n\nSorry."));
463            }
464    
465            // Return whether we're a valid device...
466            return (m_iDeviceID >= 0);
467    }
468    
469    
470    // Destroy existing device.
471    bool Device::deleteDevice (void)
472    {
473            MainForm *pMainForm = MainForm::getInstance();
474            if (pMainForm == NULL)
475                    return false;
476            if (pMainForm->client() == NULL)
477                    return false;
478    
479            // Now it depends on the device type...
480            lscp_status_t ret = LSCP_FAILED;
481            switch (m_deviceType) {
482            case Device::Audio:
483                    if ((ret = ::lscp_destroy_audio_device(pMainForm->client(),
484                                    m_iDeviceID)) != LSCP_OK)
485                            appendMessagesClient("lscp_destroy_audio_device");
486                    break;
487            case Device::Midi:
488                    if ((ret = ::lscp_destroy_midi_device(pMainForm->client(),
489                                    m_iDeviceID)) != LSCP_OK)
490                            appendMessagesClient("lscp_destroy_midi_device");
491                    break;
492            case Device::None:
493                    break;
494            }
495    
496            // Show result.
497            if (ret == LSCP_OK) {
498                    appendMessages(QObject::tr("deleted."));
499                    m_iDeviceID = -1;
500            } else {
501                    appendMessagesError(QObject::tr("Could not delete device.\n\nSorry."));
502            }
503    
504            // Return whether we've done it..
505            return (ret == LSCP_OK);
506    }
507    
508    
509    // Device parameter dependencies refreshner.
510    int Device::refreshParams (void)
511    {
512            // This should only make sense for scratch devices...
513            if (m_iDeviceID >= 0)
514                    return 0;
515            // Refresh all parameters that have dependencies...
516            int iParams = 0;
517            DeviceParamMap::ConstIterator iter;
518            for (iter = m_params.begin(); iter != m_params.end(); ++iter)
519                    iParams += refreshParam(iter.key());
520            // Return how many parameters have been refreshed...
521            return iParams;
522    }
523    
524    
525    // Device port/channel list refreshner.
526    int Device::refreshPorts (void)
527    {
528            // This should only make sense for actual devices...
529            if (m_iDeviceID < 0)
530                    return 0;
531            // Port/channel count determination...
532            int iPorts = 0;
533            switch (m_deviceType) {
534            case Device::Audio:
535                    iPorts = m_params["CHANNELS"].value.toInt();
536                    break;
537            case Device::Midi:
538                    iPorts = m_params["PORTS"].value.toInt();
539                    break;
540            case Device::None:
541                    break;
542            }
543            // Retrieve port/channel information...
544            qDeleteAll(m_ports);
545            m_ports.clear();
546            for (int iPort = 0; iPort < iPorts; iPort++)
547                    m_ports.append(new DevicePort(*this, iPort));
548            // Return how many ports have been refreshed...
549            return iPorts;
550    }
551    
552    
553    // Refresh/set dependencies given that some parameter has changed.
554    int Device::refreshDepends ( const QString& sParam )
555    {
556            // This should only make sense for scratch devices...
557            if (m_iDeviceID >= 0)
558                    return 0;
559            // Refresh all parameters that depend on this one...
560            int iDepends = 0;
561            DeviceParamMap::ConstIterator iter;
562            for (iter = m_params.begin(); iter != m_params.end(); ++iter) {
563                    const QStringList& depends = iter.value().depends;
564                    if (depends.indexOf(sParam) >= 0)
565                            iDepends += refreshParam(iter.key());
566            }
567            // Return how many dependencies have been refreshed...
568            return iDepends;
569    }
570    
571    
572    // Refresh/set given parameter based on driver supplied dependencies.
573    int Device::refreshParam ( const QString& sParam )
574    {
575            MainForm *pMainForm = MainForm::getInstance();
576            if (pMainForm == NULL)
577                    return 0;
578            if (pMainForm->client() == NULL)
579                    return 0;
580    
581            // Check if we have dependencies...
582            DeviceParam& param = m_params[sParam.toUpper()];
583            if (param.depends.isEmpty())
584                    return 0;
585    
586            int iRefresh = 0;
587    
588            // Build dependency list...
589            lscp_param_t *pDepends = new lscp_param_t [param.depends.count() + 1];
590            int iDepend = 0;
591    
592            // we need temporary lists with the final strings, because i.e.
593            // QString::toUtf8() only returns a temporary object and the
594            // C-style char* pointers for liblscp would immediately be invalidated
595            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;
607            }
608            // Null terminated.
609            pDepends[iDepend].key   = NULL;
610            pDepends[iDepend].value = NULL;
611    
612            // FIXME: Some parameter dependencies (e.g.ALSA CARD)
613            // are blocking for no reason, causing potential timeout-crashes.
614            // hopefully this gets mitigated if this dependency hell is only
615            // carried out for scratch devices...
616    
617            // Retrieve some modern parameters...
618            lscp_param_info_t *pParamInfo = NULL;
619            switch (m_deviceType) {
620            case Device::Audio:
621                    if ((pParamInfo = ::lscp_get_audio_driver_param_info(
622                                    pMainForm->client(), m_sDriverName.toUtf8().constData(),
623                                    sParam.toUtf8().constData(), pDepends)) == NULL)
624                            appendMessagesClient("lscp_get_audio_driver_param_info");
625                    break;
626            case Device::Midi:
627                    if ((pParamInfo = ::lscp_get_midi_driver_param_info(
628                                    pMainForm->client(), m_sDriverName.toUtf8().constData(),
629                                    sParam.toUtf8().constData(), pDepends)) == NULL)
630                            appendMessagesClient("lscp_get_midi_driver_param_info");
631                    break;
632            case Device::None:
633                    break;
634            }
635            if (pParamInfo) {
636                    param = DeviceParam(pParamInfo,
637                            param.value.isEmpty() ? NULL : param.value.toUtf8().constData());
638                    iRefresh++;
639            }
640    
641            // Free used parameter array.
642            delete pDepends;
643    
644            // Return whether the parameters has been changed...
645            return iRefresh;
646    }
647    
648    
649    // Redirected messages output methods.
650    void Device::appendMessages( const QString& s ) const
651    {
652            MainForm *pMainForm = MainForm::getInstance();
653            if (pMainForm)
654                    pMainForm->appendMessages(deviceName() + ' ' + s);
655    }
656    
657    void Device::appendMessagesColor( const QString& s,
658            const QString& c ) const
659    {
660            MainForm *pMainForm = MainForm::getInstance();
661            if (pMainForm)
662                    pMainForm->appendMessagesColor(deviceName() + ' ' + s, c);
663    }
664    
665    void Device::appendMessagesText( const QString& s ) const
666    {
667            MainForm *pMainForm = MainForm::getInstance();
668            if (pMainForm)
669                    pMainForm->appendMessagesText(deviceName() + ' ' + s);
670    }
671    
672    void Device::appendMessagesError( const QString& s ) const
673    {
674            MainForm *pMainForm = MainForm::getInstance();
675            if (pMainForm)
676                    pMainForm->appendMessagesError(deviceName() + "\n\n" + s);
677    }
678    
679    void Device::appendMessagesClient( const QString& s ) const
680    {
681            MainForm *pMainForm = MainForm::getInstance();
682            if (pMainForm)
683                    pMainForm->appendMessagesClient(deviceName() + ' ' + s);
684    }
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;
# Line 288  int *qsamplerDevice::getDevices ( lscp_c Line 704  int *qsamplerDevice::getDevices ( lscp_c
704    
705    
706  // Driver names enumerator.  // Driver names enumerator.
707  QStringList qsamplerDevice::getDrivers ( lscp_client_t *pClient,  QStringList Device::getDrivers ( lscp_client_t *pClient,
708          qsamplerDeviceType deviceType )          DeviceType deviceType )
709  {  {
710          QStringList drivers;          QStringList drivers;
711            
712          const char **ppszDrivers = NULL;          const char **ppszDrivers = NULL;
713          switch (deviceType) {          switch (deviceType) {
714          case qsamplerDevice::Audio:          case Device::Audio:
715                  ppszDrivers = ::lscp_get_available_audio_drivers(pClient);                  ppszDrivers = ::lscp_list_available_audio_drivers(pClient);
716                  break;                  break;
717          case qsamplerDevice::Midi:          case Device::Midi:
718                  ppszDrivers = ::lscp_get_available_midi_drivers(pClient);                  ppszDrivers = ::lscp_list_available_midi_drivers(pClient);
719                  break;                  break;
720          case qsamplerDevice::None:          case Device::None:
721                  break;                  break;
722          }          }
723            
724          for (int iDriver = 0; ppszDrivers[iDriver]; iDriver++)          for (int iDriver = 0; ppszDrivers && ppszDrivers[iDriver]; iDriver++)
725                  drivers.append(ppszDrivers[iDriver]);                  drivers.append(ppszDrivers[iDriver]);
726    
727          return drivers;          return drivers;
# Line 313  QStringList qsamplerDevice::getDrivers ( Line 729  QStringList qsamplerDevice::getDrivers (
729    
730    
731  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
732  // qsamplerDeviceItem - QListView device item.  // QSampler::DevicePort - MIDI/Audio Device port/channel structure.
733    //
734    
735    // Constructor.
736    DevicePort::DevicePort ( Device& device,
737            int iPortID ) : m_device(device)
738    {
739            setDevicePort(iPortID);
740    }
741    
742    // Default destructor.
743    DevicePort::~DevicePort (void)
744    {
745    }
746    
747    
748    // Initializer.
749    void DevicePort::setDevicePort ( int iPortID )
750    {
751            MainForm *pMainForm = MainForm::getInstance();
752            if (pMainForm == NULL)
753                    return;
754            if (pMainForm->client() == NULL)
755                    return;
756    
757            // Device port id should be always set.
758            m_iPortID = iPortID;
759    
760            // Reset port parameters anyway.
761            m_params.clear();
762    
763            // Retrieve device port/channel info, if any.
764            lscp_device_port_info_t *pPortInfo = NULL;
765            switch (m_device.deviceType()) {
766            case Device::Audio:
767                    if ((pPortInfo = ::lscp_get_audio_channel_info(pMainForm->client(),
768                                    m_device.deviceID(), m_iPortID)) == NULL)
769                            m_device.appendMessagesClient("lscp_get_audio_channel_info");
770                    break;
771            case Device::Midi:
772                    if ((pPortInfo = ::lscp_get_midi_port_info(pMainForm->client(),
773                                    m_device.deviceID(), m_iPortID)) == NULL)
774                            m_device.appendMessagesClient("lscp_get_midi_port_info");
775                    break;
776            case Device::None:
777                    break;
778            }
779    
780            // If we're bogus, bail out...
781            if (pPortInfo == NULL) {
782                    m_sPortName = QString::null;
783                    return;
784            }
785    
786            // Set device port/channel properties...
787            m_sPortName = pPortInfo->name;
788    
789            // Grab device port/channel parameters...
790            m_params.clear();
791            for (int i = 0; pPortInfo->params && pPortInfo->params[i].key; i++) {
792                    const QString sParam = pPortInfo->params[i].key;
793                    lscp_param_info_t *pParamInfo = NULL;
794                    switch (m_device.deviceType()) {
795                    case Device::Audio:
796                            if ((pParamInfo = ::lscp_get_audio_channel_param_info(
797                                            pMainForm->client(), m_device.deviceID(),
798                                            m_iPortID, sParam.toUtf8().constData())) == NULL)
799                                    m_device.appendMessagesClient("lscp_get_audio_channel_param_info");
800                            break;
801                    case Device::Midi:
802                            if ((pParamInfo = ::lscp_get_midi_port_param_info(
803                                            pMainForm->client(), m_device.deviceID(),
804                                            m_iPortID, sParam.toUtf8().constData())) == NULL)
805                                    m_device.appendMessagesClient("lscp_get_midi_port_param_info");
806                            break;
807                    case Device::None:
808                            break;
809                    }
810                    if (pParamInfo) {
811                            m_params[sParam.toUpper()] = DeviceParam(pParamInfo,
812                                    pPortInfo->params[i].value);
813                    }
814            }
815    }
816    
817    
818    // Device port/channel property accessors.
819    int DevicePort::portID (void) const
820    {
821            return m_iPortID;
822    }
823    
824    const QString& DevicePort::portName (void) const
825    {
826            return m_sPortName;
827    }
828    
829    // Device port/channel parameter accessor.
830    const DeviceParamMap& DevicePort::params (void) const
831    {
832            return m_params;
833    }
834    
835    
836    // Set the proper device port/channel parameter value.
837    bool DevicePort::setParam ( const QString& sParam,
838            const QString& sValue )
839    {
840            MainForm *pMainForm = MainForm::getInstance();
841            if (pMainForm == NULL)
842                    return false;
843            if (pMainForm->client() == NULL)
844                    return false;
845    
846            // Set proper port/channel parameter.
847            m_params[sParam.toUpper()].value = sValue;
848    
849            // If the device already exists, things get immediate...
850            int iRefresh = 0;
851            if (m_device.deviceID() >= 0 && m_iPortID >= 0) {
852    
853                    // we need temporary byte arrrays with the final strings, because
854                    // i.e. QString::toUtf8() only returns a temporary object and the
855                    // C-style char* pointers for liblscp would immediately be invalidated
856                    QByteArray finalParamKey = sParam.toUtf8();
857                    QByteArray finalParamVal = sValue.toUtf8();
858    
859                    // Prepare parameter struct.
860                    lscp_param_t param;
861                    param.key   = (char *) finalParamKey.constData();
862                    param.value = (char *) finalParamVal.constData();
863                    // Now it depends on the device type...
864                    lscp_status_t ret = LSCP_FAILED;
865                    switch (m_device.deviceType()) {
866                    case Device::Audio:
867                            if ((ret = ::lscp_set_audio_channel_param(pMainForm->client(),
868                                            m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
869                                    m_device.appendMessagesClient("lscp_set_audio_channel_param");
870                            break;
871                    case Device::Midi:
872                            if ((ret = ::lscp_set_midi_port_param(pMainForm->client(),
873                                            m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
874                                    m_device.appendMessagesClient("lscp_set_midi_port_param");
875                            break;
876                    case Device::None:
877                            break;
878                    }
879                    // Show result.
880                    if (ret == LSCP_OK) {
881                            m_device.appendMessages(m_sPortName
882                                    + ' ' + QString("%1: %2.").arg(sParam).arg(sValue));
883                            iRefresh++;
884                    } else {
885                            m_device.appendMessagesError(
886                                    QObject::tr("Could not set %1 parameter value.\n\n"
887                                            "Sorry.").arg(m_sPortName));
888                    }
889            }
890    
891            // Return whether we're need a view refresh.
892            return (iRefresh > 0);
893    }
894    
895    
896    //-------------------------------------------------------------------------
897    // QSampler::DeviceItem - QTreeWidget device item.
898  //  //
899    
900  // Constructors.  // Constructors.
901  qsamplerDeviceItem::qsamplerDeviceItem ( QListView *pListView,  DeviceItem::DeviceItem ( QTreeWidget* pTreeWidget,
902          lscp_client_t *pClient, qsamplerDevice::qsamplerDeviceType deviceType )          Device::DeviceType deviceType )
903          : QListViewItem(pListView), m_device(pClient, deviceType)          : QTreeWidgetItem(pTreeWidget, QSAMPLER_DEVICE_ITEM),
904            m_device(deviceType)
905  {  {
906          switch(m_device.deviceType()) {          switch(m_device.deviceType()) {
907          case qsamplerDevice::Audio:          case Device::Audio:
908                  QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio1.png"));                  setIcon(0, QPixmap(":/icons/audio1.png"));
909                  QListViewItem::setText(0, QObject::tr("Audio devices"));                  setText(0, QObject::tr("Audio Devices"));
910                  break;                  break;
911          case qsamplerDevice::Midi:          case Device::Midi:
912                  QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi1.png"));                  setIcon(0, QPixmap(":/icons/midi1.png"));
913                  QListViewItem::setText(0, QObject::tr("MIDI devices"));                  setText(0, QObject::tr("MIDI Devices"));
914                  break;                  break;
915          case qsamplerDevice::None:          case Device::None:
916                  break;                  break;
917          }          }
918    
919            // Root items are not selectable...
920            setFlags(flags() & ~Qt::ItemIsSelectable);
921  }  }
922    
923  qsamplerDeviceItem::qsamplerDeviceItem ( QListViewItem *pItem,  DeviceItem::DeviceItem ( QTreeWidgetItem* pItem,
924          lscp_client_t *pClient, qsamplerDevice::qsamplerDeviceType deviceType,          Device::DeviceType deviceType,
925          int iDeviceID )          int iDeviceID )
926          : QListViewItem(pItem), m_device(pClient, deviceType, iDeviceID)          : QTreeWidgetItem(pItem, QSAMPLER_DEVICE_ITEM),
927            m_device(deviceType, iDeviceID)
928  {  {
929          switch(m_device.deviceType()) {          switch(m_device.deviceType()) {
930          case qsamplerDevice::Audio:          case Device::Audio:
931                  QListViewItem::setPixmap(0, QPixmap::fromMimeSource("audio2.png"));                  setIcon(0, QPixmap(":/icons/audio2.png"));
932                  break;                  break;
933          case qsamplerDevice::Midi:          case Device::Midi:
934                  QListViewItem::setPixmap(0, QPixmap::fromMimeSource("midi2.png"));                  setIcon(0, QPixmap(":/icons/midi2.png"));
935                  break;                  break;
936          case qsamplerDevice::None:          case Device::None:
937                  break;                  break;
938          }          }
939    
940          QListViewItem::setText(0, m_device.deviceName());          setText(0, m_device.deviceName());
941  }  }
942    
943  // Default destructor.  // Default destructor.
944  qsamplerDeviceItem::~qsamplerDeviceItem (void)  DeviceItem::~DeviceItem ()
945  {  {
946  }  }
947    
948  // Instance accessors.  // Instance accessors.
949  qsamplerDevice& qsamplerDeviceItem::device (void)  Device& DeviceItem::device ()
950  {  {
951          return m_device;          return m_device;
952  }  }
953    
954  // To virtually distinguish between list view items.  
955  int qsamplerDeviceItem::rtti() const  //-------------------------------------------------------------------------
956    // QSampler::AbstractDeviceParamModel - data model base class for device parameters
957    //
958    
959    AbstractDeviceParamModel::AbstractDeviceParamModel ( QObject* pParent )
960            : QAbstractTableModel(pParent), m_bEditable(false)
961  {  {
962          return QSAMPLER_DEVICE_ITEM;          m_pParams = NULL;
963  }  }
964    
965    
966    int AbstractDeviceParamModel::rowCount ( const QModelIndex& /*parent*/) const
967    {
968            //std::cout << "model size=" << params.size() << "\n" << std::flush;
969            return (m_pParams ? m_pParams->size() : 0);
970    }
971    
 //-------------------------------------------------------------------------  
 // qsamplerDeviceParamTable - Device parameter view table.  
 //  
972    
973  // Constructor.  int AbstractDeviceParamModel::columnCount ( const QModelIndex& /*parent*/) const
974  qsamplerDeviceParamTable::qsamplerDeviceParamTable ( QWidget *pParent,  {
975          const char *pszName )          return 3;
         : 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, true); -- of course not.  
         QTable::setColumnStretchable(1, true);  
976  }  }
977    
978  // Default destructor.  
979  qsamplerDeviceParamTable::~qsamplerDeviceParamTable (void)  Qt::ItemFlags AbstractDeviceParamModel::flags ( const QModelIndex& /*index*/) const
980  {  {
981            return Qt::ItemIsEditable | Qt::ItemIsEnabled;
982  }  }
983    
984    
985  // The main table refresher.  QVariant AbstractDeviceParamModel::headerData (
986  void qsamplerDeviceParamTable::refresh ( qsamplerDevice& device )          int section, Qt::Orientation orientation, int role) const
987  {  {
988          // Always (re)start it empty.          if (role != Qt::DisplayRole)
989          QTable::setUpdatesEnabled(false);                  return QVariant();
990          QTable::setNumRows(0);  
991            if (orientation == Qt::Horizontal) {
992          // Now fill the parameter table...                  switch (section) {
993          qsamplerDeviceParamMap& params = device.params();                          case 0:  return tr("Parameter");
994          QTable::insertRows(0, params.count());                          case 1:  return tr("Value");
995          int iRow = 0;                          case 2:  return tr("Description");
996          qsamplerDeviceParamMap::ConstIterator iter;                          default: return QVariant();
         for (iter = params.begin(); iter != params.end(); ++iter) {  
                 const qsamplerDeviceParam& param = iter.data();  
                 bool bEnabled = (device.deviceID() < 0 || !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) {  
                         QComboTableItem *pComboItem = new QComboTableItem(this,  
                                 param.possibilities);  
                     pComboItem->setCurrentItem(param.value);  
                     pComboItem->setEnabled(bEnabled);  
                     pComboItem->setEditable(bEnabled && param.multiplicity);  
                         QTable::setItem(iRow, 2, pComboItem);  
             } else if (param.type == LSCP_TYPE_INT) {  
                 qsamplerDeviceParamTableSpinBox *pSpinItem =  
                                 new qsamplerDeviceParamTableSpinBox(this,  
                                         bEnabled ? QTableItem::OnTyping : QTableItem::Never);  
                         pSpinItem->setMinValue(param.range_min.toInt());  
                         pSpinItem->setMaxValue(param.range_max.toInt());  
                         pSpinItem->setValue(param.value.toInt());  
                         QTable::setItem(iRow, 2, pSpinItem);  
                 } else {  
             qsamplerDeviceParamTableEditBox *pEditItem =  
                                 new qsamplerDeviceParamTableEditBox(this,  
                                     bEnabled ? QTableItem::OnTyping : QTableItem::Never,  
                                         param.value);  
                         QTable::setItem(iRow, 2, pEditItem);  
997                  }                  }
                 ++iRow;  
998          }          }
999    
1000          // Adjust optimal column widths.          return QVariant();
1001          QTable::adjustColumn(0);  }
1002          QTable::adjustColumn(2);  
1003    
1004          QTable::setUpdatesEnabled(true);  void AbstractDeviceParamModel::refresh (
1005          QTable::updateContents();          const DeviceParamMap* pParams, bool bEditable )
1006    {
1007            m_pParams   = pParams;
1008            m_bEditable = bEditable;
1009            // inform the outer world (QTableView) that our data changed
1010            QAbstractTableModel::reset();
1011    }
1012    
1013    
1014    void AbstractDeviceParamModel::clear (void)
1015    {
1016            m_pParams = NULL;
1017            // inform the outer world (QTableView) that our data changed
1018            QAbstractTableModel::reset();
1019  }  }
1020    
1021    
1022  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1023  // qsamplerDeviceParamTableSpinBox - Custom spin box for parameter table.  // QSampler::DeviceParamModel - data model for device parameters
1024  //  //                              (used for QTableView)
1025    
1026  // Constructor.  DeviceParamModel::DeviceParamModel ( QObject *pParent )
1027  qsamplerDeviceParamTableSpinBox::qsamplerDeviceParamTableSpinBox (          : AbstractDeviceParamModel(pParent)
         QTable *pTable, EditType editType )  
         : QTableItem(pTable, editType, QString::null)  
1028  {  {
1029          m_iValue = m_iMinValue = m_iMaxValue = 0;          m_pDevice = NULL;
1030  }  }
1031    
1032  // Public accessors.  QVariant DeviceParamModel::data (
1033  void qsamplerDeviceParamTableSpinBox::setValue ( int iValue )          const QModelIndex &index, int role) const
1034  {  {
1035          m_iValue = iValue;          if (!index.isValid())
1036          QTableItem::setText(QString::number(m_iValue));                  return QVariant();
1037    
1038            if (role != Qt::DisplayRole)
1039                    return QVariant();
1040    
1041            DeviceParameterRow item;
1042            item.name  = m_pParams->keys()[index.row()];
1043            item.param = (*m_pParams)[item.name];
1044            item.alive = (m_pDevice && m_pDevice->deviceID() >= 0);
1045    
1046            return QVariant::fromValue(item);
1047  }  }
1048    
1049  void qsamplerDeviceParamTableSpinBox::setMinValue ( int iMinValue )  
1050    bool DeviceParamModel::setData (
1051            const QModelIndex& index, const QVariant& value, int /*role*/)
1052  {  {
1053          m_iMinValue = iMinValue;          if (!index.isValid())
1054                    return false;
1055    
1056            QString key = m_pParams->keys()[index.row()];
1057            //m_pParams[key].value = value.toString();
1058            m_pDevice->setParam(key, value.toString());
1059            emit dataChanged(index, index);
1060            return true;
1061  }  }
1062    
1063  void qsamplerDeviceParamTableSpinBox::setMaxValue ( int iMaxValue )  
1064    void DeviceParamModel::refresh ( Device* pDevice, bool bEditable )
1065  {  {
1066          m_iMaxValue = iMaxValue;          m_pDevice = pDevice;
1067            AbstractDeviceParamModel::refresh(&pDevice->params(), bEditable);
1068  }  }
1069    
1070  // Virtual implemetations.  
1071  QWidget *qsamplerDeviceParamTableSpinBox::createEditor (void) const  void DeviceParamModel::clear (void)
1072  {  {
1073          QSpinBox *pSpinBox = new QSpinBox(QTableItem::table()->viewport());          AbstractDeviceParamModel::clear();
1074          QObject::connect(pSpinBox, SIGNAL(valueChanged(int)),          m_pDevice = NULL;
                 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);  
 //      pSpinBox->setEnabled(QTableItem::isEnabled());  
         return pSpinBox;  
1075  }  }
1076    
1077  void qsamplerDeviceParamTableSpinBox::setContentFromEditor ( QWidget *pWidget )  
1078    //-------------------------------------------------------------------------
1079    // QSampler::PortParamModel - data model for port parameters
1080    //                            (used for QTableView)
1081    
1082    PortParamModel::PortParamModel ( QObject *pParent)
1083            : AbstractDeviceParamModel(pParent)
1084  {  {
1085          if (pWidget->inherits("QSpinBox"))          m_pPort = NULL;
1086              QTableItem::setText(QString::number(((QSpinBox *) pWidget)->value()));  }
1087          else  
1088              QTableItem::setContentFromEditor(pWidget);  QVariant PortParamModel::data ( const QModelIndex &index, int role ) const
1089    {
1090            if (!index.isValid())
1091                    return QVariant();
1092    
1093            if (role != Qt::DisplayRole)
1094                    return QVariant();
1095    
1096            DeviceParameterRow item;
1097            item.name  = m_pParams->keys()[index.row()];
1098            item.param = (*m_pParams)[item.name];
1099            item.alive = (m_pPort && m_pPort->portID() >= 0);
1100    
1101            return QVariant::fromValue(item);
1102    }
1103    
1104    
1105    bool PortParamModel::setData (
1106            const QModelIndex& index, const QVariant& value, int /*role*/)
1107    {
1108            if (!index.isValid())
1109                    return false;
1110    
1111            QString key = m_pParams->keys()[index.row()];
1112            //params[key].value = value.toString();
1113            m_pPort->setParam(key, value.toString());
1114            emit dataChanged(index, index);
1115            return true;
1116    }
1117    
1118    
1119    void PortParamModel::refresh ( DevicePort* pPort, bool bEditable )
1120    {
1121            m_pPort = pPort;
1122            AbstractDeviceParamModel::refresh(&pPort->params(), bEditable);
1123    }
1124    
1125    
1126    void PortParamModel::clear (void)
1127    {
1128            AbstractDeviceParamModel::clear();
1129            m_pPort = NULL;
1130  }  }
1131    
1132    
1133  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
1134  // qsamplerDeviceParamTableEditBox - Custom edit box for parameter table.  // QSampler::DeviceParamDelegate - table cell renderer for device/port parameters
1135  //  //
1136    
1137  // Constructor.  DeviceParamDelegate::DeviceParamDelegate ( QObject *pParent)
1138  qsamplerDeviceParamTableEditBox::qsamplerDeviceParamTableEditBox (          : QItemDelegate(pParent)
         QTable *pTable, EditType editType, const QString& sText )  
         : QTableItem(pTable, editType, sText)  
1139  {  {
1140  }  }
1141    
1142  // Virtual implemetations.  
1143  QWidget *qsamplerDeviceParamTableEditBox::createEditor (void) const  QWidget* DeviceParamDelegate::createEditor ( QWidget *pParent,
1144            const QStyleOptionViewItem& /* option */, const QModelIndex& index ) const
1145  {  {
1146          QLineEdit *pEditBox = new QLineEdit(QTableItem::table()->viewport());          if (!index.isValid())
1147          QObject::connect(pEditBox, SIGNAL(returnPressed()),                  return NULL;
1148                  QTableItem::table(), SLOT(doValueChanged()));  
1149          pEditBox->setText(QTableItem::text());          DeviceParameterRow r = index.model()->data(index,
1150  //      pEditBox->setEnabled(QTableItem::isEnabled());                  Qt::DisplayRole).value<DeviceParameterRow>();
1151          return pEditBox;  
1152            const bool bEnabled = (r.alive) ? !r.param.fix : true;
1153    
1154            QString val = (r.alive) ? r.param.value : r.param.defaultv;
1155    
1156            switch (index.column()) {
1157                    case 0:
1158                            return new QLabel(r.name, pParent);
1159                    case 1: {
1160                            if (r.param.type == LSCP_TYPE_BOOL) {
1161                                    QCheckBox *pCheckBox = new QCheckBox(pParent);
1162                                    if (val != QString::null)
1163                                            pCheckBox->setChecked(val.toLower() == "true");
1164                                    pCheckBox->setEnabled(bEnabled);
1165                                    return pCheckBox;
1166                            } else if (r.param.possibilities.count() > 0) {
1167                                    QStringList opts = r.param.possibilities;
1168                                    if (r.param.multiplicity)
1169                                            opts.prepend(tr("(none)"));
1170                                    QComboBox *pComboBox = new QComboBox(pParent);
1171                                    pComboBox->addItems(opts);
1172                                    if (r.param.value.isEmpty())
1173                                            pComboBox->setCurrentIndex(0);
1174                                    else
1175                                            pComboBox->setCurrentIndex(pComboBox->findText(val));
1176                                    pComboBox->setEnabled(bEnabled);
1177                                    return pComboBox;
1178                            } else if (r.param.type == LSCP_TYPE_INT && bEnabled) {
1179                                    QSpinBox *pSpinBox = new QSpinBox(pParent);
1180                                    pSpinBox->setMinimum(
1181                                            (!r.param.range_min.isEmpty()) ?
1182                                                    r.param.range_min.toInt() : 0 // or better a negative default min value ?
1183                                    );
1184                                    pSpinBox->setMaximum(
1185                                            (!r.param.range_max.isEmpty()) ?
1186                                                    r.param.range_max.toInt() : (1 << 16) // or better a nigher default max value ?
1187                                    );
1188                                    pSpinBox->setValue(val.toInt());
1189                                    return pSpinBox;
1190                            } else if (bEnabled) {
1191                                    QLineEdit *pLineEdit = new QLineEdit(val, pParent);
1192                                    return pLineEdit;
1193                            } else {
1194                                    QLabel *pLabel = new QLabel(val, pParent);
1195                                    return pLabel;
1196                            }
1197                    }
1198                    case 2:
1199                            return new QLabel(r.param.description, pParent);
1200                    default:
1201                            return NULL;
1202            }
1203  }  }
1204    
1205  void qsamplerDeviceParamTableEditBox::setContentFromEditor ( QWidget *pWidget )  
1206    void DeviceParamDelegate::setEditorData (
1207            QWidget* /*pEditor*/, const QModelIndex& /*index*/) const
1208  {  {
1209          if (pWidget->inherits("QLineEdit"))          // Unused, since we set the editor data already in createEditor()
1210              QTableItem::setText(((QLineEdit *) pWidget)->text());  }
1211          else  
1212              QTableItem::setContentFromEditor(pWidget);  
1213    void DeviceParamDelegate::setModelData ( QWidget *pEditor,
1214            QAbstractItemModel *pModel, const QModelIndex& index ) const
1215    {
1216            if (index.column() == 1) {
1217                    DeviceParameterRow r = index.model()->data(index,
1218                            Qt::DisplayRole).value<DeviceParameterRow> ();
1219                    if (pEditor->metaObject()->className() == QString("QCheckBox")) {
1220                            QCheckBox* pCheckBox = static_cast<QCheckBox*> (pEditor);
1221                            pModel->setData(index, QVariant(pCheckBox->checkState() == Qt::Checked));
1222                    } else if (pEditor->metaObject()->className() == QString("QComboBox")) {
1223                            QComboBox* pComboBox = static_cast<QComboBox*> (pEditor);
1224                            pModel->setData(index, pComboBox->currentText());
1225                    } else if (pEditor->metaObject()->className() == QString("QSpinBox")) {
1226                            QSpinBox* pSpinBox = static_cast<QSpinBox*> (pEditor);
1227                            pModel->setData(index, pSpinBox->value());
1228                    } else if (pEditor->metaObject()->className() == QString("QLineEdit")) {
1229                            QLineEdit* pLineEdit = static_cast<QLineEdit*> (pEditor);
1230                            pModel->setData(index, pLineEdit->text());
1231                    } else if (pEditor->metaObject()->className() == QString("QLabel")) {
1232                            QLabel* pLabel = static_cast<QLabel*> (pEditor);
1233                            pModel->setData(index, pLabel->text());
1234                    }
1235            }
1236    }
1237    
1238    void DeviceParamDelegate::updateEditorGeometry ( QWidget *pEditor,
1239            const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
1240    {
1241            if (pEditor)
1242                    pEditor->setGeometry(option.rect);
1243  }  }
1244    
1245    } // namespace QSampler
1246    
1247  // end of qsamplerDevice.cpp  // end of qsamplerDevice.cpp

Legend:
Removed from v.442  
changed lines
  Added in v.1558

  ViewVC Help
Powered by ViewVC