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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1477 - (hide annotations) (download)
Mon Nov 12 01:33:13 2007 UTC (16 years, 4 months ago) by schoenebeck
File size: 34124 byte(s)
* again just a minor step for Qt4 port: couple fixes in device management
  list view

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

  ViewVC Help
Powered by ViewVC