1
// qsamplerDeviceForm.cpp
3
/****************************************************************************
4
Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5
Copyright (C) 2007, Christian Schoenebeck
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.
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.
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.
21
*****************************************************************************/
23
#include "qsamplerDeviceForm.h"
25
#include "qsamplerAbout.h"
26
#include "qsamplerMainForm.h"
28
#include <QHeaderView>
29
#include <QMessageBox>
34
//-------------------------------------------------------------------------
35
// QSampler::DeviceForm -- Device form implementation.
38
DeviceForm::DeviceForm ( QWidget *pParent, Qt::WindowFlags wflags )
39
: QDialog(pParent, wflags)
47
m_deviceType = Device::None;
50
// No exclusive mode as default.
51
m_deviceTypeMode = Device::None;
53
m_ui.DeviceListView->header()->hide();
55
int iRowHeight = m_ui.DeviceParamTable->fontMetrics().height() + 4;
56
m_ui.DeviceParamTable->verticalHeader()->setDefaultSectionSize(iRowHeight);
57
m_ui.DevicePortParamTable->verticalHeader()->setDefaultSectionSize(iRowHeight);
58
m_ui.DeviceParamTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
59
m_ui.DevicePortParamTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
61
m_ui.DeviceParamTable->setModel(&m_deviceParamModel);
62
m_ui.DeviceParamTable->setItemDelegate(&m_deviceParamDelegate);
63
m_ui.DeviceParamTable->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
64
m_ui.DeviceParamTable->verticalHeader()->hide();
66
m_ui.DevicePortParamTable->setModel(&m_devicePortParamModel);
67
m_ui.DevicePortParamTable->setItemDelegate(&m_devicePortParamDelegate);
68
m_ui.DevicePortParamTable->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
69
m_ui.DevicePortParamTable->verticalHeader()->hide();
73
// Try to restore normal window positioning.
76
QObject::connect(m_ui.DeviceListView,
77
SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
78
SLOT(selectDevice()));
79
QObject::connect(m_ui.DeviceListView,
80
SIGNAL(customContextMenuRequested(const QPoint&)),
81
SLOT(deviceListViewContextMenu(const QPoint&)));
82
QObject::connect(m_ui.RefreshDevicesPushButton,
84
SLOT(refreshDevices()));
85
QObject::connect(m_ui.DriverNameComboBox,
86
SIGNAL(activated(const QString&)),
87
SLOT(selectDriver(const QString&)));
88
QObject::connect(m_ui.DevicePortComboBox,
89
SIGNAL(activated(int)),
90
SLOT(selectDevicePort(int)));
91
QObject::connect(m_ui.CreateDevicePushButton,
93
SLOT(createDevice()));
94
QObject::connect(m_ui.DeleteDevicePushButton,
96
SLOT(deleteDevice()));
97
QObject::connect(m_ui.ClosePushButton,
100
QObject::connect(&m_deviceParamModel,
101
SIGNAL(modelReset()),
102
SLOT(updateCellRenderers()));
103
QObject::connect(&m_deviceParamModel,
104
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
105
SLOT(updateCellRenderers(const QModelIndex&, const QModelIndex&)));
106
QObject::connect(&m_devicePortParamModel,
107
SIGNAL(modelReset()),
108
SLOT(updatePortCellRenderers()));
109
QObject::connect(&m_devicePortParamModel,
110
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
111
SLOT(updatePortCellRenderers(const QModelIndex&, const QModelIndex&)));
115
DeviceForm::~DeviceForm (void)
120
// Notify our parent that we're emerging.
121
void DeviceForm::showEvent ( QShowEvent *pShowEvent )
123
MainForm* pMainForm = MainForm::getInstance();
125
pMainForm->stabilizeForm();
127
QWidget::showEvent(pShowEvent);
133
// Notify our parent that we're closing.
134
void DeviceForm::hideEvent ( QHideEvent *pHideEvent )
136
QWidget::hideEvent(pHideEvent);
138
MainForm *pMainForm = MainForm::getInstance();
140
pMainForm->stabilizeForm();
142
// Signal special whether we changed the device set.
143
if (m_iDirtyCount > 0) {
145
emit devicesChanged();
150
// Set device type spacial exclusive mode.
151
void DeviceForm::setDeviceTypeMode (
152
Device::DeviceType deviceTypeMode )
154
// If it has not changed, do nothing.
155
if (m_deviceTypeMode == deviceTypeMode)
158
m_deviceTypeMode = deviceTypeMode;
160
// OK. Do a whole refresh around.
165
// Device driver name setup formal initializer.
166
void DeviceForm::setDriverName ( const QString& sDriverName )
168
if (m_ui.DriverNameComboBox->findText(sDriverName) < 0)
169
m_ui.DriverNameComboBox->insertItem(0, sDriverName);
170
m_ui.DriverNameComboBox->setItemText(
171
m_ui.DriverNameComboBox->currentIndex(),
176
// Set current selected device by type and id.
177
void DeviceForm::setDevice ( Device *pDevice )
179
// In case no device is given...
180
Device::DeviceType deviceType = m_deviceTypeMode;
182
deviceType = pDevice->deviceType();
184
// Get the device view root item...
185
DeviceItem *pRootItem = NULL;
186
switch (deviceType) {
188
pRootItem = m_pAudioItems;
191
pRootItem = m_pMidiItems;
197
// Is the root present?
198
if (pRootItem == NULL)
201
// So there's no device huh?
202
if (pDevice == NULL) {
203
m_ui.DeviceListView->setCurrentItem(pRootItem);
207
// For each child, test for identity...
208
for (int i = 0; i < pRootItem->childCount(); i++) {
209
DeviceItem* pDeviceItem =
210
(DeviceItem*) pRootItem->child(i);
212
// If identities match, select as current device item.
213
if (pDeviceItem->device().deviceID() == pDevice->deviceID()) {
214
pDeviceItem->setSelected(true);
222
// Create a new device from current table view.
223
void DeviceForm::createDevice (void)
225
MainForm *pMainForm = MainForm::getInstance();
226
if (pMainForm == NULL)
229
QTreeWidgetItem *pItem = m_ui.DeviceListView->currentItem();
230
if (pItem == NULL || pItem->type() != QSAMPLER_DEVICE_ITEM)
233
// About a brand new device instance...
234
Device device(((DeviceItem *) pItem)->device());
235
if (device.createDevice()) {
236
// Now it depends on the device type...
237
DeviceItem *pRootItem = NULL;
238
switch (device.deviceType()) {
240
pRootItem = m_pAudioItems;
243
pRootItem = m_pMidiItems;
248
// Append the new device item.
249
DeviceItem *pDeviceItem = new DeviceItem(pRootItem,
250
device.deviceType(), device.deviceID());
251
// Just make it the new selection...
252
pDeviceItem->setSelected(true);
253
// Main session should be marked dirty.
254
pMainForm->sessionDirty();
260
// Delete current device in table view.
261
void DeviceForm::deleteDevice (void)
263
MainForm *pMainForm = MainForm::getInstance();
264
if (pMainForm == NULL)
267
QTreeWidgetItem* pItem = m_ui.DeviceListView->currentItem();
268
if (pItem == NULL || pItem->type() != QSAMPLER_DEVICE_ITEM)
271
Device& device = ((DeviceItem *) pItem)->device();
273
// Prompt user if this is for real...
274
Options *pOptions = pMainForm->options();
275
if (pOptions && pOptions->bConfirmRemove) {
276
if (QMessageBox::warning(this,
277
QSAMPLER_TITLE ": " + tr("Warning"),
278
tr("About to delete device:\n\n"
281
.arg(device.deviceName()),
282
tr("OK"), tr("Cancel")) > 0)
287
if (device.deleteDevice()) {
288
// Remove it from the device view...
290
// Main session should be marked dirty.
291
pMainForm->sessionDirty();
297
// Refresh all device list and views.
298
void DeviceForm::refreshDevices (void)
300
MainForm *pMainForm = MainForm::getInstance();
301
if (pMainForm == NULL)
304
// Avoid nested changes.
308
// (Re)Load complete device configuration data ...
310
m_pAudioItems = NULL;
312
m_ui.DeviceListView->clear();
313
if (pMainForm->client()) {
315
// Grab and pop Audio devices...
316
if (m_deviceTypeMode == Device::None ||
317
m_deviceTypeMode == Device::Audio) {
318
m_pAudioItems = new DeviceItem(m_ui.DeviceListView,
322
piDeviceIDs = Device::getDevices(pMainForm->client(),
324
for (int i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; i++) {
325
new DeviceItem(m_pAudioItems,
326
Device::Audio, piDeviceIDs[i]);
328
m_pAudioItems->setExpanded(true);
330
// Grab and pop MIDI devices...
331
if (m_deviceTypeMode == Device::None ||
332
m_deviceTypeMode == Device::Midi) {
333
m_pMidiItems = new DeviceItem(m_ui.DeviceListView,
337
piDeviceIDs = Device::getDevices(pMainForm->client(),
339
for (int i = 0; piDeviceIDs && piDeviceIDs[i] >= 0; i++) {
340
new DeviceItem(m_pMidiItems,
341
Device::Midi, piDeviceIDs[i]);
343
m_pMidiItems->setExpanded(true);
355
// Driver selection slot.
356
void DeviceForm::selectDriver ( const QString& sDriverName )
358
if (m_iDirtySetup > 0)
362
// Driver name has changed for a new device...
365
QTreeWidgetItem* pItem = m_ui.DeviceListView->currentItem();
366
if (pItem == NULL || pItem->type() != QSAMPLER_DEVICE_ITEM)
369
Device& device = ((DeviceItem *) pItem)->device();
371
// Driver change is only valid for scratch devices...
374
device.setDriver(sDriverName);
375
m_deviceParamModel.refresh(&device, m_bNewDevice);
383
// Device selection slot.
384
void DeviceForm::selectDevice ()
386
MainForm *pMainForm = MainForm::getInstance();
387
if (pMainForm == NULL)
390
if (m_iDirtySetup > 0)
394
// Device selection has changed...
397
QTreeWidgetItem* pItem = m_ui.DeviceListView->currentItem();
398
if (pItem == NULL || pItem->type() != QSAMPLER_DEVICE_ITEM) {
399
m_deviceType = Device::None;
400
m_ui.DeviceNameTextLabel->setText(QString::null);
401
m_deviceParamModel.clear();
402
m_ui.DevicePortComboBox->clear();
403
m_devicePortParamModel.clear();
404
m_ui.DevicePortTextLabel->setEnabled(false);
405
m_ui.DevicePortComboBox->setEnabled(false);
406
m_ui.DevicePortParamTable->setEnabled(false);
411
Device& device = ((DeviceItem *) pItem)->device();
414
// Flag whether this is a new device.
415
m_bNewDevice = (device.deviceID() < 0);
417
// Fill the device/driver heading...
418
m_ui.DeviceNameTextLabel->setText(device.deviceName());
419
// The driver combobox is only rebuilt if device type has changed...
420
if (device.deviceType() != m_deviceType) {
421
m_ui.DriverNameComboBox->clear();
422
m_ui.DriverNameComboBox->insertItems(0,
423
Device::getDrivers(pMainForm->client(), device.deviceType()));
424
m_deviceType = device.deviceType();
426
// Do we need a driver name?
427
if (m_bNewDevice || device.driverName().isEmpty())
428
device.setDriver(m_ui.DriverNameComboBox->currentText());
429
setDriverName(device.driverName());
430
m_ui.DriverNameTextLabel->setEnabled(m_bNewDevice);
431
m_ui.DriverNameComboBox->setEnabled(m_bNewDevice);
432
// Fill the device parameter table...
433
m_deviceParamModel.refresh(&device, m_bNewDevice);
434
// And now the device port/channel parameter table...
435
switch (device.deviceType()) {
437
m_ui.DevicePortTextLabel->setText(tr("Ch&annel:"));
440
m_ui.DevicePortTextLabel->setText(tr("P&ort:"));
445
m_ui.DevicePortComboBox->clear();
446
m_devicePortParamModel.clear();
448
m_ui.DevicePortTextLabel->setEnabled(false);
449
m_ui.DevicePortComboBox->setEnabled(false);
450
m_ui.DevicePortParamTable->setEnabled(false);
453
switch (device.deviceType()) {
455
pixmap = QPixmap(":/icons/audio2.png");
458
pixmap = QPixmap(":/icons/midi2.png");
463
DevicePortList& ports = device.ports();
464
QListIterator<DevicePort *> iter(ports);
465
while (iter.hasNext()) {
466
DevicePort *pPort = iter.next();
467
m_ui.DevicePortComboBox->addItem(pixmap,
468
device.deviceTypeName()
469
+ ' ' + device.driverName()
470
+ ' ' + pPort->portName());
472
bool bEnabled = (ports.count() > 0);
473
m_ui.DevicePortTextLabel->setEnabled(bEnabled);
474
m_ui.DevicePortComboBox->setEnabled(bEnabled);
475
m_ui.DevicePortParamTable->setEnabled(bEnabled);
480
// Make the device port/channel selection effective.
481
selectDevicePort(m_ui.DevicePortComboBox->currentIndex());
485
// Device port/channel selection slot.
486
void DeviceForm::selectDevicePort ( int iPort )
488
if (m_iDirtySetup > 0)
492
// Device port/channel selection has changed...
495
QTreeWidgetItem* pItem = m_ui.DeviceListView->currentItem();
496
if (pItem == NULL || pItem->type() != QSAMPLER_DEVICE_ITEM)
499
Device& device = ((DeviceItem *) pItem)->device();
500
DevicePort *pPort = NULL;
501
if (iPort >= 0 && iPort < device.ports().count())
502
pPort = device.ports().at(iPort);
505
m_devicePortParamModel.refresh(pPort, false);
513
// Device parameter value change slot.
514
void DeviceForm::changeDeviceParam ( int iRow, int iCol )
516
if (m_iDirtySetup > 0)
518
if (iRow < 0 || iCol < 0)
522
// Device parameter change...
525
/* we do that in the model class now ...
526
QTreeWidgetItem* pItem = m_ui.DeviceListView->currentItem();
527
if (pItem == NULL || pItem->type() != QSAMPLER_DEVICE_ITEM)
530
Device& device = ((DeviceItem *) pItem)->device();
532
// Table 1st column has the parameter name;
533
//const QString sParam = m_ui.DeviceParamTable->text(iRow, 0);
534
//const QString sValue = m_ui.DeviceParamTable->text(iRow, iCol);
535
const QString sParam = m_deviceParamModel.data(m_deviceParamModel.index(iRow, 0), Qt::DisplayRole).value<DeviceParameterRow>().name;
536
const QString sValue = m_deviceParamModel.data(m_deviceParamModel.index(iRow, iCol), Qt::DisplayRole).value<DeviceParameterRow>().param.value;
537
// Set the local device parameter value.
538
if (device.setParam(sParam, sValue)) {
545
// Main session should be dirtier...
546
MainForm *pMainForm = MainForm::getInstance();
548
pMainForm->sessionDirty();
552
// Device port/channel parameter value change slot.
553
void DeviceForm::changeDevicePortParam ( int iRow, int iCol )
555
if (m_iDirtySetup > 0)
557
if (iRow < 0 || iCol < 0)
561
// Device port/channel parameter change...
564
/* we do that in the model class now ...
565
QTreeWidgetItem* pItem = m_ui.DeviceListView->currentItem();
566
if (pItem == NULL || pItem->type() != QSAMPLER_DEVICE_ITEM)
569
Device& device = ((DeviceItem *) pItem)->device();
571
int iPort = m_ui.DevicePortComboBox->currentIndex();
572
DevicePort *pPort = NULL;
573
if (iPort >= 0 && iPort < device.ports().count())
574
pPort = device.ports().at(iPort);
578
// Table 1st column has the parameter name;
579
//const QString sParam = m_ui.DevicePortParamTable->text(iRow, 0);
580
//const QString sValue = m_ui.DevicePortParamTable->text(iRow, iCol);
581
const QString sParam = m_devicePortParamModel.data(m_devicePortParamModel.index(iRow, 0), Qt::DisplayRole).value<DeviceParameterRow>().name;
582
const QString sValue = m_devicePortParamModel.data(m_devicePortParamModel.index(iRow, iCol), Qt::DisplayRole).value<DeviceParameterRow>().param.value;
584
// Set the local device port/channel parameter value.
585
pPort->setParam(sParam, sValue);
591
// Main session should be dirtier...
592
MainForm* pMainForm = MainForm::getInstance();
594
pMainForm->sessionDirty();
598
// Device list view context menu handler.
599
void DeviceForm::deviceListViewContextMenu ( const QPoint& pos )
601
MainForm *pMainForm = MainForm::getInstance();
602
if (pMainForm == NULL)
605
QTreeWidgetItem* pItem = m_ui.DeviceListView->itemAt(pos);
609
// Build the device context menu...
613
bool bClient = (pMainForm->client() != NULL);
614
bool bEnabled = (pItem != NULL);
615
pAction = menu.addAction(
616
QIcon(":/qsampler/pixmaps/deviceCreate.png"),
617
tr("&Create device"), this, SLOT(createDevice()));
618
pAction->setEnabled(bEnabled || (bClient && m_bNewDevice));
619
pAction = menu.addAction(
620
QIcon(":/qsampler/pixmaps/deviceDelete.png"),
621
tr("&Delete device"), this, SLOT(deleteDevice()));
622
pAction->setEnabled(bEnabled && !m_bNewDevice);
624
pAction = menu.addAction(
625
QIcon(":/qsampler/pixmaps/formRefresh.png"),
626
tr("&Refresh"), this, SLOT(refreshDevices()));
627
pAction->setEnabled(bClient);
633
// Stabilize current form state.
634
void DeviceForm::stabilizeForm (void)
636
MainForm* pMainForm = MainForm::getInstance();
637
QTreeWidgetItem* pItem = m_ui.DeviceListView->currentItem();
638
bool bClient = (pMainForm && pMainForm->client() != NULL);
639
bool bEnabled = (pItem != NULL);
640
m_ui.DeviceNameTextLabel->setEnabled(bEnabled && !m_bNewDevice);
641
m_ui.DriverNameTextLabel->setEnabled(bEnabled && m_bNewDevice);
642
m_ui.DriverNameComboBox->setEnabled(bEnabled && m_bNewDevice);
643
m_ui.DeviceParamTable->setEnabled(bEnabled);
644
m_ui.RefreshDevicesPushButton->setEnabled(bClient);
645
m_ui.CreateDevicePushButton->setEnabled(bEnabled || (bClient && m_bNewDevice));
646
m_ui.DeleteDevicePushButton->setEnabled(bEnabled && !m_bNewDevice);
650
void DeviceForm::updateCellRenderers (void)
652
const int rows = m_deviceParamModel.rowCount();
653
const int cols = m_deviceParamModel.columnCount();
655
m_deviceParamModel.index(0, 0),
656
m_deviceParamModel.index(rows - 1, cols - 1));
660
void DeviceForm::updateCellRenderers (
661
const QModelIndex& topLeft, const QModelIndex& bottomRight )
663
for (int r = topLeft.row(); r <= bottomRight.row(); r++) {
664
for (int c = topLeft.column(); c <= bottomRight.column(); c++) {
665
const QModelIndex index = m_deviceParamModel.index(r, c);
666
m_ui.DeviceParamTable->openPersistentEditor(index);
672
void DeviceForm::updatePortCellRenderers (void)
674
const int rows = m_devicePortParamModel.rowCount();
675
const int cols = m_devicePortParamModel.columnCount();
676
updatePortCellRenderers(
677
m_devicePortParamModel.index(0, 0),
678
m_devicePortParamModel.index(rows - 1, cols - 1));
682
void DeviceForm::updatePortCellRenderers (
683
const QModelIndex& topLeft, const QModelIndex& bottomRight )
685
for (int r = topLeft.row(); r <= bottomRight.row(); r++) {
686
for (int c = topLeft.column(); c <= bottomRight.column(); c++) {
687
const QModelIndex index = m_devicePortParamModel.index(r, c);
688
m_ui.DevicePortParamTable->openPersistentEditor(index);
693
} // namespace QSampler
696
// end of qsamplerDeviceForm.cpp