Files
EqualizerAPO/Editor/FilterTable.cpp
T
jthedering a1be4cc70f Improved: The Configuration Editor now saves most of its state (window positions, open files, etc.) when closing and restores it when run again.
Fixed: The GUI for the Copy command was behaving incorrectly when channels were selected by number instead of name.
Fixed: When the processing caused delay (e.g. via Delay command), the remaining audio was not output when the input signal became silence (e.g. pausing a music player), but only when the silence ended.
Fixed: The checks for missing registry values in Configuration Editor/Configurator should now be sufficient to reanimate E-APO after an OS upgrade. Also the Configurator did not launch when accepting the question in the Configuration Editor with UAC enabled.
2015-11-22 20:16:39 +00:00

1028 lines
24 KiB
C++

/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2014 Jonas Thedering
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <QDrag>
#include <QMimeData>
#include <QApplication>
#include <QClipboard>
#include <QLabel>
#include <QElapsedTimer>
#include <QLineEdit>
#include <QToolButton>
#include <QScrollBar>
#include <QToolBar>
#include <QComboBox>
#include <QAbstractSpinBox>
#include <QDial>
#include <QJsonDocument>
#include <QSettings>
#include "MainWindow.h"
#include "FilterTableRow.h"
#include "FilterTableMimeData.h"
#include "guis/ExpressionFilterGUIFactory.h"
#include "guis/CommentFilterGUIFactory.h"
#include "guis/DeviceFilterGUIFactory.h"
#include "guis/ChannelFilterGUIFactory.h"
#include "guis/StageFilterGUIFactory.h"
#include "guis/PreampFilterGUIFactory.h"
#include "guis/BiQuadFilterGUIFactory.h"
#include "guis/CopyFilterGUIFactory.h"
#include "guis/DelayFilterGUIFactory.h"
#include "guis/IncludeFilterGUIFactory.h"
#include "guis/GraphicEQFilterGUIFactory.h"
#include "guis/ConvolutionFilterGUIFactory.h"
#include "helpers/StringHelper.h"
#include "helpers/LogHelper.h"
#include "helpers/ChannelHelper.h"
#include "helpers/RegistryHelper.h"
#include "FilterTable.h"
using namespace std;
FilterTable::FilterTable(MainWindow* mainWindow, QWidget *parent) :
QWidget(parent), mainWindow(mainWindow)
{
gridLayout = new QGridLayout(this);
QPixmap pixmap(QStringLiteral(":/icons/arrow_right.png"));
insertArrow = new QLabel(this);
insertArrow->setPixmap(pixmap);
insertArrow->setVisible(false);
factories.append(new ExpressionFilterGUIFactory);
factories.append(new CommentFilterGUIFactory);
factories.append(new IncludeFilterGUIFactory);
factories.append(new DeviceFilterGUIFactory);
factories.append(new ChannelFilterGUIFactory);
factories.append(new StageFilterGUIFactory);
factories.append(new PreampFilterGUIFactory);
factories.append(new BiQuadFilterGUIFactory);
factories.append(new DelayFilterGUIFactory);
factories.append(new CopyFilterGUIFactory);
factories.append(new GraphicEQFilterGUIFactory);
factories.append(new ConvolutionFilterGUIFactory);
QApplication::instance()->installEventFilter(this);
}
void FilterTable::initialize(QScrollArea* scrollArea, const QList<DeviceAPOInfo>& outputDevices, const QList<DeviceAPOInfo>& inputDevices)
{
this->scrollArea = scrollArea;
this->outputDevices = outputDevices;
this->inputDevices = inputDevices;
for(IFilterGUIFactory* factory : factories)
factory->initialize(this);
}
void FilterTable::updateDeviceAndChannelMask(DeviceAPOInfo* selectedDevice, int channelMask)
{
this->selectedDevice = selectedDevice;
this->selectedChannelMask = channelMask;
if(!items.empty())
updateGuis();
}
void FilterTable::updateGuis()
{
QElapsedTimer timer;
timer.start();
for(Item* item : items)
{
if(item->gui != NULL)
{
item->prefs.clear();
item->gui->storePreferences(item->prefs);
}
}
delete layout();
for(QObject* object : children())
{
if(object != insertArrow)
{
QWidget* widget = qobject_cast<QWidget*>(object);
if(widget != NULL)
widget->setVisible(false);
object->deleteLater();
}
}
qDebug("Delete took %d ms", timer.elapsed());
timer.start();
gridLayout = new QGridLayout(this);
gridLayout->setMargin(0);
gridLayout->setSpacing(0);
gridLayout->setColumnStretch(0, 0);
gridLayout->setColumnStretch(1, 1);
for(IFilterGUIFactory* factory : factories)
factory->startOfFile(configPath);
int row = 0;
for(Item* item : items)
{
QString line = item->text;
IFilterGUI* gui = NULL;
int pos = line.indexOf(':');
if(pos != -1)
{
QString key = line.mid(0, pos);
QString value = line.mid(pos + 1);
// allow to use indentation
key = key.trimmed();
QString factoryKey = key;
QString factoryValue = value;
for(IFilterGUIFactory* factory : factories)
{
gui = factory->createFilterGUI(factoryKey, factoryValue);
if(gui != NULL || factoryKey == "")
break;
}
if(gui != NULL)
{
for(IFilterGUIFactory* factory : factories)
{
gui = factory->decorateFilterGUI(gui);
}
}
}
FilterTableRow* rowWidget = new FilterTableRow(this, row + 1, item, gui);
gridLayout->addWidget(rowWidget, row, 0);
item->gui = gui;
if(gui != NULL)
{
gui->loadPreferences(item->prefs);
connect(gui, SIGNAL(updateModel()), this, SLOT(updateModel()));
connect(gui, SIGNAL(updateChannels()), this, SLOT(updateChannels()));
}
row++;
}
for(IFilterGUIFactory* factory : factories)
factory->endOfFile(configPath);
propagateChannels();
QToolBar* toolBar = new QToolBar;
toolBar->setIconSize(QSize(16, 16));
QWidget* spacer = new QWidget;
spacer->setFixedWidth(25);
toolBar->addWidget(spacer);
QAction* addAction = new QAction(QIcon(":/icons/16x16/list-add-green.png"), tr("Add filter"), toolBar);
addAction->setCheckable(true);
connect(addAction, SIGNAL(triggered()), this, SLOT(addActionTriggered()));
toolBar->addAction(addAction);
gridLayout->addWidget(toolBar, row++, 0, 1, 1, Qt::AlignLeft | Qt::AlignTop);
QSpacerItem* spacerItem = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
gridLayout->addItem(spacerItem, row, 0);
gridLayout->setRowStretch(row, 1);
disableWheelForWidgets();
qDebug("Create took %d ms", timer.elapsed());
update();
}
void FilterTable::propagateChannels()
{
vector<wstring> channelNames = ChannelHelper::getChannelNames(selectedDevice->channelCount, selectedChannelMask);
for(Item* item : items)
{
if(item->gui != NULL)
item->gui->configureChannels(channelNames);
}
}
QList<QString> FilterTable::getLines()
{
QList<QString> result;
for(Item* item : items)
result.append(item->text);
return result;
}
void FilterTable::setLines(const QString& configPath, const QList<QString>& lines)
{
this->configPath = configPath;
qDeleteAll(items);
items.clear();
for(QString line : lines)
{
items.append(new Item(line));
}
QSettings settings(QString::fromWCharArray(EDITOR_PER_FILE_REGPATH), QSettings::NativeFormat);
settings.beginGroup(QString(configPath).replace('\\', '|'));
QVariant prefsValue = settings.value("rowPrefs");
QStringList prefLines;
if(prefsValue.isValid())
prefLines = prefsValue.toStringList();
for(QString prefLine : prefLines)
{
int index = prefLine.indexOf(':');
int lineNumber;
if(index != -1)
lineNumber = prefLine.left(index).toInt();
QString prefCommand;
QString prefString;
if(lineNumber > 0)
{
int index2 = prefLine.indexOf(':', index + 1);
if(index2 != -1)
{
prefCommand = prefLine.mid(index + 1, index2 - index - 1);
prefString = prefLine.mid(index2 + 1);
if(lineNumber <= items.size())
{
Item* item = items[lineNumber - 1];
QString command;
int index = item->text.indexOf(':');
if(index != -1)
command = item->text.left(index).trimmed();
if(command == prefCommand)
item->prefs = QJsonDocument::fromJson(prefString.toUtf8()).toVariant().toMap();
}
}
}
}
setScrollOffsets(settings.value("scrollX", 0).toInt(), settings.value("scrollY", 0).toInt());
settings.endGroup();
if(!items.isEmpty())
{
focused = items[0];
selectionStart = items[0];
}
else
{
focused = NULL;
selectionStart = NULL;
}
updateGuis();
}
FilterTable::Item* FilterTable::addLine(const QString& line, FilterTable::Item* before)
{
Item* newItem = new Item(line);
if(before != NULL)
{
int index = items.indexOf(before);
items.insert(index, newItem);
}
else
{
items.append(newItem);
}
emit linesChanged();
return newItem;
}
void FilterTable::removeItem(FilterTable::Item* item)
{
items.removeOne(item);
emit linesChanged();
}
QMenu* FilterTable::createAddPopupMenu()
{
QHash<QList<QString>, QMenu*> pathMap;
QMenu* rootMenu = new QMenu;
pathMap[QStringList()] = rootMenu;
for(IFilterGUIFactory* f : factories)
{
QList<FilterTemplate> templates = f->createFilterTemplates();
for(FilterTemplate t : templates)
{
QMenu* menu = pathMap.value(t.getPath());
if(menu == NULL)
{
QMenu* parentMenu = rootMenu;
QStringList currentPath;
for(QString pathSegment : t.getPath())
{
currentPath.append(pathSegment);
menu = pathMap.value(currentPath);
if(menu == NULL)
{
menu = new QMenu(pathSegment);
pathMap.insert(currentPath, menu);
parentMenu->addMenu(menu);
}
parentMenu = menu;
}
}
QAction* action = menu->addAction(t.getName());
action->setData(QVariant::fromValue(t));
}
}
return rootMenu;
}
void FilterTable::cut()
{
copy();
deleteSelectedLines();
}
void FilterTable::copy()
{
QString text;
QList<QVariantMap> prefsList;
bool first = true;
for(Item* item : items)
{
if(selected.contains(item))
{
if(first)
first = false;
else
text += "\n";
text += item->text;
prefsList.append(item->prefs);
}
}
if(selected.size() > 0)
{
FilterTableMimeData* mimeData = new FilterTableMimeData;
mimeData->setText(text);
mimeData->setPrefsList(prefsList);
QClipboard* clipboard = QApplication::clipboard();
clipboard->setMimeData(mimeData);
}
}
void FilterTable::paste()
{
QClipboard* clipboard = QApplication::clipboard();
const QMimeData* mimeData = clipboard->mimeData();
if(mimeData->hasText())
{
int dropRow = items.size();
for(int i = 0; i < items.size(); i++)
{
if(selected.contains(items[i]))
{
dropRow = i;
break;
}
}
QString text = mimeData->text();
QStringList textLines = text.split("\n");
QList<QVariantMap> prefsList;
const FilterTableMimeData* filterTableMimeData = qobject_cast<const FilterTableMimeData*>(mimeData);
if(filterTableMimeData != NULL)
prefsList = filterTableMimeData->getPrefsList();
selected.clear();
focused = NULL;
selectionStart = NULL;
for(int i = 0; i < textLines.size(); i++)
{
QString line = textLines[i];
Item* item = new Item(line);
if(!prefsList.isEmpty())
item->prefs = prefsList[i];
selected.insert(item);
items.insert(dropRow++, item);
if(focused == NULL)
{
focused = item;
selectionStart = item;
}
}
emit linesChanged();
updateGuis();
}
}
void FilterTable::deleteSelectedLines()
{
QList<Item*> newItems;
for(Item* item : items)
{
if(selected.contains(item))
{
if(item == focused)
focused = NULL;
if(item == selectionStart)
selectionStart = NULL;
delete item;
}
else
{
newItems.append(item);
}
}
selected.clear();
items = newItems;
emit linesChanged();
updateGuis();
}
void FilterTable::updateModel()
{
emit linesChanged();
}
void FilterTable::updateChannels()
{
propagateChannels();
}
void FilterTable::addActionTriggered()
{
QMenu* menu = createAddPopupMenu();
QAction* addAction = qobject_cast<QAction*>(QObject::sender());
QToolBar* toolBar = qobject_cast<QToolBar*>(addAction->parentWidget());
QRect rect = toolBar->actionGeometry(addAction);
QPoint p = toolBar->mapToGlobal(QPoint(rect.x(), rect.y() + rect.height()));
QAction* action = menu->exec(p);
addAction->setChecked(false);
if(action != NULL)
{
FilterTemplate t = action->data().value<FilterTemplate>();
QString line = t.getLine();
addLine(line);
updateGuis();
}
}
void FilterTable::openConfig(QString path)
{
mainWindow->load(path);
}
int FilterTable::getPreferredWidth()
{
if(scrollArea == NULL)
return width();
return scrollArea->viewport()->width();
}
void FilterTable::updateSizeHints()
{
for(int i = 0; i < items.size(); i++)
{
FilterTableRow* tableRow = qobject_cast<FilterTableRow*>(gridLayout->itemAtPosition(i, 0)->widget());
tableRow->updateGeometry();
}
}
QSize FilterTable::minimumSizeHint() const
{
QSize size = QWidget::minimumSizeHint();
if(size.height() < minimumHeightHint)
size.setHeight(minimumHeightHint);
return size;
}
void FilterTable::setMinimumHeightHint(int height)
{
minimumHeightHint = height;
updateGeometry();
}
void FilterTable::savePreferences()
{
if(!configPath.isEmpty())
{
QStringList prefLines;
for(int i = 0; i < items.size(); i++)
{
Item* item = items[i];
if(item->gui != NULL)
{
item->prefs.clear();
item->gui->storePreferences(item->prefs);
}
if(!item->prefs.isEmpty())
{
QString command;
int index = item->text.indexOf(':');
if(index != -1)
command = item->text.left(index).trimmed();
QByteArray byteArray = QJsonDocument::fromVariant(item->prefs).toJson(QJsonDocument::Compact);
QString string = QString("%0:%1:%2").arg(i + 1).arg(command).arg(QString::fromUtf8(byteArray));
prefLines.append(string);
}
}
QSettings settings(QString::fromWCharArray(EDITOR_PER_FILE_REGPATH), QSettings::NativeFormat);
settings.beginGroup(QString(configPath).replace('\\', '|'));
settings.setValue("rowPrefs", prefLines);
settings.setValue("scrollX", scrollArea->horizontalScrollBar()->value());
settings.setValue("scrollY", scrollArea->verticalScrollBar()->value());
settings.endGroup();
}
}
void FilterTable::setScrollOffsets(int x, int y)
{
presetScrollX = x;
presetScrollY = y;
}
void FilterTable::mousePressEvent(QMouseEvent* event)
{
if(event->buttons() & Qt::LeftButton )
{
int row = rowForPos(event->pos(), false);
if(row != -1)
{
Item* item = items[row];
if(event->modifiers() & Qt::ControlModifier)
{
if(!selected.remove(item))
selected.insert(item);
selectionStart = item;
}
else if(event->modifiers() & Qt::ShiftModifier)
{
int startRow = items.indexOf(selectionStart);
if(startRow != -1)
{
selected.clear();
for(int i = min(startRow, row); i <= max(startRow, row); i++)
{
selected.insert(items[i]);
}
}
}
else
{
if(!selected.contains(item))
{
selected.clear();
selected.insert(item);
}
selectionStart = item;
}
focused = item;
ensureRowVisible(row);
update();
dragStartPos = event->pos();
}
else
{
selected.clear();
update();
}
}
}
void FilterTable::mouseMoveEvent(QMouseEvent* event)
{
if(event->buttons() & Qt::LeftButton)
{
if((event->pos() - dragStartPos).manhattanLength() >= QApplication::startDragDistance())
{
QString text;
QList<QVariantMap> prefsList;
bool first = true;
int i = 0;
bool dragPosInside = false;
for(Item* item : items)
{
if(selected.contains(item))
{
if(first)
first = false;
else
text += "\n";
text += item->text;
if(item->gui != NULL)
item->gui->storePreferences(item->prefs);
prefsList.append(item->prefs);
if(!dragPosInside)
{
FilterTableRow* tableRow = qobject_cast<FilterTableRow*>(gridLayout->itemAtPosition(i, 0)->widget());
QRect rect = tableRow->getHeaderRect().translated(tableRow->pos());
if(rect.contains(dragStartPos))
dragPosInside = true;
}
}
i++;
}
if(selected.size() > 0 && dragPosInside)
{
FilterTableMimeData* mimeData = new FilterTableMimeData;
mimeData->setText(text);
mimeData->setPrefsList(prefsList);
QDrag* drag = new QDrag(this);
drag->setMimeData(mimeData);
QSet<Item*> selectedBefore = selected;
internalDrag = true;
Qt::DropAction action = drag->exec(Qt::MoveAction | Qt::CopyAction);
internalDrag = false;
if(action == Qt::MoveAction)
{
for(Item* item : selectedBefore)
{
items.removeOne(item);
if(focused == item)
focused = NULL;
if(selectionStart == item)
selectionStart = NULL;
selected.remove(item);
delete item;
}
}
if(action != Qt::IgnoreAction)
{
emit linesChanged();
updateGuis();
}
}
}
}
QWidget::mouseMoveEvent(event);
}
void FilterTable::dragEnterEvent(QDragEnterEvent* event)
{
if(event->mimeData()->hasText())
{
if(event->keyboardModifiers() & Qt::ControlModifier)
event->setDropAction(Qt::CopyAction);
else
event->setDropAction(Qt::MoveAction);
event->accept();
}
QWidget::dragEnterEvent(event);
}
void FilterTable::dragMoveEvent(QDragMoveEvent* event)
{
if(event->mimeData()->hasText())
{
if(event->keyboardModifiers() & Qt::ControlModifier)
event->setDropAction(Qt::CopyAction);
else
event->setDropAction(Qt::MoveAction);
int dropRow = rowForPos(event->pos(), true);
QRect rect = gridLayout->itemAtPosition(dropRow == -1 ? gridLayout->rowCount() - 2 : dropRow, 0)->geometry();
insertArrow->move(0, rect.top() - insertArrow->height() / 2 - gridLayout->verticalSpacing() / 2);
insertArrow->raise();
insertArrow->show();
}
QWidget::dragMoveEvent(event);
}
void FilterTable::dragLeaveEvent(QDragLeaveEvent* event)
{
insertArrow->hide();
}
void FilterTable::dropEvent(QDropEvent* event)
{
const QMimeData* mimeData = event->mimeData();
if(mimeData->hasText())
{
if(event->keyboardModifiers() & Qt::ControlModifier)
event->setDropAction(Qt::CopyAction);
else
event->setDropAction(Qt::MoveAction);
QString text = mimeData->text();
QStringList textLines = text.split("\n");
QList<QVariantMap> prefsList;
const FilterTableMimeData* filterTableMimeData = qobject_cast<const FilterTableMimeData*>(mimeData);
if(filterTableMimeData != NULL)
prefsList = filterTableMimeData->getPrefsList();
int dropRow = rowForPos(event->pos(), true);
if(dropRow == -1)
dropRow = items.size();
selected.clear();
focused = NULL;
selectionStart = NULL;
for(int i = 0; i < textLines.size(); i++)
{
QString line = textLines[i];
Item* item = new Item(line);
if(!prefsList.isEmpty())
item->prefs = prefsList[i];
selected.insert(item);
items.insert(dropRow++, item);
if(focused == NULL)
{
focused = item;
selectionStart = item;
}
}
event->accept();
if(!internalDrag)
{
emit linesChanged();
updateGuis();
}
}
insertArrow->hide();
QWidget::dropEvent(event);
}
void FilterTable::keyPressEvent(QKeyEvent* event)
{
if(event->key() == Qt::Key_Down || event->key() == Qt::Key_Up)
{
if(focused != NULL)
{
int row = items.indexOf(focused);
if(row != -1)
{
int newRow = row;
if(event->key() == Qt::Key_Down && row + 1 < items.size())
newRow = row + 1;
else if(event->key() == Qt::Key_Up && row - 1 >= 0)
newRow = row - 1;
if(newRow != row)
{
focused = items[newRow];
if(event->modifiers() & Qt::ControlModifier)
{
}
else if(event->modifiers() & Qt::ShiftModifier)
{
int startRow = items.indexOf(selectionStart);
if(startRow != -1)
{
selected.clear();
for(int i = min(startRow, newRow); i <= max(startRow, newRow); i++)
{
selected.insert(items[i]);
}
}
}
else
{
selected.clear();
selected.insert(focused);
selectionStart = focused;
}
ensureRowVisible(newRow);
update();
}
}
}
}
if(event->key() == Qt::Key_Space)
{
if(!(event->modifiers() & Qt::ControlModifier) || !selected.remove(focused))
selected.insert(focused);
update();
}
if(event->key() == Qt::Key_F2)
{
if(focused != NULL)
{
int rowIndex = items.indexOf(focused);
if(rowIndex != -1)
{
QLayoutItem* layoutItem = gridLayout->itemAtPosition(rowIndex, 0);
FilterTableRow* tableRow = qobject_cast<FilterTableRow*>(layoutItem->widget());
if(tableRow != NULL)
tableRow->editText();
}
}
}
if(event->key() == Qt::Key_Delete)
{
deleteSelectedLines();
}
}
void FilterTable::wheelEvent(QWheelEvent * event)
{
scrollingNow = true;
scrollStartPoint = event->globalPos();
QWidget::wheelEvent(event);
}
bool FilterTable::eventFilter(QObject* obj, QEvent* event)
{
QEvent::Type type = event->type();
if(scrollingNow)
{
if(type == QEvent::Wheel)
{
QWidget* widget = qobject_cast<QWidget*>(obj);
if(widget != NULL)
{
if(isAncestorOf(widget))
{
QApplication::sendEvent(parent(), event);
return true;
}
}
}
else if(type == QEvent::MouseMove)
{
QMouseEvent* mouseEvent = (QMouseEvent*)event;
if((mouseEvent->globalPos() - scrollStartPoint).manhattanLength() > QApplication::startDragDistance())
scrollingNow = false;
}
}
if(obj == scrollArea && type == QEvent::Resize)
{
updateSizeHints();
}
return false;
}
void FilterTable::showEvent(QShowEvent*)
{
if(presetScrollX != -1)
{
scrollArea->horizontalScrollBar()->setValue(presetScrollX);
presetScrollX = -1;
}
if(presetScrollY != -1)
{
scrollArea->verticalScrollBar()->setValue(presetScrollY);
presetScrollY = -1;
}
}
void FilterTable::ensureRowVisible(int row)
{
QScrollBar* vScrollBar = scrollArea->verticalScrollBar();
if(vScrollBar != NULL)
{
QRect rect = rowRect(row).toAlignedRect();
if(rect.top() < vScrollBar->value())
vScrollBar->setValue(max(0, rect.top()));
else if(rect.bottom() + 1 > vScrollBar->value() + scrollArea->viewport()->height())
vScrollBar->setValue(min(vScrollBar->maximum(), rect.bottom() + 1 - scrollArea->viewport()->height()));
}
}
int FilterTable::rowForPos(QPoint pos, bool insert)
{
int row = -1;
for(int i = 0; i < gridLayout->rowCount() - 2; i++)
{
QRect rect = gridLayout->itemAtPosition(i, 0)->geometry();
int y;
if(insert)
y = rect.center().y();
else
y = rect.bottom();
if(pos.y() <= y)
{
row = i;
break;
}
}
return row;
}
QRectF FilterTable::rowRect(int row)
{
QRectF rect = gridLayout->itemAtPosition(row, 0)->geometry();
rect = rect.marginsAdded(QMarginsF(-1.5, -1.5, -1.5, -0.5));
return rect;
}
void FilterTable::disableWheelForWidgets()
{
QList<QWidget*> widgets = findChildren<QWidget*>();
for(QWidget* widget : widgets)
{
if(qobject_cast<QComboBox*>(widget) || qobject_cast<QAbstractSpinBox*>(widget) || qobject_cast<QDial*>(widget))
{
widget->installEventFilter(new DisableWheelFilter(this, widget));
if(widget->focusPolicy() == Qt::WheelFocus)
widget->setFocusPolicy(Qt::StrongFocus);
}
}
}
QString FilterTable::getConfigPath() const
{
return configPath;
}
void FilterTable::setConfigPath(const QString& value)
{
configPath = value;
}
FilterTable::Item* FilterTable::getFocusedItem() const
{
return focused;
}
const QSet<FilterTable::Item*>& FilterTable::getSelectedItems() const
{
return selected;
}
const QList<DeviceAPOInfo>& FilterTable::getOutputDevices() const
{
return outputDevices;
}
const QList<DeviceAPOInfo>& FilterTable::getInputDevices() const
{
return inputDevices;
}
DeviceAPOInfo* FilterTable::getSelectedDevice() const
{
return selectedDevice;
}
int FilterTable::getSelectedChannelMask() const
{
return selectedChannelMask;
}