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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC