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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1461 - (hide annotations) (download)
Sun Oct 28 23:30:36 2007 UTC (16 years, 5 months ago) by schoenebeck
File size: 34131 byte(s)
* started to port QSampler to Qt4 (NOTE: this version is yet broken, use
  the latest tarball release 0.1.5 until the Qt4 port is completed)

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

  ViewVC Help
Powered by ViewVC