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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3788 - (hide annotations) (download)
Thu Jun 11 16:59:09 2020 UTC (3 years, 10 months ago) by capela
File size: 34048 byte(s)
- Messages widget micro-refactoring.
1 capela 426 // qsamplerDevice.cpp
2     //
3     /****************************************************************************
4 capela 3788 Copyright (C) 2004-2020, 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 capela 3555 if (pParamInfo == nullptr)
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 3555 if (pMainForm == nullptr)
135 capela 961 return;
136 capela 3555 if (pMainForm->client() == nullptr)
137 capela 961 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 3555 lscp_device_info_t *pDeviceInfo = nullptr;
150 capela 429 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 3555 pMainForm->client(), m_iDeviceID)) == nullptr)
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 3555 pMainForm->client(), m_iDeviceID)) == nullptr)
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 capela 3555 if (pDeviceInfo == nullptr) {
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 3555 lscp_param_info_t *pParamInfo = nullptr;
183 capela 429 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 capela 3555 sParam.toUtf8().constData(), nullptr)) == nullptr)
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 capela 3555 sParam.toUtf8().constData(), nullptr)) == nullptr)
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 3555 if (pMainForm == nullptr)
217 capela 961 return;
218 capela 3555 if (pMainForm->client() == nullptr)
219 capela 961 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 capela 3555 lscp_driver_info_t *pDriverInfo = nullptr;
232 capela 431 switch (m_deviceType) {
233 capela 1558 case Device::Audio:
234 capela 961 if ((pDriverInfo = ::lscp_get_audio_driver_info(pMainForm->client(),
235 capela 3555 sDriverName.toUtf8().constData())) == nullptr)
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 3555 sDriverName.toUtf8().constData())) == nullptr)
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 capela 3555 if (pDriverInfo == nullptr)
249 capela 431 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 3555 lscp_param_info_t *pParamInfo = nullptr;
258 capela 431 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 capela 3555 sParam.toUtf8().constData(), nullptr)) == nullptr)
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 capela 3555 sParam.toUtf8().constData(), nullptr)) == nullptr)
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 3555 if (pMainForm == nullptr)
324 capela 961 return false;
325 capela 3555 if (pMainForm->client() == nullptr)
326 capela 961 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 3555 if (pMainForm == nullptr)
401 capela 484 return false;
402 capela 3555 if (pMainForm->client() == nullptr)
403 capela 961 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 capela 3555 pParams[iParam].key = nullptr;
429     pParams[iParam].value = nullptr;
430 capela 484
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 3555 if (pMainForm == nullptr)
469 capela 961 return false;
470 capela 3555 if (pMainForm->client() == nullptr)
471 capela 961 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 3555 if (pMainForm == nullptr)
571 capela 961 return 0;
572 capela 3555 if (pMainForm->client() == nullptr)
573 capela 961 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 capela 3555 pDepends[iDepend].key = nullptr;
604     pDepends[iDepend].value = nullptr;
605 capela 467
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 capela 3555 lscp_param_info_t *pParamInfo = nullptr;
613 capela 467 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 capela 3555 sParam.toUtf8().constData(), pDepends)) == nullptr)
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 capela 3555 sParam.toUtf8().constData(), pDepends)) == nullptr)
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 3555 param.value.isEmpty() ? nullptr : 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 3788 void Device::appendMessagesColor( const QString& s, const QColor& rgb ) const
652 capela 484 {
653 schoenebeck 1461 MainForm *pMainForm = MainForm::getInstance();
654 capela 961 if (pMainForm)
655 capela 3788 pMainForm->appendMessagesColor(deviceName() + ' ' + s, rgb);
656 capela 484 }
657    
658 capela 1558 void Device::appendMessagesText( const QString& s ) const
659 capela 484 {
660 schoenebeck 1461 MainForm *pMainForm = MainForm::getInstance();
661 capela 961 if (pMainForm)
662     pMainForm->appendMessagesText(deviceName() + ' ' + s);
663 capela 484 }
664    
665 capela 1558 void Device::appendMessagesError( const QString& s ) const
666 capela 484 {
667 schoenebeck 1461 MainForm *pMainForm = MainForm::getInstance();
668 capela 961 if (pMainForm)
669     pMainForm->appendMessagesError(deviceName() + "\n\n" + s);
670 capela 484 }
671    
672 capela 1558 void Device::appendMessagesClient( const QString& s ) const
673 capela 484 {
674 schoenebeck 1461 MainForm *pMainForm = MainForm::getInstance();
675 capela 961 if (pMainForm)
676     pMainForm->appendMessagesClient(deviceName() + ' ' + s);
677 capela 484 }
678    
679    
680 capela 430 // Device ids enumerator.
681 capela 1558 int *Device::getDevices ( lscp_client_t *pClient,
682 capela 1509 DeviceType deviceType )
683 capela 429 {
684 capela 3555 int *piDeviceIDs = nullptr;
685 capela 429 switch (deviceType) {
686 capela 1558 case Device::Audio:
687 capela 431 piDeviceIDs = ::lscp_list_audio_devices(pClient);
688 capela 429 break;
689 capela 1558 case Device::Midi:
690 capela 431 piDeviceIDs = ::lscp_list_midi_devices(pClient);
691     break;
692 capela 1558 case Device::None:
693 capela 436 break;
694 capela 429 }
695     return piDeviceIDs;
696     }
697    
698 schoenebeck 1698 std::set<int> Device::getDeviceIDs(lscp_client_t *pClient,
699     DeviceType deviceType)
700     {
701     std::set<int> result;
702     int* piDeviceIDs = getDevices(pClient, deviceType);
703     if (!piDeviceIDs) return result;
704     for (int i = 0; piDeviceIDs[i] != -1; ++i)
705     result.insert(piDeviceIDs[i]);
706     return result;
707     }
708 capela 430
709 schoenebeck 1698
710 capela 430 // Driver names enumerator.
711 capela 1558 QStringList Device::getDrivers ( lscp_client_t *pClient,
712 capela 1509 DeviceType deviceType )
713 capela 430 {
714     QStringList drivers;
715 capela 490
716 capela 3555 const char **ppszDrivers = nullptr;
717 capela 430 switch (deviceType) {
718 capela 1558 case Device::Audio:
719 capela 525 ppszDrivers = ::lscp_list_available_audio_drivers(pClient);
720 capela 430 break;
721 capela 1558 case Device::Midi:
722 capela 525 ppszDrivers = ::lscp_list_available_midi_drivers(pClient);
723 capela 431 break;
724 capela 1558 case Device::None:
725 capela 436 break;
726 capela 430 }
727 capela 490
728 capela 980 for (int iDriver = 0; ppszDrivers && ppszDrivers[iDriver]; iDriver++)
729 capela 431 drivers.append(ppszDrivers[iDriver]);
730 capela 430
731     return drivers;
732     }
733    
734    
735 capela 429 //-------------------------------------------------------------------------
736 capela 1558 // QSampler::DevicePort - MIDI/Audio Device port/channel structure.
737 capela 462 //
738    
739     // Constructor.
740 capela 1558 DevicePort::DevicePort ( Device& device,
741 capela 484 int iPortID ) : m_device(device)
742 capela 462 {
743 capela 484 setDevicePort(iPortID);
744 capela 462 }
745    
746     // Default destructor.
747 capela 1558 DevicePort::~DevicePort (void)
748 capela 462 {
749     }
750    
751    
752     // Initializer.
753 capela 1558 void DevicePort::setDevicePort ( int iPortID )
754 capela 462 {
755 schoenebeck 1461 MainForm *pMainForm = MainForm::getInstance();
756 capela 3555 if (pMainForm == nullptr)
757 capela 961 return;
758 capela 3555 if (pMainForm->client() == nullptr)
759 capela 961 return;
760    
761 capela 462 // Device port id should be always set.
762     m_iPortID = iPortID;
763    
764 capela 463 // Reset port parameters anyway.
765 capela 467 m_params.clear();
766 capela 463
767 capela 462 // Retrieve device port/channel info, if any.
768 capela 3555 lscp_device_port_info_t *pPortInfo = nullptr;
769 capela 484 switch (m_device.deviceType()) {
770 capela 1558 case Device::Audio:
771 capela 961 if ((pPortInfo = ::lscp_get_audio_channel_info(pMainForm->client(),
772 capela 3555 m_device.deviceID(), m_iPortID)) == nullptr)
773 capela 484 m_device.appendMessagesClient("lscp_get_audio_channel_info");
774 capela 462 break;
775 capela 1558 case Device::Midi:
776 capela 961 if ((pPortInfo = ::lscp_get_midi_port_info(pMainForm->client(),
777 capela 3555 m_device.deviceID(), m_iPortID)) == nullptr)
778 capela 484 m_device.appendMessagesClient("lscp_get_midi_port_info");
779 capela 462 break;
780 capela 1558 case Device::None:
781 capela 462 break;
782     }
783    
784     // If we're bogus, bail out...
785 capela 3555 if (pPortInfo == nullptr) {
786 capela 3518 m_sPortName.clear();
787 capela 462 return;
788     }
789    
790     // Set device port/channel properties...
791 capela 484 m_sPortName = pPortInfo->name;
792 capela 462
793     // Grab device port/channel parameters...
794     m_params.clear();
795     for (int i = 0; pPortInfo->params && pPortInfo->params[i].key; i++) {
796 capela 463 const QString sParam = pPortInfo->params[i].key;
797 capela 3555 lscp_param_info_t *pParamInfo = nullptr;
798 capela 484 switch (m_device.deviceType()) {
799 capela 1558 case Device::Audio:
800 capela 484 if ((pParamInfo = ::lscp_get_audio_channel_param_info(
801 capela 961 pMainForm->client(), m_device.deviceID(),
802 capela 3555 m_iPortID, sParam.toUtf8().constData())) == nullptr)
803 capela 484 m_device.appendMessagesClient("lscp_get_audio_channel_param_info");
804 capela 462 break;
805 capela 1558 case Device::Midi:
806 capela 484 if ((pParamInfo = ::lscp_get_midi_port_param_info(
807 capela 961 pMainForm->client(), m_device.deviceID(),
808 capela 3555 m_iPortID, sParam.toUtf8().constData())) == nullptr)
809 capela 484 m_device.appendMessagesClient("lscp_get_midi_port_param_info");
810 capela 462 break;
811 capela 1558 case Device::None:
812 capela 462 break;
813     }
814     if (pParamInfo) {
815 capela 1558 m_params[sParam.toUpper()] = DeviceParam(pParamInfo,
816 capela 462 pPortInfo->params[i].value);
817     }
818     }
819     }
820    
821    
822     // Device port/channel property accessors.
823 capela 1558 int DevicePort::portID (void) const
824 capela 462 {
825     return m_iPortID;
826     }
827    
828 capela 1558 const QString& DevicePort::portName (void) const
829 capela 462 {
830     return m_sPortName;
831     }
832    
833     // Device port/channel parameter accessor.
834 capela 1558 const DeviceParamMap& DevicePort::params (void) const
835 capela 462 {
836     return m_params;
837     }
838    
839    
840     // Set the proper device port/channel parameter value.
841 capela 1558 bool DevicePort::setParam ( const QString& sParam,
842 capela 462 const QString& sValue )
843     {
844 schoenebeck 1461 MainForm *pMainForm = MainForm::getInstance();
845 capela 3555 if (pMainForm == nullptr)
846 capela 961 return false;
847 capela 3555 if (pMainForm->client() == nullptr)
848 capela 961 return false;
849    
850 capela 484 // Set proper port/channel parameter.
851 capela 1499 m_params[sParam.toUpper()].value = sValue;
852 capela 484
853     // If the device already exists, things get immediate...
854     int iRefresh = 0;
855     if (m_device.deviceID() >= 0 && m_iPortID >= 0) {
856 schoenebeck 1508
857     // we need temporary byte arrrays with the final strings, because
858     // i.e. QString::toUtf8() only returns a temporary object and the
859     // C-style char* pointers for liblscp would immediately be invalidated
860     QByteArray finalParamKey = sParam.toUtf8();
861     QByteArray finalParamVal = sValue.toUtf8();
862    
863 capela 484 // Prepare parameter struct.
864     lscp_param_t param;
865 schoenebeck 1508 param.key = (char *) finalParamKey.constData();
866     param.value = (char *) finalParamVal.constData();
867 capela 484 // Now it depends on the device type...
868     lscp_status_t ret = LSCP_FAILED;
869     switch (m_device.deviceType()) {
870 capela 1558 case Device::Audio:
871 capela 961 if ((ret = ::lscp_set_audio_channel_param(pMainForm->client(),
872 capela 484 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
873     m_device.appendMessagesClient("lscp_set_audio_channel_param");
874     break;
875 capela 1558 case Device::Midi:
876 capela 961 if ((ret = ::lscp_set_midi_port_param(pMainForm->client(),
877 capela 484 m_device.deviceID(), m_iPortID, &param)) != LSCP_OK)
878     m_device.appendMessagesClient("lscp_set_midi_port_param");
879     break;
880 capela 1558 case Device::None:
881 capela 484 break;
882     }
883     // Show result.
884     if (ret == LSCP_OK) {
885     m_device.appendMessages(m_sPortName
886     + ' ' + QString("%1: %2.").arg(sParam).arg(sValue));
887     iRefresh++;
888     } else {
889     m_device.appendMessagesError(
890     QObject::tr("Could not set %1 parameter value.\n\n"
891     "Sorry.").arg(m_sPortName));
892     }
893     }
894    
895     // Return whether we're need a view refresh.
896     return (iRefresh > 0);
897 capela 462 }
898    
899    
900     //-------------------------------------------------------------------------
901 capela 1558 // QSampler::DeviceItem - QTreeWidget device item.
902 capela 429 //
903    
904     // Constructors.
905 capela 1558 DeviceItem::DeviceItem ( QTreeWidget* pTreeWidget,
906     Device::DeviceType deviceType )
907 schoenebeck 1461 : QTreeWidgetItem(pTreeWidget, QSAMPLER_DEVICE_ITEM),
908 capela 1559 m_device(deviceType)
909 capela 429 {
910     switch(m_device.deviceType()) {
911 capela 1558 case Device::Audio:
912 capela 2074 setIcon(0, QPixmap(":/images/audio1.png"));
913 schoenebeck 1477 setText(0, QObject::tr("Audio Devices"));
914 capela 429 break;
915 capela 1558 case Device::Midi:
916 capela 2074 setIcon(0, QPixmap(":/images/midi1.png"));
917 schoenebeck 1477 setText(0, QObject::tr("MIDI Devices"));
918 capela 429 break;
919 capela 1558 case Device::None:
920 capela 436 break;
921 capela 429 }
922 capela 1558
923     // Root items are not selectable...
924     setFlags(flags() & ~Qt::ItemIsSelectable);
925 capela 429 }
926    
927 capela 1558 DeviceItem::DeviceItem ( QTreeWidgetItem* pItem,
928     Device::DeviceType deviceType,
929 capela 433 int iDeviceID )
930 schoenebeck 1461 : QTreeWidgetItem(pItem, QSAMPLER_DEVICE_ITEM),
931 capela 1559 m_device(deviceType, iDeviceID)
932 capela 429 {
933     switch(m_device.deviceType()) {
934 capela 1558 case Device::Audio:
935 capela 2074 setIcon(0, QPixmap(":/images/audio2.png"));
936 capela 429 break;
937 capela 1558 case Device::Midi:
938 capela 2074 setIcon(0, QPixmap(":/images/midi2.png"));
939 capela 429 break;
940 capela 1558 case Device::None:
941 capela 436 break;
942 capela 429 }
943    
944 schoenebeck 1486 setText(0, m_device.deviceName());
945 capela 429 }
946    
947     // Default destructor.
948 capela 1558 DeviceItem::~DeviceItem ()
949 capela 429 {
950     }
951    
952     // Instance accessors.
953 capela 1558 Device& DeviceItem::device ()
954 capela 429 {
955     return m_device;
956     }
957    
958    
959     //-------------------------------------------------------------------------
960 capela 1558 // QSampler::AbstractDeviceParamModel - data model base class for device parameters
961 capela 429 //
962 capela 426
963 capela 1509 AbstractDeviceParamModel::AbstractDeviceParamModel ( QObject* pParent )
964     : QAbstractTableModel(pParent), m_bEditable(false)
965     {
966 capela 3555 m_pParams = nullptr;
967 capela 426 }
968    
969 capela 1509
970     int AbstractDeviceParamModel::rowCount ( const QModelIndex& /*parent*/) const
971     {
972     //std::cout << "model size=" << params.size() << "\n" << std::flush;
973 capela 1510 return (m_pParams ? m_pParams->size() : 0);
974 capela 429 }
975    
976 capela 1509
977     int AbstractDeviceParamModel::columnCount ( const QModelIndex& /*parent*/) const
978     {
979     return 3;
980 schoenebeck 1461 }
981 capela 429
982 capela 1509
983     Qt::ItemFlags AbstractDeviceParamModel::flags ( const QModelIndex& /*index*/) const
984     {
985 schoenebeck 1518 return Qt::ItemIsEditable | Qt::ItemIsEnabled;
986 schoenebeck 1461 }
987    
988    
989 capela 1509 QVariant AbstractDeviceParamModel::headerData (
990     int section, Qt::Orientation orientation, int role) const
991     {
992     if (role != Qt::DisplayRole)
993     return QVariant();
994 schoenebeck 1461
995 capela 1509 if (orientation == Qt::Horizontal) {
996     switch (section) {
997     case 0: return tr("Parameter");
998     case 1: return tr("Value");
999     case 2: return tr("Description");
1000     default: return QVariant();
1001     }
1002     }
1003    
1004     return QVariant();
1005 schoenebeck 1461 }
1006    
1007 capela 1509
1008     void AbstractDeviceParamModel::refresh (
1009 capela 1558 const DeviceParamMap* pParams, bool bEditable )
1010 capela 1509 {
1011 capela 1510 m_pParams = pParams;
1012 capela 1509 m_bEditable = bEditable;
1013     // inform the outer world (QTableView) that our data changed
1014 capela 3520 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1015 capela 1509 QAbstractTableModel::reset();
1016 capela 2387 #else
1017     QAbstractTableModel::beginResetModel();
1018     QAbstractTableModel::endResetModel();
1019     #endif
1020 schoenebeck 1461 }
1021    
1022 capela 1509
1023     void AbstractDeviceParamModel::clear (void)
1024     {
1025 capela 3555 m_pParams = nullptr;
1026 capela 1509 // inform the outer world (QTableView) that our data changed
1027 capela 3520 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1028 capela 1509 QAbstractTableModel::reset();
1029 capela 2387 #else
1030     QAbstractTableModel::beginResetModel();
1031     QAbstractTableModel::endResetModel();
1032     #endif
1033 schoenebeck 1486 }
1034    
1035    
1036     //-------------------------------------------------------------------------
1037 capela 1558 // QSampler::DeviceParamModel - data model for device parameters
1038     // (used for QTableView)
1039 schoenebeck 1486
1040 capela 1509 DeviceParamModel::DeviceParamModel ( QObject *pParent )
1041     : AbstractDeviceParamModel(pParent)
1042     {
1043 capela 3555 m_pDevice = nullptr;
1044 schoenebeck 1486 }
1045    
1046 capela 1509 QVariant DeviceParamModel::data (
1047     const QModelIndex &index, int role) const
1048     {
1049     if (!index.isValid())
1050     return QVariant();
1051 schoenebeck 1508
1052 capela 1509 if (role != Qt::DisplayRole)
1053     return QVariant();
1054 schoenebeck 1508
1055 capela 1509 DeviceParameterRow item;
1056 capela 1510 item.name = m_pParams->keys()[index.row()];
1057     item.param = (*m_pParams)[item.name];
1058     item.alive = (m_pDevice && m_pDevice->deviceID() >= 0);
1059 capela 1509
1060     return QVariant::fromValue(item);
1061 schoenebeck 1508 }
1062    
1063 capela 1509
1064     bool DeviceParamModel::setData (
1065     const QModelIndex& index, const QVariant& value, int /*role*/)
1066     {
1067     if (!index.isValid())
1068     return false;
1069    
1070 capela 1510 QString key = m_pParams->keys()[index.row()];
1071     //m_pParams[key].value = value.toString();
1072     m_pDevice->setParam(key, value.toString());
1073 capela 1509 emit dataChanged(index, index);
1074     return true;
1075 schoenebeck 1486 }
1076    
1077 capela 1509
1078 capela 1558 void DeviceParamModel::refresh ( Device* pDevice, bool bEditable )
1079 capela 1509 {
1080 capela 1510 m_pDevice = pDevice;
1081 capela 1509 AbstractDeviceParamModel::refresh(&pDevice->params(), bEditable);
1082 schoenebeck 1486 }
1083    
1084 capela 1509
1085     void DeviceParamModel::clear (void)
1086     {
1087     AbstractDeviceParamModel::clear();
1088 capela 3555 m_pDevice = nullptr;
1089 schoenebeck 1461 }
1090    
1091    
1092 schoenebeck 1486 //-------------------------------------------------------------------------
1093 capela 1558 // QSampler::PortParamModel - data model for port parameters
1094     // (used for QTableView)
1095 schoenebeck 1486
1096 capela 1509 PortParamModel::PortParamModel ( QObject *pParent)
1097     : AbstractDeviceParamModel(pParent)
1098     {
1099 capela 3555 m_pPort = nullptr;
1100 schoenebeck 1486 }
1101    
1102 capela 1509 QVariant PortParamModel::data ( const QModelIndex &index, int role ) const
1103     {
1104     if (!index.isValid())
1105     return QVariant();
1106 schoenebeck 1508
1107 capela 1509 if (role != Qt::DisplayRole)
1108     return QVariant();
1109 schoenebeck 1508
1110 capela 1509 DeviceParameterRow item;
1111 capela 1510 item.name = m_pParams->keys()[index.row()];
1112     item.param = (*m_pParams)[item.name];
1113     item.alive = (m_pPort && m_pPort->portID() >= 0);
1114 capela 1509
1115     return QVariant::fromValue(item);
1116 schoenebeck 1508 }
1117    
1118 capela 1509
1119     bool PortParamModel::setData (
1120     const QModelIndex& index, const QVariant& value, int /*role*/)
1121     {
1122     if (!index.isValid())
1123     return false;
1124    
1125 capela 1510 QString key = m_pParams->keys()[index.row()];
1126 capela 1509 //params[key].value = value.toString();
1127 capela 1510 m_pPort->setParam(key, value.toString());
1128 capela 1509 emit dataChanged(index, index);
1129     return true;
1130 schoenebeck 1486 }
1131    
1132 capela 1509
1133 capela 1558 void PortParamModel::refresh ( DevicePort* pPort, bool bEditable )
1134 capela 1509 {
1135 capela 1510 m_pPort = pPort;
1136     AbstractDeviceParamModel::refresh(&pPort->params(), bEditable);
1137 schoenebeck 1486 }
1138    
1139 capela 1509
1140     void PortParamModel::clear (void)
1141     {
1142     AbstractDeviceParamModel::clear();
1143 capela 3555 m_pPort = nullptr;
1144 schoenebeck 1486 }
1145    
1146    
1147     //-------------------------------------------------------------------------
1148 capela 1558 // QSampler::DeviceParamDelegate - table cell renderer for device/port parameters
1149 schoenebeck 1486 //
1150    
1151 capela 1509 DeviceParamDelegate::DeviceParamDelegate ( QObject *pParent)
1152     : QItemDelegate(pParent)
1153     {
1154 schoenebeck 1461 }
1155    
1156 capela 1509
1157     QWidget* DeviceParamDelegate::createEditor ( QWidget *pParent,
1158     const QStyleOptionViewItem& /* option */, const QModelIndex& index ) const
1159 schoenebeck 1461 {
1160 capela 1509 if (!index.isValid())
1161 capela 3555 return nullptr;
1162 schoenebeck 1486
1163 capela 1509 DeviceParameterRow r = index.model()->data(index,
1164     Qt::DisplayRole).value<DeviceParameterRow>();
1165 schoenebeck 1461
1166 capela 1509 const bool bEnabled = (r.alive) ? !r.param.fix : true;
1167 capela 3405 const bool bFix = r.param.fix;
1168 schoenebeck 1461
1169 capela 1509 QString val = (r.alive) ? r.param.value : r.param.defaultv;
1170 schoenebeck 1508
1171 capela 1509 switch (index.column()) {
1172     case 0:
1173     return new QLabel(r.name, pParent);
1174     case 1: {
1175     if (r.param.type == LSCP_TYPE_BOOL) {
1176 capela 1510 QCheckBox *pCheckBox = new QCheckBox(pParent);
1177 capela 3518 if (!val.isEmpty())
1178 capela 1509 pCheckBox->setChecked(val.toLower() == "true");
1179     pCheckBox->setEnabled(bEnabled);
1180 capela 3405 pCheckBox->setCheckable(!bFix);
1181 capela 1509 return pCheckBox;
1182     } else if (r.param.possibilities.count() > 0) {
1183     QStringList opts = r.param.possibilities;
1184     if (r.param.multiplicity)
1185     opts.prepend(tr("(none)"));
1186 capela 1510 QComboBox *pComboBox = new QComboBox(pParent);
1187 capela 1509 pComboBox->addItems(opts);
1188     if (r.param.value.isEmpty())
1189     pComboBox->setCurrentIndex(0);
1190     else
1191     pComboBox->setCurrentIndex(pComboBox->findText(val));
1192     pComboBox->setEnabled(bEnabled);
1193 capela 3405 pComboBox->setEditable(!bFix);
1194 capela 1509 return pComboBox;
1195     } else if (r.param.type == LSCP_TYPE_INT && bEnabled) {
1196 capela 1510 QSpinBox *pSpinBox = new QSpinBox(pParent);
1197 capela 1509 pSpinBox->setMinimum(
1198     (!r.param.range_min.isEmpty()) ?
1199     r.param.range_min.toInt() : 0 // or better a negative default min value ?
1200     );
1201     pSpinBox->setMaximum(
1202     (!r.param.range_max.isEmpty()) ?
1203 capela 2059 r.param.range_max.toInt() : (1 << 24) // or better a higher default max value ?
1204 capela 1509 );
1205     pSpinBox->setValue(val.toInt());
1206 capela 3405 pSpinBox->setReadOnly(bFix);
1207 capela 1509 return pSpinBox;
1208     } else if (bEnabled) {
1209 capela 1510 QLineEdit *pLineEdit = new QLineEdit(val, pParent);
1210 capela 3405 pLineEdit->setReadOnly(bFix);
1211 capela 1509 return pLineEdit;
1212     } else {
1213 capela 1510 QLabel *pLabel = new QLabel(val, pParent);
1214 capela 1509 return pLabel;
1215     }
1216     }
1217     case 2:
1218     return new QLabel(r.param.description, pParent);
1219     default:
1220 capela 3555 return nullptr;
1221 capela 1509 }
1222 schoenebeck 1461 }
1223    
1224 capela 1509
1225     void DeviceParamDelegate::setEditorData (
1226     QWidget* /*pEditor*/, const QModelIndex& /*index*/) const
1227     {
1228     // Unused, since we set the editor data already in createEditor()
1229 schoenebeck 1461 }
1230    
1231 capela 1509
1232     void DeviceParamDelegate::setModelData ( QWidget *pEditor,
1233 capela 1510 QAbstractItemModel *pModel, const QModelIndex& index ) const
1234 capela 1509 {
1235     if (index.column() == 1) {
1236     DeviceParameterRow r = index.model()->data(index,
1237     Qt::DisplayRole).value<DeviceParameterRow> ();
1238 schoenebeck 1511 if (pEditor->metaObject()->className() == QString("QCheckBox")) {
1239 capela 1559 QCheckBox *pCheckBox = static_cast<QCheckBox *> (pEditor);
1240 capela 1510 pModel->setData(index, QVariant(pCheckBox->checkState() == Qt::Checked));
1241 schoenebeck 1511 } else if (pEditor->metaObject()->className() == QString("QComboBox")) {
1242 capela 1559 QComboBox *pComboBox = static_cast<QComboBox *> (pEditor);
1243 capela 1510 pModel->setData(index, pComboBox->currentText());
1244 schoenebeck 1511 } else if (pEditor->metaObject()->className() == QString("QSpinBox")) {
1245 capela 1559 QSpinBox *pSpinBox = static_cast<QSpinBox *> (pEditor);
1246 capela 1510 pModel->setData(index, pSpinBox->value());
1247 schoenebeck 1511 } else if (pEditor->metaObject()->className() == QString("QLineEdit")) {
1248 capela 1559 QLineEdit *pLineEdit = static_cast<QLineEdit *> (pEditor);
1249 capela 1510 pModel->setData(index, pLineEdit->text());
1250 schoenebeck 1511 } else if (pEditor->metaObject()->className() == QString("QLabel")) {
1251 capela 1559 QLabel *pLabel = static_cast<QLabel *> (pEditor);
1252 capela 1510 pModel->setData(index, pLabel->text());
1253 capela 1509 }
1254     }
1255 schoenebeck 1461 }
1256    
1257 capela 1509 void DeviceParamDelegate::updateEditorGeometry ( QWidget *pEditor,
1258 schoenebeck 1461 const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
1259     {
1260 capela 1509 if (pEditor)
1261     pEditor->setGeometry(option.rect);
1262 schoenebeck 1461 }
1263    
1264 capela 1558 } // namespace QSampler
1265    
1266 capela 426 // end of qsamplerDevice.cpp

  ViewVC Help
Powered by ViewVC