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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC