Version 1.0

Added: Configuration Editor, which allows to edit configurations in a graphical user interface. Contains GUIs for most commands supported by E-APO, but as lines can also be edited directly, all commands can be used.
Added: Command "GraphicEQ", which can act as a regular, fixed-band graphic equalizer (via the GUI) but also supports variable bands so that any desired frequency response can be specified. Internally, it is implemented via convolution with a generated IR.
Added: Command "Convolution", which allows to convolve the signal with a user-provided impulse response to achieve e.g. equalization or reverberation effects.
Improved: Configurator performs checks for registry values that are needed for the operation of E-APO, which may be changed by driver installations, fixing the values if necessary.
Improved: Configurator shows which is the default device as a hint to the user.
This commit is contained in:
jthedering committed 2015-09-27 16:01:21 +00:00
1 parent d68b958bc8
commit b8cdd47f71
284 files changed
+17622 -322

No files matched your search

+338
View File
@@ -0,0 +1,338 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#define _USE_MATH_DEFINES
#include <cmath>
#include "BiQuadFilterGUI.h"
#include "ui_BiQuadFilterGUI.h"
#include <QStandardItemModel>
static const double dialFreqSteps = 1000;
static const double dialFreqMin = 20;
static const double dialFreqMax = 20000;
static const double dialQSteps = 1000;
static const double dialQMin = 0.3333;
static const double dialQMax = 33.3333;
BiQuadFilterGUI::BiQuadFilterGUI(BiQuadFilter* filter) :
ui(new Ui::BiQuadFilterGUI)
{
ui->setupUi(this);
ui->typeComboBox->addItem(tr("Peaking filter"), BiQuad::PEAKING);
ui->typeComboBox->addItem(tr("Low-pass filter"), BiQuad::LOW_PASS);
ui->typeComboBox->addItem(tr("High-pass filter"), BiQuad::HIGH_PASS);
ui->typeComboBox->addItem(tr("Band-pass filter"), BiQuad::BAND_PASS);
ui->typeComboBox->addItem(tr("Low-shelf filter"), BiQuad::LOW_SHELF);
ui->typeComboBox->addItem(tr("High-shelf filter"), BiQuad::HIGH_SHELF);
ui->typeComboBox->addItem(tr("Notch filter"), BiQuad::NOTCH);
ui->typeComboBox->addItem(tr("All-pass filter"), BiQuad::ALL_PASS);
BiQuad::Type type = filter->getType();
int typeIndex = ui->typeComboBox->findData(type);
if(typeIndex != -1)
ui->typeComboBox->setCurrentIndex(typeIndex);
if(type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF )
ui->freqComboBox->setCurrentIndex(filter->getIsCornerFreq() ? 1 : 0);
ui->freqSpinBox->setValue(filter->getFreq());
if(type == BiQuad::PEAKING )
ui->qComboBox->setCurrentIndex(filter->getIsBandwidth() ? 1 : 0);
else if(type == BiQuad::LOW_PASS || type == BiQuad::HIGH_PASS || type == BiQuad::BAND_PASS)
ui->qComboBox->setCurrentIndex(filter->getBandwidthOrQOrS() == M_SQRT1_2 ? 0 : 1);
else if((type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF) && !filter->getIsCornerFreq())
ui->qComboBox->setCurrentIndex(filter->getBandwidthOrQOrS() == 0.9 ? 0 : 1);
if((type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF) && filter->getBandwidthOrQOrS() != 0.9)
ui->qSpinBox->setValue(filter->getBandwidthOrQOrS() * 12.0);
else
ui->qSpinBox->setValue(filter->getBandwidthOrQOrS());
ui->gainSpinBox->setValue(filter->getDbGain());
}
BiQuadFilterGUI::~BiQuadFilterGUI()
{
delete ui;
}
void BiQuadFilterGUI::store(QString& command, QString& parameters)
{
BiQuad::Type type = (BiQuad::Type)ui->typeComboBox->currentData().toInt();
QChar freqMode = ui->freqComboBox->currentData().toChar();
QChar mode = ui->qComboBox->currentData().toChar();
command = "Filter";
parameters = "ON ";
switch(type)
{
case BiQuad::PEAKING:
parameters += "PK";
break;
case BiQuad::LOW_PASS:
if(mode == 'F')
parameters += "LP";
else
parameters += "LPQ";
break;
case BiQuad::HIGH_PASS:
if(mode == 'F')
parameters += "HP";
else
parameters += "HPQ";
break;
case BiQuad::BAND_PASS:
parameters += "BP";
break;
case BiQuad::LOW_SHELF:
if(freqMode == 'E' && mode == 'S')
parameters += "LSC";
else
parameters += "LS";
break;
case BiQuad::HIGH_SHELF:
if(freqMode == 'E' && mode == 'S')
parameters += "HSC";
else
parameters += "HS";
break;
case BiQuad::NOTCH:
parameters += "NO";
break;
case BiQuad::ALL_PASS:
parameters += "AP";
break;
}
if((type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF) && mode == 'S')
parameters += QString(" %1 dB").arg(ui->qSpinBox->value());
parameters += QString(" Fc %1 Hz").arg(ui->freqSpinBox->value());
if(type == BiQuad::PEAKING || type == BiQuad::LOW_SHELF
|| type == BiQuad::HIGH_SHELF)
parameters += QString(" Gain %1 dB").arg(ui->gainSpinBox->value());
if(mode == 'Q')
parameters += QString(" Q %1").arg(ui->qSpinBox->value());
else if(mode == 'B')
parameters += QString(" BW Oct %1").arg(ui->qSpinBox->value());
}
void BiQuadFilterGUI::on_freqDial_valueChanged(int value)
{
ui->freqSpinBox->setValue(pow(dialFreqMax / dialFreqMin, value / dialFreqSteps) * dialFreqMin);
}
void BiQuadFilterGUI::on_freqSpinBox_valueChanged(double value)
{
bool previousValue = ui->freqDial->blockSignals(true);
ui->freqDial->setValue(round(dialFreqSteps * log(value / dialFreqMin) / log(dialFreqMax / dialFreqMin)));
ui->freqDial->blockSignals(previousValue);
emit updateModel();
}
void BiQuadFilterGUI::on_qDial_valueChanged(int value)
{
ui->qSpinBox->setValue(pow(dialQMax / dialQMin, value / dialQSteps) * dialQMin);
}
void BiQuadFilterGUI::on_qSpinBox_valueChanged(double value)
{
bool previousValue = ui->qDial->blockSignals(true);
ui->qDial->setValue(round(dialQSteps * log(value / dialQMin) / log(dialQMax / dialQMin)));
ui->qDial->blockSignals(previousValue);
emit updateModel();
}
void BiQuadFilterGUI::on_gainDial_valueChanged(int value)
{
ui->gainSpinBox->setValue(value * 0.1);
}
void BiQuadFilterGUI::on_gainSpinBox_valueChanged(double value)
{
bool previousValue = ui->gainDial->blockSignals(true);
ui->gainDial->setValue(round(value / 0.1));
ui->gainDial->blockSignals(previousValue);
emit updateModel();
}
void BiQuadFilterGUI::on_typeComboBox_currentIndexChanged(int index)
{
BiQuad::Type type = (BiQuad::Type)ui->typeComboBox->itemData(index).toInt();
bool sameTypeCategory = getTypeCategory(previousType) == getTypeCategory(type);
QChar freqMode = ui->freqComboBox->currentData().toChar();
double freqValue = ui->freqSpinBox->value();
ui->freqComboBox->clear();
if(type == BiQuad::PEAKING || type == BiQuad::BAND_PASS || type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF || type == BiQuad::NOTCH || type == BiQuad::ALL_PASS )
ui->freqComboBox->addItem(tr("Center frequency"), 'E');
if(type == BiQuad::LOW_PASS || type == BiQuad::HIGH_PASS || type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF)
ui->freqComboBox->addItem(tr("Corner frequency"), 'O');
ui->freqComboBox->setEnabled(ui->freqComboBox->count() > 1);
int freqIndex = ui->freqComboBox->findData(freqMode);
if(freqIndex != -1 && sameTypeCategory)
{
ui->freqComboBox->setCurrentIndex(freqIndex);
ui->freqSpinBox->setValue(freqValue);
}
else
{
freqMode = ui->freqComboBox->currentData().toChar();
}
QChar mode = ui->qComboBox->currentData().toChar();
double qValue = ui->qSpinBox->value();
ui->qComboBox->clear();
if(type == BiQuad::LOW_PASS || type == BiQuad::HIGH_PASS || type == BiQuad::BAND_PASS || type == BiQuad::NOTCH )
ui->qComboBox->addItem(tr("Fixed Q"), 'F');
else if((type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF) && freqMode == 'E')
ui->qComboBox->addItem(tr("Fixed S"), 'F');
if(type == BiQuad::PEAKING || type == BiQuad::LOW_PASS || type == BiQuad::HIGH_PASS || type == BiQuad::ALL_PASS || type == BiQuad::BAND_PASS || type == BiQuad::NOTCH)
ui->qComboBox->addItem(tr("Q factor"), 'Q');
if(type == BiQuad::PEAKING)
ui->qComboBox->addItem(tr("Bandwidth"), 'B');
if(type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF)
ui->qComboBox->addItem(tr("Slope"), 'S');
ui->qComboBox->setEnabled(ui->qComboBox->count() > 1);
int qIndex = ui->qComboBox->findData(mode);
if(qIndex != -1 && sameTypeCategory)
{
ui->qComboBox->setCurrentIndex(qIndex);
ui->qSpinBox->setValue(qValue);
}
else if(type == BiQuad::PEAKING || type == BiQuad::ALL_PASS)
{
ui->qSpinBox->setValue(10);
}
bool gainVisible = type == BiQuad::PEAKING || type == BiQuad::LOW_SHELF
|| type == BiQuad::HIGH_SHELF;
ui->gainDial->setVisible(gainVisible);
ui->gainLabel->setVisible(gainVisible);
ui->gainSpinBox->setVisible(gainVisible);
previousType = type;
emit updateModel();
}
void BiQuadFilterGUI::on_freqComboBox_currentIndexChanged(int index)
{
BiQuad::Type type = (BiQuad::Type)ui->typeComboBox->currentData().toInt();
QChar freqMode = ui->freqComboBox->itemData(index).toChar();
if(type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF)
{
QChar mode = ui->qComboBox->currentData().toChar();
double qValue = ui->qSpinBox->value();
ui->qComboBox->clear();
if(freqMode == 'E')
ui->qComboBox->addItem(tr("Fixed S"), 'F');
ui->qComboBox->addItem(tr("Slope"), 'S');
ui->qComboBox->setEnabled(ui->qComboBox->count() > 1);
int qIndex = ui->qComboBox->findData(mode);
if(qIndex != -1)
{
ui->qComboBox->setCurrentIndex(qIndex);
ui->qSpinBox->setValue(qValue);
}
double centerFreqFactor = pow(10.0, abs(ui->gainSpinBox->value()) / 80.0 / (ui->qSpinBox->value() / 12.0));
double freq = ui->freqSpinBox->value();
if((freqMode == 'E') == (type == BiQuad::LOW_SHELF) )
freq *= centerFreqFactor;
else
freq /= centerFreqFactor;
ui->freqSpinBox->setValue(freq);
}
}
void BiQuadFilterGUI::on_qComboBox_currentIndexChanged(int index)
{
QChar mode = ui->qComboBox->currentData().toChar();
if(mode == 'F' || mode == 'Q')
ui->qSpinBox->setSuffix("");
else if(mode == 'B')
ui->qSpinBox->setSuffix(" Oct");
else if(mode == 'S')
ui->qSpinBox->setSuffix(" dB/Oct");
ui->qDial->setEnabled(mode != 'F');
ui->qSpinBox->setEnabled(mode != 'F');
if(mode == 'F')
{
BiQuad::Type type = (BiQuad::Type)ui->typeComboBox->currentData().toInt();
if(type == BiQuad::LOW_PASS || type == BiQuad::HIGH_PASS || type == BiQuad::BAND_PASS)
ui->qSpinBox->setValue(M_SQRT1_2);
else if(type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF)
ui->qSpinBox->setValue(0.9);
else if(type == BiQuad::NOTCH)
ui->qSpinBox->setValue(30);
}
else if(qIsBw && mode == 'Q')
{
double n = ui->qSpinBox->value();
double p2n = pow(2.0, n);
double q = sqrt(p2n) / (p2n - 1.0);
ui->qSpinBox->setValue(q);
qIsBw = false;
}
else if(!qIsBw && mode == 'B')
{
double q = ui->qSpinBox->value();
double n = 2.0 / M_LN2 * asinh(1.0 / (2.0 * q));
ui->qSpinBox->setValue(n);
qIsBw = true;
}
else if(mode == 'S')
{
ui->qSpinBox->setValue(12.0);
}
emit updateModel();
}
int BiQuadFilterGUI::getTypeCategory(BiQuad::Type type)
{
switch(type)
{
case BiQuad::PEAKING:
return 0;
case BiQuad::LOW_PASS:
case BiQuad::HIGH_PASS:
case BiQuad::BAND_PASS:
return 1;
case BiQuad::LOW_SHELF:
case BiQuad::HIGH_SHELF:
return 2;
case BiQuad::NOTCH:
return 3;
case BiQuad::ALL_PASS:
return 4;
}
return -1;
}
+56
View File
@@ -0,0 +1,56 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
#include <filters/BiQuadFilter.h>
namespace Ui
{
class BiQuadFilterGUI;
}
class BiQuadFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
BiQuadFilterGUI(BiQuadFilter* filter);
~BiQuadFilterGUI();
void store(QString& command, QString& parameters) override;
private slots:
void on_freqDial_valueChanged(int value);
void on_freqSpinBox_valueChanged(double value);
void on_qDial_valueChanged(int value);
void on_qSpinBox_valueChanged(double value);
void on_gainDial_valueChanged(int value);
void on_gainSpinBox_valueChanged(double value);
void on_typeComboBox_currentIndexChanged(int index);
void on_freqComboBox_currentIndexChanged(int index);
void on_qComboBox_currentIndexChanged(int index);
private:
int getTypeCategory(BiQuad::Type type);
Ui::BiQuadFilterGUI* ui;
BiQuad::Type previousType = BiQuad::PEAKING;
bool qIsBw = false;
};
+238
View File
@@ -0,0 +1,238 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BiQuadFilterGUI</class>
<widget class="QWidget" name="BiQuadFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>734</width>
<height>66</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="2" rowspan="2">
<widget class="QDial" name="freqDial">
<property name="minimumSize">
<size>
<width>0</width>
<height>66</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>66</height>
</size>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="value">
<number>566</number>
</property>
</widget>
</item>
<item row="0" column="8" rowspan="2">
<widget class="QDial" name="qDial">
<property name="minimumSize">
<size>
<width>0</width>
<height>66</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>66</height>
</size>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="notchesVisible">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QDoubleSpinBox" name="freqSpinBox">
<property name="showGroupSeparator" stdset="0">
<bool>true</bool>
</property>
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>99999.990000000005239</double>
</property>
<property name="value">
<double>1000.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="5" rowspan="2">
<widget class="QDial" name="gainDial">
<property name="minimumSize">
<size>
<width>0</width>
<height>66</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>66</height>
</size>
</property>
<property name="minimum">
<number>-200</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="pageStep">
<number>20</number>
</property>
<property name="notchTarget">
<double>9.850000000000000</double>
</property>
<property name="notchesVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QDoubleSpinBox" name="gainSpinBox">
<property name="suffix">
<string> dB</string>
</property>
<property name="minimum">
<double>-199.990000000000009</double>
</property>
<property name="maximum">
<double>199.990000000000009</double>
</property>
</widget>
</item>
<item row="1" column="9">
<widget class="QDoubleSpinBox" name="qSpinBox">
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>0.000100000000000</double>
</property>
<property name="maximum">
<double>999.999900000000025</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="gainLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Gain:</string>
</property>
</widget>
</item>
<item row="0" column="9">
<widget class="QComboBox" name="qComboBox"/>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="freqComboBox"/>
</item>
<item row="0" column="7">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QComboBox" name="typeComboBox"/>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+64
View File
@@ -0,0 +1,64 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "BiQuadFilterGUI.h"
#include "BiQuadFilterGUIFactory.h"
#include <filters/BiQuadFilterFactory.h>
BiQuadFilterGUIFactory::BiQuadFilterGUIFactory()
{
}
QList<FilterTemplate> BiQuadFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Peaking filter"), "Filter: ON PK Fc 100 Hz Gain 0 dB Q 10.0", QStringList(tr("Parametric filters"))));
list.append(FilterTemplate(tr("Low-pass filter"), "Filter: ON LP Fc 100 Hz", QStringList(tr("Parametric filters"))));
list.append(FilterTemplate(tr("High-pass filter"), "Filter: ON LP Fc 100 Hz", QStringList(tr("Parametric filters"))));
list.append(FilterTemplate(tr("Band-pass filter"), "Filter: ON BP Fc 100 Hz Q 10.0", QStringList(tr("Parametric filters"))));
list.append(FilterTemplate(tr("Low-shelf filter"), "Filter: ON LS Fc 100 Hz Gain 0 dB", QStringList(tr("Parametric filters"))));
list.append(FilterTemplate(tr("High-shelf filter"), "Filter: ON HS Fc 100 Hz Gain 0 dB", QStringList(tr("Parametric filters"))));
list.append(FilterTemplate(tr("Notch filter"), "Filter: ON NO Fc 100 Hz", QStringList(tr("Parametric filters"))));
list.append(FilterTemplate(tr("All-pass filter"), "Filter: ON AP Fc 100 Hz Q 10.0", QStringList(tr("Parametric filters"))));
return list;
}
IFilterGUI* BiQuadFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
BiQuadFilterGUI* result = NULL;
if(command.startsWith("Filter"))
{
BiQuadFilterFactory factory;
std::vector<IFilter*> filters = factory.createFilter(L"", command.toStdWString(), parameters.toStdWString());
if(!filters.empty())
{
BiQuadFilter* filter = (BiQuadFilter*)filters[0];
result = new BiQuadFilterGUI(filter);
}
for(IFilter* f : filters)
{
f->~IFilter();
MemoryHelper::free(f);
}
}
return result;
}
+33
View File
@@ -0,0 +1,33 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class BiQuadFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
explicit BiQuadFilterGUIFactory();
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
};
+86
View File
@@ -0,0 +1,86 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "ChannelFilterGUI.h"
#include "ChannelFilterGUIDialog.h"
#include "ui_ChannelFilterGUI.h"
using namespace std;
ChannelFilterGUI::ChannelFilterGUI(const QString& parameters, int selectedChannelMask) :
ui(new Ui::ChannelFilterGUI)
{
ui->setupUi(this);
this->selectedChannelMask = selectedChannelMask;
scene = new ChannelFilterGUIScene;
ui->graphicsView->setScene(scene);
ui->graphicsView->setBackgroundRole(QPalette::Window);
connect(scene, SIGNAL(selectionChanged()), this, SLOT(updateSelectedChannels()));
selectedChannels.clear();
QStringList words = parameters.trimmed().split(' ', QString::SkipEmptyParts);
for(QString word : words)
if(word.length() > 0)
selectedChannels.append(word.toUpper());
}
ChannelFilterGUI::~ChannelFilterGUI()
{
delete ui;
}
void ChannelFilterGUI::configureChannels(vector<wstring>& channelNames)
{
this->channelNames = channelNames;
refreshGui();
}
void ChannelFilterGUI::store(QString& command, QString& parameters)
{
command = "Channel";
selectedChannels = scene->getSelectedChannels();
parameters = selectedChannels.join(' ');
}
void ChannelFilterGUI::on_pushButton_clicked()
{
ChannelFilterGUIDialog dialog(this, selectedChannels, selectedChannelMask, channelNames);
if(dialog.exec() == QDialog::Accepted)
{
selectedChannels = dialog.getSelectedChannels();
refreshGui();
emit updateModel();
}
}
void ChannelFilterGUI::updateSelectedChannels()
{
selectedChannels = scene->getSelectedChannels();
updateModel();
}
void ChannelFilterGUI::refreshGui()
{
scene->load(channelNames, selectedChannels);
}
+51
View File
@@ -0,0 +1,51 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
#include "ChannelFilterGUIScene.h"
namespace Ui {
class ChannelFilterGUI;
}
class ChannelFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit ChannelFilterGUI(const QString& parameters, int selectedChannelMask);
~ChannelFilterGUI();
void configureChannels(std::vector<std::wstring>& channelNames) override;
void store(QString& command, QString& parameters) override;
private slots:
void on_pushButton_clicked();
void updateSelectedChannels();
private:
void refreshGui();
Ui::ChannelFilterGUI *ui;
QStringList selectedChannels;
int selectedChannelMask;
std::vector<std::wstring> channelNames;
ChannelFilterGUIScene* scene;
};
+81
View File
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChannelFilterGUI</class>
<widget class="QWidget" name="ChannelFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>529</width>
<height>44</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1" rowspan="2">
<widget class="QGraphicsView" name="graphicsView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="renderHints">
<set>QPainter::Antialiasing|QPainter::TextAntialiasing</set>
</property>
<property name="dragMode">
<enum>QGraphicsView::RubberBandDrag</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Change...</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Selected channels:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,46 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <QPainter>
#include "ChannelFilterGUIScene.h"
#include "ChannelFilterGUIChannelItem.h"
ChannelFilterGUIChannelItem::ChannelFilterGUIChannelItem(const QString& name) :
ChannelGraphItem(name)
{
setFlag(ItemIsSelectable);
}
void ChannelFilterGUIChannelItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
QColor color;
if(isSelected())
{
color = QColor(176, 229, 255);
}
else
{
painter->setPen(QColor(156, 156, 156));
color = QColor(204, 204, 204);
}
ChannelGraphItem::paint(painter, color);
}
+36
View File
@@ -0,0 +1,36 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/widgets/ChannelGraphItem.h"
class ChannelFilterGUIChannelItem : public ChannelGraphItem
{
public:
ChannelFilterGUIChannelItem(const QString& name);
enum { Type = UserType + 2 };
virtual int type() const
{
return Type;
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
};
+180
View File
@@ -0,0 +1,180 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <algorithm>
#include <Ks.h>
#include <KsMedia.h>
#include "Editor/helpers/GUIChannelHelper.h"
#include "ChannelFilterGUIDialog.h"
#include "ui_ChannelFilterGUIDialog.h"
#define PROPERTY_POSITION "CHANNEL_POSITION"
#define PROPERTY_NAME "CHANNEL_NAME"
using namespace std;
ChannelFilterGUIDialog::ChannelFilterGUIDialog(QWidget *parent, QStringList selectedChannels, int selectedChannelMask, const vector<wstring>& channelNames) :
QDialog(parent),
ui(new Ui::ChannelFilterGUIDialog)
{
ui->setupUi(this);
ui->centerCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_FRONT_CENTER);
ui->leftCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_FRONT_LEFT);
ui->rightCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_FRONT_RIGHT);
ui->sideLeftCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_SIDE_LEFT);
ui->sideRightCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_SIDE_RIGHT);
ui->rearLeftCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_BACK_LEFT);
ui->rearRightCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_BACK_RIGHT);
ui->rearCenterCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_BACK_CENTER);
ui->subWooferCheckBox->setProperty(PROPERTY_POSITION, SPEAKER_LOW_FREQUENCY);
ui->centerCheckBox->setProperty(PROPERTY_NAME, "C");
ui->leftCheckBox->setProperty(PROPERTY_NAME, "L");
ui->rightCheckBox->setProperty(PROPERTY_NAME, "R");
ui->sideLeftCheckBox->setProperty(PROPERTY_NAME, "SL");
ui->sideRightCheckBox->setProperty(PROPERTY_NAME, "SR");
ui->rearLeftCheckBox->setProperty(PROPERTY_NAME, "RL");
ui->rearRightCheckBox->setProperty(PROPERTY_NAME, "RR");
ui->rearCenterCheckBox->setProperty(PROPERTY_NAME, "RC");
ui->subWooferCheckBox->setProperty(PROPERTY_NAME, "SUB");
checkBoxes.append(ui->centerCheckBox);
checkBoxes.append(ui->leftCheckBox);
checkBoxes.append(ui->rightCheckBox);
checkBoxes.append(ui->sideLeftCheckBox);
checkBoxes.append(ui->sideRightCheckBox);
checkBoxes.append(ui->rearLeftCheckBox);
checkBoxes.append(ui->rearRightCheckBox);
checkBoxes.append(ui->rearCenterCheckBox);
checkBoxes.append(ui->subWooferCheckBox);
vector<wstring> remainingChannelNames = channelNames;
QStringList remainingSelectedChannels = selectedChannels;
if(selectedChannels.contains("ALL"))
{
ui->allChannelsCheckBox->setChecked(true);
remainingSelectedChannels.clear();
}
int channelIndex = 0;
for(QCheckBox* checkBox : checkBoxes)
{
int channelPos = checkBox->property(PROPERTY_POSITION).toInt();
QString channelName = checkBox->property(PROPERTY_NAME).toString();
bool exists = selectedChannelMask & channelPos;
checkBox->setVisible(exists);
if(exists)
{
channelIndex++;
bool checked = false;
remainingChannelNames.erase(remove(remainingChannelNames.begin(), remainingChannelNames.end(), channelName.toStdWString()), remainingChannelNames.end());
if(remainingSelectedChannels.removeOne(channelName))
checked = true;
if(remainingSelectedChannels.removeOne(QString(channelIndex)))
checked = true;
checkBox->setChecked(checked);
}
else
{
checkBox->setChecked(false);
}
}
ui->listWidget->clear();
for(wstring channelName : remainingChannelNames)
{
QListWidgetItem* item = new QListWidgetItem(QString::fromStdWString(channelName));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
if(remainingSelectedChannels.removeOne(QString::fromStdWString(channelName)))
item->setCheckState(Qt::Checked);
else
item->setCheckState(Qt::Unchecked);
ui->listWidget->addItem(item);
}
for(QString c : remainingSelectedChannels)
{
QListWidgetItem* item = new QListWidgetItem(c);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Checked);
ui->listWidget->addItem(item);
}
ui->stackedWidget->setCurrentIndex(selectedChannelMask & SPEAKER_BACK_CENTER ? 1 : 0);
}
ChannelFilterGUIDialog::~ChannelFilterGUIDialog()
{
delete ui;
}
void ChannelFilterGUIDialog::on_addButton_clicked()
{
QListWidgetItem* item = new QListWidgetItem("");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Checked);
ui->listWidget->addItem(item);
ui->listWidget->editItem(item);
}
void ChannelFilterGUIDialog::on_removeButton_clicked()
{
qDeleteAll(ui->listWidget->selectedItems());
}
QStringList ChannelFilterGUIDialog::getSelectedChannels() const
{
QStringList selectedChannels;
if(ui->allChannelsCheckBox->isChecked())
{
selectedChannels.append("ALL");
}
else
{
for(QCheckBox* checkBox : checkBoxes)
{
if(checkBox->isChecked())
{
QString channelName = checkBox->property(PROPERTY_NAME).toString();
selectedChannels.append(channelName);
}
}
for(int i = 0; i < ui->listWidget->count(); i++)
{
QListWidgetItem* item = ui->listWidget->item(i);
if(item->checkState() == Qt::Checked)
{
QString text = item->text().trimmed();
if(text.length() > 0)
selectedChannels.append(text.toUpper());
}
}
}
return selectedChannels;
}
void ChannelFilterGUIDialog::on_allChannelsCheckBox_toggled(bool checked)
{
ui->positionsGroupBox->setEnabled(!checked);
ui->additionalChannelsGroupBox->setEnabled(!checked);
}
+49
View File
@@ -0,0 +1,49 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <QCheckBox>
#include <QDialog>
namespace Ui {
class ChannelFilterGUIDialog;
}
class ChannelFilterGUIDialog : public QDialog
{
Q_OBJECT
public:
explicit ChannelFilterGUIDialog(QWidget *parent, QStringList selectedChannels, int selectedChannelMask, const std::vector<std::wstring>& channelNames);
~ChannelFilterGUIDialog();
QStringList getSelectedChannels() const;
private slots:
void on_addButton_clicked();
void on_removeButton_clicked();
void on_allChannelsCheckBox_toggled(bool checked);
private:
Ui::ChannelFilterGUIDialog *ui;
QList<QCheckBox*> checkBoxes;
};
+302
View File
@@ -0,0 +1,302 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChannelFilterGUIDialog</class>
<widget class="QDialog" name="ChannelFilterGUIDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>355</width>
<height>329</height>
</rect>
</property>
<property name="windowTitle">
<string>Channel selection</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="allChannelsCheckBox">
<property name="text">
<string>Select all channels</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="positionsGroupBox">
<property name="title">
<string>Speaker positions</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="2">
<widget class="QCheckBox" name="sideRightCheckBox">
<property name="text">
<string>SR (Side right)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="centerCheckBox">
<property name="text">
<string>C (Center)</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="subWooferCheckBox">
<property name="text">
<string>SUB (Subwoofer)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="leftCheckBox">
<property name="text">
<string>L (Left)</string>
</property>
</widget>
</item>
<item row="4" column="0" rowspan="2" colspan="3">
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="rearLeftCheckBox">
<property name="text">
<string>RL (Rear left)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="rearRightCheckBox">
<property name="text">
<string>RR (Rear right)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="rearCenterCheckBox">
<property name="text">
<string>RC (Rear center)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="sideLeftCheckBox">
<property name="text">
<string>SL (Side left)</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="rightCheckBox">
<property name="text">
<string>R (Right)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="additionalChannelsGroupBox">
<property name="title">
<string>Additional channels</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="2">
<widget class="QToolButton" name="removeButton">
<property name="text">
<string>Remove channel</string>
</property>
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/list-remove-red.png</normaloff>:/icons/16x16/list-remove-red.png</iconset>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QToolButton" name="addButton">
<property name="text">
<string>Add channel</string>
</property>
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/list-add-green.png</normaloff>:/icons/16x16/list-add-green.png</iconset>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="3">
<widget class="QListWidget" name="listWidget">
<property name="editTriggers">
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../Editor.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ChannelFilterGUIDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>303</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ChannelFilterGUIDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>303</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+50
View File
@@ -0,0 +1,50 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "Editor/FilterTable.h"
#include "ChannelFilterGUI.h"
#include "ChannelFilterGUIFactory.h"
ChannelFilterGUIFactory::ChannelFilterGUIFactory()
{
}
void ChannelFilterGUIFactory::initialize(FilterTable* filterTable)
{
this->filterTable = filterTable;
}
QList<FilterTemplate> ChannelFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Channel (Select channels)"), "Channel: all", QStringList(tr("Control"))));
return list;
}
IFilterGUI* ChannelFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
ChannelFilterGUI* result = NULL;
if(command == "Channel")
{
result = new ChannelFilterGUI(parameters, filterTable->getSelectedChannelMask());
}
return result;
}
+39
View File
@@ -0,0 +1,39 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "DeviceAPOInfo.h"
#include "Editor/IFilterGUIFactory.h"
class ChannelFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
ChannelFilterGUIFactory();
void initialize(FilterTable* filterTable) override;
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
private:
FilterTable* filterTable;
};
+88
View File
@@ -0,0 +1,88 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "ChannelFilterGUIChannelItem.h"
#include "ChannelFilterGUIScene.h"
using namespace std;
ChannelFilterGUIScene::ChannelFilterGUIScene()
{
}
void ChannelFilterGUIScene::load(vector<wstring> channelNames, QStringList selectedChannels)
{
blockSignals(true);
clear();
QHash<QString, ChannelFilterGUIChannelItem*> channelMap;
QGraphicsItem* lastItem = NULL;
channelNames.push_back(L"ALL");
for(unsigned i = 0; i < channelNames.size(); i++)
{
QString c = QString::fromStdWString(channelNames[i]);
ChannelFilterGUIChannelItem* item = new ChannelFilterGUIChannelItem(c);
item->setPos(getNextChannelPoint(lastItem, false));
addItem(item);
channelMap.insert(c, item);
if(c != "ALL")
channelMap.insert(QString().setNum(i), item);
lastItem = item;
}
for(QString c : selectedChannels)
{
ChannelFilterGUIChannelItem* item = channelMap.value(c.toUpper());
if(item == NULL)
{
item = new ChannelFilterGUIChannelItem(c);
item->setPos(getNextChannelPoint(lastItem, false));
addItem(item);
channelMap.insert(c, item);
lastItem = item;
}
item->setSelected(true);
}
setSceneRect(itemsBoundingRect().marginsAdded(QMarginsF(2, 2, 2, 2)));
blockSignals(false);
}
QStringList ChannelFilterGUIScene::getSelectedChannels()
{
QStringList selectedChannels;
for(QGraphicsItem* item : items(Qt::AscendingOrder))
{
ChannelFilterGUIChannelItem* channelItem = qgraphicsitem_cast<ChannelFilterGUIChannelItem*>(item);
if(channelItem != NULL)
{
if(channelItem->isSelected())
selectedChannels.append(channelItem->getName());
}
}
return selectedChannels;
}
+35
View File
@@ -0,0 +1,35 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <string>
#include <vector>
#include "Editor/widgets/ChannelGraphScene.h"
class ChannelFilterGUIScene : public ChannelGraphScene
{
Q_OBJECT
public:
explicit ChannelFilterGUIScene();
void load(std::vector<std::wstring> channelNames, QStringList selectedChannels);
QStringList getSelectedChannels();
};
+77
View File
@@ -0,0 +1,77 @@
/*
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 "CommentFilterGUI.h"
#include "ui_CommentFilterGUI.h"
using namespace std;
CommentFilterGUI::CommentFilterGUI(IFilterGUI* child, bool isComment)
{
ui = new Ui::CommentFilterGUI;
ui->setupUi(this);
this->child = child;
connect(child, SIGNAL(updateModel()), this, SIGNAL(updateModel()));
connect(child, SIGNAL(updateChannels()), this, SIGNAL(updateChannels()));
ui->horizontalLayout->removeItem(ui->horizontalSpacer);
ui->horizontalLayout->addWidget(child);
ui->actionPowerOn->setChecked(!isComment);
ui->toolBar->setIconSize(QSize(24, 24));
ui->toolBar->addAction(ui->actionPowerOn);
ui->toolBar->updateMaximumHeight();
child->setEnabled(!isComment);
}
CommentFilterGUI::~CommentFilterGUI()
{
delete ui;
}
void CommentFilterGUI::configureChannels(vector<wstring>& channelNames)
{
if(ui->actionPowerOn->isChecked())
{
child->configureChannels(channelNames);
}
else
{
// prevent modification of channel names
vector<wstring> copy = channelNames;
child->configureChannels(copy);
}
}
void CommentFilterGUI::store(QString& command, QString& parameters)
{
child->store(command, parameters);
if(!ui->actionPowerOn->isChecked())
command = "# " + command;
}
void CommentFilterGUI::on_actionPowerOn_toggled(bool checked)
{
child->setEnabled(checked);
emit updateModel();
}
+45
View File
@@ -0,0 +1,45 @@
/*
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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
namespace Ui
{
class CommentFilterGUI;
}
class CommentFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit CommentFilterGUI(IFilterGUI* child, bool isComment);
~CommentFilterGUI();
void configureChannels(std::vector<std::wstring>& channelNames) override;
void store(QString& command, QString& parameters) override;
private slots:
void on_actionPowerOn_toggled(bool checked);
private:
Ui::CommentFilterGUI* ui;
IFilterGUI* child;
};
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CommentFilterGUI</class>
<widget class="QWidget" name="CommentFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>104</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="CompactToolBar" name="toolBar" native="true"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>379</width>
<height>37</height>
</size>
</property>
</spacer>
</item>
</layout>
<action name="actionPowerOn">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/power_off.png</normaloff>
<normalon>:/icons/power_on.png</normalon>:/icons/power_off.png</iconset>
</property>
<property name="text">
<string>Power on</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>CompactToolBar</class>
<extends>QWidget</extends>
<header>Editor/widgets/CompactToolBar.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../Editor.qrc"/>
</resources>
<connections/>
</ui>
+51
View File
@@ -0,0 +1,51 @@
/*
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 "helpers/StringHelper.h"
#include "CommentFilterGUI.h"
#include "CommentFilterGUIFactory.h"
using namespace std;
CommentFilterGUIFactory::CommentFilterGUIFactory()
{
}
QList<FilterTemplate> CommentFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Comment"), "# ", QStringList()));
return list;
}
IFilterGUI* CommentFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
lastWasComment = command.length() > 0 && command[0] == '#';
if(lastWasComment)
command = command.mid(1).trimmed();
return NULL;
}
IFilterGUI* CommentFilterGUIFactory::decorateFilterGUI(IFilterGUI* gui)
{
gui = new CommentFilterGUI(gui, lastWasComment);
return gui;
}
+38
View File
@@ -0,0 +1,38 @@
/*
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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class CommentFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
CommentFilterGUIFactory();
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
IFilterGUI* decorateFilterGUI(IFilterGUI* gui) override;
private:
bool lastWasComment;
};
+137
View File
@@ -0,0 +1,137 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <QFileDialog>
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
#include <sndfile.h>
#include "ConvolutionFilterGUI.h"
#include "ui_ConvolutionFilterGUI.h"
ConvolutionFilterGUI::ConvolutionFilterGUI(const QString& configPath, unsigned deviceSampleRate, const QString& path) :
ui(new Ui::ConvolutionFilterGUI), deviceSampleRate(deviceSampleRate)
{
ui->setupUi(this);
this->configPath = configPath;
ui->pathLineEdit->setText(path);
updateFileInfo();
}
ConvolutionFilterGUI::~ConvolutionFilterGUI()
{
delete ui;
}
void ConvolutionFilterGUI::store(QString& command, QString& parameters)
{
command = "Convolution";
parameters = ui->pathLineEdit->text();
}
void ConvolutionFilterGUI::on_selectFileToolButton_clicked()
{
QFileInfo fileInfo(configPath);
QDir configDir = fileInfo.absoluteDir();
QString path = ui->pathLineEdit->text();
if(path.length() > 0)
fileInfo.setFile(configDir, path);
QFileDialog dialog(this, tr("Select impulse response file"), fileInfo.absolutePath(), "*.wav;*.flac;*.ogg");
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("Impulse response (*.wav *.flac *.ogg)"));
if(path.length() > 0)
dialog.selectFile(fileInfo.fileName());
if(dialog.exec() == QDialog::Accepted)
{
QString absolutePath = dialog.selectedFiles().first();
QString relativePath = configDir.relativeFilePath(absolutePath);
if(relativePath.startsWith("../../"))
relativePath = absolutePath;
ui->pathLineEdit->setText(QDir::toNativeSeparators(relativePath));
updateFileInfo();
emit updateModel();
}
}
void ConvolutionFilterGUI::on_pathLineEdit_editingFinished()
{
updateFileInfo();
emit updateModel();
}
void ConvolutionFilterGUI::updateFileInfo()
{
bool labelsVisible = true;
QString error = "";
QString path = ui->pathLineEdit->text();
if(path.length() == 0)
{
error = tr("No file selected");
labelsVisible = false;
}
else
{
QFileInfo fileInfo(configPath);
QDir configDir = fileInfo.absoluteDir();
fileInfo.setFile(configDir, path);
if(!fileInfo.exists())
{
error = tr("File not found");
labelsVisible = false;
}
else
{
path = fileInfo.absoluteFilePath();
SF_INFO info;
SNDFILE* file = sf_wchar_open(path.toStdWString().c_str(), SFM_READ, &info);
if(file == NULL)
{
error = tr("Unsupported file format");
labelsVisible = false;
}
else
{
int sampleRate = info.samplerate;
double length = info.frames * 1000.0 / sampleRate;
ui->labelLengthValue->setText(tr("%0 ms (%1 samples)").arg(length).arg(info.frames));
ui->labelSampleRateValue->setText(tr("%0 Hz").arg(sampleRate));
sf_close(file);
if(sampleRate != deviceSampleRate)
{
error = tr("The file sample rate does not match the device sample rate (%0 Hz)!\nSelect a different file or change the device configuration.").arg(deviceSampleRate);
}
}
}
}
ui->labelLength->setVisible(labelsVisible);
ui->labelLengthValue->setVisible(labelsVisible);
ui->labelSampleRate->setVisible(labelsVisible);
ui->labelSampleRateValue->setVisible(labelsVisible);
ui->labelError->setVisible(error.length() > 0);
ui->labelError->setText(error);
}
+49
View File
@@ -0,0 +1,49 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
namespace Ui {
class ConvolutionFilterGUI;
}
class ConvolutionFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit ConvolutionFilterGUI(const QString& configPath, unsigned deviceSampleRate, const QString& path);
~ConvolutionFilterGUI();
void store(QString& command, QString& parameters) override;
private slots:
void on_selectFileToolButton_clicked();
void on_pathLineEdit_editingFinished();
private:
void updateFileInfo();
Ui::ConvolutionFilterGUI *ui;
QString configPath;
unsigned deviceSampleRate;
};
+173
View File
@@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConvolutionFilterGUI</class>
<widget class="QWidget" name="ConvolutionFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>652</width>
<height>65</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,1">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="2">
<widget class="QToolButton" name="selectFileToolButton">
<property name="text">
<string>Select file</string>
</property>
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/document-open.png</normaloff>:/icons/16x16/document-open.png</iconset>
</property>
</widget>
</item>
<item row="0" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>123</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="convolutionLabel">
<property name="text">
<string>Convolution with impulse response:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ResizingLineEdit" name="pathLineEdit"/>
</item>
<item row="0" column="3">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>File information</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="3">
<widget class="QLabel" name="labelSampleRate">
<property name="text">
<string>Sample rate:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelLengthValue">
<property name="text">
<string>No file selected</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="5">
<widget class="QLabel" name="labelError">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelLength">
<property name="text">
<string>Length:</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="labelSampleRateValue">
<property name="text">
<string>No file selected</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ResizingLineEdit</class>
<extends>QLineEdit</extends>
<header>Editor/widgets/ResizingLineEdit.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../Editor.qrc"/>
</resources>
<connections/>
</ui>
@@ -0,0 +1,56 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "DeviceAPOInfo.h"
#include "Editor/FilterTable.h"
#include "ConvolutionFilterGUI.h"
#include "ConvolutionFilterGUIFactory.h"
ConvolutionFilterGUIFactory::ConvolutionFilterGUIFactory()
{
}
void ConvolutionFilterGUIFactory::initialize(FilterTable* filterTable)
{
deviceSampleRate = filterTable->getSelectedDevice()->sampleRate;
}
QList<FilterTemplate> ConvolutionFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Convolution (Convolution with impulse response)"), "Convolution:", QStringList(tr("Advanced filters"))));
return list;
}
void ConvolutionFilterGUIFactory::startOfFile(const QString& configPath)
{
this->configPath = configPath;
}
IFilterGUI* ConvolutionFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
ConvolutionFilterGUI* result = NULL;
if(command == "Convolution")
{
result = new ConvolutionFilterGUI(configPath, deviceSampleRate, parameters.trimmed());
}
return result;
}
+40
View File
@@ -0,0 +1,40 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class ConvolutionFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
explicit ConvolutionFilterGUIFactory();
void initialize(FilterTable* filterTable) override;
QList<FilterTemplate> createFilterTemplates() override;
void startOfFile(const QString& configPath) override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
private:
QString configPath;
unsigned deviceSampleRate;
};
+151
View File
@@ -0,0 +1,151 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "helpers/ChannelHelper.h"
#include "CopyFilterGUIForm.h"
#include "CopyFilterGUI.h"
#include "ui_CopyFilterGUI.h"
using namespace std;
CopyFilterGUI::CopyFilterGUI(CopyFilter* filter) :
ui(new Ui::CopyFilterGUI)
{
ui->setupUi(this);
scene = new CopyFilterGUIScene;
ui->graphicsView->setScene(scene);
ui->graphicsView->setBackgroundRole(QPalette::Window);
ui->form->load(filter->getAssignments());
connect(scene, SIGNAL(updateModel()), this, SIGNAL(updateModel()));
connect(scene, SIGNAL(updateChannels()), this, SIGNAL(updateChannels()));
connect(ui->form, SIGNAL(updateModel()), this, SIGNAL(updateModel()));
connect(ui->form, SIGNAL(updateChannels()), this, SIGNAL(updateChannels()));
}
CopyFilterGUI::~CopyFilterGUI()
{
delete ui;
}
void CopyFilterGUI::configureChannels(vector<wstring>& channelNames)
{
vector<Assignment> assignments = ui->form->buildAssignments();
if(channelNames != inputChannelNames)
{
inputChannelNames = channelNames;
scene->load(inputChannelNames, assignments);
ui->form->setChannelNames(channelNames);
}
for(Assignment assignment : assignments)
{
if(assignment.targetChannel == L"")
continue;
bool hasSummand = false;
for(Assignment::Summand summand : assignment.sourceSum)
{
if(summand.channel != L" ")
{
hasSummand = true;
break;
}
}
if(!hasSummand)
continue;
int channelIndex = ChannelHelper::getChannelIndex(assignment.targetChannel, channelNames, true);
if(channelIndex == -1)
channelNames.push_back(assignment.targetChannel);
}
}
void CopyFilterGUI::store(QString& command, QString& parameters)
{
command = "Copy";
std::vector<Assignment> assignments;
if(ui->tabWidget->currentIndex() == 0)
assignments = scene->buildAssignments();
else
assignments = ui->form->buildAssignments();
bool firstAssignment = true;
for(const Assignment& assignment : assignments)
{
if(assignment.targetChannel == L"")
continue;
bool firstSummand = true;
for(const Assignment::Summand& summand : assignment.sourceSum)
{
// skip not yet filled row
if(summand.channel == L" ")
continue;
if(firstSummand)
{
firstSummand = false;
if(firstAssignment)
firstAssignment = false;
else
parameters += " ";
parameters += QString::fromStdWString(assignment.targetChannel);
parameters += "=";
}
else
{
parameters += "+";
}
bool hasChannel = summand.channel != L"";
bool hasFactor = !hasChannel || summand.factor != 1.0 || summand.isDecibel;
if(hasFactor)
{
QString factorString;
factorString.setNum(summand.factor);
if(factorString != "0" && !factorString.contains('.'))
factorString += ".0";
parameters += factorString;
if(summand.isDecibel)
parameters += "dB";
}
if(hasFactor && hasChannel)
parameters += "*";
if(hasChannel)
parameters += QString::fromStdWString(summand.channel);
}
if(ui->tabWidget->currentIndex() == 0)
ui->form->load(assignments);
else
scene->load(inputChannelNames, assignments);
}
}
+47
View File
@@ -0,0 +1,47 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "filters/CopyFilter.h"
#include "Editor/IFilterGUI.h"
#include "CopyFilterGUIScene.h"
namespace Ui {
class CopyFilterGUI;
}
class CopyFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit CopyFilterGUI(CopyFilter* filter);
~CopyFilterGUI();
void configureChannels(std::vector<std::wstring>& channelNames) override;
void store(QString& command, QString& parameters) override;
private:
Ui::CopyFilterGUI *ui;
CopyFilterGUIScene* scene;
std::vector<std::wstring> inputChannelNames;
};
+170
View File
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CopyFilterGUI</class>
<widget class="QWidget" name="CopyFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>488</width>
<height>94</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="copyLabel">
<property name="text">
<string>Copy channels:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QTabWidget" name="tabWidget">
<property name="tabPosition">
<enum>QTabWidget::East</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="elideMode">
<enum>Qt::ElideRight</enum>
</property>
<property name="usesScrollButtons">
<bool>false</bool>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/applications-graphics-rotated.png</normaloff>:/icons/16x16/applications-graphics-rotated.png</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Graph</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="renderHints">
<set>QPainter::Antialiasing|QPainter::TextAntialiasing</set>
</property>
<property name="dragMode">
<enum>QGraphicsView::RubberBandDrag</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/format-justify-fill-rotated.png</normaloff>:/icons/16x16/format-justify-fill-rotated.png</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Assignments</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="CopyFilterGUIForm" name="form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>366</width>
<height>92</height>
</rect>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="spaceReserveLabel">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Selected channels:</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CopyFilterGUIForm</class>
<extends>QWidget</extends>
<header>CopyFilterGUIForm.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../Editor.qrc"/>
</resources>
<connections/>
</ui>
+168
View File
@@ -0,0 +1,168 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <QGraphicsScene>
#include "CopyFilterGUIScene.h"
#include "CopyFilterGUIChannelItem.h"
CopyFilterGUIChannelItem::CopyFilterGUIChannelItem(const QString& name, bool output) :
ChannelGraphItem(name), output(output)
{
setZValue(-1);
}
void CopyFilterGUIChannelItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
QColor color;
if(output)
color = QColor(255, 194, 194);
else
color = QColor(176, 255, 176);
ChannelGraphItem::paint(painter, color) ;
}
QPointF CopyFilterGUIChannelItem::getPerimeterPointTo(QPointF oppositePoint)
{
QRectF rect = boundingRect();
if(output)
return scenePos() + QPointF(rect.center().x(), rect.top());
else
return scenePos() + QPointF(rect.center().x(), rect.top() + rect.height());
}
CopyFilterGUIChannelItem* CopyFilterGUIChannelItem::findAt(QPointF mousePos)
{
CopyFilterGUIChannelItem* result = NULL;
QList<QGraphicsItem*> items = scene()->items(mousePos);
for(QGraphicsItem* item : items)
{
CopyFilterGUIChannelItem* channelItem = qgraphicsitem_cast<CopyFilterGUIChannelItem*>(item);
if(channelItem != NULL && channelItem->output != output)
{
result = channelItem;
break;
}
}
return result;
}
QLineF CopyFilterGUIChannelItem::getLineTo(CopyFilterGUIChannelItem* item)
{
QPointF endPoint = item->getPerimeterPointTo(scenePos());
QPointF startPoint = getPerimeterPointTo(endPoint);
QLineF line;
if(output)
line = QLineF(endPoint, startPoint);
else
line = QLineF(startPoint, endPoint);
return line;
}
void CopyFilterGUIChannelItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
}
void CopyFilterGUIChannelItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
if(currentConnection == NULL)
{
if( !boundingRect().contains(event->pos()))
{
currentConnection = new CopyFilterGUIConnectionItem();
scene()->addItem(currentConnection);
}
}
if(currentConnection != NULL)
{
CopyFilterGUIChannelItem* item = findAt(event->scenePos());
if(item == NULL)
{
QLineF line;
if(output)
line = QLineF(event->scenePos(), getPerimeterPointTo(event->scenePos()));
else
line = QLineF(getPerimeterPointTo(event->scenePos()), event->scenePos());
currentConnection->setLine(line);
}
else
{
currentConnection->setLine(getLineTo(item));
}
}
}
void CopyFilterGUIChannelItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
if(currentConnection != NULL)
{
CopyFilterGUIChannelItem* item = findAt(event->scenePos());
if(item != NULL)
{
CopyFilterGUIChannelItem* source;
CopyFilterGUIChannelItem* target;
if(output)
{
source = item;
target = this;
}
else
{
source = this;
target = item;
}
double factor = 1.0;
if(source->getName() == "")
factor = 0.0;
scene()->addItem(new CopyFilterGUIConnectionItem(source, target, factor, false));
emit ((CopyFilterGUIScene*)scene())->updateModel();
emit ((CopyFilterGUIScene*)scene())->updateChannels();
}
scene()->removeItem(currentConnection);
delete currentConnection;
currentConnection = NULL;
}
else
{
scene()->clearSelection();
QList<QGraphicsItem*> items = scene()->items();
for(QGraphicsItem* item : items)
{
CopyFilterGUIConnectionItem* connItem = qgraphicsitem_cast<CopyFilterGUIConnectionItem*>(item);
if(connItem != NULL)
{
if(connItem->getSource() == this || connItem->getTarget() == this)
connItem->setSelected(true);
}
}
}
}
+53
View File
@@ -0,0 +1,53 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include "Editor/widgets/ChannelGraphItem.h"
#include "CopyFilterGUIConnectionItem.h"
class CopyFilterGUIChannelItem : public ChannelGraphItem
{
public:
CopyFilterGUIChannelItem(const QString& name, bool output);
enum { Type = UserType + 2 };
virtual int type() const
{
return Type;
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
QPointF getPerimeterPointTo(QPointF oppositePoint);
CopyFilterGUIChannelItem* findAt(QPointF mousePos);
QLineF getLineTo(CopyFilterGUIChannelItem* item);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
private:
bool output;
CopyFilterGUIConnectionItem* currentConnection = NULL;
};
+253
View File
@@ -0,0 +1,253 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsProxyWidget>
#include <QPainter>
#include <QLineEdit>
#include "Editor/widgets/ResizingLineEdit.h"
#include "CopyFilterGUIChannelItem.h"
#include "CopyFilterGUIScene.h"
#include "CopyFilterGUIConnectionItem.h"
static const int maxArrowSize = 6;
CopyFilterGUIConnectionItem::CopyFilterGUIConnectionItem()
{
}
CopyFilterGUIConnectionItem::CopyFilterGUIConnectionItem(CopyFilterGUIChannelItem* source, CopyFilterGUIChannelItem* target, double factor, bool isDecibel)
{
this->source = source;
this->target = target;
this->factor = factor;
this->isDecibel = isDecibel;
setLine(source->getLineTo(target));
setFlag(ItemIsSelectable);
setAcceptHoverEvents(true);
}
QRectF CopyFilterGUIConnectionItem::boundingRect() const
{
QRectF rect = QGraphicsLineItem::boundingRect();
QPointF p2 = line().p2();
QRectF rect2 = QRectF(p2.x() - maxArrowSize, p2.y() - maxArrowSize, 2 * maxArrowSize, 2 * maxArrowSize);
return rect.united(rect2);
}
QPainterPath CopyFilterGUIConnectionItem::shape() const
{
QLineF l = line();
QPainterPath path;
path.setFillRule(Qt::WindingFill);
double length = line().length();
if(length > 0)
{
double offset = min(length, maxArrowSize);
QLineF unit = l.unitVector();
QLineF normal = l.normalVector().unitVector();
QPointF v(unit.dx(), unit.dy());
QPointF n(normal.dx(), normal.dy());
QPointF p2 = l.p2();
QPointF p3 = p2 - v * offset + 0.5 * n * offset;
QPointF p4 = p2 - v * offset - 0.5 * n * offset;
QPolygonF polygon;
polygon.append(p4);
polygon.append(p3);
polygon.append(p2);
path.addPolygon(polygon);
QPolygonF polygon2;
QPointF p1 = l.p1();
polygon2.append(p2 + 3 * n);
polygon2.append(p2 - 2 * n);
polygon2.append(p1 - 2 * n);
polygon2.append(p1 + 3 * n);
path.addPolygon(polygon2);
if(factor != 1.0 || isDecibel)
{
QFont font;
font.setPixelSize(10);
QPointF center = (l.p1() + l.p2()) / 2;
QString text = QString("%1").arg(factor);
if(isDecibel)
text += " dB";
QFontMetrics fontMetrics(font);
QSizeF size = fontMetrics.size(0, text);
size += QSizeF(2, 0);
QRectF rect;
rect.setSize(size);
rect.moveCenter(center);
path.addRoundedRect(rect.adjusted(-0.5, 0.5, 0.5, 0.5), 3, 3);
}
}
return path;
}
bool CopyFilterGUIConnectionItem::contains(const QPointF& point) const
{
return shape().contains(point);
}
void CopyFilterGUIConnectionItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
QLineF l = line();
if(!l.isNull())
{
painter->setBrush(Qt::black);
if(isSelected())
{
painter->setBrush(Qt::blue);
painter->setPen(QPen(Qt::blue, 1.5));
}
painter->drawLine(line());
double length = line().length();
double offset = min(length, maxArrowSize);
QLineF unit = l.unitVector();
QLineF normal = l.normalVector().unitVector();
QPointF v(unit.dx(), unit.dy());
QPointF n(normal.dx(), normal.dy());
QPointF p2 = l.p2();
QPointF p3 = p2 - v * offset + 0.5 * n * offset;
QPointF p4 = p2 - v * offset - 0.5 * n * offset;
QPolygonF polygon;
polygon.append(p2);
polygon.append(p3);
polygon.append(p4);
painter->drawPolygon(polygon);
if(factor != 1.0 || isDecibel)
{
QFont font = painter->font();
font.setPixelSize(10);
painter->setFont(font);
QPointF center = (l.p1() + l.p2()) / 2;
QString text = QString("%1").arg(factor);
if(isDecibel)
text += " dB";
QSizeF size = painter->fontMetrics().size(0, text);
size += QSizeF(2, 0);
QRectF rect;
rect.setSize(size);
rect.moveCenter(center);
painter->setBrush(Qt::white);
painter->drawRoundedRect(rect.adjusted(-0.5, 0.5, 0.5, 0.5), 3, 3);
painter->drawText(rect, Qt::AlignCenter, text);
}
}
}
void CopyFilterGUIConnectionItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
{
QString text = QString("%1").arg(factor);
if(isDecibel)
text += " dB";
ResizingLineEdit* lineEdit = new ResizingLineEdit("");
connect(lineEdit, SIGNAL(editingFinished()), this, SLOT(lineEditEditingFinished()));
QGraphicsProxyWidget* proxyItem = scene()->addWidget(lineEdit);
QLineF l = line();
QPointF center = (l.p1() + l.p2()) / 2;
QRectF rect;
rect.setSize(lineEdit->size());
rect.moveCenter(center);
proxyItem->setPos(rect.topLeft());
proxyItem->setZValue(10);
lineEdit->setFocus();
}
void CopyFilterGUIConnectionItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
setZValue(isSelected() ? 3 : 2);
}
void CopyFilterGUIConnectionItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
setZValue(isSelected() ? 1 : 0);
}
QVariant CopyFilterGUIConnectionItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
{
if(change == ItemSelectedHasChanged)
{
setZValue(isSelected() ? 1 : 0);
}
return QGraphicsItem::itemChange(change, value);
}
void CopyFilterGUIConnectionItem::lineEditEditingFinished()
{
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(QObject::sender());
// might be called twice
if(!lineEdit->isVisible())
return;
QString text = lineEdit->text();
text.replace(',', '.');
bool ok = false;
int lengthBefore = text.length();
text.replace("db", "", Qt::CaseInsensitive);
double value = text.toDouble(&ok);
if(ok)
{
factor = value;
isDecibel = text.length() < lengthBefore;
}
lineEdit->setVisible(false);
lineEdit->deleteLater();
emit ((CopyFilterGUIScene*)scene())->updateModel();
}
CopyFilterGUIChannelItem* CopyFilterGUIConnectionItem::getSource() const
{
return source;
}
CopyFilterGUIChannelItem* CopyFilterGUIConnectionItem::getTarget() const
{
return target;
}
double CopyFilterGUIConnectionItem::getFactor() const
{
return factor;
}
bool CopyFilterGUIConnectionItem::getIsDecibel() const
{
return isDecibel;
}
+64
View File
@@ -0,0 +1,64 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <QGraphicsLineItem>
class CopyFilterGUIChannelItem;
class CopyFilterGUIConnectionItem : public QObject, public QGraphicsLineItem
{
Q_OBJECT
public:
CopyFilterGUIConnectionItem();
CopyFilterGUIConnectionItem(CopyFilterGUIChannelItem* source, CopyFilterGUIChannelItem* target, double factor, bool isDecibel);
enum { Type = UserType + 1 };
virtual int type() const
{
return Type;
}
QRectF boundingRect() const override;
QPainterPath shape() const override;
bool contains(const QPointF& point) const override;
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
CopyFilterGUIChannelItem* getSource() const;
CopyFilterGUIChannelItem* getTarget() const;
double getFactor() const;
bool getIsDecibel() const;
protected:
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) override;
void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
QVariant itemChange(GraphicsItemChange change, const QVariant& value) override;
private slots:
void lineEditEditingFinished();
private:
CopyFilterGUIChannelItem* source = NULL;
CopyFilterGUIChannelItem* target = NULL;
double factor = 1.0;
bool isDecibel = false;
};
+58
View File
@@ -0,0 +1,58 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "filters/CopyFilter.h"
#include "filters/CopyFilterFactory.h"
#include "CopyFilterGUI.h"
#include "CopyFilterGUIFactory.h"
CopyFilterGUIFactory::CopyFilterGUIFactory()
{
}
QList<FilterTemplate> CopyFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Copy (Copy between channels)"), "Copy: ", QStringList(tr("Basic filters"))));
return list;
}
IFilterGUI* CopyFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
CopyFilterGUI* result = NULL;
if(command == "Copy")
{
CopyFilterFactory factory;
std::vector<IFilter*> filters = factory.createFilter(L"", command.toStdWString(), parameters.toStdWString());
if(!filters.empty())
{
CopyFilter* filter = (CopyFilter*)filters[0];
result = new CopyFilterGUI(filter);
}
for(IFilter* f : filters)
{
f->~IFilter();
MemoryHelper::free(f);
}
}
return result;
}
+33
View File
@@ -0,0 +1,33 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class CopyFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
CopyFilterGUIFactory();
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
};
+236
View File
@@ -0,0 +1,236 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <algorithm>
#include <QComboBox>
#include <QDoubleSpinBox>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
#include "CopyFilterGUIRow.h"
#include "CopyFilterGUIForm.h"
using namespace std;
CopyFilterGUIForm::CopyFilterGUIForm(QWidget *parent) :
QWidget(parent)
{
}
void CopyFilterGUIForm::load(vector<Assignment> assignments)
{
if(gridLayout != NULL)
delete gridLayout;
for(QObject* object : children())
{
QWidget* widget = qobject_cast<QWidget*>(object);
if(widget != NULL)
widget->setVisible(false);
object->deleteLater();
}
gridLayout = new QGridLayout(this);
gridLayout->setContentsMargins(2, 2, 2, 2);
gridLayout->setHorizontalSpacing(2);
gridLayout->setVerticalSpacing(2);
gridLayout->setColumnStretch(4, 1);
gridLayout->setColumnStretch(5, 1);
int row = 0;
for(Assignment assignment : assignments)
{
QString oc = QString::fromStdWString(assignment.targetChannel);
bool firstSummand = true;
for(Assignment::Summand summand : assignment.sourceSum)
{
if(firstSummand)
{
gridLayout->addWidget(new QLabel(tr("Channel"), this), row, 0);
QComboBox* targetComboBox = new QComboBox(this);
targetComboBox->setEditable(true);
for(wstring channelName : inputChannelNames)
targetComboBox->addItem(QString::fromStdWString(channelName));
targetComboBox->setEditText(oc);
connect(targetComboBox, SIGNAL(editTextChanged(QString)), this, SIGNAL(updateModel()));
connect(targetComboBox, SIGNAL(editTextChanged(QString)), this, SIGNAL(updateChannels()));
gridLayout->addWidget(targetComboBox, row, 1);
gridLayout->addWidget(new QLabel("=", this), row, 2);
firstSummand = false;
}
else
{
gridLayout->addWidget(new QLabel("+", this), row, 2);
}
CopyFilterGUIRow* rowWidget = new CopyFilterGUIRow(summand, inputChannelNames, this);
connect(rowWidget, SIGNAL(updateModel()), this, SIGNAL(updateModel()));
connect(rowWidget, SIGNAL(updateChannels()), this, SIGNAL(updateChannels()));
gridLayout->addWidget(rowWidget, row, 3);
QPushButton* addSummandButton = new QPushButton(this);
addSummandButton->setText(tr("Add summand"));
addSummandButton->setIcon(QIcon(":/icons/16x16/list-add-green.png"));
gridLayout->addWidget(addSummandButton, row, 4);
connect(addSummandButton, SIGNAL(pressed()), this, SLOT(addSummand()));
QPushButton* removeButton = new QPushButton(this);
if(assignment.sourceSum.size() == 1)
removeButton->setText(tr("Remove assignment"));
else
removeButton->setText(tr("Remove summand"));
removeButton->setIcon(QIcon(":/icons/16x16/list-remove-red.png"));
gridLayout->addWidget(removeButton, row, 5);
connect(removeButton, SIGNAL(pressed()), this, SLOT(remove()));
QSpacerItem* spacerItem = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout->addItem(spacerItem, row, 6);
row++;
}
}
QPushButton* addAssignmentButton = new QPushButton(this);
addAssignmentButton->setText(tr("Add assignment"));
addAssignmentButton->setIcon(QIcon(":/icons/16x16/list-add-green.png"));
gridLayout->addWidget(addAssignmentButton, row++, 0, 1, 4);
connect(addAssignmentButton, SIGNAL(pressed()), this, SLOT(addAssignment()));
}
void CopyFilterGUIForm::setChannelNames(const vector<wstring>& channelNames)
{
inputChannelNames = channelNames;
for(int row = 0; row < gridLayout->rowCount() - 1; row++)
{
QLayoutItem* item = gridLayout->itemAtPosition(row, 1);
if(item != NULL)
{
QComboBox* targetComboBox = qobject_cast<QComboBox*>(item->widget());
targetComboBox->blockSignals(true);
QString text = targetComboBox->currentText();
targetComboBox->clear();
for(wstring channelName : channelNames)
targetComboBox->addItem(QString::fromStdWString(channelName));
targetComboBox->setEditText(text);
targetComboBox->blockSignals(false);
}
QLayoutItem* summandItem = gridLayout->itemAtPosition(row, 3);
CopyFilterGUIRow* summandWidget = qobject_cast<CopyFilterGUIRow*>(summandItem->widget());
summandWidget->setChannelNames(channelNames);
}
}
vector<Assignment> CopyFilterGUIForm::buildAssignments(QWidget* pressedButton)
{
vector<Assignment> assignments;
Assignment* currentAssignment = NULL;
for(int row = 0; row < gridLayout->rowCount() - 1; row++)
{
QLayoutItem* item = gridLayout->itemAtPosition(row, 1);
if(item != NULL)
{
QComboBox* targetComboBox = qobject_cast<QComboBox*>(item->widget());
QString oc = targetComboBox->currentText().trimmed();
assignments.push_back(Assignment());
currentAssignment = &assignments.back();
currentAssignment->targetChannel = oc.toStdWString();
}
if(currentAssignment != NULL)
{
if(pressedButton != NULL)
{
QWidget* removeButton = gridLayout->itemAtPosition(row, 5)->widget();
if(removeButton == pressedButton)
{
continue;
}
}
QLayoutItem* summandItem = gridLayout->itemAtPosition(row, 3);
CopyFilterGUIRow* summandWidget = qobject_cast<CopyFilterGUIRow*>(summandItem->widget());
currentAssignment->sourceSum.push_back(summandWidget->buildSummand());
if(pressedButton != NULL)
{
QWidget* addSummandButton = gridLayout->itemAtPosition(row, 4)->widget();
if(addSummandButton == pressedButton)
{
Assignment::Summand newSummand;
newSummand.channel = L" ";
newSummand.factor = 1.0;
newSummand.isDecibel = false;
currentAssignment->sourceSum.push_back(newSummand);
}
}
}
}
// remove empty assignments (can be caused by remove button)
assignments.erase(remove_if(assignments.begin(), assignments.end(), [](Assignment assignment) {
return assignment.sourceSum.empty();
}), assignments.end());
return assignments;
}
void CopyFilterGUIForm::addSummand()
{
QWidget* addSummandButton = qobject_cast<QWidget*>(sender());
vector<Assignment> assignments = buildAssignments(addSummandButton);
load(assignments);
}
void CopyFilterGUIForm::remove()
{
QWidget* removeButton = qobject_cast<QWidget*>(sender());
vector<Assignment> assignments = buildAssignments(removeButton);
load(assignments);
emit updateModel();
emit updateChannels();
}
void CopyFilterGUIForm::addAssignment()
{
vector<Assignment> assignments = buildAssignments();
Assignment newAssignment;
Assignment::Summand summand;
summand.channel = L" ";
summand.factor = 1.0;
summand.isDecibel = false;
newAssignment.sourceSum.push_back(summand);
assignments.push_back(newAssignment);
load(assignments);
}
+50
View File
@@ -0,0 +1,50 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <vector>
#include <QWidget>
#include <QGridLayout>
#include "filters/CopyFilter.h"
class CopyFilterGUIForm : public QWidget
{
Q_OBJECT
public:
explicit CopyFilterGUIForm(QWidget *parent = 0);
void load(std::vector<Assignment> assignments);
void setChannelNames(const std::vector<std::wstring>& channelNames);
std::vector<Assignment> buildAssignments(QWidget* pressedButton = NULL);
signals:
void updateModel();
void updateChannels();
private slots:
void addSummand();
void remove();
void addAssignment();
private:
QGridLayout* gridLayout = NULL;
std::vector<std::wstring> inputChannelNames;
};
+107
View File
@@ -0,0 +1,107 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "CopyFilterGUIRow.h"
#include "ui_CopyFilterGUIRow.h"
using namespace std;
CopyFilterGUIRow::CopyFilterGUIRow(Assignment::Summand summand, std::vector<wstring> channelNames, QWidget *parent) :
QWidget(parent),
ui(new Ui::CopyFilterGUIRow)
{
ui->setupUi(this);
ui->modeComboBox->addItem(tr("Channel"), 'c');
ui->modeComboBox->addItem(tr("Factor * channel"), 'f');
ui->modeComboBox->addItem(tr("dB factor * channel"), 'd');
ui->modeComboBox->addItem(tr("Constant value"), 'v');
QChar mode;
if(summand.channel == L"")
mode = 'v';
else if(summand.isDecibel)
mode = 'd';
else if(summand.factor != 1.0)
mode = 'f';
else
mode = 'c';
ui->modeComboBox->setCurrentIndex(ui->modeComboBox->findData(mode));
ui->factorSpinBox->setValue(summand.factor);
for(wstring channelName : channelNames)
ui->channelComboBox->addItem(QString::fromStdWString(channelName));
ui->channelComboBox->setEditText(QString::fromStdWString(summand.channel).trimmed());
connect(ui->modeComboBox, SIGNAL(activated(int)), this, SIGNAL(updateModel()));
connect(ui->factorSpinBox, SIGNAL(valueChanged(double)), this, SIGNAL(updateModel()));
connect(ui->channelComboBox, SIGNAL(editTextChanged(QString)), this, SIGNAL(updateModel()));
connect(ui->channelComboBox, SIGNAL(editTextChanged(QString)), this, SIGNAL(updateChannels()));
}
CopyFilterGUIRow::~CopyFilterGUIRow()
{
delete ui;
}
void CopyFilterGUIRow::setChannelNames(const vector<wstring>& channelNames)
{
ui->channelComboBox->blockSignals(true);
QString text = ui->channelComboBox->currentText();
ui->channelComboBox->clear();
for(wstring channelName : channelNames)
ui->channelComboBox->addItem(QString::fromStdWString(channelName));
ui->channelComboBox->setEditText(text);
ui->channelComboBox->blockSignals(false);
}
Assignment::Summand CopyFilterGUIRow::buildSummand()
{
Assignment::Summand summand;
QChar mode = ui->modeComboBox->currentData().toChar();
if(mode != 'c')
summand.factor = ui->factorSpinBox->value();
else
summand.factor = 1.0;
// fix for rounding error when using the spin buttons
if(abs(summand.factor) < 1e-10)
summand.factor = 0.0;
if(mode != 'v')
summand.channel = ui->channelComboBox->currentText().trimmed().toStdWString();
// allow channel mode to be remembered when reloading
if(mode == 'c' && summand.channel == L"")
summand.channel = L" ";
summand.isDecibel = mode == 'd';
return summand;
}
void CopyFilterGUIRow::on_modeComboBox_currentIndexChanged(int index)
{
QChar mode = ui->modeComboBox->itemData(index).toChar();
ui->factorSpinBox->setVisible(mode != 'c');
ui->asteriskLabel->setVisible(mode == 'f' || mode == 'd');
ui->channelComboBox->setVisible(mode != 'v');
ui->factorSpinBox->setSuffix(mode == 'd' ? " dB" : "");
}
+50
View File
@@ -0,0 +1,50 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <QWidget>
#include "filters/CopyFilter.h"
namespace Ui {
class CopyFilterGUIRow;
}
class CopyFilterGUIRow : public QWidget
{
Q_OBJECT
public:
explicit CopyFilterGUIRow(Assignment::Summand summand, std::vector<std::wstring> channelNames, QWidget *parent = 0);
~CopyFilterGUIRow();
void setChannelNames(const std::vector<std::wstring>& channelNames);
Assignment::Summand buildSummand();
signals:
void updateModel();
void updateChannels();
private slots:
void on_modeComboBox_currentIndexChanged(int index);
private:
Ui::CopyFilterGUIRow *ui;
};
+63
View File
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CopyFilterGUIRow</class>
<widget class="QWidget" name="CopyFilterGUIRow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>523</width>
<height>128</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="modeComboBox"/>
</item>
<item>
<widget class="QDoubleSpinBox" name="factorSpinBox">
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-99.989999999999995</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="asteriskLabel">
<property name="text">
<string notr="true">*</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="channelComboBox">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+217
View File
@@ -0,0 +1,217 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <algorithm>
#include <QKeyEvent>
#include <QGraphicsProxyWidget>
#include <QLineEdit>
#include <QToolButton>
#include "Editor/widgets/ResizingLineEdit.h"
#include "CopyFilterGUIChannelItem.h"
#include "CopyFilterGUIScene.h"
using namespace std;
void CopyFilterGUIScene::load(const vector<wstring>& channelNames, vector<Assignment> assignments)
{
clear();
QHash<QString, CopyFilterGUIChannelItem*> inputChannelMap;
QHash<QString, CopyFilterGUIChannelItem*> outputChannelMap;
QGraphicsItem* lastInputItem = NULL;
lastOutputItem = NULL;
for(unsigned i = 0; i < channelNames.size(); i++)
{
QString c = QString::fromStdWString(channelNames[i]);
CopyFilterGUIChannelItem* inputItem = new CopyFilterGUIChannelItem(c, false);
inputItem->setPos(getNextChannelPoint(lastInputItem, false));
addItem(inputItem);
inputChannelMap.insert(c, inputItem);
inputChannelMap.insert(QString().setNum(i), inputItem);
lastInputItem = inputItem;
CopyFilterGUIChannelItem* outputItem = new CopyFilterGUIChannelItem(c, true);
outputItem->setPos(getNextChannelPoint(lastOutputItem, true));
addItem(outputItem);
outputChannelMap.insert(c, outputItem);
outputChannelMap.insert(QString().setNum(i), outputItem);
lastOutputItem = outputItem;
}
CopyFilterGUIChannelItem* noChannelItem = new CopyFilterGUIChannelItem("", false);
noChannelItem->setPos(getNextChannelPoint(lastInputItem, false));
addItem(noChannelItem);
inputChannelMap.insert("", noChannelItem);
for(Assignment assignment : assignments)
{
QString oc = QString::fromStdWString(assignment.targetChannel);
if(oc == "")
continue;
CopyFilterGUIChannelItem* outputItem = outputChannelMap.value(oc.toUpper());
if(outputItem == NULL)
{
outputItem = new CopyFilterGUIChannelItem(oc, true);
outputItem->setPos(getNextChannelPoint(lastOutputItem, true));
addItem(outputItem);
outputChannelMap.insert(oc, outputItem);
lastOutputItem = outputItem;
}
for(Assignment::Summand summand : assignment.sourceSum)
{
QString ic = QString::fromStdWString(summand.channel);
if(ic == " ")
continue;
CopyFilterGUIChannelItem* inputItem = inputChannelMap.value(ic.toUpper());
if(inputItem == NULL)
{
inputItem = new CopyFilterGUIChannelItem(ic, false);
inputItem->setPos(getNextChannelPoint(lastInputItem, false));
addItem(inputItem);
inputChannelMap.insert(ic, inputItem);
lastInputItem = inputItem;
}
CopyFilterGUIConnectionItem* connItem = new CopyFilterGUIConnectionItem(inputItem, outputItem, summand.factor, summand.isDecibel);
addItem(connItem);
}
}
QToolButton* addButton = new QToolButton;
addButton->setIcon(QIcon(":/icons/16x16/list-add-green.png"));
connect(addButton, SIGNAL(clicked()), this, SLOT(addOutputChannel()));
addProxyItem = addWidget(addButton);
addProxyItem->setPos(getNextChannelPoint(lastOutputItem, true));
setSceneRect(itemsBoundingRect().marginsAdded(QMarginsF(2, 2, 2, 2)));
}
std::vector<Assignment> CopyFilterGUIScene::buildAssignments()
{
std::vector<CopyFilterGUIConnectionItem*> connItems;
for(QGraphicsItem* item : items())
{
CopyFilterGUIConnectionItem* connItem = qgraphicsitem_cast<CopyFilterGUIConnectionItem*>(item);
if(connItem != NULL && connItem->getTarget() != NULL)
{
connItems.push_back(connItem);
}
}
std::sort(connItems.begin(), connItems.end(), [](CopyFilterGUIConnectionItem * a, CopyFilterGUIConnectionItem * b)
{
double diff = a->getTarget()->x() - b->getTarget()->x();
if(diff == 0.0)
diff = a->getSource()->x() - b->getSource()->x();
return diff < 0;
});
std::vector<Assignment> assignments;
QHash<QString, Assignment*> channelAssignmentMap;
for(CopyFilterGUIConnectionItem* connItem : connItems)
{
QString oc = connItem->getTarget()->getName();
Assignment* assignment = channelAssignmentMap.value(oc);
if(assignment == NULL)
{
Assignment newAssignment;
newAssignment.targetChannel = oc.toStdWString();
assignments.push_back(newAssignment);
assignment = &assignments.back();
channelAssignmentMap.insert(oc, assignment);
}
QString ic = connItem->getSource()->getName();
Assignment::Summand summand;
summand.channel = ic.toStdWString();
summand.factor = connItem->getFactor();
summand.isDecibel = connItem->getIsDecibel();
assignment->sourceSum.push_back(summand);
}
return assignments;
}
void CopyFilterGUIScene::addOutputChannel()
{
ResizingLineEdit* lineEdit = new ResizingLineEdit("");
connect(lineEdit, SIGNAL(editingFinished()), this, SLOT(lineEditEditingFinished()));
QGraphicsProxyWidget* proxyItem = addWidget(lineEdit);
QPointF point = getNextChannelPoint(lastOutputItem, true);
QRectF rect;
rect.setSize(lineEdit->size());
rect.moveTo(point);
proxyItem->setPos(rect.topLeft());
proxyItem->setZValue(10);
lineEdit->setFocus();
addProxyItem->setVisible(false);
}
void CopyFilterGUIScene::lineEditEditingFinished()
{
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(QObject::sender());
// might be called twice
if(!lineEdit->isVisible())
return;
QString text = lineEdit->text();
CopyFilterGUIChannelItem* item = new CopyFilterGUIChannelItem(text, true);
item->setPos(getNextChannelPoint(lastOutputItem, true));
addItem(item);
lastOutputItem = item;
addProxyItem->setPos(getNextChannelPoint(lastOutputItem, true));
addProxyItem->setVisible(true);
lineEdit->setVisible(false);
lineEdit->deleteLater();
}
void CopyFilterGUIScene::keyPressEvent(QKeyEvent* event)
{
// focusItem != NULL means that the cursor is inside a line edit
if(event->key() == Qt::Key_Delete && focusItem() == NULL)
{
for(QGraphicsItem* item : selectedItems())
{
CopyFilterGUIConnectionItem* connectionItem = qgraphicsitem_cast<CopyFilterGUIConnectionItem*>(item);
if(connectionItem != NULL)
{
removeItem(connectionItem);
delete connectionItem;
}
}
emit updateModel();
emit updateChannels();
}
QGraphicsScene::keyPressEvent(event);
}
+50
View File
@@ -0,0 +1,50 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <vector>
#include <QGraphicsScene>
#include "Editor/widgets/ChannelGraphScene.h"
#include "filters/CopyFilter.h"
class CopyFilterGUIScene : public ChannelGraphScene
{
Q_OBJECT
public:
void load(const std::vector<std::wstring>& channelNames, std::vector<Assignment> assignments);
std::vector<Assignment> buildAssignments();
signals:
void updateModel();
void updateChannels();
protected:
void keyPressEvent(QKeyEvent* event) override;
private slots:
void addOutputChannel();
void lineEditEditingFinished();
private:
QGraphicsItem* lastOutputItem;
QGraphicsProxyWidget* addProxyItem;
};
+71
View File
@@ -0,0 +1,71 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "DelayFilterGUI.h"
#include "ui_DelayFilterGUI.h"
static const double dialSteps = 1000;
static const double dialMin = 1.0;
static const double dialMax = 10000.0;
DelayFilterGUI::DelayFilterGUI(double delay, bool isMs) :
ui(new Ui::DelayFilterGUI)
{
ui->setupUi(this);
ui->unitComboBox->setCurrentIndex(isMs ? 0 : 1);
ui->delaySpinBox->setValue(delay);
}
DelayFilterGUI::~DelayFilterGUI()
{
delete ui;
}
void DelayFilterGUI::store(QString& command, QString& parameters)
{
command = "Delay";
parameters = QString("%0").arg(ui->delaySpinBox->value());
if(ui->unitComboBox->currentIndex() == 0)
parameters += " ms";
else
parameters += " samples";
}
void DelayFilterGUI::on_unitComboBox_currentIndexChanged(int index)
{
ui->delaySpinBox->setSuffix(index == 0 ? tr(" ms") : tr(" samples"));
ui->delaySpinBox->setDecimals(index == 0 ? 2 : 0);
emit updateModel();
}
void DelayFilterGUI::on_delayDial_valueChanged(int value)
{
ui->delaySpinBox->setValue(pow(dialMax / dialMin, value / dialSteps) * dialMin);
}
void DelayFilterGUI::on_delaySpinBox_valueChanged(double value)
{
bool previousValue = ui->delayDial->blockSignals(true);
ui->delayDial->setValue(round(dialSteps * log(value / dialMin) / log(dialMax / dialMin)));
ui->delayDial->blockSignals(previousValue);
emit updateModel();
}
+47
View File
@@ -0,0 +1,47 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
namespace Ui {
class DelayFilterGUI;
}
class DelayFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit DelayFilterGUI(double delay, bool isMs);
~DelayFilterGUI();
void store(QString& command, QString& parameters) override;
private slots:
void on_unitComboBox_currentIndexChanged(int index);
void on_delayDial_valueChanged(int value);
void on_delaySpinBox_valueChanged(double value);
private:
Ui::DelayFilterGUI *ui;
};
+96
View File
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DelayFilterGUI</class>
<widget class="QWidget" name="DelayFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>262</width>
<height>66</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,1">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="2">
<widget class="QDoubleSpinBox" name="delaySpinBox">
<property name="suffix">
<string> ms</string>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="delayLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Delay:</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QDial" name="delayDial">
<property name="minimumSize">
<size>
<width>0</width>
<height>66</height>
</size>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="unitComboBox">
<item>
<property name="text">
<string>Time</string>
</property>
</item>
<item>
<property name="text">
<string>Samples</string>
</property>
</item>
</widget>
</item>
<item row="0" column="3" rowspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+58
View File
@@ -0,0 +1,58 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "filters/DelayFilter.h"
#include "filters/DelayFilterFactory.h"
#include "DelayFilterGUI.h"
#include "DelayFilterGUIFactory.h"
DelayFilterGUIFactory::DelayFilterGUIFactory()
{
}
QList<FilterTemplate> DelayFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Delay"), "Delay: 0 ms", QStringList(tr("Basic filters"))));
return list;
}
IFilterGUI* DelayFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
DelayFilterGUI* result = NULL;
if(command == "Delay")
{
DelayFilterFactory factory;
std::vector<IFilter*> filters = factory.createFilter(L"", command.toStdWString(), parameters.toStdWString());
if(!filters.empty())
{
DelayFilter* filter = (DelayFilter*)filters[0];
result = new DelayFilterGUI(filter->getDelay(), filter->getIsMs());
}
for(IFilter* f : filters)
{
f->~IFilter();
MemoryHelper::free(f);
}
}
return result;
}
+33
View File
@@ -0,0 +1,33 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class DelayFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
explicit DelayFilterGUIFactory();
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI*createFilterGUI(QString& command, QString& parameters) override;;
};
+129
View File
@@ -0,0 +1,129 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <string>
#include "DeviceFilterGUI.h"
#include "DeviceFilterGUIDialog.h"
#include <filters/DeviceFilterFactory.h>
#include "ui_DeviceFilterGUI.h"
using namespace std;
DeviceFilterGUI::DeviceFilterGUI(DeviceFilterGUIFactory* factory):
ui(new Ui::DeviceFilterGUI)
{
ui->setupUi(this);
this->factory = factory;
}
DeviceFilterGUI::~DeviceFilterGUI()
{
delete ui;
}
void DeviceFilterGUI::load(const QString& parameters)
{
pattern = parameters;
ui->treeWidget->clear();
QStringList labels;
labels.append(tr("Type"));
labels.append(tr("Connection"));
labels.append(tr("Device"));
labels.append(tr("State"));
ui->treeWidget->setHeaderLabels(labels);
QTreeWidgetItem* lastItem = NULL;
if(parameters.trimmed() == "all")
{
QStringList values;
values.append("");
values.append(tr("All devices"));
values.append("");
lastItem = new QTreeWidgetItem(ui->treeWidget, values);
}
else
{
const QList<DeviceAPOInfo>& devices = factory->getDevices();
for(const DeviceAPOInfo& apoInfo : devices)
{
if(!apoInfo.isInstalled)
continue;
wstring deviceString = apoInfo.connectionName + L" " + apoInfo.deviceName + L" " + apoInfo.deviceGuid;
if(DeviceFilterFactory::matchDevice(deviceString, pattern.toStdWString()))
{
QStringList values;
if(apoInfo.isInput)
values.append(tr("Capture"));
else
values.append(tr("Playback"));
values.append(QString::fromStdWString(apoInfo.connectionName));
values.append(QString::fromStdWString(apoInfo.deviceName));
QString state;
if(apoInfo.isInstalled)
state = tr("APO installed");
else
state = tr("APO not installed");
values.append(state);
lastItem = new QTreeWidgetItem(ui->treeWidget, values);
}
}
if(ui->treeWidget->topLevelItemCount() == 0)
{
QStringList values;
values.append("");
values.append(tr("No device matched!"));
values.append("");
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget, values);
item->setForeground(1, QBrush(Qt::red));
lastItem = item;
}
}
for(int i = 0; i < ui->treeWidget->columnCount(); i++)
ui->treeWidget->resizeColumnToContents(i);
int headerHeight = ui->treeWidget->header()->height();
int itemAreaHeight = 0;
if(lastItem != NULL)
itemAreaHeight = ui->treeWidget->visualItemRect(lastItem).bottom() + 1;
ui->treeWidget->setFixedHeight(headerHeight + itemAreaHeight + 3);
}
void DeviceFilterGUI::store(QString& command, QString& parameters)
{
command = "Device";
parameters = pattern;
}
void DeviceFilterGUI::on_pushButton_clicked()
{
DeviceFilterGUIDialog dialog(this, factory, pattern);
if(dialog.exec() == QDialog::Accepted)
{
load(dialog.getPattern());
emit updateModel();
}
}
+46
View File
@@ -0,0 +1,46 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
#include "DeviceFilterGUIFactory.h"
namespace Ui {
class DeviceFilterGUI;
}
class DeviceFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit DeviceFilterGUI(DeviceFilterGUIFactory* factory);
~DeviceFilterGUI();
void load(const QString& parameters);
void store(QString& command, QString& parameters) override;
private slots:
void on_pushButton_clicked();
private:
Ui::DeviceFilterGUI *ui;
DeviceFilterGUIFactory* factory;
QString pattern;
};
+106
View File
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DeviceFilterGUI</class>
<widget class="QWidget" name="DeviceFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>71</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="3">
<widget class="QTreeWidget" name="treeWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="columnCount">
<number>3</number>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">3</string>
</property>
</column>
</widget>
</item>
<item row="0" column="2">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Selected devices:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Change...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+128
View File
@@ -0,0 +1,128 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "DeviceFilterGUIDialog.h"
#include "ui_DeviceFilterGUIDialog.h"
#include <filters/DeviceFilterFactory.h>
using namespace std;
DeviceFilterGUIDialog::DeviceFilterGUIDialog(DeviceFilterGUI* gui, DeviceFilterGUIFactory* factory, const QString& pattern) :
QDialog(gui),
ui(new Ui::DeviceFilterGUIDialog)
{
ui->setupUi(this);
bool all = pattern.trimmed() == "all";
ui->allDevicesCheckBox->setChecked(all);
QStringList labels;
labels.append(tr("Connection"));
labels.append(tr("Device"));
labels.append(tr("State"));
ui->treeWidget->setHeaderLabels(labels);
QTreeWidgetItem* outputNode = new QTreeWidgetItem(ui->treeWidget, QStringList(tr("Playback devices")));
outputNode->setExpanded(true);
QTreeWidgetItem* inputNode = new QTreeWidgetItem(ui->treeWidget, QStringList(tr("Capture devices")));
inputNode->setExpanded(true);
const QList<DeviceAPOInfo>& devices = factory->getDevices();
for(const DeviceAPOInfo& apoInfo : devices)
{
QStringList values;
values.append(QString::fromStdWString(apoInfo.connectionName));
values.append(QString::fromStdWString(apoInfo.deviceName));
QString state;
if(apoInfo.isInstalled)
state = tr("APO installed");
else
state = tr("APO not installed");
values.append(state);
QTreeWidgetItem* item = new QTreeWidgetItem(apoInfo.isInput ? inputNode : outputNode, values);
wstring deviceString = apoInfo.connectionName + L" " + apoInfo.deviceName + L" " + apoInfo.deviceGuid;
bool matches = !all && DeviceFilterFactory::matchDevice(deviceString, pattern.toStdWString());
item->setCheckState(0, matches ? Qt::Checked : Qt::Unchecked);
item->setData(0, Qt::UserRole, QVariant::fromValue(&apoInfo));
item->setHidden(!matches && !apoInfo.isInstalled && ui->showOnlyInstalledCheckBox->isChecked());
if(!apoInfo.isInstalled)
for(int i = 0; i < ui->treeWidget->columnCount(); i++)
item->setForeground(i, QBrush(Qt::gray));
}
for(int i = 0; i < ui->treeWidget->columnCount(); i++)
ui->treeWidget->resizeColumnToContents(i);
}
DeviceFilterGUIDialog::~DeviceFilterGUIDialog()
{
delete ui;
}
QString DeviceFilterGUIDialog::getPattern()
{
if(ui->allDevicesCheckBox->isChecked())
{
return "all";
}
else
{
QString pattern = "";
for(int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
{
QTreeWidgetItem* groupItem = ui->treeWidget->topLevelItem(i);
for(int j = 0; j < groupItem->childCount(); j++)
{
QTreeWidgetItem* item = groupItem->child(j);
if(item->checkState(0) == Qt::Checked)
{
if(pattern != "")
pattern += "; ";
const DeviceAPOInfo* apoInfo = item->data(0, Qt::UserRole).value<const DeviceAPOInfo*>();
wstring deviceString = apoInfo->connectionName + L" " + apoInfo->deviceName + L" " + apoInfo->deviceGuid;
pattern += QString::fromStdWString(deviceString);
}
}
}
return pattern;
}
}
void DeviceFilterGUIDialog::on_allDevicesCheckBox_toggled(bool checked)
{
ui->treeWidget->setEnabled(!checked);
}
void DeviceFilterGUIDialog::on_showOnlyInstalledCheckBox_toggled(bool checked)
{
for(int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
{
QTreeWidgetItem* groupItem = ui->treeWidget->topLevelItem(i);
for(int j = 0; j < groupItem->childCount(); j++)
{
QTreeWidgetItem* item = groupItem->child(j);
const DeviceAPOInfo* apoInfo = item->data(0, Qt::UserRole).value<const DeviceAPOInfo*>();
item->setHidden(item->checkState(0) != Qt::Checked && !apoInfo->isInstalled && checked);
}
}
for(int i = 0; i < ui->treeWidget->columnCount(); i++)
ui->treeWidget->resizeColumnToContents(i);
}
+50
View File
@@ -0,0 +1,50 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <QDialog>
#include "DeviceFilterGUI.h"
#include "DeviceFilterGUIFactory.h"
namespace Ui {
class DeviceFilterGUIDialog;
}
class DeviceFilterGUIDialog : public QDialog
{
Q_OBJECT
public:
explicit DeviceFilterGUIDialog( DeviceFilterGUI* gui, DeviceFilterGUIFactory* factory, const QString& pattern);
~DeviceFilterGUIDialog();
QString getPattern();
private slots:
void on_allDevicesCheckBox_toggled(bool checked);
void on_showOnlyInstalledCheckBox_toggled(bool checked);
private:
Ui::DeviceFilterGUIDialog *ui;
};
Q_DECLARE_METATYPE(const DeviceAPOInfo*)
+103
View File
@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DeviceFilterGUIDialog</class>
<widget class="QDialog" name="DeviceFilterGUIDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>350</height>
</rect>
</property>
<property name="windowTitle">
<string>Device selection</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QTreeWidget" name="treeWidget">
<property name="columnCount">
<number>3</number>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">3</string>
</property>
</column>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="allDevicesCheckBox">
<property name="text">
<string>Select all devices</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="showOnlyInstalledCheckBox">
<property name="text">
<string>Show only devices with APO installed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DeviceFilterGUIDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DeviceFilterGUIDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+57
View File
@@ -0,0 +1,57 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "Editor/FilterTable.h"
#include "DeviceFilterGUI.h"
#include "DeviceFilterGUIFactory.h"
DeviceFilterGUIFactory::DeviceFilterGUIFactory()
{
}
void DeviceFilterGUIFactory::initialize(FilterTable* filterTable)
{
devices.append(filterTable->getOutputDevices());
devices.append(filterTable->getInputDevices());
}
QList<FilterTemplate> DeviceFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Device (Select device)"), "Device: all", QStringList(tr("Control"))));
return list;
}
IFilterGUI* DeviceFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
DeviceFilterGUI* result = NULL;
if(command == "Device")
{
result = new DeviceFilterGUI(this);
result->load(parameters);
}
return result;
}
const QList<DeviceAPOInfo>& DeviceFilterGUIFactory::getDevices() const
{
return devices;
}
+41
View File
@@ -0,0 +1,41 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "DeviceAPOInfo.h"
#include "Editor/IFilterGUIFactory.h"
class DeviceFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
DeviceFilterGUIFactory();
void initialize(FilterTable* filterTable) override;
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
const QList<DeviceAPOInfo>& getDevices() const;
private:
QList<DeviceAPOInfo> devices;
};
@@ -0,0 +1,29 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "ExpressionFilterGUIFactory.h"
IFilterGUI* ExpressionFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
// do not create a gui if parameters contain expressions
if(parameters.contains('`'))
command = "";
return NULL;
}
+28
View File
@@ -0,0 +1,28 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class ExpressionFilterGUIFactory : public IFilterGUIFactory
{
public:
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
};
+389
View File
@@ -0,0 +1,389 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <vector>
#include <QFileDialog>
#include <QScrollBar>
#include <QTextStream>
#include "helpers/GainIterator.h"
#include "GraphicEQFilterGUIView.h"
#include "GraphicEQFilterGUI.h"
#include "ui_GraphicEQFilterGUI.h"
using namespace std;
QRegularExpression GraphicEQFilterGUI::numberRegEx("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
GraphicEQFilterGUI::GraphicEQFilterGUI(GraphicEQFilter* filter, QString configPath) :
ui(new Ui::GraphicEQFilterGUI), configPath(configPath)
{
ui->setupUi(this);
setFixedHeight(150);
scene = new GraphicEQFilterGUIScene(ui->graphicsView);
ui->graphicsView->setScene(scene);
ui->toolBar->addAction(ui->actionImport);
ui->toolBar->addAction(ui->actionExport);
ui->toolBar->addAction(ui->actionMirrorResponse);
ui->toolBar->addAction(ui->actionNormalizeResponse);
ui->toolBar->addAction(ui->actionResetResponse);
connect(scene, SIGNAL(nodeInserted(int, double, double)), this, SLOT(insertRow(int, double, double)));
connect(scene, SIGNAL(nodeRemoved(int)), this, SLOT(removeRow(int)));
connect(scene, SIGNAL(nodeUpdated(int, double, double)), this, SLOT(updateRow(int, double, double)));
connect(scene, SIGNAL(nodeMoved(int, int)), this, SLOT(moveRow(int, int)));
connect(scene, SIGNAL(nodeSelectionChanged(int, bool)), this, SLOT(selectRow(int, bool)));
connect(scene, SIGNAL(updateModel()), this, SIGNAL(updateModel()));
scene->setNodes(filter->getNodes());
int bandCount = scene->verifyBands(filter->getNodes());
switch(bandCount)
{
case 15:
ui->radioButton15->click();
break;
case 31:
ui->radioButton31->click();
break;
default:
ui->radioButtonVar->click();
}
ui->tableWidget->resizeColumnsToContents();
}
GraphicEQFilterGUI::~GraphicEQFilterGUI()
{
delete ui;
}
void GraphicEQFilterGUI::store(QString& command, QString& parameters)
{
command = "GraphicEQ";
bool first = true;
for(FilterNode node : scene->getNodes())
{
if(first)
first = false;
else
parameters += "; ";
parameters += QString("%0 %1").arg(node.freq).arg(node.dbGain);
}
}
void GraphicEQFilterGUI::insertRow(int index, double hz, double db)
{
ui->tableWidget->blockSignals(true);
ui->tableWidget->insertRow(index);
QTableWidgetItem* freqItem = new QTableWidgetItem(QString("%0").arg(hz));
ui->tableWidget->setItem(index, 0, freqItem);
QTableWidgetItem* gainItem = new QTableWidgetItem(QString("%0").arg(db));
ui->tableWidget->setItem(index, 1, gainItem);
ui->tableWidget->blockSignals(false);
}
void GraphicEQFilterGUI::removeRow(int index)
{
ui->tableWidget->blockSignals(true);
ui->tableWidget->removeRow(index);
ui->tableWidget->blockSignals(false);
}
void GraphicEQFilterGUI::updateRow(int index, double hz, double db)
{
ui->tableWidget->blockSignals(true);
QTableWidgetItem* freqItem = ui->tableWidget->item(index, 0);
freqItem->setText(QString("%0").arg(hz));
QTableWidgetItem* gainItem = ui->tableWidget->item(index, 1);
gainItem->setText(QString("%0").arg(db));
ui->tableWidget->blockSignals(false);
}
void GraphicEQFilterGUI::moveRow(int fromIndex, int toIndex)
{
ui->tableWidget->blockSignals(true);
QTableWidgetItem* freqItem = ui->tableWidget->takeItem(fromIndex, 0);
QTableWidgetItem* gainItem = ui->tableWidget->takeItem(fromIndex, 1);
bool selected = ui->tableWidget->selectionModel()->isRowSelected(fromIndex, ui->tableWidget->rootIndex());
ui->tableWidget->removeRow(fromIndex);
ui->tableWidget->insertRow(toIndex);
ui->tableWidget->setItem(toIndex, 0, freqItem);
ui->tableWidget->setItem(toIndex, 1, gainItem);
if(selected)
{
QModelIndex modelIndex = ui->tableWidget->model()->index(toIndex, 0);
ui->tableWidget->selectionModel()->select(modelIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select);
ui->tableWidget->scrollTo(modelIndex);
}
ui->tableWidget->blockSignals(false);
}
void GraphicEQFilterGUI::selectRow(int index, bool select)
{
ui->tableWidget->blockSignals(true);
QItemSelectionModel::SelectionFlags command = QItemSelectionModel::Rows;
if(select)
command |= QItemSelectionModel::Select;
else
command |= QItemSelectionModel::Deselect;
QModelIndex modelIndex = ui->tableWidget->model()->index(index, 0);
ui->tableWidget->selectionModel()->select(modelIndex, command);
ui->tableWidget->scrollTo(modelIndex);
ui->tableWidget->blockSignals(false);
}
void GraphicEQFilterGUI::on_tableWidget_cellChanged(int row, int column)
{
if(column == 0)
{
QTableWidgetItem* freqItem = ui->tableWidget->item(row, 0);
bool ok;
double freq = freqItem->text().toDouble(&ok);
if(ok)
{
double gain = scene->getNodes()[row].dbGain;
scene->setNode(row, freq, gain);
}
else
{
freq = scene->getNodes()[row].freq;
freqItem->setText(QString("%0").arg(freq));
}
}
else if(column == 1)
{
QTableWidgetItem* gainItem = ui->tableWidget->item(row, 1);
bool ok;
double gain = gainItem->text().toDouble(&ok);
if(ok)
{
double freq = scene->getNodes()[row].freq;
scene->setNode(row, freq, gain);
}
else
{
gain = scene->getNodes()[row].dbGain;
gainItem->setText(QString("%0").arg(gain));
}
}
}
void GraphicEQFilterGUI::on_tableWidget_itemSelectionChanged()
{
QSet<int> selectedRows;
for(QTableWidgetItem* item : ui->tableWidget->selectedItems())
selectedRows.insert(item->row());
scene->setSelectedNodes(selectedRows);
}
void GraphicEQFilterGUI::on_radioButton15_toggled(bool checked)
{
if(checked)
{
scene->setBandCount(15);
setFreqEditable(false);
}
}
void GraphicEQFilterGUI::on_radioButton31_toggled(bool checked)
{
if(checked)
{
scene->setBandCount(31);
setFreqEditable(false);
}
}
void GraphicEQFilterGUI::on_radioButtonVar_toggled(bool checked)
{
if(checked)
{
scene->setBandCount(-1);
setFreqEditable(true);
}
}
void GraphicEQFilterGUI::setFreqEditable(bool editable)
{
ui->tableWidget->blockSignals(true);
for(int i = 0; i < ui->tableWidget->rowCount(); i++)
{
QTableWidgetItem* item = ui->tableWidget->item(i, 0);
if(editable)
item->setFlags(item->flags() | Qt::ItemIsEditable | Qt::ItemIsEnabled);
else
item->setFlags(item->flags() & ~(Qt::ItemIsEditable | Qt::ItemIsEnabled));
}
ui->tableWidget->blockSignals(false);
}
void GraphicEQFilterGUI::on_actionImport_triggered()
{
QFileInfo fileInfo(configPath);
QFileDialog dialog(this, tr("Import frequency response"), fileInfo.absolutePath(), "*.csv");
dialog.setFileMode(QFileDialog::ExistingFiles);
QStringList nameFilters;
nameFilters.append(tr("Frequency response (*.csv)"));
nameFilters.append(tr("All files (*.*)"));
dialog.setNameFilters(nameFilters);
if(dialog.exec() == QDialog::Accepted)
{
vector<FilterNode> newNodes;
for(QString path : dialog.selectedFiles())
{
QFile file(path);
if(file.open(QFile::ReadOnly))
{
QTextStream stream(&file);
QString text = stream.readAll();
if(!text.contains('.'))
text = text.replace(',', '.');
QRegularExpressionMatchIterator it = numberRegEx.globalMatch(text);
while(it.hasNext())
{
QRegularExpressionMatch match = it.next();
QString freqString = match.captured();
bool ok;
double freq = freqString.toDouble(&ok);
if(ok && it.hasNext())
{
match = it.next();
QString gainString = match.captured();
double gain = gainString.toDouble(&ok);
if(ok)
newNodes.push_back(FilterNode(freq, gain));
}
}
}
}
sort(newNodes.begin(), newNodes.end());
scene->setNodes(newNodes);
int bandCount = scene->verifyBands(newNodes);
if(bandCount != scene->getBandCount())
{
switch(bandCount)
{
case 15:
ui->radioButton15->click();
break;
case 31:
ui->radioButton31->click();
break;
default:
ui->radioButtonVar->click();
}
}
else
{
emit updateModel();
}
ui->tableWidget->resizeColumnsToContents();
}
}
void GraphicEQFilterGUI::on_actionExport_triggered()
{
QFileInfo fileInfo(configPath);
QFileDialog dialog(this, tr("Export frequency response"), fileInfo.absolutePath(), "*.csv");
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setAcceptMode(QFileDialog::AcceptSave);
QStringList nameFilters;
nameFilters.append(tr("Frequency response (*.csv)"));
nameFilters.append(tr("All files (*.*)"));
dialog.setNameFilters(nameFilters);
dialog.setDefaultSuffix(".csv");
if(dialog.exec() == QDialog::Accepted)
{
QString savePath = dialog.selectedFiles().first();
QFile file(savePath);
if(file.open(QFile::WriteOnly | QFile::Truncate))
{
QTextStream stream(&file);
for(FilterNode node : scene->getNodes())
{
stream << node.freq << '\t' << node.dbGain << '\n';
}
stream.flush();
}
}
}
void GraphicEQFilterGUI::on_actionMirrorResponse_triggered()
{
vector<FilterNode> newNodes = scene->getNodes();
for(FilterNode& node : newNodes)
node.dbGain = -node.dbGain;
scene->setNodes(newNodes);
emit updateModel();
}
void GraphicEQFilterGUI::on_actionNormalizeResponse_triggered()
{
vector<FilterNode> newNodes = scene->getNodes();
double maxGain = -DBL_MAX;
for(FilterNode node : newNodes)
{
if(node.dbGain > maxGain)
maxGain = node.dbGain;
}
if(maxGain != 0)
{
for(FilterNode& node : newNodes)
node.dbGain -= maxGain;
scene->setNodes(newNodes);
emit updateModel();
}
}
void GraphicEQFilterGUI::on_actionResetResponse_triggered()
{
vector<FilterNode> newNodes = scene->getNodes();
QSet<int> selectedIndices = scene->getSelectedIndices();
int index = 0;
for(FilterNode& node : newNodes)
{
if(selectedIndices.isEmpty() || selectedIndices.contains(index))
node.dbGain = 0.0;
index++;
}
scene->setNodes(newNodes);
scene->setSelectedNodes(selectedIndices);
emit updateModel();
}
+73
View File
@@ -0,0 +1,73 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <QRegularExpression>
#include "Editor/IFilterGUI.h"
#include "filters/GraphicEQFilter.h"
#include "GraphicEQFilterGUIScene.h"
namespace Ui {
class GraphicEQFilterGUI;
}
class GraphicEQFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit GraphicEQFilterGUI(GraphicEQFilter* filter, QString configPath);
~GraphicEQFilterGUI();
void store(QString& command, QString& parameters) override;
private slots:
void insertRow(int index, double hz, double db);
void removeRow(int index);
void updateRow(int index, double hz, double db);
void moveRow(int fromIndex, int toIndex);
void selectRow(int index, bool select);
void on_tableWidget_cellChanged(int row, int column);
void on_tableWidget_itemSelectionChanged();
void on_radioButton15_toggled(bool checked);
void on_radioButton31_toggled(bool checked);
void on_radioButtonVar_toggled(bool checked);
void on_actionImport_triggered();
void on_actionExport_triggered();
void on_actionMirrorResponse_triggered();
void on_actionNormalizeResponse_triggered();
void on_actionResetResponse_triggered();
private:
void setFreqEditable(bool editable);
Ui::GraphicEQFilterGUI *ui;
GraphicEQFilterGUIScene* scene;
QString configPath;
static QRegularExpression numberRegEx;
};
+247
View File
@@ -0,0 +1,247 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GraphicEQFilterGUI</class>
<widget class="QWidget" name="GraphicEQFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>442</width>
<height>170</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="1,0,0" columnstretch="0,1,0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Graphic EQ:</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QTableWidget" name="tableWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>51</red>
<green>153</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>122</red>
<green>189</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>51</red>
<green>153</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>40</number>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>40</number>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>20</number>
</attribute>
<column>
<property name="text">
<string>Freq.</string>
</property>
</column>
<column>
<property name="text">
<string>Gain</string>
</property>
</column>
</widget>
</item>
<item row="2" column="2">
<widget class="QToolBar" name="toolBar">
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="3">
<widget class="GraphicEQFilterGUIView" name="graphicsView">
<property name="renderHints">
<set>QPainter::Antialiasing|QPainter::TextAntialiasing</set>
</property>
<property name="dragMode">
<enum>QGraphicsView::RubberBandDrag</enum>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QRadioButton" name="radioButton15">
<property name="text">
<string>15-band</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton31">
<property name="text">
<string>31-band</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonVar">
<property name="text">
<string>variable</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<action name="actionImport">
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/document-open.png</normaloff>:/icons/16x16/document-open.png</iconset>
</property>
<property name="text">
<string>Import</string>
</property>
</action>
<action name="actionExport">
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/document-save-as.png</normaloff>:/icons/16x16/document-save-as.png</iconset>
</property>
<property name="text">
<string>Export</string>
</property>
</action>
<action name="actionMirrorResponse">
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/mirror_response.png</normaloff>:/icons/mirror_response.png</iconset>
</property>
<property name="text">
<string>Mirror response</string>
</property>
</action>
<action name="actionNormalizeResponse">
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/normalize_response.png</normaloff>:/icons/normalize_response.png</iconset>
</property>
<property name="text">
<string>Normalize response</string>
</property>
</action>
<action name="actionResetResponse">
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/reset_response.png</normaloff>:/icons/reset_response.png</iconset>
</property>
<property name="text">
<string>Reset response</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>GraphicEQFilterGUIView</class>
<extends>QGraphicsView</extends>
<header>GraphicEQFilterGUIView.h</header>
<slots>
<signal>itemMoved()</signal>
</slots>
</customwidget>
</customwidgets>
<resources>
<include location="../Editor.qrc"/>
</resources>
<connections/>
<slots>
<slot>updateItemList()</slot>
</slots>
</ui>
+65
View File
@@ -0,0 +1,65 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "filters/GraphicEQFilter.h"
#include "filters/GraphicEQFilterFactory.h"
#include "GraphicEQFilterGUI.h"
#include "GraphicEQFilterGUIFactory.h"
GraphicEQFilterGUIFactory::GraphicEQFilterGUIFactory()
{
}
QList<FilterTemplate> GraphicEQFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("15-band graphic equalizer"), "GraphicEQ: 25 0; 40 0; 63 0; 100 0; 160 0; 250 0; 400 0; 630 0; 1000 0; 1600 0; 2500 0; 4000 0; 6300 0; 10000 0; 16000 0", QStringList(tr("Graphic equalizers"))));
list.append(FilterTemplate(tr("31-band graphic equalizer"), "GraphicEQ: 20 0; 25 0; 31.5 0; 40 0; 50 0; 63 0; 80 0; 100 0; 125 0; 160 0; 200 0; 250 0; 315 0; 400 0; 500 0; 630 0; 800 0; 1000 0; 1250 0; 1600 0; 2000 0; 2500 0; 3150 0; 4000 0; 5000 0; 6300 0; 8000 0; 10000 0; 12500 0; 16000 0; 20000 0", QStringList(tr("Graphic equalizers"))));
list.append(FilterTemplate(tr("Graphic equalizer with variable bands"), "GraphicEQ: ", QStringList(tr("Graphic equalizers"))));
return list;
}
void GraphicEQFilterGUIFactory::startOfFile(const QString& configPath)
{
this->configPath = configPath;
}
IFilterGUI* GraphicEQFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
GraphicEQFilterGUI* result = NULL;
if(command == "GraphicEQ")
{
GraphicEQFilterFactory factory;
std::vector<IFilter*> filters = factory.createFilter(L"", command.toStdWString(), parameters.toStdWString());
if(!filters.empty())
{
GraphicEQFilter* filter = (GraphicEQFilter*)filters[0];
result = new GraphicEQFilterGUI(filter, configPath);
}
for(IFilter* f : filters)
{
f->~IFilter();
MemoryHelper::free(f);
}
}
return result;
}
+38
View File
@@ -0,0 +1,38 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class GraphicEQFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
GraphicEQFilterGUIFactory();
QList<FilterTemplate> createFilterTemplates() override;
void startOfFile(const QString& configPath) override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
private:
QString configPath;
};
+103
View File
@@ -0,0 +1,103 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <QPainter>
#include "GraphicEQFilterGUIScene.h"
#include "GraphicEQFilterGUIItem.h"
static double size = 10;
GraphicEQFilterGUIItem::GraphicEQFilterGUIItem(int index, double hz, double db)
: FrequencyPlotItem(hz, db), index(index)
{
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
}
QRectF GraphicEQFilterGUIItem::boundingRect() const
{
return QRectF(-size / 2, -size / 2, size, size);
}
QPainterPath GraphicEQFilterGUIItem::shape() const
{
QPainterPath path;
path.addEllipse(boundingRect());
return path;
}
void GraphicEQFilterGUIItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->setBrush(Qt::white);
if(isSelected())
painter->setBrush(QColor(38, 147, 255));
painter->drawPath(shape());
if(index < 99)
{
if(isSelected())
painter->setPen(Qt::white);
QFont font;
font.setPixelSize(9);
font.setLetterSpacing(QFont::AbsoluteSpacing, -1);
QFontMetrics metrics(font);
painter->setFont(font);
QString text = QString::number(index + 1);
painter->drawText(-metrics.width(text) / 2, metrics.boundingRect('0').height() / 2, text);
}
}
QVariant GraphicEQFilterGUIItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
{
QVariant result = QGraphicsItem::itemChange(change, value);
if(change == ItemScenePositionHasChanged)
{
GraphicEQFilterGUIScene* s = qobject_cast<GraphicEQFilterGUIScene*>(scene());
s->itemMoved(index);
}
else if(change == ItemSelectedHasChanged)
{
GraphicEQFilterGUIScene* s = qobject_cast<GraphicEQFilterGUIScene*>(scene());
s->itemSelectionChanged(index, value.toBool());
}
else if(change == ItemPositionChange)
{
GraphicEQFilterGUIScene* s = qobject_cast<GraphicEQFilterGUIScene*>(scene());
if(s->getBandCount() != -1)
{
QPointF newPos = value.toPointF();
newPos.setX(s->hzToX(getHz()));
result = newPos;
}
}
return result;
}
int GraphicEQFilterGUIItem::getIndex() const
{
return index;
}
void GraphicEQFilterGUIItem::setIndex(int value)
{
index = value;
}
+47
View File
@@ -0,0 +1,47 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/widgets/FrequencyPlotItem.h"
class GraphicEQFilterGUIItem: public FrequencyPlotItem
{
public:
GraphicEQFilterGUIItem(int index, double hz, double db);
enum { Type = UserType + 2 };
virtual int type() const
{
return Type;
}
QRectF boundingRect() const override;
QPainterPath shape() const override;
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
int getIndex() const;
void setIndex(int value);
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant& value) override;
private:
int index;
};
+371
View File
@@ -0,0 +1,371 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <algorithm>
#include <QGraphicsSceneMouseEvent>
#include <QKeyEvent>
#include "Editor/widgets/FrequencyPlotView.h"
#include "GraphicEQFilterGUIScene.h"
using namespace std;
GraphicEQFilterGUIScene::GraphicEQFilterGUIScene(QObject* parent) :
FrequencyPlotScene(parent)
{
}
void GraphicEQFilterGUIScene::setNodes(const std::vector<FilterNode>& nodes)
{
noUpdateModel = true;
for(int i = (int)this->nodes.size() - 1; i >= 0; i--)
removeNode(i);
this->nodes = nodes;
int i = 0;
for(FilterNode node : nodes)
{
GraphicEQFilterGUIItem* item = new GraphicEQFilterGUIItem(i, node.freq, node.dbGain);
addItem(item);
item->updatePos();
items.append(item);
emit nodeInserted(i, node.freq, node.dbGain);
i++;
}
update();
noUpdateModel = false;
}
void GraphicEQFilterGUIScene::addNode(double hz, double db)
{
FilterNode node(hz, db);
vector<FilterNode>::iterator it = lower_bound(nodes.begin(), nodes.end(), node);
int index = it - nodes.begin();
nodes.insert(it, node);
GraphicEQFilterGUIItem* item = new GraphicEQFilterGUIItem(index, hz, db);
addItem(item);
item->updatePos();
items.insert(index, item);
for(int i = index + 1; i < items.size(); i++)
items[i]->setIndex(i);
emit nodeInserted(index, hz, db);
QRectF rect = sceneRect();
if(index > 0)
rect.setLeft(items[index - 1]->x());
if(index + 1 < items.size())
rect.setRight(items[index + 1]->x());
update(rect);
for(int i = index + 1; i < items.size(); i++)
items[i]->update();
if(!noUpdateModel)
emit updateModel();
}
void GraphicEQFilterGUIScene::removeNode(int index)
{
nodes.erase(nodes.begin() + index);
GraphicEQFilterGUIItem* item = items[index];
removeItem(item);
items.removeAt(index);
for(int i = index; i < items.size(); i++)
items[i]->setIndex(i);
emit nodeRemoved(index);
QRectF rect = sceneRect();
if(index > 0)
rect.setLeft(items[index - 1]->x());
if(index < items.size())
rect.setRight(items[index]->x());
update(rect);
for(int i = index; i < items.size(); i++)
items[i]->update();
if(!noUpdateModel)
emit updateModel();
}
void GraphicEQFilterGUIScene::setNode(int index, double hz, double db)
{
GraphicEQFilterGUIItem* item = items[index];
item->setHz(hz);
item->setDb(db);
item->updatePos();
FilterNode node(hz, db);
vector<FilterNode>::iterator it = lower_bound(nodes.begin(), nodes.end(), node);
int newIndex = it - nodes.begin();
if(newIndex > index)
newIndex--;
if(newIndex != index)
{
items.move(index, newIndex);
if(newIndex < index)
{
for(int i = index; i > newIndex; i--)
nodes[i] = nodes[i - 1];
for(int i = newIndex; i <= index; i++)
items[i]->setIndex(i);
emit nodeMoved(index, newIndex);
}
else
{
for(int i = index; i < newIndex; i++)
nodes[i] = nodes[i + 1];
for(int i = index; i <= newIndex; i++)
items[i]->setIndex(i);
emit nodeMoved(index, newIndex);
}
}
nodes[newIndex] = node;
emit nodeUpdated(newIndex, hz, db);
QRectF rect = sceneRect();
int lowerIndex = min(index, newIndex);
int upperIndex = max(index, newIndex);
if(lowerIndex > 0)
rect.setLeft(items[lowerIndex - 1]->x());
if(upperIndex + 1 < items.size())
rect.setRight(items[upperIndex + 1]->x());
update(rect);
if(!noUpdateModel)
emit updateModel();
}
void GraphicEQFilterGUIScene::setSelectedNodes(QSet<int> indices)
{
for(GraphicEQFilterGUIItem* item : items)
item->setSelected(indices.contains(item->getIndex()));
}
QSet<int> GraphicEQFilterGUIScene::getSelectedIndices()
{
QSet<int> set;
for(GraphicEQFilterGUIItem* item : items)
if(item->isSelected())
set.insert(item->getIndex());
return set;
}
void GraphicEQFilterGUIScene::itemMoved(int index)
{
GraphicEQFilterGUIItem* item = items[index];
double db = yToDb(item->scenePos().y());
double oldHz = item->getHz();
double hz;
if(getBandCount() != -1)
{
hz = oldHz;
}
else
{
hz = xToHz(item->scenePos().x());
if(hz >= 10000)
hz = round(hz);
else
hz = round(hz * 10) / 10;
item->setHz(hz);
}
if(getZoom() < 4)
db = round(db * 10) / 10;
else
db = round(db * 100) / 100;
item->setDb(db);
int newIndex = index;
if(hz < oldHz)
{
while(newIndex > 0 && nodes[newIndex - 1].freq > hz)
{
nodes[newIndex] = nodes[newIndex - 1];
items[newIndex] = items[newIndex - 1];
items[newIndex]->setIndex(newIndex);
newIndex--;
}
}
else if(hz > oldHz)
{
while(newIndex < (int)nodes.size() - 1 && nodes[newIndex + 1].freq < hz)
{
nodes[newIndex] = nodes[newIndex + 1];
items[newIndex] = items[newIndex + 1];
items[newIndex]->setIndex(newIndex);
newIndex++;
}
}
nodes[newIndex] = FilterNode(hz, db);
if(newIndex != index)
{
items[newIndex] = item;
item->setIndex(newIndex);
emit nodeMoved(index, newIndex);
}
emit nodeUpdated(newIndex, hz, db);
QRectF rect = sceneRect();
int lowerIndex = min(index, newIndex);
int upperIndex = max(index, newIndex);
if(lowerIndex > 0)
rect.setLeft(items[lowerIndex - 1]->x());
if(upperIndex + 1 < items.size())
rect.setRight(items[upperIndex + 1]->x());
update(rect);
if(!noUpdateModel)
emit updateModel();
}
void GraphicEQFilterGUIScene::itemSelectionChanged(int index, bool selected)
{
emit nodeSelectionChanged(index, selected);
}
void GraphicEQFilterGUIScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
{
if(getBandCount() != -1)
return;
double hz = xToHz(event->scenePos().x());
double db = yToDb(event->scenePos().y());
addNode(hz, db);
}
void GraphicEQFilterGUIScene::keyPressEvent(QKeyEvent* event)
{
switch(event->key())
{
case Qt::Key_Delete:
if(getBandCount() == -1)
{
for(QGraphicsItem* item : selectedItems())
{
GraphicEQFilterGUIItem* plotItem = qgraphicsitem_cast<GraphicEQFilterGUIItem*>(item);
if(plotItem != NULL)
{
// this works for multiple items because the index of the other items is updated inside removeNode
int index = plotItem->getIndex();
removeNode(index);
}
}
}
break;
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Left:
case Qt::Key_Right:
for(QGraphicsItem* item : selectedItems())
{
GraphicEQFilterGUIItem* plotItem = qgraphicsitem_cast<GraphicEQFilterGUIItem*>(item);
if(plotItem != NULL)
{
int index = plotItem->getIndex();
FilterNode node = nodes[index];
switch(event->key())
{
case Qt::Key_Up:
node.dbGain += 1;
break;
case Qt::Key_Down:
node.dbGain -= 1;
break;
case Qt::Key_Left:
node.freq -= 1;
break;
case Qt::Key_Right:
node.freq += 1;
break;
}
setNode(index, node.freq, node.dbGain);
}
}
break;
case Qt::Key_A:
if(event->modifiers() & Qt::ControlModifier)
{
QPainterPath painterPath;
painterPath.addRect(sceneRect());
setSelectionArea(painterPath);
}
break;
}
}
vector<FilterNode>& GraphicEQFilterGUIScene::getNodes()
{
return nodes;
}
int GraphicEQFilterGUIScene::verifyBands(const std::vector<FilterNode>& nodes)
{
const vector<double>& bands = getBands((int)nodes.size());
int bandCount = -1;
if(!bands.empty())
{
bandCount = (int)nodes.size();
for(unsigned i = 0; i < nodes.size(); i++)
{
if(abs(nodes[i].freq - bands[i]) > 0.1)
{
bandCount = -1;
break;
}
}
}
return bandCount;
}
void GraphicEQFilterGUIScene::setBandCount(int value)
{
if(value != getBandCount())
{
const vector<double>& bands = getBands(value);
if(!bands.empty())
{
vector<FilterNode> newNodes;
GainIterator gainIterator(nodes);
for(double band : bands)
{
double dbGain = gainIterator.gainAt(band);
dbGain = round(dbGain * 100) / 100;
FilterNode node(band, dbGain);
newNodes.push_back(node);
}
setNodes(newNodes);
}
FrequencyPlotScene::setBandCount(value);
if(!noUpdateModel)
emit updateModel();
}
}
+63
View File
@@ -0,0 +1,63 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include <vector>
#include "Editor/widgets/FrequencyPlotScene.h"
#include "helpers/GainIterator.h"
#include "GraphicEQFilterGUIItem.h"
class GraphicEQFilterGUIScene : public FrequencyPlotScene
{
Q_OBJECT
public:
explicit GraphicEQFilterGUIScene(QObject *parent = 0);
void setNodes(const std::vector<FilterNode>& nodes);
void addNode(double hz, double db);
void removeNode(int index);
void setNode(int index, double hz, double db);
void setSelectedNodes(QSet<int> indices);
QSet<int> getSelectedIndices();
void itemMoved(int index);
void itemSelectionChanged(int index, bool selected);
std::vector<FilterNode>& getNodes();
int verifyBands(const std::vector<FilterNode>& nodes);
void setBandCount(int value) override;
signals:
void nodeInserted(int index, double hz, double db);
void nodeRemoved(int index);
void nodeUpdated(int index, double hz, double db);
void nodeMoved(int fromIndex, int toIndex);
void nodeSelectionChanged(int index, bool selected);
void updateModel();
protected:
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
private:
std::vector<FilterNode> nodes;
QList<GraphicEQFilterGUIItem*> items;
bool noUpdateModel = false;
};
+59
View File
@@ -0,0 +1,59 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "GraphicEQFilterGUIScene.h"
#include "GraphicEQFilterGUIView.h"
GraphicEQFilterGUIView::GraphicEQFilterGUIView(QWidget *parent) :
FrequencyPlotView(parent)
{
}
void GraphicEQFilterGUIView::drawBackground(QPainter* painter, const QRectF& rect)
{
FrequencyPlotView::drawBackground(painter, rect);
painter->setRenderHint(QPainter::Antialiasing, true);
GraphicEQFilterGUIScene* s = qobject_cast<GraphicEQFilterGUIScene*>(scene());
std::vector<FilterNode>& nodes = s->getNodes();
GainIterator gainIterator(nodes);
QPainterPath path;
bool first = true;
double lastDb = -1000;
for(int x = rect.left() - 1; x <= rect.right() + 1; x++)
{
double hz = s->xToHz(x);
double db = gainIterator.gainAt(hz);
double y = s->dbToY(db);
if(db == lastDb)
y = floor(y) + 0.5;
lastDb = db;
if(first)
{
path.moveTo(x, y);
first = false;
}
else
{
path.lineTo(x, y);
}
}
painter->setPen(Qt::black);
painter->drawPath(path);
}
+33
View File
@@ -0,0 +1,33 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/widgets/FrequencyPlotView.h"
class GraphicEQFilterGUIView : public FrequencyPlotView
{
Q_OBJECT
public:
explicit GraphicEQFilterGUIView(QWidget *parent = 0);
protected:
void drawBackground(QPainter* painter, const QRectF& rect) override;
};
+85
View File
@@ -0,0 +1,85 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 <QFileDialog>
#include "IncludeFilterGUI.h"
#include "ui_IncludeFilterGUI.h"
IncludeFilterGUI::IncludeFilterGUI(FilterTable* filterTable, const QString& path) :
ui(new Ui::IncludeFilterGUI), filterTable(filterTable)
{
ui->setupUi(this);
ui->pathLineEdit->setText(path);
}
IncludeFilterGUI::~IncludeFilterGUI()
{
delete ui;
}
void IncludeFilterGUI::store(QString& command, QString& parameters)
{
command = "Include";
parameters = ui->pathLineEdit->text();
}
void IncludeFilterGUI::on_selectFileToolButton_clicked()
{
QFileInfo fileInfo(filterTable->getConfigPath());
QDir configDir = fileInfo.absoluteDir();
QString path = ui->pathLineEdit->text();
if(path.length() > 0)
fileInfo.setFile(configDir, path);
QFileDialog dialog(this, tr("Include file"), fileInfo.absolutePath(), "*.txt");
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("E-APO configurations (*.txt)"));
if(path.length() > 0)
dialog.selectFile(fileInfo.fileName());
if(dialog.exec() == QDialog::Accepted)
{
QString absolutePath = dialog.selectedFiles().first();
QString relativePath = configDir.relativeFilePath(absolutePath);
if(relativePath.startsWith("../../"))
relativePath = absolutePath;
ui->pathLineEdit->setText(QDir::toNativeSeparators(relativePath));
emit updateModel();
}
}
void IncludeFilterGUI::on_pathLineEdit_editingFinished()
{
emit updateModel();
}
void IncludeFilterGUI::on_openFileToolButton_clicked()
{
QFileInfo fileInfo(filterTable->getConfigPath());
QDir configDir = fileInfo.absoluteDir();
QString path = ui->pathLineEdit->text();
if(path.length() > 0)
{
fileInfo.setFile(configDir, path);
filterTable->openConfig(fileInfo.absoluteFilePath());
}
}
+47
View File
@@ -0,0 +1,47 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
#include "Editor/FilterTable.h"
namespace Ui {
class IncludeFilterGUI;
}
class IncludeFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit IncludeFilterGUI(FilterTable* filterTable, const QString& path);
~IncludeFilterGUI();
void store(QString& command, QString& parameters) override;
private slots:
void on_selectFileToolButton_clicked();
void on_pathLineEdit_editingFinished();
void on_openFileToolButton_clicked();
private:
Ui::IncludeFilterGUI *ui;
FilterTable* filterTable;
};
+87
View File
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IncludeFilterGUI</class>
<widget class="QWidget" name="IncludeFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>22</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,1,0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="includeLabel">
<property name="text">
<string>Include:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="ResizingLineEdit" name="pathLineEdit"/>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="selectFileToolButton">
<property name="text">
<string>Select file</string>
</property>
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/document-open.png</normaloff>:/icons/16x16/document-open.png</iconset>
</property>
</widget>
</item>
<item row="0" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="openFileToolButton">
<property name="text">
<string>Open file in editor</string>
</property>
<property name="icon">
<iconset resource="../Editor.qrc">
<normaloff>:/icons/16x16/go-up.png</normaloff>:/icons/16x16/go-up.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ResizingLineEdit</class>
<extends>QLineEdit</extends>
<header>Editor/widgets/ResizingLineEdit.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../Editor.qrc"/>
</resources>
<connections/>
</ui>
+49
View File
@@ -0,0 +1,49 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "IncludeFilterGUI.h"
#include "IncludeFilterGUIFactory.h"
IncludeFilterGUIFactory::IncludeFilterGUIFactory()
{
}
void IncludeFilterGUIFactory::initialize(FilterTable* filterTable)
{
this->filterTable = filterTable;
}
QList<FilterTemplate> IncludeFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Include (Include configuration file)"), "Include:", QStringList(tr("Control"))));
return list;
}
IFilterGUI* IncludeFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
IncludeFilterGUI* result = NULL;
if(command == "Include")
{
result = new IncludeFilterGUI(filterTable, parameters.trimmed());
}
return result;
}
+38
View File
@@ -0,0 +1,38 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class IncludeFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
explicit IncludeFilterGUIFactory();
void initialize(FilterTable* filterTable) override;
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
private:
FilterTable* filterTable;
};
+58
View File
@@ -0,0 +1,58 @@
/*
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 <cmath>
#include "PreampFilterGUI.h"
#include "ui_PreampFilterGUI.h"
using namespace std;
PreampFilterGUI::PreampFilterGUI(double dbGain):
ui(new Ui::PreampFilterGUI)
{
ui->setupUi(this);
ui->doubleSpinBox->setValue(dbGain);
}
PreampFilterGUI::~PreampFilterGUI()
{
delete ui;
}
void PreampFilterGUI::store(QString& command, QString& parameters)
{
command = "Preamp";
parameters = QString("%1 dB").arg(ui->doubleSpinBox->value());
}
void PreampFilterGUI::on_dial_valueChanged(int value)
{
ui->doubleSpinBox->setValue(value * 0.1);
}
void PreampFilterGUI::on_doubleSpinBox_valueChanged(double value)
{
bool previousValue = ui->dial->blockSignals(true);
ui->dial->setValue(round(value / 0.1));
ui->dial->blockSignals(previousValue);
emit updateModel();
}
+46
View File
@@ -0,0 +1,46 @@
/*
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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
#include <filters/PreampFilter.h>
namespace Ui
{
class PreampFilterGUI;
}
class PreampFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
PreampFilterGUI(double dbGain);
~PreampFilterGUI();
void store(QString& command, QString& parameters) override;
private slots:
void on_doubleSpinBox_valueChanged(double value);
void on_dial_valueChanged(int value);
private:
Ui::PreampFilterGUI* ui;
};
+134
View File
@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PreampFilterGUI</class>
<widget class="QWidget" name="PreampFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>525</width>
<height>66</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="4">
<widget class="QLabel" name="gainLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Gain:</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QDoubleSpinBox" name="doubleSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="suffix">
<string> dB</string>
</property>
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QDial" name="dial">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>66</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>66</height>
</size>
</property>
<property name="minimum">
<number>-200</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="pageStep">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="notchTarget">
<double>9.850000000000000</double>
</property>
<property name="notchesVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="5" rowspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>229</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Preamplification:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+53
View File
@@ -0,0 +1,53 @@
/*
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 "PreampFilterGUI.h"
#include <filters/PreampFilterFactory.h>
#include "PreampFilterGUIFactory.h"
QList<FilterTemplate> PreampFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Preamp (Preamplification)"), "Preamp: 0 dB", QStringList(tr("Basic filters"))));
return list;
}
IFilterGUI* PreampFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
PreampFilterGUI* result = NULL;
if(command == "Preamp")
{
PreampFilterFactory factory;
std::vector<IFilter*> filters = factory.createFilter(L"", command.toStdWString(), parameters.toStdWString());
if(!filters.empty())
{
PreampFilter* filter = (PreampFilter*)filters[0];
result = new PreampFilterGUI(filter->getDbGain());
}
for(IFilter* f : filters)
{
f->~IFilter();
MemoryHelper::free(f);
}
}
return result;
}
+31
View File
@@ -0,0 +1,31 @@
/*
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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class PreampFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
};
+66
View File
@@ -0,0 +1,66 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "StageFilterGUI.h"
#include "ui_StageFilterGUI.h"
StageFilterGUI::StageFilterGUI(const QString& parameters) :
ui(new Ui::StageFilterGUI)
{
ui->setupUi(this);
QStringList parts = parameters.toLower().split(' ');
ui->preMixCheckBox->setChecked(parts.contains("pre-mix"));
ui->postMixCheckBox->setChecked(parts.contains("post-mix"));
ui->captureCheckBox->setChecked(parts.contains("capture"));
}
StageFilterGUI::~StageFilterGUI()
{
delete ui;
}
void StageFilterGUI::store(QString& command, QString& parameters)
{
command = "Stage";
QStringList list;
if(ui->preMixCheckBox->isChecked())
list.append("pre-mix");
if(ui->postMixCheckBox->isChecked())
list.append("post-mix");
if(ui->captureCheckBox->isChecked())
list.append("capture");
parameters = list.join(' ');
}
void StageFilterGUI::on_preMixCheckBox_toggled(bool checked)
{
emit updateModel();
}
void StageFilterGUI::on_postMixCheckBox_toggled(bool checked)
{
emit updateModel();
}
void StageFilterGUI::on_captureCheckBox_toggled(bool checked)
{
emit updateModel();
}
+47
View File
@@ -0,0 +1,47 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUI.h"
namespace Ui {
class StageFilterGUI;
}
class StageFilterGUI : public IFilterGUI
{
Q_OBJECT
public:
explicit StageFilterGUI(const QString& parameters);
~StageFilterGUI();
void store(QString& command, QString& parameters) override;
private slots:
void on_preMixCheckBox_toggled(bool checked);
void on_postMixCheckBox_toggled(bool checked);
void on_captureCheckBox_toggled(bool checked);
private:
Ui::StageFilterGUI *ui;
};
+92
View File
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>StageFilterGUI</class>
<widget class="QWidget" name="StageFilterGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>639</width>
<height>68</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Selected processing stage:</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="playbackGroupBox">
<property name="title">
<string>Playback</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="preMixCheckBox">
<property name="text">
<string>Pre-mix</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="postMixCheckBox">
<property name="text">
<string>Post-mix</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="captureGroupBox">
<property name="title">
<string>Capture</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="captureCheckBox">
<property name="text">
<string>Capture</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+40
View File
@@ -0,0 +1,40 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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 "StageFilterGUI.h"
#include "StageFilterGUIFactory.h"
QList<FilterTemplate> StageFilterGUIFactory::createFilterTemplates()
{
QList<FilterTemplate> list;
list.append(FilterTemplate(tr("Stage (Select processing stage)"), "Stage: post-mix", QStringList(tr("Control"))));
return list;
}
IFilterGUI* StageFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
{
StageFilterGUI* result = NULL;
if(command == "Stage")
{
result = new StageFilterGUI(parameters);
}
return result;
}
+31
View File
@@ -0,0 +1,31 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 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.
*/
#pragma once
#include "Editor/IFilterGUIFactory.h"
class StageFilterGUIFactory : public IFilterGUIFactory
{
Q_OBJECT
public:
QList<FilterTemplate> createFilterTemplates() override;
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
};