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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2982 - (show annotations) (download)
Sun Aug 28 13:48:55 2016 UTC (7 years, 7 months ago) by capela
File size: 25248 byte(s)
- Fixed channel dialog freeze on auto instrument file drop-down list.
1 // qsamplerChannelForm.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2016, 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 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 >= 0x050000
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 = NULL;
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 == NULL)
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 == NULL)
173 return;
174 if (pMainForm->client() == NULL)
175 return;
176
177 Options *pOptions = pMainForm->options();
178 if (pOptions == NULL)
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->setItemText(
271 m_ui.MidiDeviceComboBox->currentIndex(),
272 midiDevice.deviceName());
273 }
274 selectMidiDeviceItem(m_ui.MidiDeviceComboBox->currentIndex());
275 // MIDI input port...
276 m_ui.MidiPortSpinBox->setValue(pChannel->midiPort());
277 // MIDI input channel...
278 int iMidiChannel = pChannel->midiChannel();
279 // When new, try to suggest a sensible MIDI channel...
280 if (iMidiChannel < 0)
281 iMidiChannel = (::lscp_get_channels(pMainForm->client()) % 16);
282 m_ui.MidiChannelComboBox->setCurrentIndex(iMidiChannel);
283 // MIDI instrument map...
284 int iMidiMap = (bNew ? pOptions->iMidiMap : pChannel->midiMap());
285 // When new, try to suggest a sensible MIDI map...
286 if (iMidiMap < 0)
287 iMidiMap = 0;
288 const QString& sMapName = Instrument::getMapName(iMidiMap);
289 if (!sMapName.isEmpty()) {
290 m_ui.MidiMapComboBox->setItemText(
291 m_ui.MidiMapComboBox->currentIndex(),
292 sMapName);
293 }
294 // It might be no maps around...
295 const bool bMidiMapEnabled = (m_ui.MidiMapComboBox->count() > 0);
296 m_ui.MidiMapTextLabel->setEnabled(bMidiMapEnabled);
297 m_ui.MidiMapComboBox->setEnabled(bMidiMapEnabled);
298
299 // Audio output device...
300 const Device audioDevice(Device::Audio, m_pChannel->audioDevice());
301 // Audio output driver...
302 QString sAudioDriver = audioDevice.driverName();
303 if (sAudioDriver.isEmpty() || bNew)
304 sAudioDriver = pOptions->sAudioDriver.toUpper();
305 if (!sAudioDriver.isEmpty()) {
306 if (m_ui.AudioDriverComboBox->findText(sAudioDriver,
307 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
308 m_ui.AudioDriverComboBox->insertItem(0, sAudioDriver);
309 }
310 m_ui.AudioDriverComboBox->setCurrentIndex(
311 m_ui.AudioDriverComboBox->findText(sAudioDriver,
312 Qt::MatchExactly | Qt::MatchCaseSensitive)
313 );
314 }
315 selectAudioDriverItem(sAudioDriver);
316 if (!bNew) {
317 m_ui.AudioDeviceComboBox->setItemText(
318 m_ui.AudioDeviceComboBox->currentIndex(),
319 audioDevice.deviceName());
320 }
321 selectAudioDeviceItem(m_ui.AudioDeviceComboBox->currentIndex());
322
323 // Let the audio routing table see the light,
324 // if we're editing an existing sampler channel...
325 m_ui.AudioRoutingTable->setVisible(!bNew);
326
327 const QString sInstrumentNrToolTip =
328 (pOptions->bInstrumentNames) ?
329 "Select an instrument of the file" :
330 "You might want to enable instrument name retrieval in the "
331 "settings dialog";
332 m_ui.InstrumentNrComboBox->setToolTip(
333 QObject::tr(sInstrumentNrToolTip.toUtf8().data())
334 );
335
336 #if 0
337 // As convenient, make it ready on stabilizeForm() for
338 // prompt acceptance, if we got the minimum required...
339 if (sEngineName != Channel::noEngineName() &&
340 sInstrumentFile != Channel::noInstrumentName())
341 m_iDirtyCount++;
342 #endif
343
344 // Done.
345 m_iDirtySetup--;
346 stabilizeForm();
347 }
348
349
350 // Accept settings (OK button slot).
351 void ChannelForm::accept (void)
352 {
353 if (m_pChannel == NULL)
354 return;
355
356 MainForm *pMainForm = MainForm::getInstance();
357 if (pMainForm == NULL)
358 return;
359 if (pMainForm->client() == NULL)
360 return;
361
362 Options *pOptions = pMainForm->options();
363 if (pOptions == NULL)
364 return;
365
366 // Flush any pending editing...
367 //m_ui.AudioRoutingTable->flush();
368
369 // We'll go for it!
370 if (m_iDirtyCount > 0) {
371 int iErrors = 0;
372 // Are we a new channel?
373 if (!m_pChannel->addChannel())
374 iErrors++;
375 // Accept Audio driver or device selection...
376 if (m_audioDevices.isEmpty()) {
377 if (!m_pChannel->setAudioDriver(m_ui.AudioDriverComboBox->currentText()))
378 iErrors++;
379 } else {
380 Device *pDevice = NULL;
381 const int iAudioItem = m_ui.AudioDeviceComboBox->currentIndex();
382 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
383 pDevice = m_audioDevices.at(iAudioItem);
384 ChannelRoutingMap routingMap = m_routingModel.routingMap();
385 if (pDevice == NULL)
386 iErrors++;
387 else if (!m_pChannel->setAudioDevice(pDevice->deviceID()))
388 iErrors++;
389 else if (!routingMap.isEmpty()) {
390 // Set the audio route changes...
391 ChannelRoutingMap::ConstIterator iter;
392 for (iter = routingMap.begin();
393 iter != routingMap.end(); ++iter) {
394 if (!m_pChannel->setAudioChannel(iter.key(), iter.value()))
395 iErrors++;
396 }
397 }
398 }
399 // Accept MIDI driver or device selection...
400 if (m_midiDevices.isEmpty()) {
401 if (!m_pChannel->setMidiDriver(m_ui.MidiDriverComboBox->currentText()))
402 iErrors++;
403 } else {
404 Device *pDevice = NULL;
405 const int iMidiItem = m_ui.MidiDeviceComboBox->currentIndex();
406 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
407 pDevice = m_midiDevices.at(iMidiItem);
408 if (pDevice == NULL)
409 iErrors++;
410 else if (!m_pChannel->setMidiDevice(pDevice->deviceID()))
411 iErrors++;
412 }
413 // MIDI input port number...
414 if (!m_pChannel->setMidiPort(m_ui.MidiPortSpinBox->value()))
415 iErrors++;
416 // MIDI input channel...
417 if (!m_pChannel->setMidiChannel(m_ui.MidiChannelComboBox->currentIndex()))
418 iErrors++;
419 // Engine name...
420 if (!m_pChannel->loadEngine(m_ui.EngineNameComboBox->currentText()))
421 iErrors++;
422 // Instrument file and index...
423 const QString& sPath = m_ui.InstrumentFileComboBox->currentText();
424 if (!sPath.isEmpty() && QFileInfo(sPath).exists()) {
425 if (!m_pChannel->loadInstrument(sPath, m_ui.InstrumentNrComboBox->currentIndex()))
426 iErrors++;
427 }
428 // MIDI intrument map...
429 if (!m_pChannel->setMidiMap(m_ui.MidiMapComboBox->currentIndex()))
430 iErrors++;
431 // Show error messages?
432 if (iErrors > 0) {
433 m_pChannel->appendMessagesError(
434 tr("Some channel settings could not be set.\n\nSorry."));
435 }
436 }
437
438 // Save default engine name, instrument directory and history...
439 pOptions->sInstrumentDir = QFileInfo(
440 m_ui.InstrumentFileComboBox->currentText()).dir().absolutePath();
441 pOptions->sEngineName = m_ui.EngineNameComboBox->currentText();
442 pOptions->sAudioDriver = m_ui.AudioDriverComboBox->currentText();
443 pOptions->sMidiDriver = m_ui.MidiDriverComboBox->currentText();
444 pOptions->iMidiMap = m_ui.MidiMapComboBox->currentIndex();
445 pOptions->saveComboBoxHistory(m_ui.InstrumentFileComboBox);
446
447 // Just go with dialog acceptance.
448 QDialog::accept();
449 }
450
451
452 // Reject settings (Cancel button slot).
453 void ChannelForm::reject (void)
454 {
455 bool bReject = true;
456
457 // Check if there's any pending changes...
458 if (m_iDirtyCount > 0) {
459 switch (QMessageBox::warning(this,
460 QSAMPLER_TITLE ": " + tr("Warning"),
461 tr("Some channel settings have been changed.\n\n"
462 "Do you want to apply the changes?"),
463 QMessageBox::Apply |
464 QMessageBox::Discard |
465 QMessageBox::Cancel)) {
466 case QMessageBox::Apply:
467 accept();
468 return;
469 case QMessageBox::Discard:
470 break;
471 default: // Cancel.
472 bReject = false;
473 break;
474 }
475 }
476
477 if (bReject)
478 QDialog::reject();
479 }
480
481
482 // Browse and open an instrument file.
483 void ChannelForm::openInstrumentFile (void)
484 {
485 MainForm *pMainForm = MainForm::getInstance();
486 if (pMainForm == NULL)
487 return;
488 if (pMainForm->client() == NULL)
489 return;
490
491 Options *pOptions = pMainForm->options();
492 if (pOptions == NULL)
493 return;
494
495 // FIXME: the instrument file filters should be restricted,
496 // depending on the current engine.
497 QStringList filters;
498 const QString& sEngineName = m_ui.EngineNameComboBox->currentText().toUpper();
499 if (sEngineName.contains("GIG"))
500 filters << tr("GIG Instrument files") + " (*.gig *.dls)";
501 if (sEngineName.contains("SFZ"))
502 filters << tr("SFZ Instrument files") + " (*.sfz)";
503 if (sEngineName.contains("SF2"))
504 filters << tr("SF2 Instrument files") + " (*.sf2)";
505 filters << tr("All files") + " (*.*)";
506 const QString& filter = filters.join(";;");
507
508 QString sInstrumentFile = QFileDialog::getOpenFileName(this,
509 QSAMPLER_TITLE ": " + tr("Instrument files"), // Caption.
510 pOptions->sInstrumentDir, // Start here.
511 filter // File filter.
512 );
513
514 if (sInstrumentFile.isEmpty())
515 return;
516
517 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
518 updateInstrumentName();
519 }
520
521
522 // Refresh the actual instrument name.
523 void ChannelForm::updateInstrumentName (void)
524 {
525 MainForm *pMainForm = MainForm::getInstance();
526 if (pMainForm == NULL)
527 return;
528 if (pMainForm->client() == NULL)
529 return;
530
531 Options *pOptions = pMainForm->options();
532 if (pOptions == NULL)
533 return;
534
535 // Finally this better idea would be to use libgig
536 // to retrieve the REAL instrument names.
537 m_ui.InstrumentNrComboBox->clear();
538 m_ui.InstrumentNrComboBox->insertItems(0,
539 Channel::getInstrumentList(
540 m_ui.InstrumentFileComboBox->currentText(),
541 pOptions->bInstrumentNames)
542 );
543
544 optionsChanged();
545 }
546
547
548 // Show device options dialog.
549 void ChannelForm::setupDevice ( Device *pDevice,
550 Device::DeviceType deviceTypeMode,
551 const QString& sDriverName )
552 {
553 MainForm *pMainForm = MainForm::getInstance();
554 if (pMainForm == NULL)
555 return;
556 if (pMainForm->client() == NULL)
557 return;
558
559 // Create the device form if not already...
560 if (m_pDeviceForm == NULL) {
561 m_pDeviceForm = new DeviceForm(this, Qt::Dialog);
562 m_pDeviceForm->setAttribute(Qt::WA_ShowModal);
563 QObject::connect(m_pDeviceForm, SIGNAL(devicesChanged()),
564 this, SLOT(updateDevices()));
565 }
566
567 // Refresh the device form with selected data.
568 if (m_pDeviceForm) {
569 m_pDeviceForm->setDeviceTypeMode(deviceTypeMode);
570 m_pDeviceForm->refreshDevices();
571 m_pDeviceForm->setDevice(pDevice);
572 m_pDeviceForm->setDriverName(sDriverName);
573 m_pDeviceForm->show();
574 }
575 }
576
577
578 // Refresh MIDI driver item devices.
579 void ChannelForm::selectMidiDriverItem ( const QString& sMidiDriver )
580 {
581 MainForm *pMainForm = MainForm::getInstance();
582 if (pMainForm == NULL)
583 return;
584 if (pMainForm->client() == NULL)
585 return;
586
587 const QString sDriverName = sMidiDriver.toUpper();
588
589 // Save current device id.
590 int iDeviceID = 0;
591 Device *pDevice = NULL;
592 int iMidiItem = m_ui.MidiDeviceComboBox->currentIndex();
593 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
594 pDevice = m_midiDevices.at(iMidiItem);
595 if (pDevice)
596 iDeviceID = pDevice->deviceID();
597
598 // Clean maplist.
599 m_ui.MidiDeviceComboBox->clear();
600 qDeleteAll(m_midiDevices);
601 m_midiDevices.clear();
602
603 // Populate with the current ones...
604 const QPixmap midiPixmap(":/images/midi2.png");
605 int *piDeviceIDs = Device::getDevices(pMainForm->client(), Device::Midi);
606 for (int i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; i++) {
607 pDevice = new Device(Device::Midi, piDeviceIDs[i]);
608 if (pDevice->driverName().toUpper() == sDriverName) {
609 m_ui.MidiDeviceComboBox->insertItem(0,
610 midiPixmap, pDevice->deviceName());
611 m_midiDevices.append(pDevice);
612 } else {
613 delete pDevice;
614 }
615 }
616
617 // Do proper enabling...
618 const bool bEnabled = !m_midiDevices.isEmpty();
619 if (bEnabled) {
620 // Select the previous current device...
621 iMidiItem = 0;
622 QListIterator<Device *> iter(m_midiDevices);
623 while (iter.hasNext()) {
624 pDevice = iter.next();
625 if (pDevice->deviceID() == iDeviceID) {
626 m_ui.MidiDeviceComboBox->setCurrentIndex(iMidiItem);
627 selectMidiDeviceItem(iMidiItem);
628 break;
629 }
630 iMidiItem++;
631 }
632 } else {
633 m_ui.MidiDeviceComboBox->insertItem(0,
634 tr("(New MIDI %1 device)").arg(sMidiDriver));
635 }
636 m_ui.MidiDeviceTextLabel->setEnabled(bEnabled);
637 m_ui.MidiDeviceComboBox->setEnabled(bEnabled);
638 }
639
640
641 // Refresh MIDI device options slot.
642 void ChannelForm::selectMidiDriver ( const QString& sMidiDriver )
643 {
644 if (m_iDirtySetup > 0)
645 return;
646
647 selectMidiDriverItem(sMidiDriver);
648 optionsChanged();
649 }
650
651
652 // Select MIDI device item.
653 void ChannelForm::selectMidiDeviceItem ( int iMidiItem )
654 {
655 Device *pDevice = NULL;
656 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
657 pDevice = m_midiDevices.at(iMidiItem);
658 if (pDevice) {
659 const DeviceParamMap& params = pDevice->params();
660 const int iPorts = params["PORTS"].value.toInt();
661 m_ui.MidiPortTextLabel->setEnabled(iPorts > 0);
662 m_ui.MidiPortSpinBox->setEnabled(iPorts > 0);
663 if (iPorts > 0)
664 m_ui.MidiPortSpinBox->setMaximum(iPorts - 1);
665 }
666 }
667
668
669 // Select MIDI device options slot.
670 void ChannelForm::selectMidiDevice ( int iMidiItem )
671 {
672 if (m_iDirtySetup > 0)
673 return;
674
675 selectMidiDeviceItem(iMidiItem);
676 optionsChanged();
677 }
678
679
680 // MIDI device options.
681 void ChannelForm::setupMidiDevice (void)
682 {
683 Device *pDevice = NULL;
684 const int iMidiItem = m_ui.MidiDeviceComboBox->currentIndex();
685 if (iMidiItem >= 0 && iMidiItem < m_midiDevices.count())
686 pDevice = m_midiDevices.at(iMidiItem);
687 setupDevice(pDevice,
688 Device::Midi, m_ui.MidiDriverComboBox->currentText());
689 }
690
691
692 // Refresh Audio driver item devices.
693 void ChannelForm::selectAudioDriverItem ( const QString& sAudioDriver )
694 {
695 MainForm *pMainForm = MainForm::getInstance();
696 if (pMainForm == NULL)
697 return;
698 if (pMainForm->client() == NULL)
699 return;
700
701 const QString sDriverName = sAudioDriver.toUpper();
702
703 // Save current device id.
704 int iDeviceID = 0;
705 Device *pDevice = NULL;
706 int iAudioItem = m_ui.AudioDeviceComboBox->currentIndex();
707 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
708 pDevice = m_audioDevices.at(iAudioItem);
709 if (pDevice)
710 iDeviceID = pDevice->deviceID();
711
712 // Clean maplist.
713 m_ui.AudioDeviceComboBox->clear();
714 qDeleteAll(m_audioDevices);
715 m_audioDevices.clear();
716
717 // Populate with the current ones...
718 const QPixmap audioPixmap(":/images/audio2.png");
719 int *piDeviceIDs = Device::getDevices(pMainForm->client(),
720 Device::Audio);
721 for (int i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; i++) {
722 pDevice = new Device(Device::Audio, piDeviceIDs[i]);
723 if (pDevice->driverName().toUpper() == sDriverName) {
724 m_ui.AudioDeviceComboBox->insertItem(0,
725 audioPixmap, pDevice->deviceName());
726 m_audioDevices.append(pDevice);
727 } else {
728 delete pDevice;
729 }
730 }
731
732 // Do proper enabling...
733 const bool bEnabled = !m_audioDevices.isEmpty();
734 if (bEnabled) {
735 // Select the previous current device...
736 iAudioItem = 0;
737 QListIterator<Device *> iter(m_audioDevices);
738 while (iter.hasNext()) {
739 pDevice = iter.next();
740 if (pDevice->deviceID() == iDeviceID) {
741 m_ui.AudioDeviceComboBox->setCurrentIndex(iAudioItem);
742 selectAudioDeviceItem(iAudioItem);
743 break;
744 }
745 iAudioItem++;
746 }
747 } else {
748 m_ui.AudioDeviceComboBox->insertItem(0,
749 tr("(New Audio %1 device)").arg(sAudioDriver));
750 //m_ui.AudioRoutingTable->setNumRows(0);
751 }
752 m_ui.AudioDeviceTextLabel->setEnabled(bEnabled);
753 m_ui.AudioDeviceComboBox->setEnabled(bEnabled);
754 m_ui.AudioRoutingTable->setEnabled(bEnabled);
755 }
756
757
758 // Refresh Audio device options slot.
759 void ChannelForm::selectAudioDriver ( const QString& sAudioDriver )
760 {
761 if (m_iDirtySetup > 0)
762 return;
763
764 selectAudioDriverItem(sAudioDriver);
765 optionsChanged();
766 }
767
768
769 // Select Audio device item.
770 void ChannelForm::selectAudioDeviceItem ( int iAudioItem )
771 {
772 Device *pDevice = NULL;
773 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
774 pDevice = m_audioDevices.at(iAudioItem);
775 if (pDevice) {
776 // Refresh the audio routing table.
777 m_routingModel.refresh(pDevice, m_pChannel->audioRouting());
778 // Reset routing change map.
779 m_routingModel.clear();
780 }
781 }
782
783
784 // Select Audio device options slot.
785 void ChannelForm::selectAudioDevice ( int iAudioItem )
786 {
787 if (m_iDirtySetup > 0)
788 return;
789
790 selectAudioDeviceItem(iAudioItem);
791 optionsChanged();
792 }
793
794
795 // Audio device options.
796 void ChannelForm::setupAudioDevice (void)
797 {
798 Device *pDevice = NULL;
799 const int iAudioItem = m_ui.AudioDeviceComboBox->currentIndex();
800 if (iAudioItem >= 0 && iAudioItem < m_audioDevices.count())
801 pDevice = m_audioDevices.at(iAudioItem);
802 setupDevice(pDevice,
803 Device::Audio, m_ui.AudioDriverComboBox->currentText());
804 }
805
806 // UPdate all device lists slot.
807 void ChannelForm::updateDevices (void)
808 {
809 if (m_iDirtySetup > 0)
810 return;
811
812 selectMidiDriverItem(m_ui.MidiDriverComboBox->currentText());
813 selectAudioDriverItem(m_ui.AudioDriverComboBox->currentText());
814 optionsChanged();
815 }
816
817
818 // Dirty up settings.
819 void ChannelForm::optionsChanged (void)
820 {
821 if (m_iDirtySetup > 0)
822 return;
823
824 m_iDirtyCount++;
825 stabilizeForm();
826 }
827
828
829 // Stabilize current form state.
830 void ChannelForm::stabilizeForm (void)
831 {
832 bool bValid = m_ui.EngineNameComboBox->currentIndex() >= 0 &&
833 m_ui.EngineNameComboBox->currentText() != Channel::noEngineName();
834
835 const QString& sPath = m_ui.InstrumentFileComboBox->currentText();
836 bValid = bValid && !sPath.isEmpty() && QFileInfo(sPath).exists();
837
838 m_ui.DialogButtonBox->button(
839 QDialogButtonBox::Ok)->setEnabled(m_iDirtyCount > 0 && bValid);
840 }
841
842
843 void ChannelForm::updateTableCellRenderers (void)
844 {
845 const int rows = m_routingModel.rowCount();
846 const int cols = m_routingModel.columnCount();
847 updateTableCellRenderers(
848 m_routingModel.index(0, 0),
849 m_routingModel.index(rows - 1, cols - 1));
850 }
851
852
853 void ChannelForm::updateTableCellRenderers (
854 const QModelIndex& topLeft, const QModelIndex& bottomRight )
855 {
856 for (int r = topLeft.row(); r <= bottomRight.row(); r++) {
857 for (int c = topLeft.column(); c <= bottomRight.column(); c++) {
858 const QModelIndex index = m_routingModel.index(r, c);
859 m_ui.AudioRoutingTable->openPersistentEditor(index);
860 }
861 }
862 }
863
864 } // namespace QSampler
865
866
867 // end of qsamplerChannelForm.cpp

  ViewVC Help
Powered by ViewVC