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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2110 - (show annotations) (download)
Sat Jul 17 12:21:01 2010 UTC (13 years, 9 months ago) by capela
File size: 24633 byte(s)
- Sampler channel and instrument file requester support for
  other than GIG engine instrument files (*gig; *.dls) has
  been added, making roads for the newer SFZ and SF2 engines
  instrument files (*.sfz; *.sf2).

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

  ViewVC Help
Powered by ViewVC