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

Contents of /qsampler/trunk/src/qsamplerChannelForm.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1509 - (show annotations) (download)
Thu Nov 22 11:10:44 2007 UTC (16 years, 5 months ago) by capela
File size: 23781 byte(s)
* Audio routing table is initially hidden in the dialog, when
  creating a new sampler channel.

* README requirements and configuration notes update.

1 // qsamplerChannelForm.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5 Copyright (C) 2007, Christian Schoenebeck
6
7 This program is free software; you can redistribute it and/or
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 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
21 *****************************************************************************/
22
23 #include "qsamplerChannelForm.h"
24
25 #include "qsamplerAbout.h"
26 #include "qsamplerDeviceForm.h"
27
28 #include "qsamplerMainForm.h"
29 #include "qsamplerInstrument.h"
30
31 #include <QValidator>
32 #include <QMessageBox>
33 #include <QFileDialog>
34 #include <QFileInfo>
35
36 #include <QHeaderView>
37
38
39 namespace QSampler {
40
41 ChannelForm::ChannelForm ( QWidget* pParent )
42 : QDialog(pParent)
43 {
44 m_ui.setupUi(this);
45
46 // Initialize locals.
47 m_pChannel = NULL;
48
49 m_iDirtySetup = 0;
50 m_iDirtyCount = 0;
51
52 // m_midiDevices.setAutoDelete(true);
53 // m_audioDevices.setAutoDelete(true);
54
55 m_pDeviceForm = NULL;
56
57 m_ui.AudioRoutingTable->setModel(&m_routingModel);
58 m_ui.AudioRoutingTable->setItemDelegate(&m_routingDelegate);
59 m_ui.AudioRoutingTable->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
60 // m_ui.AudioRoutingTable->verticalHeader()->hide();
61
62 // This goes initially hidden, and will be shown
63 // on setup() for currently existing channels...
64 m_ui.AudioRoutingTable->hide();
65
66 // Try to restore normal window positioning.
67 adjustSize();
68
69 QObject::connect(m_ui.EngineNameComboBox,
70 SIGNAL(activated(int)),
71 SLOT(optionsChanged()));
72 QObject::connect(m_ui.InstrumentFileComboBox,
73 SIGNAL(activated(const QString&)),
74 SLOT(updateInstrumentName()));
75 QObject::connect(m_ui.InstrumentFileToolButton,
76 SIGNAL(clicked()),
77 SLOT(openInstrumentFile()));
78 QObject::connect(m_ui.InstrumentNrComboBox,
79 SIGNAL(activated(int)),
80 SLOT(optionsChanged()));
81 QObject::connect(m_ui.MidiDriverComboBox,
82 SIGNAL(activated(const QString&)),
83 SLOT(selectMidiDriver(const QString&)));
84 QObject::connect(m_ui.MidiDeviceComboBox,
85 SIGNAL(activated(int)),
86 SLOT(selectMidiDevice(int)));
87 QObject::connect(m_ui.MidiPortSpinBox,
88 SIGNAL(valueChanged(int)),
89 SLOT(optionsChanged()));
90 QObject::connect(m_ui.MidiChannelComboBox,
91 SIGNAL(activated(int)),
92 SLOT(optionsChanged()));
93 QObject::connect(m_ui.MidiMapComboBox,
94 SIGNAL(activated(int)),
95 SLOT(optionsChanged()));
96 QObject::connect(m_ui.AudioDriverComboBox,
97 SIGNAL(activated(const QString&)),
98 SLOT(selectAudioDriver(const QString&)));
99 QObject::connect(m_ui.AudioDeviceComboBox,
100 SIGNAL(activated(int)),
101 SLOT(selectAudioDevice(int)));
102 QObject::connect(m_ui.OkPushButton,
103 SIGNAL(clicked()),
104 SLOT(accept()));
105 QObject::connect(m_ui.CancelPushButton,
106 SIGNAL(clicked()),
107 SLOT(reject()));
108 QObject::connect(m_ui.MidiDeviceToolButton,
109 SIGNAL(clicked()),
110 SLOT(setupMidiDevice()));
111 QObject::connect(m_ui.AudioDeviceToolButton,
112 SIGNAL(clicked()),
113 SLOT(setupAudioDevice()));
114 QObject::connect(&m_routingModel,
115 SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
116 SLOT(optionsChanged()));
117 QObject::connect(&m_routingModel,
118 SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
119 SLOT(updateTableCellRenderers(const QModelIndex&, const QModelIndex&)));
120 QObject::connect(&m_routingModel,
121 SIGNAL(modelReset()),
122 SLOT(updateTableCellRenderers()));
123 }
124
125 ChannelForm::~ChannelForm()
126 {
127 if (m_pDeviceForm)
128 delete m_pDeviceForm;
129 m_pDeviceForm = NULL;
130
131 qDeleteAll(m_midiDevices);
132 m_midiDevices.clear();
133
134 qDeleteAll(m_audioDevices);
135 m_audioDevices.clear();
136 }
137
138
139 // Channel dialog setup formal initializer.
140 void ChannelForm::setup ( qsamplerChannel *pChannel )
141 {
142 m_pChannel = pChannel;
143
144 m_iDirtySetup = 0;
145 m_iDirtyCount = 0;
146
147 if (m_pChannel == NULL)
148 return;
149
150 // It can be a brand new channel, remember?
151 bool bNew = (m_pChannel->channelID() < 0);
152 setWindowTitle(QSAMPLER_TITLE ": " + m_pChannel->channelName());
153
154 // Check if we're up and connected.
155 MainForm *pMainForm = MainForm::getInstance();
156 if (pMainForm == NULL)
157 return;
158 if (pMainForm->client() == NULL)
159 return;
160
161 qsamplerOptions *pOptions = pMainForm->options();
162 if (pOptions == NULL)
163 return;
164
165 // Avoid nested changes.
166 m_iDirtySetup++;
167
168 // Load combo box history...
169 pOptions->loadComboBoxHistory(m_ui.InstrumentFileComboBox);
170
171 // Populate Engines list.
172 const char **ppszEngines = ::lscp_list_available_engines(pMainForm->client());
173 if (ppszEngines) {
174 m_ui.EngineNameComboBox->clear();
175 for (int iEngine = 0; ppszEngines[iEngine]; iEngine++)
176 m_ui.EngineNameComboBox->addItem(QString(ppszEngines[iEngine]));
177 }
178 else m_pChannel->appendMessagesClient("lscp_list_available_engines");
179
180 // Populate Audio output type list.
181 m_ui.AudioDriverComboBox->clear();
182 m_ui.AudioDriverComboBox->insertItems(0,
183 qsamplerDevice::getDrivers(pMainForm->client(), qsamplerDevice::Audio));
184
185 // Populate MIDI input type list.
186 m_ui.MidiDriverComboBox->clear();
187 m_ui.MidiDriverComboBox->insertItems(0,
188 qsamplerDevice::getDrivers(pMainForm->client(), qsamplerDevice::Midi));
189
190 // Populate Maps list.
191 m_ui.MidiMapComboBox->clear();
192 m_ui.MidiMapComboBox->insertItems(0,
193 qsamplerInstrument::getMapNames());
194
195 // Read proper channel information,
196 // and populate the channel form fields.
197
198 // Engine name...
199 QString sEngineName = pChannel->engineName();
200 if (sEngineName.isEmpty() || bNew)
201 sEngineName = pOptions->sEngineName;
202 if (sEngineName.isEmpty())
203 sEngineName = qsamplerChannel::noEngineName();
204 if (m_ui.EngineNameComboBox->findText(sEngineName,
205 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
206 m_ui.EngineNameComboBox->addItem(sEngineName);
207 }
208 m_ui.EngineNameComboBox->setCurrentIndex(
209 m_ui.EngineNameComboBox->findText(sEngineName,
210 Qt::MatchExactly | Qt::MatchCaseSensitive));
211
212 // Instrument filename and index...
213 QString sInstrumentFile = pChannel->instrumentFile();
214 if (sInstrumentFile.isEmpty())
215 sInstrumentFile = qsamplerChannel::noInstrumentName();
216 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
217 m_ui.InstrumentNrComboBox->clear();
218 m_ui.InstrumentNrComboBox->insertItems(0,
219 qsamplerChannel::getInstrumentList(sInstrumentFile,
220 pOptions->bInstrumentNames));
221 m_ui.InstrumentNrComboBox->setCurrentIndex(pChannel->instrumentNr());
222
223 // MIDI input device...
224 qsamplerDevice midiDevice(qsamplerDevice::Midi, m_pChannel->midiDevice());
225 // MIDI input driver...
226 QString sMidiDriver = midiDevice.driverName();
227 if (sMidiDriver.isEmpty() || bNew)
228 sMidiDriver = pOptions->sMidiDriver.toUpper();
229 if (!sMidiDriver.isEmpty()) {
230 if (m_ui.MidiDriverComboBox->findText(sMidiDriver,
231 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
232 m_ui.MidiDriverComboBox->insertItem(0, sMidiDriver);
233 }
234 m_ui.MidiDriverComboBox->setItemText(
235 m_ui.MidiDriverComboBox->currentIndex(),
236 sMidiDriver);
237 }
238 selectMidiDriverItem(sMidiDriver);
239 if (!bNew) {
240 m_ui.MidiDeviceComboBox->setItemText(
241 m_ui.MidiDeviceComboBox->currentIndex(),
242 midiDevice.deviceName());
243 }
244 selectMidiDeviceItem(m_ui.MidiDeviceComboBox->currentIndex());
245 // MIDI input port...
246 m_ui.MidiPortSpinBox->setValue(pChannel->midiPort());
247 // MIDI input channel...
248 int iMidiChannel = pChannel->midiChannel();
249 // When new, try to suggest a sensible MIDI channel...
250 if (iMidiChannel < 0)
251 iMidiChannel = (::lscp_get_channels(pMainForm->client()) % 16);
252 m_ui.MidiChannelComboBox->setCurrentIndex(iMidiChannel);
253 // MIDI instrument map...
254 int iMidiMap = (bNew ? pOptions->iMidiMap : pChannel->midiMap());
255 // When new, try to suggest a sensible MIDI map...
256 if (iMidiMap < 0)
257 iMidiMap = 0;
258 const QString& sMapName = qsamplerInstrument::getMapName(iMidiMap);
259 if (!sMapName.isEmpty()) {
260 m_ui.MidiMapComboBox->setItemText(
261 m_ui.MidiMapComboBox->currentIndex(),
262 sMapName);
263 }
264 // It might be no maps around...
265 bool bMidiMapEnabled = (m_ui.MidiMapComboBox->count() > 0);
266 m_ui.MidiMapTextLabel->setEnabled(bMidiMapEnabled);
267 m_ui.MidiMapComboBox->setEnabled(bMidiMapEnabled);
268
269 // Audio output device...
270 qsamplerDevice audioDevice(qsamplerDevice::Audio, m_pChannel->audioDevice());
271 // Audio output driver...
272 QString sAudioDriver = audioDevice.driverName();
273 if (sAudioDriver.isEmpty() || bNew)
274 sAudioDriver = pOptions->sAudioDriver.toUpper();
275 if (!sAudioDriver.isEmpty()) {
276 if (m_ui.AudioDriverComboBox->findText(sAudioDriver,
277 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
278 m_ui.AudioDriverComboBox->insertItem(0, sAudioDriver);
279 }
280 m_ui.AudioDriverComboBox->setItemText(
281 m_ui.AudioDriverComboBox->currentIndex(),
282 sAudioDriver);
283 }
284 selectAudioDriverItem(sAudioDriver);
285 if (!bNew) {
286 m_ui.AudioDeviceComboBox->setItemText(
287 m_ui.AudioDeviceComboBox->currentIndex(),
288 audioDevice.deviceName());
289 }
290 selectAudioDeviceItem(m_ui.AudioDeviceComboBox->currentIndex());
291
292 // Let the audio routing table see the light,
293 // if we're editing an existing sampler channel...
294 m_ui.AudioRoutingTable->setVisible(!bNew);
295
296 // As convenient, make it ready on stabilizeForm() for
297 // prompt acceptance, if we got the minimum required...
298 /* if (sEngineName != qsamplerChannel::noEngineName() &&
299 sInstrumentFile != qsamplerChannel::noInstrumentName())
300 m_iDirtyCount++; */
301 // Done.
302 m_iDirtySetup--;
303 stabilizeForm();
304 }
305
306
307 // Accept settings (OK button slot).
308 void ChannelForm::accept (void)
309 {
310 if (m_pChannel == NULL)
311 return;
312
313 MainForm *pMainForm = MainForm::getInstance();
314 if (pMainForm == NULL)
315 return;
316 if (pMainForm->client() == NULL)
317 return;
318
319 qsamplerOptions *pOptions = pMainForm->options();
320 if (pOptions == NULL)
321 return;
322
323 // Flush any pending editing...
324 //m_ui.AudioRoutingTable->flush();
325
326 // We'll go for it!
327 if (m_iDirtyCount > 0) {
328 int iErrors = 0;
329 // Are we a new channel?
330 if (!m_pChannel->addChannel())
331 iErrors++;
332 // Accept Audio driver or device selection...
333 if (m_audioDevices.isEmpty()) {
334 if (!m_pChannel->setAudioDriver(m_ui.AudioDriverComboBox->currentText()))
335 iErrors++;
336 } else {
337 qsamplerDevice *pDevice = NULL;
338 int iAudioItem = m_ui.AudioDeviceComboBox->currentIndex();
339 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
340 pDevice = m_audioDevices.at(iAudioItem);
341 qsamplerChannelRoutingMap routingMap = m_routingModel.routingMap();
342 if (pDevice == NULL)
343 iErrors++;
344 else if (!m_pChannel->setAudioDevice(pDevice->deviceID()))
345 iErrors++;
346 else if (!routingMap.isEmpty()) {
347 // Set the audio route changes...
348 qsamplerChannelRoutingMap::ConstIterator iter;
349 for (iter = routingMap.begin();
350 iter != routingMap.end(); ++iter) {
351 if (!m_pChannel->setAudioChannel(iter.key(), iter.value()))
352 iErrors++;
353 }
354 }
355 }
356 // Accept MIDI driver or device selection...
357 if (m_midiDevices.isEmpty()) {
358 if (!m_pChannel->setMidiDriver(m_ui.MidiDriverComboBox->currentText()))
359 iErrors++;
360 } else {
361 qsamplerDevice *pDevice = NULL;
362 int iMidiItem = m_ui.MidiDeviceComboBox->currentIndex();
363 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
364 pDevice = m_midiDevices.at(iMidiItem);
365 if (pDevice == NULL)
366 iErrors++;
367 else if (!m_pChannel->setMidiDevice(pDevice->deviceID()))
368 iErrors++;
369 }
370 // MIDI input port number...
371 if (!m_pChannel->setMidiPort(m_ui.MidiPortSpinBox->value()))
372 iErrors++;
373 // MIDI input channel...
374 if (!m_pChannel->setMidiChannel(m_ui.MidiChannelComboBox->currentIndex()))
375 iErrors++;
376 // Engine name...
377 if (!m_pChannel->loadEngine(m_ui.EngineNameComboBox->currentText()))
378 iErrors++;
379 // Instrument file and index...
380 const QString& sPath = m_ui.InstrumentFileComboBox->currentText();
381 if (!sPath.isEmpty() && QFileInfo(sPath).exists()) {
382 if (!m_pChannel->loadInstrument(sPath, m_ui.InstrumentNrComboBox->currentIndex()))
383 iErrors++;
384 }
385 // MIDI intrument map...
386 if (!m_pChannel->setMidiMap(m_ui.MidiMapComboBox->currentIndex()))
387 iErrors++;
388 // Show error messages?
389 if (iErrors > 0)
390 m_pChannel->appendMessagesError(tr("Some channel settings could not be set.\n\nSorry."));
391 }
392
393 // Save default engine name, instrument directory and history...
394 pOptions->sInstrumentDir = QFileInfo(
395 m_ui.InstrumentFileComboBox->currentText()).dir().absolutePath();
396 pOptions->sEngineName = m_ui.EngineNameComboBox->currentText();
397 pOptions->sAudioDriver = m_ui.AudioDriverComboBox->currentText();
398 pOptions->sMidiDriver = m_ui.MidiDriverComboBox->currentText();
399 pOptions->iMidiMap = m_ui.MidiMapComboBox->currentIndex();
400 pOptions->saveComboBoxHistory(m_ui.InstrumentFileComboBox);
401
402 // Just go with dialog acceptance.
403 QDialog::accept();
404 }
405
406
407 // Reject settings (Cancel button slot).
408 void ChannelForm::reject (void)
409 {
410 bool bReject = true;
411
412 // Check if there's any pending changes...
413 if (m_iDirtyCount > 0 && m_ui.OkPushButton->isEnabled()) {
414 switch (QMessageBox::warning(this,
415 QSAMPLER_TITLE ": " + tr("Warning"),
416 tr("Some channel settings have been changed.\n\n"
417 "Do you want to apply the changes?"),
418 tr("Apply"), tr("Discard"), tr("Cancel"))) {
419 case 0: // Apply...
420 accept();
421 return;
422 case 1: // Discard
423 break;
424 default: // Cancel.
425 bReject = false;
426 break;
427 }
428 }
429
430 if (bReject)
431 QDialog::reject();
432 }
433
434
435 // Browse and open an instrument file.
436 void ChannelForm::openInstrumentFile (void)
437 {
438 MainForm *pMainForm = MainForm::getInstance();
439 if (pMainForm == NULL)
440 return;
441 if (pMainForm->client() == NULL)
442 return;
443
444 qsamplerOptions *pOptions = pMainForm->options();
445 if (pOptions == NULL)
446 return;
447
448 // FIXME: the instrument file filters should be restricted,
449 // depending on the current engine.
450 QString sInstrumentFile = QFileDialog::getOpenFileName(this,
451 QSAMPLER_TITLE ": " + tr("Instrument files"), // Caption.
452 pOptions->sInstrumentDir, // Start here.
453 tr("Instrument files") + " (*.gig *.dls)" // Filter (GIG and DLS files)
454 );
455
456 if (sInstrumentFile.isEmpty())
457 return;
458
459 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
460 updateInstrumentName();
461 }
462
463
464 // Refresh the actual instrument name.
465 void ChannelForm::updateInstrumentName (void)
466 {
467 MainForm *pMainForm = MainForm::getInstance();
468 if (pMainForm == NULL)
469 return;
470 if (pMainForm->client() == NULL)
471 return;
472
473 qsamplerOptions *pOptions = pMainForm->options();
474 if (pOptions == NULL)
475 return;
476
477 // Finally this better idea would be to use libgig
478 // to retrieve the REAL instrument names.
479 m_ui.InstrumentNrComboBox->clear();
480 m_ui.InstrumentNrComboBox->insertItems(0,
481 qsamplerChannel::getInstrumentList(
482 m_ui.InstrumentFileComboBox->currentText(),
483 pOptions->bInstrumentNames)
484 );
485
486 optionsChanged();
487 }
488
489
490 // Show device options dialog.
491 void ChannelForm::setupDevice ( qsamplerDevice *pDevice,
492 qsamplerDevice::DeviceType deviceTypeMode,
493 const QString& sDriverName )
494 {
495 if (pDevice == NULL)
496 return;
497
498 MainForm *pMainForm = MainForm::getInstance();
499 if (pMainForm == NULL)
500 return;
501 if (pMainForm->client() == NULL)
502 return;
503
504 // Create the device form if not already...
505 if (m_pDeviceForm == NULL) {
506 m_pDeviceForm = new DeviceForm(this, Qt::Dialog);
507 m_pDeviceForm->setAttribute(Qt::WA_ShowModal);
508 QObject::connect(m_pDeviceForm, SIGNAL(devicesChanged()),
509 this, SLOT(updateDevices()));
510 }
511
512 // Refresh the device form with selected data.
513 if (m_pDeviceForm) {
514 m_pDeviceForm->setDeviceTypeMode(deviceTypeMode);
515 m_pDeviceForm->refreshDevices();
516 m_pDeviceForm->setDevice(pDevice);
517 m_pDeviceForm->setDriverName(sDriverName);
518 m_pDeviceForm->show();
519 }
520 }
521
522
523 // Refresh MIDI driver item devices.
524 void ChannelForm::selectMidiDriverItem ( const QString& sMidiDriver )
525 {
526 MainForm *pMainForm = MainForm::getInstance();
527 if (pMainForm == NULL)
528 return;
529 if (pMainForm->client() == NULL)
530 return;
531
532 const QString sDriverName = sMidiDriver.toUpper();
533
534 // Save current device id.
535 // Save current device id.
536 int iDeviceID = 0;
537 qsamplerDevice *pDevice = NULL;
538 int iMidiItem = m_ui.MidiDeviceComboBox->currentIndex();
539 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
540 pDevice = m_midiDevices.at(iMidiItem);
541 if (pDevice)
542 iDeviceID = pDevice->deviceID();
543
544 // Clean maplist.
545 m_ui.MidiDeviceComboBox->clear();
546 qDeleteAll(m_midiDevices);
547 m_midiDevices.clear();
548
549 // Populate with the current ones...
550 const QPixmap midiPixmap(":/icons/midi2.png");
551 int *piDeviceIDs = qsamplerDevice::getDevices(pMainForm->client(),
552 qsamplerDevice::Midi);
553 for (int i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; i++) {
554 pDevice = new qsamplerDevice(qsamplerDevice::Midi, piDeviceIDs[i]);
555 if (pDevice->driverName().toUpper() == sDriverName) {
556 m_ui.MidiDeviceComboBox->insertItem(0, midiPixmap, pDevice->deviceName());
557 m_midiDevices.append(pDevice);
558 } else {
559 delete pDevice;
560 }
561 }
562
563 // Do proper enabling...
564 bool bEnabled = !m_midiDevices.isEmpty();
565 if (bEnabled) {
566 // Select the previous current device...
567 iMidiItem = 0;
568 QListIterator<qsamplerDevice *> iter(m_midiDevices);
569 while (iter.hasNext()) {
570 pDevice = iter.next();
571 if (pDevice->deviceID() == iDeviceID) {
572 m_ui.MidiDeviceComboBox->setCurrentIndex(iMidiItem);
573 selectMidiDeviceItem(iMidiItem);
574 break;
575 }
576 iMidiItem++;
577 }
578 } else {
579 m_ui.MidiDeviceComboBox->insertItem(0,
580 tr("(New MIDI %1 device)").arg(sMidiDriver));
581 }
582 m_ui.MidiDeviceTextLabel->setEnabled(bEnabled);
583 m_ui.MidiDeviceComboBox->setEnabled(bEnabled);
584 }
585
586
587 // Refresh MIDI device options slot.
588 void ChannelForm::selectMidiDriver ( const QString& sMidiDriver )
589 {
590 if (m_iDirtySetup > 0)
591 return;
592
593 selectMidiDriverItem(sMidiDriver);
594 optionsChanged();
595 }
596
597
598 // Select MIDI device item.
599 void ChannelForm::selectMidiDeviceItem ( int iMidiItem )
600 {
601 qsamplerDevice *pDevice = NULL;
602 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
603 pDevice = m_midiDevices.at(iMidiItem);
604 if (pDevice) {
605 const qsamplerDeviceParamMap& params = pDevice->params();
606 int iPorts = params["PORTS"].value.toInt();
607 m_ui.MidiPortTextLabel->setEnabled(iPorts > 0);
608 m_ui.MidiPortSpinBox->setEnabled(iPorts > 0);
609 if (iPorts > 0)
610 m_ui.MidiPortSpinBox->setMaximum(iPorts - 1);
611 }
612 }
613
614
615 // Select MIDI device options slot.
616 void ChannelForm::selectMidiDevice ( int iMidiItem )
617 {
618 if (m_iDirtySetup > 0)
619 return;
620
621 selectMidiDeviceItem(iMidiItem);
622 optionsChanged();
623 }
624
625
626 // MIDI device options.
627 void ChannelForm::setupMidiDevice (void)
628 {
629 qsamplerDevice *pDevice = NULL;
630 int iMidiItem = m_ui.MidiDeviceComboBox->currentIndex();
631 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
632 pDevice = m_midiDevices.at(iMidiItem);
633 setupDevice(pDevice,
634 qsamplerDevice::Midi, m_ui.MidiDriverComboBox->currentText());
635 }
636
637
638 // Refresh Audio driver item devices.
639 void ChannelForm::selectAudioDriverItem ( const QString& sAudioDriver )
640 {
641 MainForm *pMainForm = MainForm::getInstance();
642 if (pMainForm == NULL)
643 return;
644 if (pMainForm->client() == NULL)
645 return;
646
647 const QString sDriverName = sAudioDriver.toUpper();
648
649 // Save current device id.
650 int iDeviceID = 0;
651 qsamplerDevice *pDevice = NULL;
652 int iAudioItem = m_ui.AudioDeviceComboBox->currentIndex();
653 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
654 pDevice = m_audioDevices.at(iAudioItem);
655 if (pDevice)
656 iDeviceID = pDevice->deviceID();
657
658 // Clean maplist.
659 m_ui.AudioDeviceComboBox->clear();
660 qDeleteAll(m_audioDevices);
661 m_audioDevices.clear();
662
663 // Populate with the current ones...
664 const QPixmap audioPixmap(":/icons/audio2.png");
665 int *piDeviceIDs = qsamplerDevice::getDevices(pMainForm->client(),
666 qsamplerDevice::Audio);
667 for (int i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; i++) {
668 pDevice = new qsamplerDevice(qsamplerDevice::Audio, piDeviceIDs[i]);
669 if (pDevice->driverName().toUpper() == sDriverName) {
670 m_ui.AudioDeviceComboBox->insertItem(0, audioPixmap, pDevice->deviceName());
671 m_audioDevices.append(pDevice);
672 } else {
673 delete pDevice;
674 }
675 }
676
677 // Do proper enabling...
678 bool bEnabled = !m_audioDevices.isEmpty();
679 if (bEnabled) {
680 // Select the previous current device...
681 iAudioItem = 0;
682 QListIterator<qsamplerDevice *> iter(m_audioDevices);
683 while (iter.hasNext()) {
684 pDevice = iter.next();
685 if (pDevice->deviceID() == iDeviceID) {
686 m_ui.AudioDeviceComboBox->setCurrentIndex(iAudioItem);
687 selectAudioDeviceItem(iAudioItem);
688 break;
689 }
690 iAudioItem++;
691 }
692 } else {
693 m_ui.AudioDeviceComboBox->insertItem(0,
694 tr("(New Audio %1 device)").arg(sAudioDriver));
695 //m_ui.AudioRoutingTable->setNumRows(0);
696 }
697 m_ui.AudioDeviceTextLabel->setEnabled(bEnabled);
698 m_ui.AudioDeviceComboBox->setEnabled(bEnabled);
699 m_ui.AudioRoutingTable->setEnabled(bEnabled);
700 }
701
702
703 // Refresh Audio device options slot.
704 void ChannelForm::selectAudioDriver ( const QString& sAudioDriver )
705 {
706 if (m_iDirtySetup > 0)
707 return;
708
709 selectAudioDriverItem(sAudioDriver);
710 optionsChanged();
711 }
712
713
714 // Select Audio device item.
715 void ChannelForm::selectAudioDeviceItem ( int iAudioItem )
716 {
717 qsamplerDevice *pDevice = NULL;
718 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
719 pDevice = m_audioDevices.at(iAudioItem);
720 if (pDevice) {
721 // Refresh the audio routing table.
722 m_routingModel.refresh(pDevice, m_pChannel->audioRouting());
723 // Reset routing change map.
724 m_routingModel.clear();
725 }
726 }
727
728
729 // Select Audio device options slot.
730 void ChannelForm::selectAudioDevice ( int iAudioItem )
731 {
732 if (m_iDirtySetup > 0)
733 return;
734
735 selectAudioDeviceItem(iAudioItem);
736 optionsChanged();
737 }
738
739
740 // Audio device options.
741 void ChannelForm::setupAudioDevice (void)
742 {
743 qsamplerDevice *pDevice = NULL;
744 int iAudioItem = m_ui.AudioDeviceComboBox->currentIndex();
745 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
746 pDevice = m_audioDevices.at(iAudioItem);
747 setupDevice(pDevice,
748 qsamplerDevice::Audio, m_ui.AudioDriverComboBox->currentText());
749 }
750
751 // UPdate all device lists slot.
752 void ChannelForm::updateDevices (void)
753 {
754 if (m_iDirtySetup > 0)
755 return;
756
757 selectMidiDriverItem(m_ui.MidiDriverComboBox->currentText());
758 selectAudioDriverItem(m_ui.AudioDriverComboBox->currentText());
759 optionsChanged();
760 }
761
762
763 // Dirty up settings.
764 void ChannelForm::optionsChanged (void)
765 {
766 if (m_iDirtySetup > 0)
767 return;
768
769 m_iDirtyCount++;
770 stabilizeForm();
771 }
772
773
774 // Stabilize current form state.
775 void ChannelForm::stabilizeForm (void)
776 {
777 const bool bValid =
778 m_ui.EngineNameComboBox->currentIndex() >= 0 &&
779 m_ui.EngineNameComboBox->currentText() !=
780 qsamplerChannel::noEngineName();
781 #if 0
782 const QString& sPath = InstrumentFileComboBox->currentText();
783 bValid = bValid && !sPath.isEmpty() && QFileInfo(sPath).exists();
784 #endif
785 m_ui.OkPushButton->setEnabled(m_iDirtyCount > 0 && bValid);
786 }
787
788
789 void ChannelForm::updateTableCellRenderers (void)
790 {
791 const int rows = m_routingModel.rowCount();
792 const int cols = m_routingModel.columnCount();
793 updateTableCellRenderers(
794 m_routingModel.index(0, 0),
795 m_routingModel.index(rows - 1, cols - 1));
796 }
797
798
799 void ChannelForm::updateTableCellRenderers (
800 const QModelIndex& topLeft, const QModelIndex& bottomRight )
801 {
802 for (int r = topLeft.row(); r <= bottomRight.row(); r++) {
803 for (int c = topLeft.column(); c <= bottomRight.column(); c++) {
804 const QModelIndex index = m_routingModel.index(r, c);
805 m_ui.AudioRoutingTable->openPersistentEditor(index);
806 }
807 }
808 }
809
810 } // namespace QSampler
811
812
813 // end of qsamplerChannelForm.cpp

  ViewVC Help
Powered by ViewVC