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:
1 parent
d68b958bc8
commit
b8cdd47f71
284 files changed
+17622
-322
No files matched your search
@@ -17,6 +17,7 @@
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
@@ -214,7 +215,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
printf("\nWriting output to %s\n", output.c_str());
|
printf("\nWriting output to %s\n", output.c_str());
|
||||||
|
|
||||||
SF_INFO info = {frameCount, sampleRate, channelCount, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 0};
|
SF_INFO info = {frameCount, (int)sampleRate, (int)channelCount, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 0};
|
||||||
SNDFILE* outFile = sf_open(output.c_str(), SFM_WRITE, &info);
|
SNDFILE* outFile = sf_open(output.c_str(), SFM_WRITE, &info);
|
||||||
if(outFile == NULL)
|
if(outFile == NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
+43
-21
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
@@ -22,29 +22,34 @@
|
|||||||
<ProjectGuid>{D4474852-5724-4253-95C6-7A6DC424F194}</ProjectGuid>
|
<ProjectGuid>{D4474852-5724-4253-95C6-7A6DC424F194}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>Benchmark</RootNamespace>
|
<RootNamespace>Benchmark</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
@@ -64,28 +69,27 @@
|
|||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;C:\Program Files (x86)\fftw3;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files (x86)\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files (x86)\libsndfile\lib;C:\Program Files (x86)\fftw3;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;C:\Program Files\fftw3;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files\libsndfile\lib;C:\Program Files\fftw3;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;C:\Program Files (x86)\fftw3;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files (x86)\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files (x86)\libsndfile\lib;C:\Program Files (x86)\fftw3;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir);C:\Program Files\tclap-1.2.1\include;C:\Program Files\libsndfile\include;C:\Program Files\fftw3;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>C:\Program Files\libsndfile\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>C:\Program Files\libsndfile\lib;C:\Program Files\fftw3;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@@ -93,13 +97,12 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>muparserxd.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>muparserxd.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@@ -107,14 +110,13 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>muparserxd.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>muparserxd.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
@@ -126,14 +128,13 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>muparserx.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>muparserx.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
@@ -145,7 +146,7 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>muparserx.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>muparserx.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -156,12 +157,16 @@
|
|||||||
<ClCompile Include="..\filters\BiQuadFilterFactory.cpp" />
|
<ClCompile Include="..\filters\BiQuadFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\ChannelFilter.cpp" />
|
<ClCompile Include="..\filters\ChannelFilter.cpp" />
|
||||||
<ClCompile Include="..\filters\ChannelFilterFactory.cpp" />
|
<ClCompile Include="..\filters\ChannelFilterFactory.cpp" />
|
||||||
|
<ClCompile Include="..\filters\ConvolutionFilter.cpp" />
|
||||||
|
<ClCompile Include="..\filters\ConvolutionFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\CopyFilter.cpp" />
|
<ClCompile Include="..\filters\CopyFilter.cpp" />
|
||||||
<ClCompile Include="..\filters\CopyFilterFactory.cpp" />
|
<ClCompile Include="..\filters\CopyFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\DelayFilter.cpp" />
|
<ClCompile Include="..\filters\DelayFilter.cpp" />
|
||||||
<ClCompile Include="..\filters\DelayFilterFactory.cpp" />
|
<ClCompile Include="..\filters\DelayFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\DeviceFilterFactory.cpp" />
|
<ClCompile Include="..\filters\DeviceFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\ExpressionFilterFactory.cpp" />
|
<ClCompile Include="..\filters\ExpressionFilterFactory.cpp" />
|
||||||
|
<ClCompile Include="..\filters\GraphicEQFilter.cpp" />
|
||||||
|
<ClCompile Include="..\filters\GraphicEQFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\IfFilterFactory.cpp" />
|
<ClCompile Include="..\filters\IfFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\IIRFilter.cpp" />
|
<ClCompile Include="..\filters\IIRFilter.cpp" />
|
||||||
<ClCompile Include="..\filters\IIRFilterFactory.cpp" />
|
<ClCompile Include="..\filters\IIRFilterFactory.cpp" />
|
||||||
@@ -169,14 +174,23 @@
|
|||||||
<ClCompile Include="..\filters\PreampFilter.cpp" />
|
<ClCompile Include="..\filters\PreampFilter.cpp" />
|
||||||
<ClCompile Include="..\filters\PreampFilterFactory.cpp" />
|
<ClCompile Include="..\filters\PreampFilterFactory.cpp" />
|
||||||
<ClCompile Include="..\filters\StageFilterFactory.cpp" />
|
<ClCompile Include="..\filters\StageFilterFactory.cpp" />
|
||||||
|
<ClCompile Include="..\helpers\ChannelHelper.cpp" />
|
||||||
|
<ClCompile Include="..\helpers\GainIterator.cpp" />
|
||||||
<ClCompile Include="..\helpers\LogHelper.cpp" />
|
<ClCompile Include="..\helpers\LogHelper.cpp" />
|
||||||
<ClCompile Include="..\helpers\MemoryHelper.cpp" />
|
<ClCompile Include="..\helpers\MemoryHelper.cpp" />
|
||||||
<ClCompile Include="..\helpers\RegistryHelper.cpp" />
|
<ClCompile Include="..\helpers\RegistryHelper.cpp" />
|
||||||
<ClCompile Include="..\helpers\StringHelper.cpp" />
|
<ClCompile Include="..\helpers\StringHelper.cpp" />
|
||||||
<ClCompile Include="..\IFilter.cpp" />
|
<ClCompile Include="..\IFilter.cpp" />
|
||||||
|
<ClCompile Include="..\libHybridConv-0.1.1\libHybridConv_eapo.cpp" />
|
||||||
<ClCompile Include="..\parser\RegexFunctions.cpp" />
|
<ClCompile Include="..\parser\RegexFunctions.cpp" />
|
||||||
<ClCompile Include="..\parser\RegistryFunctions.cpp" />
|
<ClCompile Include="..\parser\RegistryFunctions.cpp" />
|
||||||
<ClCompile Include="..\parser\StringOperators.cpp" />
|
<ClCompile Include="..\parser\StringOperators.cpp" />
|
||||||
|
<ClCompile Include="..\stdafx.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="Benchmark.cpp" />
|
<ClCompile Include="Benchmark.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -187,12 +201,16 @@
|
|||||||
<ClInclude Include="..\filters\BiQuadFilterFactory.h" />
|
<ClInclude Include="..\filters\BiQuadFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\ChannelFilter.h" />
|
<ClInclude Include="..\filters\ChannelFilter.h" />
|
||||||
<ClInclude Include="..\filters\ChannelFilterFactory.h" />
|
<ClInclude Include="..\filters\ChannelFilterFactory.h" />
|
||||||
|
<ClInclude Include="..\filters\ConvolutionFilter.h" />
|
||||||
|
<ClInclude Include="..\filters\ConvolutionFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\CopyFilter.h" />
|
<ClInclude Include="..\filters\CopyFilter.h" />
|
||||||
<ClInclude Include="..\filters\CopyFilterFactory.h" />
|
<ClInclude Include="..\filters\CopyFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\DelayFilter.h" />
|
<ClInclude Include="..\filters\DelayFilter.h" />
|
||||||
<ClInclude Include="..\filters\DelayFilterFactory.h" />
|
<ClInclude Include="..\filters\DelayFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\DeviceFilterFactory.h" />
|
<ClInclude Include="..\filters\DeviceFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\ExpressionFilterFactory.h" />
|
<ClInclude Include="..\filters\ExpressionFilterFactory.h" />
|
||||||
|
<ClInclude Include="..\filters\GraphicEQFilter.h" />
|
||||||
|
<ClInclude Include="..\filters\GraphicEQFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\IfFilterFactory.h" />
|
<ClInclude Include="..\filters\IfFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\IIRFilter.h" />
|
<ClInclude Include="..\filters\IIRFilter.h" />
|
||||||
<ClInclude Include="..\filters\IIRFilterFactory.h" />
|
<ClInclude Include="..\filters\IIRFilterFactory.h" />
|
||||||
@@ -200,6 +218,8 @@
|
|||||||
<ClInclude Include="..\filters\PreampFilter.h" />
|
<ClInclude Include="..\filters\PreampFilter.h" />
|
||||||
<ClInclude Include="..\filters\PreampFilterFactory.h" />
|
<ClInclude Include="..\filters\PreampFilterFactory.h" />
|
||||||
<ClInclude Include="..\filters\StageFilterFactory.h" />
|
<ClInclude Include="..\filters\StageFilterFactory.h" />
|
||||||
|
<ClInclude Include="..\helpers\ChannelHelper.h" />
|
||||||
|
<ClInclude Include="..\helpers\GainIterator.h" />
|
||||||
<ClInclude Include="..\helpers\LogHelper.h" />
|
<ClInclude Include="..\helpers\LogHelper.h" />
|
||||||
<ClInclude Include="..\helpers\MemoryHelper.h" />
|
<ClInclude Include="..\helpers\MemoryHelper.h" />
|
||||||
<ClInclude Include="..\helpers\PrecisionTimer.h" />
|
<ClInclude Include="..\helpers\PrecisionTimer.h" />
|
||||||
@@ -207,9 +227,11 @@
|
|||||||
<ClInclude Include="..\helpers\StringHelper.h" />
|
<ClInclude Include="..\helpers\StringHelper.h" />
|
||||||
<ClInclude Include="..\IFilter.h" />
|
<ClInclude Include="..\IFilter.h" />
|
||||||
<ClInclude Include="..\IFilterFactory.h" />
|
<ClInclude Include="..\IFilterFactory.h" />
|
||||||
|
<ClInclude Include="..\libHybridConv-0.1.1\libHybridConv_eapo.h" />
|
||||||
<ClInclude Include="..\parser\RegexFunctions.h" />
|
<ClInclude Include="..\parser\RegexFunctions.h" />
|
||||||
<ClInclude Include="..\parser\RegistryFunctions.h" />
|
<ClInclude Include="..\parser\RegistryFunctions.h" />
|
||||||
<ClInclude Include="..\parser\StringOperators.h" />
|
<ClInclude Include="..\parser\StringOperators.h" />
|
||||||
|
<ClInclude Include="..\stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|||||||
@@ -80,6 +80,28 @@
|
|||||||
<ClCompile Include="..\parser\StringOperators.cpp">
|
<ClCompile Include="..\parser\StringOperators.cpp">
|
||||||
<Filter>parser</Filter>
|
<Filter>parser</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\helpers\ChannelHelper.cpp">
|
||||||
|
<Filter>helpers</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\filters\GraphicEQFilterFactory.cpp">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\filters\GraphicEQFilter.cpp">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\helpers\GainIterator.cpp">
|
||||||
|
<Filter>helpers</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libHybridConv-0.1.1\libHybridConv_eapo.cpp">
|
||||||
|
<Filter>libHybridConv-0.1.1</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\filters\ConvolutionFilter.cpp">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\filters\ConvolutionFilterFactory.cpp">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\stdafx.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\FilterEngine.h" />
|
<ClInclude Include="..\FilterEngine.h" />
|
||||||
@@ -164,6 +186,28 @@
|
|||||||
<ClInclude Include="..\parser\StringOperators.h">
|
<ClInclude Include="..\parser\StringOperators.h">
|
||||||
<Filter>parser</Filter>
|
<Filter>parser</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\helpers\ChannelHelper.h">
|
||||||
|
<Filter>helpers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\filters\GraphicEQFilterFactory.h">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\filters\GraphicEQFilter.h">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\helpers\GainIterator.h">
|
||||||
|
<Filter>helpers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libHybridConv-0.1.1\libHybridConv_eapo.h">
|
||||||
|
<Filter>libHybridConv-0.1.1</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\filters\ConvolutionFilterFactory.h">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\filters\ConvolutionFilter.h">
|
||||||
|
<Filter>filters</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="parser">
|
<Filter Include="parser">
|
||||||
@@ -175,5 +219,8 @@
|
|||||||
<Filter Include="helpers">
|
<Filter Include="helpers">
|
||||||
<UniqueIdentifier>{4bf76d90-8b50-493a-848b-019f88fa1f11}</UniqueIdentifier>
|
<UniqueIdentifier>{4bf76d90-8b50-493a-848b-019f88fa1f11}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="libHybridConv-0.1.1">
|
||||||
|
<UniqueIdentifier>{35b3b6f1-e4df-4214-bd4c-fa058942e547}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
#include "EqualizerAPO.h"
|
#include "EqualizerAPO.h"
|
||||||
#include "helpers/LogHelper.h"
|
#include "helpers/LogHelper.h"
|
||||||
#include "ClassFactory.h"
|
#include "ClassFactory.h"
|
||||||
|
|||||||
@@ -17,10 +17,12 @@
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
|
#include <ObjBase.h>
|
||||||
#include "helpers/StringHelper.h"
|
#include "helpers/StringHelper.h"
|
||||||
#include "helpers/RegistryHelper.h"
|
#include "helpers/RegistryHelper.h"
|
||||||
#include "Configurator.h"
|
#include "Configurator.h"
|
||||||
@@ -55,6 +57,7 @@ void Configurator::onInitDialog(HWND hDlg)
|
|||||||
useOriginalAPOPreMix = GetDlgItem(hDlg, IDC_USE_ORIGINAL_APO_PRE_MIX);
|
useOriginalAPOPreMix = GetDlgItem(hDlg, IDC_USE_ORIGINAL_APO_PRE_MIX);
|
||||||
useOriginalAPOPostMix = GetDlgItem(hDlg, IDC_USE_ORIGINAL_APO_POST_MIX);
|
useOriginalAPOPostMix = GetDlgItem(hDlg, IDC_USE_ORIGINAL_APO_POST_MIX);
|
||||||
installModeComboBox = GetDlgItem(hDlg, IDC_INSTALL_MODE_COMBOBOX);
|
installModeComboBox = GetDlgItem(hDlg, IDC_INSTALL_MODE_COMBOBOX);
|
||||||
|
selectOneDeviceLabel = GetDlgItem(hDlg, IDC_SELECT_ONE_DEVICE);
|
||||||
|
|
||||||
expandTroubleShooting(false);
|
expandTroubleShooting(false);
|
||||||
|
|
||||||
@@ -118,6 +121,9 @@ void Configurator::onInitDialog(HWND hDlg)
|
|||||||
}
|
}
|
||||||
ComboBox_SetCurSel(installModeComboBox, 0);
|
ComboBox_SetCurSel(installModeComboBox, 0);
|
||||||
|
|
||||||
|
LoadStringW(hInstance, IDS_SELECT_ONE_DEVICE, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
|
||||||
|
SetWindowTextW(selectOneDeviceLabel, stringBuf);
|
||||||
|
|
||||||
for(int i=0; i<=1; i++)
|
for(int i=0; i<=1; i++)
|
||||||
{
|
{
|
||||||
HWND deviceList = deviceLists[i];
|
HWND deviceList = deviceLists[i];
|
||||||
@@ -143,6 +149,7 @@ void Configurator::onInitDialog(HWND hDlg)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
apoInfos[i] = DeviceAPOInfo::loadAllInfos(i==1);
|
apoInfos[i] = DeviceAPOInfo::loadAllInfos(i==1);
|
||||||
|
wstring defaultDevice = StringHelper::toLowerCase(DeviceAPOInfo::getDefaultDevice(i==1));
|
||||||
|
|
||||||
int itemCount=0;
|
int itemCount=0;
|
||||||
for(vector<DeviceAPOInfo>::iterator it = apoInfos[i].begin(); it != apoInfos[i].end(); it++)
|
for(vector<DeviceAPOInfo>::iterator it = apoInfos[i].begin(); it != apoInfos[i].end(); it++)
|
||||||
@@ -158,19 +165,31 @@ void Configurator::onInitDialog(HWND hDlg)
|
|||||||
{
|
{
|
||||||
ListView_SetCheckState(deviceList, itemCount, TRUE);
|
ListView_SetCheckState(deviceList, itemCount, TRUE);
|
||||||
if(it->canBeUpgraded())
|
if(it->canBeUpgraded())
|
||||||
LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
|
||||||
|
else if(it->isEnhancementsDisabled)
|
||||||
|
LoadStringW(hInstance, IDS_ENHANCEMENTS_WILL_BE_ENABLED, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
|
||||||
else
|
else
|
||||||
LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
ListView_SetItemText(deviceList, itemCount, 2, stringBuf);
|
|
||||||
}
|
}
|
||||||
else if(it->isExperimental())
|
else if(it->isExperimental())
|
||||||
{
|
{
|
||||||
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED_EXPERIMENTAL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED_EXPERIMENTAL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
ListView_SetItemText(deviceList, itemCount, 2, stringBuf);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(it->isDefaultDevice)
|
||||||
|
{
|
||||||
|
wstring statusText = stringBuf;
|
||||||
|
LoadStringW(hInstance, IDS_DEFAULT_DEVICE, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
|
statusText = wstring(stringBuf) + L", " + statusText;
|
||||||
|
|
||||||
|
ListView_SetItemText(deviceList, itemCount, 2, const_cast<wchar_t*>(statusText.c_str()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ListView_SetItemText(deviceList, itemCount, 2, stringBuf);
|
ListView_SetItemText(deviceList, itemCount, 2, stringBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,6 +205,12 @@ void Configurator::onInitDialog(HWND hDlg)
|
|||||||
ListView_SetColumnWidth(deviceList, 1, LVSCW_AUTOSIZE);
|
ListView_SetColumnWidth(deviceList, 1, LVSCW_AUTOSIZE);
|
||||||
ListView_SetColumnWidth(deviceList, 2, LVSCW_AUTOSIZE);
|
ListView_SetColumnWidth(deviceList, 2, LVSCW_AUTOSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!DeviceAPOInfo::checkProtectedAudioDG(true))
|
||||||
|
{
|
||||||
|
LoadStringW(hInstance, IDS_REGISTRY_VALUE_FIXED, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
|
||||||
|
MessageBoxW(hDlg, stringBuf, L"Info", MB_ICONINFORMATION | MB_OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configurator::onLvnItemChanged(unsigned sourceId, LPNMLISTVIEW info)
|
void Configurator::onLvnItemChanged(unsigned sourceId, LPNMLISTVIEW info)
|
||||||
@@ -221,7 +246,7 @@ bool Configurator::onButtonClicked(unsigned sourceId)
|
|||||||
info.install();
|
info.install();
|
||||||
else if(!ListView_GetCheckState(deviceList, i) && info.isInstalled)
|
else if(!ListView_GetCheckState(deviceList, i) && info.isInstalled)
|
||||||
info.uninstall();
|
info.uninstall();
|
||||||
else if(ListView_GetCheckState(deviceList, i) && (info.canBeUpgraded() || info.hasChanges()))
|
else if(ListView_GetCheckState(deviceList, i) && (info.canBeUpgraded() || info.hasChanges() || info.isEnhancementsDisabled))
|
||||||
{
|
{
|
||||||
info.uninstall();
|
info.uninstall();
|
||||||
info.load(info.deviceGuid);
|
info.load(info.deviceGuid);
|
||||||
@@ -398,6 +423,33 @@ void Configurator::onTcnSelChange(unsigned sourceId)
|
|||||||
updateButtons(index);
|
updateButtons(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Configurator::isAnySelected()
|
||||||
|
{
|
||||||
|
bool anySelected = false;
|
||||||
|
|
||||||
|
for(int index = 0; index <= 1; index++)
|
||||||
|
{
|
||||||
|
HWND deviceList = deviceLists[index];
|
||||||
|
|
||||||
|
for(int i = 0; i < ListView_GetItemCount(deviceList); i++)
|
||||||
|
{
|
||||||
|
LVITEM item;
|
||||||
|
item.iItem = i;
|
||||||
|
item.iSubItem = 0;
|
||||||
|
item.mask = LVIF_PARAM;
|
||||||
|
ListView_GetItem(deviceList, &item);
|
||||||
|
DeviceAPOInfo apoInfo = apoInfos[index][item.lParam];
|
||||||
|
if(ListView_GetCheckState(deviceList, i) != 0)
|
||||||
|
{
|
||||||
|
anySelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return anySelected;
|
||||||
|
}
|
||||||
|
|
||||||
bool Configurator::isChanged()
|
bool Configurator::isChanged()
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
@@ -415,7 +467,7 @@ bool Configurator::isChanged()
|
|||||||
ListView_GetItem(deviceList, &item);
|
ListView_GetItem(deviceList, &item);
|
||||||
DeviceAPOInfo apoInfo = apoInfos[index][item.lParam];
|
DeviceAPOInfo apoInfo = apoInfos[index][item.lParam];
|
||||||
if((ListView_GetCheckState(deviceList, i) != 0) != apoInfo.isInstalled
|
if((ListView_GetCheckState(deviceList, i) != 0) != apoInfo.isInstalled
|
||||||
|| ListView_GetCheckState(deviceList, i) && apoInfo.isInstalled && (apoInfo.canBeUpgraded() || apoInfo.hasChanges()))
|
|| ListView_GetCheckState(deviceList, i) && apoInfo.isInstalled && (apoInfo.canBeUpgraded() || apoInfo.hasChanges() || apoInfo.isEnhancementsDisabled))
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
break;
|
break;
|
||||||
@@ -442,7 +494,7 @@ bool Configurator::hasUpgrades()
|
|||||||
item.mask = LVIF_PARAM;
|
item.mask = LVIF_PARAM;
|
||||||
ListView_GetItem(deviceList, &item);
|
ListView_GetItem(deviceList, &item);
|
||||||
DeviceAPOInfo apoInfo = apoInfos[index][item.lParam];
|
DeviceAPOInfo apoInfo = apoInfos[index][item.lParam];
|
||||||
if(ListView_GetCheckState(deviceList, i) && apoInfo.isInstalled && apoInfo.canBeUpgraded())
|
if(ListView_GetCheckState(deviceList, i) && apoInfo.isInstalled && (apoInfo.canBeUpgraded() || apoInfo.isEnhancementsDisabled))
|
||||||
{
|
{
|
||||||
hasUpgrades = true;
|
hasUpgrades = true;
|
||||||
break;
|
break;
|
||||||
@@ -457,6 +509,7 @@ void Configurator::expandTroubleShooting(bool expand)
|
|||||||
{
|
{
|
||||||
int showCmd = expand ? SW_SHOW : SW_HIDE;
|
int showCmd = expand ? SW_SHOW : SW_HIDE;
|
||||||
ShowWindow(troubleShootingGroup, showCmd);
|
ShowWindow(troubleShootingGroup, showCmd);
|
||||||
|
showCmd = expand && !IsWindowEnabled(selectOneDeviceLabel) ? SW_SHOW : SW_HIDE;
|
||||||
ShowWindow(preMixLabel, showCmd);
|
ShowWindow(preMixLabel, showCmd);
|
||||||
ShowWindow(postMixLabel, showCmd);
|
ShowWindow(postMixLabel, showCmd);
|
||||||
ShowWindow(postMixLabel, showCmd);
|
ShowWindow(postMixLabel, showCmd);
|
||||||
@@ -465,6 +518,8 @@ void Configurator::expandTroubleShooting(bool expand)
|
|||||||
ShowWindow(useOriginalAPOPreMix, showCmd);
|
ShowWindow(useOriginalAPOPreMix, showCmd);
|
||||||
ShowWindow(useOriginalAPOPostMix, showCmd);
|
ShowWindow(useOriginalAPOPostMix, showCmd);
|
||||||
ShowWindow(installModeComboBox, showCmd);
|
ShowWindow(installModeComboBox, showCmd);
|
||||||
|
showCmd = expand && IsWindowEnabled(selectOneDeviceLabel) ? SW_SHOW : SW_HIDE;
|
||||||
|
ShowWindow(selectOneDeviceLabel, showCmd);
|
||||||
|
|
||||||
int y = expand ? 229 : 188;
|
int y = expand ? 229 : 188;
|
||||||
|
|
||||||
@@ -509,6 +564,8 @@ void Configurator::updateList(int listIndex, int itemIndex)
|
|||||||
LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
else if(apoInfo.isInstalled && apoInfo.hasChanges())
|
else if(apoInfo.isInstalled && apoInfo.hasChanges())
|
||||||
LoadStringW(hInstance, IDS_WILL_BE_CHANGED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_WILL_BE_CHANGED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
|
else if(apoInfo.isInstalled && apoInfo.isEnhancementsDisabled)
|
||||||
|
LoadStringW(hInstance, IDS_ENHANCEMENTS_WILL_BE_ENABLED, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
|
||||||
else if(apoInfo.isInstalled)
|
else if(apoInfo.isInstalled)
|
||||||
LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
else if(apoInfo.isExperimental())
|
else if(apoInfo.isExperimental())
|
||||||
@@ -516,7 +573,18 @@ void Configurator::updateList(int listIndex, int itemIndex)
|
|||||||
else
|
else
|
||||||
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
|
|
||||||
ListView_SetItemText(deviceList, itemIndex, 2, stringBuf);
|
if(apoInfo.isDefaultDevice)
|
||||||
|
{
|
||||||
|
wstring statusText = stringBuf;
|
||||||
|
LoadStringW(hInstance, IDS_DEFAULT_DEVICE, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
|
||||||
|
statusText = wstring(stringBuf) + L", " + statusText;
|
||||||
|
|
||||||
|
ListView_SetItemText(deviceList, itemIndex, 2, const_cast<wchar_t*>(statusText.c_str()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ListView_SetItemText(deviceList, itemIndex, 2, stringBuf);
|
||||||
|
}
|
||||||
|
|
||||||
ListView_SetColumnWidth(deviceList, 2, LVSCW_AUTOSIZE);
|
ListView_SetColumnWidth(deviceList, 2, LVSCW_AUTOSIZE);
|
||||||
}
|
}
|
||||||
@@ -526,7 +594,21 @@ void Configurator::updateButtons(int listIndex)
|
|||||||
{
|
{
|
||||||
HWND deviceList = deviceLists[listIndex];
|
HWND deviceList = deviceLists[listIndex];
|
||||||
|
|
||||||
EnableWindow(okButton, isChanged());
|
wchar_t stringBuf[255];
|
||||||
|
bool changed = isChanged();
|
||||||
|
if(changed || !isAnySelected())
|
||||||
|
{
|
||||||
|
ShowWindow(okButton, SW_SHOW);
|
||||||
|
EnableWindow(okButton, changed);
|
||||||
|
LoadStringW(hInstance, IDS_CANCEL, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
|
||||||
|
SetWindowText(cancelButton, stringBuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShowWindow(okButton, SW_HIDE);
|
||||||
|
LoadStringW(hInstance, IDS_CLOSE, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
|
||||||
|
SetWindowText(cancelButton, stringBuf);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned selectedCount = ListView_GetSelectedCount(deviceList);
|
unsigned selectedCount = ListView_GetSelectedCount(deviceList);
|
||||||
EnableWindow(copyDeviceCommandButton, selectedCount > 0);
|
EnableWindow(copyDeviceCommandButton, selectedCount > 0);
|
||||||
@@ -558,6 +640,7 @@ void Configurator::updateButtons(int listIndex)
|
|||||||
EnableWindow(useOriginalAPOPreMix, enable && hasOriginalAPOPreMix && installState.installPreMix);
|
EnableWindow(useOriginalAPOPreMix, enable && hasOriginalAPOPreMix && installState.installPreMix);
|
||||||
EnableWindow(useOriginalAPOPostMix, enable && !isInput && hasOriginalAPOPostMix && installState.installPostMix);
|
EnableWindow(useOriginalAPOPostMix, enable && !isInput && hasOriginalAPOPostMix && installState.installPostMix);
|
||||||
EnableWindow(installModeComboBox, enable);
|
EnableWindow(installModeComboBox, enable);
|
||||||
|
EnableWindow(selectOneDeviceLabel, !enable);
|
||||||
|
|
||||||
Button_SetCheck(installPreMix, installState.installPreMix);
|
Button_SetCheck(installPreMix, installState.installPreMix);
|
||||||
Button_SetCheck(installPostMix, installState.installPostMix);
|
Button_SetCheck(installPostMix, installState.installPostMix);
|
||||||
@@ -566,6 +649,8 @@ void Configurator::updateButtons(int listIndex)
|
|||||||
|
|
||||||
if(RegistryHelper::isWindowsVersionAtLeast(6, 3)) // Windows 8.1
|
if(RegistryHelper::isWindowsVersionAtLeast(6, 3)) // Windows 8.1
|
||||||
ComboBox_SetCurSel(installModeComboBox, installState.installMode);
|
ComboBox_SetCurSel(installModeComboBox, installState.installMode);
|
||||||
|
|
||||||
|
expandTroubleShooting(Button_GetCheck(toggleTroubleShooting) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
INT_PTR CALLBACK dlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
INT_PTR CALLBACK dlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
@@ -575,6 +660,8 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
|
|||||||
LPWSTR lpCmdLine,
|
LPWSTR lpCmdLine,
|
||||||
int nCmdShow)
|
int nCmdShow)
|
||||||
{
|
{
|
||||||
|
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
|
|
||||||
INITCOMMONCONTROLSEX InitCtrls;
|
INITCOMMONCONTROLSEX InitCtrls;
|
||||||
InitCtrls.dwSize = sizeof(InitCtrls);
|
InitCtrls.dwSize = sizeof(InitCtrls);
|
||||||
InitCtrls.dwICC = ICC_WIN95_CLASSES;
|
InitCtrls.dwICC = ICC_WIN95_CLASSES;
|
||||||
@@ -608,6 +695,8 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
|
|||||||
configurator = new Configurator(hInstance, lpCmdLine);
|
configurator = new Configurator(hInstance, lpCmdLine);
|
||||||
DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINWINDOW), GetDesktopWindow(), dlgProc);
|
DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINWINDOW), GetDesktopWindow(), dlgProc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public:
|
|||||||
void onLvnItemChanged(unsigned sourceId, LPNMLISTVIEW info);
|
void onLvnItemChanged(unsigned sourceId, LPNMLISTVIEW info);
|
||||||
bool onButtonClicked(unsigned sourceId);
|
bool onButtonClicked(unsigned sourceId);
|
||||||
void onTcnSelChange(unsigned sourceId);
|
void onTcnSelChange(unsigned sourceId);
|
||||||
|
bool isAnySelected();
|
||||||
bool isChanged();
|
bool isChanged();
|
||||||
bool hasUpgrades();
|
bool hasUpgrades();
|
||||||
|
|
||||||
@@ -53,6 +54,7 @@ private:
|
|||||||
HWND useOriginalAPOPreMix;
|
HWND useOriginalAPOPreMix;
|
||||||
HWND useOriginalAPOPostMix;
|
HWND useOriginalAPOPostMix;
|
||||||
HWND installModeComboBox;
|
HWND installModeComboBox;
|
||||||
|
HWND selectOneDeviceLabel;
|
||||||
|
|
||||||
std::wstring cmdLine;
|
std::wstring cmdLine;
|
||||||
void expandTroubleShooting(bool expand);
|
void expandTroubleShooting(bool expand);
|
||||||
|
|||||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
<ClInclude Include="..\helpers\PrecisionTimer.h" />
|
<ClInclude Include="..\helpers\PrecisionTimer.h" />
|
||||||
<ClInclude Include="..\helpers\RegistryHelper.h" />
|
<ClInclude Include="..\helpers\RegistryHelper.h" />
|
||||||
<ClInclude Include="..\helpers\StringHelper.h" />
|
<ClInclude Include="..\helpers\StringHelper.h" />
|
||||||
|
<ClInclude Include="..\stdafx.h" />
|
||||||
<ClInclude Include="Configurator.h" />
|
<ClInclude Include="Configurator.h" />
|
||||||
<ClInclude Include="Resource.h" />
|
<ClInclude Include="Resource.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -34,6 +35,12 @@
|
|||||||
<ClCompile Include="..\helpers\MemoryHelper.cpp" />
|
<ClCompile Include="..\helpers\MemoryHelper.cpp" />
|
||||||
<ClCompile Include="..\helpers\RegistryHelper.cpp" />
|
<ClCompile Include="..\helpers\RegistryHelper.cpp" />
|
||||||
<ClCompile Include="..\helpers\StringHelper.cpp" />
|
<ClCompile Include="..\helpers\StringHelper.cpp" />
|
||||||
|
<ClCompile Include="..\stdafx.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="Configurator.cpp" />
|
<ClCompile Include="Configurator.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -52,29 +59,34 @@
|
|||||||
<ProjectGuid>{E18E1CA7-3D6C-4CD5-9CE9-E72565A206E5}</ProjectGuid>
|
<ProjectGuid>{E18E1CA7-3D6C-4CD5-9CE9-E72565A206E5}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>Configurator</RootNamespace>
|
<RootNamespace>Configurator</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
@@ -118,7 +130,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;USE_WINDDK;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;USE_WINDDK;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@@ -131,7 +143,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;USE_WINDDK;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;USE_WINDDK;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
@@ -139,13 +151,13 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>audioeng.lib;version.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
@@ -162,7 +174,7 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<ClCompile Include="..\helpers\StringHelper.cpp">
|
<ClCompile Include="..\helpers\StringHelper.cpp">
|
||||||
<Filter>helpers</Filter>
|
<Filter>helpers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\stdafx.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\DeviceAPOInfo.h" />
|
<ClInclude Include="..\DeviceAPOInfo.h" />
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
<ClInclude Include="..\helpers\StringHelper.h">
|
<ClInclude Include="..\helpers\StringHelper.h">
|
||||||
<Filter>helpers</Filter>
|
<Filter>helpers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="Configurator.rc" />
|
<ResourceCompile Include="Configurator.rc" />
|
||||||
|
|||||||
Binary file not shown.
+108
-13
@@ -17,16 +17,19 @@
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
|
#include <mmreg.h>
|
||||||
|
|
||||||
#include "DeviceAPOInfo.h"
|
#include "DeviceAPOInfo.h"
|
||||||
|
|
||||||
#include "EqualizerAPO.h"
|
|
||||||
#include "helpers/StringHelper.h"
|
#include "helpers/StringHelper.h"
|
||||||
#include "helpers/RegistryHelper.h"
|
#include "helpers/RegistryHelper.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#define protectedDGKeyPath L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Audio"
|
||||||
|
#define protectedDGValueName L"DisableProtectedAudioDG"
|
||||||
#define commonKeyPath L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio"
|
#define commonKeyPath L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio"
|
||||||
#define renderKeyPath commonKeyPath L"\\Render"
|
#define renderKeyPath commonKeyPath L"\\Render"
|
||||||
#define captureKeyPath commonKeyPath L"\\Capture"
|
#define captureKeyPath commonKeyPath L"\\Capture"
|
||||||
@@ -36,6 +39,8 @@ static const wchar_t* postMixChildGuidValueName = L"PostMixChild";
|
|||||||
static const wchar_t* versionValueName = L"Version";
|
static const wchar_t* versionValueName = L"Version";
|
||||||
static const wchar_t* connectionValueName = L"{a45c254e-df1c-4efd-8020-67d146a850e0},2";
|
static const wchar_t* connectionValueName = L"{a45c254e-df1c-4efd-8020-67d146a850e0},2";
|
||||||
static const wchar_t* deviceValueName = L"{b3f8fa53-0004-438e-9003-51a46e139bfc},6";
|
static const wchar_t* deviceValueName = L"{b3f8fa53-0004-438e-9003-51a46e139bfc},6";
|
||||||
|
static const wchar_t* formatValueName = L"{f19f064d-082c-4e27-bc73-6882a1bb8e4c},0";
|
||||||
|
static const wchar_t* channelMaskValueName = L"{1da5d803-d492-4edd-8c23-e0c0ffee7f0e},3";
|
||||||
static const wchar_t* lfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},1";
|
static const wchar_t* lfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},1";
|
||||||
static const wchar_t* gfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},2";
|
static const wchar_t* gfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},2";
|
||||||
static const wchar_t* sfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},5";
|
static const wchar_t* sfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},5";
|
||||||
@@ -43,7 +48,7 @@ static const wchar_t* mfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d
|
|||||||
static const wchar_t* efxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},7";
|
static const wchar_t* efxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},7";
|
||||||
static const unsigned allGuidValueNameCount = 5;
|
static const unsigned allGuidValueNameCount = 5;
|
||||||
static const wchar_t* allGuidValueNames[] = {lfxGuidValueName, gfxGuidValueName, sfxGuidValueName, mfxGuidValueName, efxGuidValueName};
|
static const wchar_t* allGuidValueNames[] = {lfxGuidValueName, gfxGuidValueName, sfxGuidValueName, mfxGuidValueName, efxGuidValueName};
|
||||||
static enum GuidValueIndices
|
enum GuidValueIndices
|
||||||
{
|
{
|
||||||
LFX_INDEX = 0,
|
LFX_INDEX = 0,
|
||||||
GFX_INDEX = 1,
|
GFX_INDEX = 1,
|
||||||
@@ -56,18 +61,21 @@ static const wchar_t* sfxProcessingModesValueName = L"{d3993a3f-99c2-4402-b5ec-a
|
|||||||
static const wchar_t* mfxProcessingModesValueName = L"{d3993a3f-99c2-4402-b5ec-a92a0367664b},6";
|
static const wchar_t* mfxProcessingModesValueName = L"{d3993a3f-99c2-4402-b5ec-a92a0367664b},6";
|
||||||
static const wchar_t* efxProcessingModesValueName = L"{d3993a3f-99c2-4402-b5ec-a92a0367664b},7";
|
static const wchar_t* efxProcessingModesValueName = L"{d3993a3f-99c2-4402-b5ec-a92a0367664b},7";
|
||||||
static const wchar_t* defaultProcessingModeValue = L"{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}";
|
static const wchar_t* defaultProcessingModeValue = L"{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}";
|
||||||
|
static const wchar_t* disableEnhancementsValueName = L"{1da5d803-d492-4edd-8c23-e0c0ffee7f0e},5";
|
||||||
static const wchar_t* installVersion = L"2";
|
static const wchar_t* installVersion = L"2";
|
||||||
|
static PROPERTYKEY guidPropertyKey = {{0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e}, 4};
|
||||||
|
|
||||||
vector<DeviceAPOInfo> DeviceAPOInfo::loadAllInfos(bool input)
|
vector<DeviceAPOInfo> DeviceAPOInfo::loadAllInfos(bool input)
|
||||||
{
|
{
|
||||||
vector<DeviceAPOInfo> result;
|
vector<DeviceAPOInfo> result;
|
||||||
vector<wstring> deviceGuidStrings = RegistryHelper::enumSubKeys(input ? captureKeyPath : renderKeyPath);
|
vector<wstring> deviceGuidStrings = RegistryHelper::enumSubKeys(input ? captureKeyPath : renderKeyPath);
|
||||||
|
wstring defaultDeviceGuid = getDefaultDevice(input);
|
||||||
for(vector<wstring>::iterator it = deviceGuidStrings.begin(); it != deviceGuidStrings.end(); it++)
|
for(vector<wstring>::iterator it = deviceGuidStrings.begin(); it != deviceGuidStrings.end(); it++)
|
||||||
{
|
{
|
||||||
wstring deviceGuidString = *it;
|
wstring deviceGuidString = *it;
|
||||||
|
|
||||||
DeviceAPOInfo info;
|
DeviceAPOInfo info;
|
||||||
if(info.load(deviceGuidString))
|
if(info.load(deviceGuidString, defaultDeviceGuid))
|
||||||
{
|
{
|
||||||
info.selectedInstallState = info.currentInstallState;
|
info.selectedInstallState = info.currentInstallState;
|
||||||
result.push_back(info);
|
result.push_back(info);
|
||||||
@@ -77,7 +85,56 @@ vector<DeviceAPOInfo> DeviceAPOInfo::loadAllInfos(bool input)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceAPOInfo::load(const wstring& deviceGuid)
|
wstring DeviceAPOInfo::getDefaultDevice(bool input, int role)
|
||||||
|
{
|
||||||
|
wstring result;
|
||||||
|
|
||||||
|
IMMDeviceEnumerator* enumerator = NULL;
|
||||||
|
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&enumerator);
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
IMMDevice* endPoint = NULL;
|
||||||
|
hr = enumerator->GetDefaultAudioEndpoint(input ? eCapture : eRender, (ERole)role, &endPoint);
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
IPropertyStore* propertyStore = NULL;
|
||||||
|
hr = endPoint->OpenPropertyStore(STGM_READ, &propertyStore);
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
PROPVARIANT variant;
|
||||||
|
PropVariantInit(&variant);
|
||||||
|
hr = propertyStore->GetValue(guidPropertyKey, &variant);
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
result = variant.pwszVal;
|
||||||
|
PropVariantClear(&variant);
|
||||||
|
}
|
||||||
|
propertyStore->Release();
|
||||||
|
}
|
||||||
|
endPoint->Release();
|
||||||
|
}
|
||||||
|
enumerator->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceAPOInfo::checkProtectedAudioDG(bool fix)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
if (!RegistryHelper::valueExists(protectedDGKeyPath, protectedDGValueName) || RegistryHelper::readDWORDValue(protectedDGKeyPath, protectedDGValueName) != 1)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
|
||||||
|
if (fix)
|
||||||
|
RegistryHelper::writeDWORDValue(protectedDGKeyPath, protectedDGValueName, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceAPOInfo::load(const wstring& deviceGuid, wstring defaultDeviceGuid)
|
||||||
{
|
{
|
||||||
wstring keyPath;
|
wstring keyPath;
|
||||||
if(RegistryHelper::keyExists(renderKeyPath L"\\" + deviceGuid))
|
if(RegistryHelper::keyExists(renderKeyPath L"\\" + deviceGuid))
|
||||||
@@ -100,6 +157,40 @@ bool DeviceAPOInfo::load(const wstring& deviceGuid)
|
|||||||
connectionName = RegistryHelper::readValue(keyPath + L"\\Properties", connectionValueName);
|
connectionName = RegistryHelper::readValue(keyPath + L"\\Properties", connectionValueName);
|
||||||
deviceName = RegistryHelper::readValue(keyPath + L"\\Properties", deviceValueName);
|
deviceName = RegistryHelper::readValue(keyPath + L"\\Properties", deviceValueName);
|
||||||
|
|
||||||
|
channelCount = 0;
|
||||||
|
sampleRate = 0;
|
||||||
|
channelMask = 0;
|
||||||
|
if(RegistryHelper::valueExists(keyPath + L"\\Properties", formatValueName))
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> format = RegistryHelper::readBinaryValue(keyPath + L"\\Properties", formatValueName);
|
||||||
|
if(format.size() >= sizeof(WAVEFORMATEX) + 8)
|
||||||
|
{
|
||||||
|
WAVEFORMATEX* waveFormat = (WAVEFORMATEX*)&format[8];
|
||||||
|
channelCount = waveFormat->nChannels;
|
||||||
|
sampleRate = waveFormat->nSamplesPerSec;
|
||||||
|
if(waveFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
|
||||||
|
{
|
||||||
|
WAVEFORMATEXTENSIBLE* waveFormatExtensible = (WAVEFORMATEXTENSIBLE*)waveFormat;
|
||||||
|
channelMask = waveFormatExtensible->dwChannelMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(channelMask == 0 && RegistryHelper::valueExists(keyPath + L"\\Properties", channelMaskValueName))
|
||||||
|
channelMask = RegistryHelper::readDWORDValue(keyPath + L"\\Properties", channelMaskValueName);
|
||||||
|
|
||||||
|
if(defaultDeviceGuid == L"")
|
||||||
|
defaultDeviceGuid = getDefaultDevice(isInput);
|
||||||
|
|
||||||
|
GUID guid1, guid2;
|
||||||
|
if(SUCCEEDED(CLSIDFromString(deviceGuid.c_str(), &guid1)) && SUCCEEDED(CLSIDFromString(defaultDeviceGuid.c_str(), &guid2)))
|
||||||
|
isDefaultDevice = (guid1 == guid2) != 0;
|
||||||
|
else
|
||||||
|
isDefaultDevice = false;
|
||||||
|
|
||||||
|
isEnhancementsDisabled = false;
|
||||||
|
if(RegistryHelper::keyExists(keyPath + L"\\FxProperties") && RegistryHelper::valueExists(keyPath + L"\\FxProperties", disableEnhancementsValueName))
|
||||||
|
isEnhancementsDisabled = RegistryHelper::readDWORDValue(keyPath + L"\\FxProperties", disableEnhancementsValueName) != 0;
|
||||||
|
|
||||||
isInstalled = false;
|
isInstalled = false;
|
||||||
currentInstallState.installMode = INSTALL_LFX_GFX;
|
currentInstallState.installMode = INSTALL_LFX_GFX;
|
||||||
version = L"0";
|
version = L"0";
|
||||||
@@ -112,12 +203,12 @@ bool DeviceAPOInfo::load(const wstring& deviceGuid)
|
|||||||
|
|
||||||
if(!RegistryHelper::keyExists(keyPath + L"\\FxProperties"))
|
if(!RegistryHelper::keyExists(keyPath + L"\\FxProperties"))
|
||||||
{
|
{
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
originalApoGuids[i] = APOGUID_NOKEY;
|
originalApoGuids[i] = APOGUID_NOKEY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
{
|
{
|
||||||
if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", allGuidValueNames[i]))
|
if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", allGuidValueNames[i]))
|
||||||
originalApoGuids[i] = RegistryHelper::readValue(keyPath + L"\\FxProperties", allGuidValueNames[i]);
|
originalApoGuids[i] = RegistryHelper::readValue(keyPath + L"\\FxProperties", allGuidValueNames[i]);
|
||||||
@@ -127,7 +218,7 @@ bool DeviceAPOInfo::load(const wstring& deviceGuid)
|
|||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
bool foundAt[allGuidValueNameCount];
|
bool foundAt[allGuidValueNameCount];
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
{
|
{
|
||||||
foundAt[i] = false;
|
foundAt[i] = false;
|
||||||
|
|
||||||
@@ -164,7 +255,7 @@ bool DeviceAPOInfo::load(const wstring& deviceGuid)
|
|||||||
version = L"1";
|
version = L"1";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
{
|
{
|
||||||
if(RegistryHelper::valueExists(childApoPath L"\\" + deviceGuid, allGuidValueNames[i]))
|
if(RegistryHelper::valueExists(childApoPath L"\\" + deviceGuid, allGuidValueNames[i]))
|
||||||
originalApoGuids[i] = RegistryHelper::readValue(childApoPath L"\\" + deviceGuid, allGuidValueNames[i]);
|
originalApoGuids[i] = RegistryHelper::readValue(childApoPath L"\\" + deviceGuid, allGuidValueNames[i]);
|
||||||
@@ -208,7 +299,7 @@ bool DeviceAPOInfo::load(const wstring& deviceGuid)
|
|||||||
}
|
}
|
||||||
else if(RegistryHelper::valueExists(childApoPath, deviceGuid))
|
else if(RegistryHelper::valueExists(childApoPath, deviceGuid))
|
||||||
{
|
{
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
{
|
{
|
||||||
if(foundAt[i])
|
if(foundAt[i])
|
||||||
{
|
{
|
||||||
@@ -335,7 +426,7 @@ void DeviceAPOInfo::install()
|
|||||||
|
|
||||||
RegistryHelper::writeValue(keyPath + L"\\FxProperties", fxTitleValueName, L"Equalizer APO");
|
RegistryHelper::writeValue(keyPath + L"\\FxProperties", fxTitleValueName, L"Equalizer APO");
|
||||||
|
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
{
|
{
|
||||||
RegistryHelper::writeValue(childApoPath L"\\" + deviceGuid, allGuidValueNames[i], APOGUID_NOKEY);
|
RegistryHelper::writeValue(childApoPath L"\\" + deviceGuid, allGuidValueNames[i], APOGUID_NOKEY);
|
||||||
}
|
}
|
||||||
@@ -344,7 +435,7 @@ void DeviceAPOInfo::install()
|
|||||||
{
|
{
|
||||||
vector<wstring> valuenames;
|
vector<wstring> valuenames;
|
||||||
|
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
{
|
{
|
||||||
wstring apoGuidString = APOGUID_NOVALUE;
|
wstring apoGuidString = APOGUID_NOVALUE;
|
||||||
if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", allGuidValueNames[i]))
|
if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", allGuidValueNames[i]))
|
||||||
@@ -358,7 +449,7 @@ void DeviceAPOInfo::install()
|
|||||||
|
|
||||||
if(!valuenames.empty())
|
if(!valuenames.empty())
|
||||||
RegistryHelper::saveToFile(keyPath + L"\\FxProperties", valuenames,
|
RegistryHelper::saveToFile(keyPath + L"\\FxProperties", valuenames,
|
||||||
L"backup_" + StringHelper::replaceIllegalCharacters(deviceName) + L"_" + StringHelper::replaceIllegalCharacters(connectionName) + L".reg");
|
L"backup_" + StringHelper::replaceIllegalCharacters(deviceName) + L"_" + StringHelper::replaceIllegalCharacters(connectionName) + L".reg");
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring preMixValue;
|
wstring preMixValue;
|
||||||
@@ -425,6 +516,10 @@ void DeviceAPOInfo::install()
|
|||||||
RegistryHelper::writeMultiValue(keyPath + L"\\FxProperties", efxProcessingModesValueName, defaultProcessingModeValue);
|
RegistryHelper::writeMultiValue(keyPath + L"\\FxProperties", efxProcessingModesValueName, defaultProcessingModeValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// force-enable enhancements
|
||||||
|
if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", disableEnhancementsValueName))
|
||||||
|
RegistryHelper::deleteValue(keyPath + L"\\FxProperties", disableEnhancementsValueName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceAPOInfo::uninstall()
|
void DeviceAPOInfo::uninstall()
|
||||||
@@ -441,7 +536,7 @@ void DeviceAPOInfo::uninstall()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int i=0; i < allGuidValueNameCount; i++)
|
for(int i = 0; i < allGuidValueNameCount; i++)
|
||||||
{
|
{
|
||||||
if(originalApoGuids[i] == APOGUID_NOVALUE)
|
if(originalApoGuids[i] == APOGUID_NOVALUE)
|
||||||
{
|
{
|
||||||
|
|||||||
+8
-1
@@ -60,7 +60,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<DeviceAPOInfo> loadAllInfos(bool input);
|
static std::vector<DeviceAPOInfo> loadAllInfos(bool input);
|
||||||
bool load(const std::wstring& deviceGuid);
|
static std::wstring getDefaultDevice(bool input, int role = 1);
|
||||||
|
static bool checkProtectedAudioDG(bool fix);
|
||||||
|
bool load(const std::wstring& deviceGuid, std::wstring defaultDeviceGuid = L"");
|
||||||
bool canBeUpgraded();
|
bool canBeUpgraded();
|
||||||
bool hasChanges();
|
bool hasChanges();
|
||||||
bool isExperimental();
|
bool isExperimental();
|
||||||
@@ -72,6 +74,11 @@ public:
|
|||||||
std::wstring deviceName;
|
std::wstring deviceName;
|
||||||
std::wstring connectionName;
|
std::wstring connectionName;
|
||||||
std::wstring deviceGuid;
|
std::wstring deviceGuid;
|
||||||
|
unsigned channelCount;
|
||||||
|
unsigned sampleRate;
|
||||||
|
unsigned long channelMask;
|
||||||
|
bool isDefaultDevice;
|
||||||
|
bool isEnhancementsDisabled;
|
||||||
|
|
||||||
// used for creating child APO
|
// used for creating child APO
|
||||||
std::wstring preMixChildGuid;
|
std::wstring preMixChildGuid;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2014-10-21T22:44:17
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core gui
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
TARGET = Editor
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
PRECOMPILED_HEADER = stable.h
|
||||||
|
QMAKE_CXXFLAGS_WARN_ON -= -w34100
|
||||||
|
|
||||||
|
DEFINES += NO_FILTERENGINE
|
||||||
|
|
||||||
|
SOURCES += main.cpp\
|
||||||
|
../helpers/LogHelper.cpp \
|
||||||
|
../helpers/StringHelper.cpp \
|
||||||
|
../helpers/RegistryHelper.cpp \
|
||||||
|
IFilterGUIFactory.cpp \
|
||||||
|
IFilterGUI.cpp \
|
||||||
|
guis/PreampFilterGUI.cpp \
|
||||||
|
guis/PreampFilterGUIFactory.cpp \
|
||||||
|
guis/CommentFilterGUIFactory.cpp \
|
||||||
|
guis/CommentFilterGUI.cpp \
|
||||||
|
FilterTable.cpp \
|
||||||
|
../filters/PreampFilter.cpp \
|
||||||
|
../filters/PreampFilterFactory.cpp \
|
||||||
|
../helpers/MemoryHelper.cpp \
|
||||||
|
FilterTableRow.cpp \
|
||||||
|
FilterTemplate.cpp \
|
||||||
|
guis/DeviceFilterGUI.cpp \
|
||||||
|
guis/DeviceFilterGUIFactory.cpp \
|
||||||
|
../DeviceAPOInfo.cpp \
|
||||||
|
guis/DeviceFilterGUIDialog.cpp \
|
||||||
|
../filters/DeviceFilterFactory.cpp \
|
||||||
|
guis/ChannelFilterGUIDialog.cpp \
|
||||||
|
guis/ChannelFilterGUI.cpp \
|
||||||
|
guis/ChannelFilterGUIFactory.cpp \
|
||||||
|
guis/BiQuadFilterGUI.cpp \
|
||||||
|
../filters/BiQuad.cpp \
|
||||||
|
../filters/BiQuadFilter.cpp \
|
||||||
|
../filters/BiQuadFilterFactory.cpp \
|
||||||
|
guis/BiQuadFilterGUIFactory.cpp \
|
||||||
|
guis/CopyFilterGUIFactory.cpp \
|
||||||
|
guis/CopyFilterGUI.cpp \
|
||||||
|
guis/CopyFilterGUIConnectionItem.cpp \
|
||||||
|
guis/CopyFilterGUIChannelItem.cpp \
|
||||||
|
../filters/CopyFilter.cpp \
|
||||||
|
../filters/CopyFilterFactory.cpp \
|
||||||
|
../IFilter.cpp \
|
||||||
|
guis/CopyFilterGUIScene.cpp \
|
||||||
|
guis/CopyFilterGUIForm.cpp \
|
||||||
|
guis/CopyFilterGUIRow.cpp \
|
||||||
|
helpers/GUIChannelHelper.cpp \
|
||||||
|
../helpers/ChannelHelper.cpp \
|
||||||
|
guis/DelayFilterGUI.cpp \
|
||||||
|
guis/DelayFilterGUIFactory.cpp \
|
||||||
|
../filters/DelayFilter.cpp \
|
||||||
|
../filters/DelayFilterFactory.cpp \
|
||||||
|
guis/IncludeFilterGUI.cpp \
|
||||||
|
guis/IncludeFilterGUIFactory.cpp \
|
||||||
|
widgets/ResizingLineEdit.cpp \
|
||||||
|
widgets/ChannelGraphScene.cpp \
|
||||||
|
widgets/ChannelGraphItem.cpp \
|
||||||
|
guis/ChannelFilterGUIScene.cpp \
|
||||||
|
guis/ChannelFilterGUIChannelItem.cpp \
|
||||||
|
guis/GraphicEQFilterGUIFactory.cpp \
|
||||||
|
guis/GraphicEQFilterGUI.cpp \
|
||||||
|
../filters/GraphicEQFilter.cpp \
|
||||||
|
../filters/GraphicEQFilterFactory.cpp \
|
||||||
|
../libHybridConv-0.1.1/libHybridConv_eapo.cpp \
|
||||||
|
../helpers/GainIterator.cpp \
|
||||||
|
guis/GraphicEQFilterGUIScene.cpp \
|
||||||
|
widgets/FrequencyPlotView.cpp \
|
||||||
|
widgets/FrequencyPlotHRuler.cpp \
|
||||||
|
widgets/FrequencyPlotVRuler.cpp \
|
||||||
|
widgets/FrequencyPlotItem.cpp \
|
||||||
|
guis/GraphicEQFilterGUIItem.cpp \
|
||||||
|
guis/GraphicEQFilterGUIView.cpp \
|
||||||
|
widgets/FrequencyPlotScene.cpp \
|
||||||
|
widgets/CompactToolBar.cpp \
|
||||||
|
guis/ConvolutionFilterGUIFactory.cpp \
|
||||||
|
guis/ConvolutionFilterGUI.cpp \
|
||||||
|
helpers/DisableWheelFilter.cpp \
|
||||||
|
widgets/EscapableLineEdit.cpp \
|
||||||
|
MainWindow.cpp \
|
||||||
|
guis/StageFilterGUI.cpp \
|
||||||
|
guis/StageFilterGUIFactory.cpp \
|
||||||
|
guis/ExpressionFilterGUIFactory.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
../helpers/LogHelper.h \
|
||||||
|
../helpers/StringHelper.h \
|
||||||
|
../helpers/RegistryHelper.h \
|
||||||
|
IFilterGUIFactory.h \
|
||||||
|
stable.h \
|
||||||
|
IFilterGUI.h \
|
||||||
|
guis/PreampFilterGUI.h \
|
||||||
|
guis/PreampFilterGUIFactory.h \
|
||||||
|
guis/CommentFilterGUIFactory.h \
|
||||||
|
guis/CommentFilterGUI.h \
|
||||||
|
FilterTable.h \
|
||||||
|
../filters/PreampFilter.h \
|
||||||
|
../filters/PreampFilterFactory.h \
|
||||||
|
../helpers/MemoryHelper.h \
|
||||||
|
FilterTableRow.h \
|
||||||
|
FilterTemplate.h \
|
||||||
|
guis/DeviceFilterGUI.h \
|
||||||
|
guis/DeviceFilterGUIFactory.h \
|
||||||
|
../DeviceAPOInfo.h \
|
||||||
|
guis/DeviceFilterGUIDialog.h \
|
||||||
|
../filters/DeviceFilterFactory.h \
|
||||||
|
guis/ChannelFilterGUIDialog.h \
|
||||||
|
guis/ChannelFilterGUI.h \
|
||||||
|
guis/ChannelFilterGUIFactory.h \
|
||||||
|
guis/BiQuadFilterGUI.h \
|
||||||
|
../filters/BiQuad.h \
|
||||||
|
../filters/BiQuadFilter.h \
|
||||||
|
../filters/BiQuadFilterFactory.h \
|
||||||
|
guis/BiQuadFilterGUIFactory.h \
|
||||||
|
guis/CopyFilterGUIFactory.h \
|
||||||
|
guis/CopyFilterGUI.h \
|
||||||
|
guis/CopyFilterGUIConnectionItem.h \
|
||||||
|
guis/CopyFilterGUIChannelItem.h \
|
||||||
|
../filters/CopyFilter.h \
|
||||||
|
../filters/CopyFilterFactory.h \
|
||||||
|
../IFilter.h \
|
||||||
|
../IFilterFactory.h \
|
||||||
|
guis/CopyFilterGUIScene.h \
|
||||||
|
guis/CopyFilterGUIForm.h \
|
||||||
|
guis/CopyFilterGUIRow.h \
|
||||||
|
helpers/GUIChannelHelper.h \
|
||||||
|
../helpers/ChannelHelper.h \
|
||||||
|
guis/DelayFilterGUI.h \
|
||||||
|
guis/DelayFilterGUIFactory.h \
|
||||||
|
../filters/DelayFilter.h \
|
||||||
|
../filters/DelayFilterFactory.h \
|
||||||
|
guis/IncludeFilterGUI.h \
|
||||||
|
guis/IncludeFilterGUIFactory.h \
|
||||||
|
widgets/ResizingLineEdit.h \
|
||||||
|
widgets/ChannelGraphScene.h \
|
||||||
|
widgets/ChannelGraphItem.h \
|
||||||
|
guis/ChannelFilterGUIScene.h \
|
||||||
|
guis/ChannelFilterGUIChannelItem.h \
|
||||||
|
guis/GraphicEQFilterGUIFactory.h \
|
||||||
|
guis/GraphicEQFilterGUI.h \
|
||||||
|
../filters/GraphicEQFilter.h \
|
||||||
|
../filters/GraphicEQFilterFactory.h \
|
||||||
|
../libHybridConv-0.1.1/libHybridConv_eapo.h \
|
||||||
|
../helpers/GainIterator.h \
|
||||||
|
guis/GraphicEQFilterGUIScene.h \
|
||||||
|
widgets/FrequencyPlotView.h \
|
||||||
|
widgets/FrequencyPlotHRuler.h \
|
||||||
|
widgets/FrequencyPlotVRuler.h \
|
||||||
|
widgets/FrequencyPlotItem.h \
|
||||||
|
guis/GraphicEQFilterGUIItem.h \
|
||||||
|
guis/GraphicEQFilterGUIView.h \
|
||||||
|
widgets/FrequencyPlotScene.h \
|
||||||
|
widgets/CompactToolBar.h \
|
||||||
|
guis/ConvolutionFilterGUIFactory.h \
|
||||||
|
guis/ConvolutionFilterGUI.h \
|
||||||
|
helpers/DisableWheelFilter.h \
|
||||||
|
widgets/EscapableLineEdit.h \
|
||||||
|
../version.h \
|
||||||
|
../stdafx.h \
|
||||||
|
MainWindow.h \
|
||||||
|
guis/StageFilterGUI.h \
|
||||||
|
guis/StageFilterGUIFactory.h \
|
||||||
|
guis/ExpressionFilterGUIFactory.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
guis/PreampFilterGUI.ui \
|
||||||
|
guis/CommentFilterGUI.ui \
|
||||||
|
FilterTableRow.ui \
|
||||||
|
guis/DeviceFilterGUI.ui \
|
||||||
|
guis/DeviceFilterGUIDialog.ui \
|
||||||
|
guis/ChannelFilterGUIDialog.ui \
|
||||||
|
guis/ChannelFilterGUI.ui \
|
||||||
|
guis/BiQuadFilterGUI.ui \
|
||||||
|
guis/CopyFilterGUI.ui \
|
||||||
|
guis/CopyFilterGUIRow.ui \
|
||||||
|
guis/DelayFilterGUI.ui \
|
||||||
|
guis/IncludeFilterGUI.ui \
|
||||||
|
guis/GraphicEQFilterGUI.ui \
|
||||||
|
guis/ConvolutionFilterGUI.ui \
|
||||||
|
MainWindow.ui \
|
||||||
|
guis/StageFilterGUI.ui
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/.. "C:/Program Files/libsndfile/include" "C:/Program Files/fftw3"
|
||||||
|
LIBS += advapi32.lib version.lib ole32.lib libsndfile-1.lib libfftw3f-3.lib
|
||||||
|
contains(QT_ARCH, x86_64) {
|
||||||
|
QMAKE_LIBDIR += "C:/Program Files/libsndfile/lib" "C:/Program Files/fftw3"
|
||||||
|
} else {
|
||||||
|
QMAKE_LIBDIR += "C:/Program Files (x86)/libsndfile/lib" "C:/Program Files (x86)/fftw3"
|
||||||
|
}
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
Editor.qrc
|
||||||
|
TRANSLATIONS += translations/Editor_de.ts
|
||||||
|
|
||||||
|
RC_ICONS = icons/accessories-text-editor.ico
|
||||||
|
|
||||||
|
DISTFILES +=
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>icons/arrow_right.png</file>
|
||||||
|
<file>icons/16x16/document-open.png</file>
|
||||||
|
<file>icons/16x16/document-new.png</file>
|
||||||
|
<file>icons/16x16/document-save-as.png</file>
|
||||||
|
<file>icons/16x16/document-save.png</file>
|
||||||
|
<file>icons/16x16/edit-copy.png</file>
|
||||||
|
<file>icons/16x16/edit-cut.png</file>
|
||||||
|
<file>icons/16x16/edit-delete.png</file>
|
||||||
|
<file>icons/16x16/edit-paste.png</file>
|
||||||
|
<file>icons/16x16/accessories-text-editor.png</file>
|
||||||
|
<file>icons/16x16/list-add-green.png</file>
|
||||||
|
<file>icons/16x16/list-remove-red.png</file>
|
||||||
|
<file>icons/mirror_response.png</file>
|
||||||
|
<file>icons/normalize_response.png</file>
|
||||||
|
<file>icons/power_off.png</file>
|
||||||
|
<file>icons/power_on.png</file>
|
||||||
|
<file>icons/16x16/applications-graphics-rotated.png</file>
|
||||||
|
<file>icons/16x16/format-justify-fill-rotated.png</file>
|
||||||
|
<file>translations/Editor_de.qm</file>
|
||||||
|
<file>translations/qtbase_de.qm</file>
|
||||||
|
<file>icons/16x16/go-up.png</file>
|
||||||
|
<file>icons/reset_response.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
@@ -0,0 +1,847 @@
|
|||||||
|
/*
|
||||||
|
This file is part of EqualizerAPO, a system-wide equalizer.
|
||||||
|
Copyright (C) 2014 Jonas Thedering
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QDrag>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QAbstractSpinBox>
|
||||||
|
#include <QDial>
|
||||||
|
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "FilterTableRow.h"
|
||||||
|
#include "guis/ExpressionFilterGUIFactory.h"
|
||||||
|
#include "guis/CommentFilterGUIFactory.h"
|
||||||
|
#include "guis/DeviceFilterGUIFactory.h"
|
||||||
|
#include "guis/ChannelFilterGUIFactory.h"
|
||||||
|
#include "guis/StageFilterGUIFactory.h"
|
||||||
|
#include "guis/PreampFilterGUIFactory.h"
|
||||||
|
#include "guis/BiQuadFilterGUIFactory.h"
|
||||||
|
#include "guis/CopyFilterGUIFactory.h"
|
||||||
|
#include "guis/DelayFilterGUIFactory.h"
|
||||||
|
#include "guis/IncludeFilterGUIFactory.h"
|
||||||
|
#include "guis/GraphicEQFilterGUIFactory.h"
|
||||||
|
#include "guis/ConvolutionFilterGUIFactory.h"
|
||||||
|
#include "helpers/StringHelper.h"
|
||||||
|
#include "helpers/LogHelper.h"
|
||||||
|
#include "helpers/ChannelHelper.h"
|
||||||
|
#include "FilterTable.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
FilterTable::FilterTable(MainWindow* mainWindow, QWidget *parent) :
|
||||||
|
QWidget(parent), mainWindow(mainWindow)
|
||||||
|
{
|
||||||
|
gridLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
QPixmap pixmap(QStringLiteral(":/icons/arrow_right.png"));
|
||||||
|
insertArrow = new QLabel(this);
|
||||||
|
insertArrow->setPixmap(pixmap);
|
||||||
|
insertArrow->setVisible(false);
|
||||||
|
|
||||||
|
factories.append(new ExpressionFilterGUIFactory);
|
||||||
|
factories.append(new CommentFilterGUIFactory);
|
||||||
|
factories.append(new IncludeFilterGUIFactory);
|
||||||
|
factories.append(new DeviceFilterGUIFactory);
|
||||||
|
factories.append(new ChannelFilterGUIFactory);
|
||||||
|
factories.append(new StageFilterGUIFactory);
|
||||||
|
factories.append(new PreampFilterGUIFactory);
|
||||||
|
factories.append(new BiQuadFilterGUIFactory);
|
||||||
|
factories.append(new DelayFilterGUIFactory);
|
||||||
|
factories.append(new CopyFilterGUIFactory);
|
||||||
|
factories.append(new GraphicEQFilterGUIFactory);
|
||||||
|
factories.append(new ConvolutionFilterGUIFactory);
|
||||||
|
|
||||||
|
QApplication::instance()->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::initialize(QScrollArea* scrollArea, const QList<DeviceAPOInfo>& outputDevices, const QList<DeviceAPOInfo>& inputDevices)
|
||||||
|
{
|
||||||
|
this->scrollArea = scrollArea;
|
||||||
|
this->outputDevices = outputDevices;
|
||||||
|
this->inputDevices = inputDevices;
|
||||||
|
|
||||||
|
for(IFilterGUIFactory* factory : factories)
|
||||||
|
factory->initialize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::updateDeviceAndChannelMask(DeviceAPOInfo* selectedDevice, int channelMask)
|
||||||
|
{
|
||||||
|
this->selectedDevice = selectedDevice;
|
||||||
|
this->selectedChannelMask = channelMask;
|
||||||
|
|
||||||
|
if(!items.empty())
|
||||||
|
updateGuis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::updateGuis()
|
||||||
|
{
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
guis.clear();
|
||||||
|
delete layout();
|
||||||
|
|
||||||
|
for(QObject* object : children())
|
||||||
|
{
|
||||||
|
if(object != insertArrow)
|
||||||
|
{
|
||||||
|
QWidget* widget = qobject_cast<QWidget*>(object);
|
||||||
|
if(widget != NULL)
|
||||||
|
widget->setVisible(false);
|
||||||
|
object->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("Delete took %d ms", timer.elapsed());
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
gridLayout = new QGridLayout(this);
|
||||||
|
gridLayout->setMargin(0);
|
||||||
|
gridLayout->setSpacing(0);
|
||||||
|
gridLayout->setColumnStretch(0, 0);
|
||||||
|
gridLayout->setColumnStretch(1, 1);
|
||||||
|
|
||||||
|
for(IFilterGUIFactory* factory : factories)
|
||||||
|
factory->startOfFile(configPath);
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
for(Item* item : items)
|
||||||
|
{
|
||||||
|
QString line = item->text;
|
||||||
|
IFilterGUI* gui = NULL;
|
||||||
|
int pos = line.indexOf(L':');
|
||||||
|
if(pos != -1)
|
||||||
|
{
|
||||||
|
QString key = line.mid(0, pos);
|
||||||
|
QString value = line.mid(pos + 1);
|
||||||
|
|
||||||
|
// allow to use indentation
|
||||||
|
key = key.trimmed();
|
||||||
|
QString factoryKey = key;
|
||||||
|
QString factoryValue = value;
|
||||||
|
|
||||||
|
for(IFilterGUIFactory* factory : factories)
|
||||||
|
{
|
||||||
|
gui = factory->createFilterGUI(factoryKey, factoryValue);
|
||||||
|
|
||||||
|
if(gui != NULL || factoryKey == "")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gui != NULL)
|
||||||
|
{
|
||||||
|
for(IFilterGUIFactory* factory : factories)
|
||||||
|
{
|
||||||
|
gui = factory->decorateFilterGUI(gui);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTableRow* rowWidget = new FilterTableRow(this, row + 1, item, gui);
|
||||||
|
gridLayout->addWidget(rowWidget, row, 0);
|
||||||
|
|
||||||
|
if(gui != NULL)
|
||||||
|
{
|
||||||
|
guis.append(gui);
|
||||||
|
connect(gui, SIGNAL(updateModel()), this, SLOT(updateModel()));
|
||||||
|
connect(gui, SIGNAL(updateChannels()), this, SLOT(updateChannels()));
|
||||||
|
}
|
||||||
|
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(IFilterGUIFactory* factory : factories)
|
||||||
|
factory->endOfFile(configPath);
|
||||||
|
|
||||||
|
propagateChannels();
|
||||||
|
|
||||||
|
QToolBar* toolBar = new QToolBar;
|
||||||
|
toolBar->setIconSize(QSize(16, 16));
|
||||||
|
|
||||||
|
QWidget* spacer = new QWidget;
|
||||||
|
spacer->setFixedWidth(25);
|
||||||
|
toolBar->addWidget(spacer);
|
||||||
|
|
||||||
|
QAction* addAction = new QAction(QIcon(":/icons/16x16/list-add-green.png"), tr("Add filter"), toolBar);
|
||||||
|
addAction->setCheckable(true);
|
||||||
|
connect(addAction, SIGNAL(triggered()), this, SLOT(addActionTriggered()));
|
||||||
|
toolBar->addAction(addAction);
|
||||||
|
|
||||||
|
gridLayout->addWidget(toolBar, row++, 0, 1, 1, Qt::AlignLeft | Qt::AlignTop);
|
||||||
|
|
||||||
|
QSpacerItem* spacerItem = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||||
|
gridLayout->addItem(spacerItem, row, 0);
|
||||||
|
|
||||||
|
gridLayout->setRowStretch(row, 1);
|
||||||
|
|
||||||
|
disableWheelForWidgets();
|
||||||
|
|
||||||
|
qDebug("Create took %d ms", timer.elapsed());
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::propagateChannels()
|
||||||
|
{
|
||||||
|
vector<wstring> channelNames = ChannelHelper::getChannelNames(selectedDevice->channelCount, selectedChannelMask);
|
||||||
|
|
||||||
|
for(IFilterGUI* gui : guis)
|
||||||
|
{
|
||||||
|
gui->configureChannels(channelNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> FilterTable::getLines()
|
||||||
|
{
|
||||||
|
QList<QString> result;
|
||||||
|
for(Item* item : items)
|
||||||
|
result.append(item->text);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::setLines(const QString& configPath, const QList<QString>& lines)
|
||||||
|
{
|
||||||
|
this->configPath = configPath;
|
||||||
|
|
||||||
|
qDeleteAll(items);
|
||||||
|
items.clear();
|
||||||
|
|
||||||
|
for(QString line : lines)
|
||||||
|
items.append(new Item(line));
|
||||||
|
|
||||||
|
if(!items.isEmpty())
|
||||||
|
{
|
||||||
|
focused = items[0];
|
||||||
|
selectionStart = items[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
focused = NULL;
|
||||||
|
selectionStart = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGuis();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTable::Item* FilterTable::addLine(const QString& line, FilterTable::Item* before)
|
||||||
|
{
|
||||||
|
Item* newItem = new Item(line);
|
||||||
|
|
||||||
|
if(before != NULL)
|
||||||
|
{
|
||||||
|
int index = items.indexOf(before);
|
||||||
|
items.insert(index, newItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items.append(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit linesChanged();
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::removeItem(FilterTable::Item* item)
|
||||||
|
{
|
||||||
|
items.removeOne(item);
|
||||||
|
emit linesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu* FilterTable::createAddPopupMenu()
|
||||||
|
{
|
||||||
|
QHash<QList<QString>, QMenu*> pathMap;
|
||||||
|
QMenu* rootMenu = new QMenu;
|
||||||
|
pathMap[QStringList()] = rootMenu;
|
||||||
|
|
||||||
|
for(IFilterGUIFactory* f : factories)
|
||||||
|
{
|
||||||
|
QList<FilterTemplate> templates = f->createFilterTemplates();
|
||||||
|
for(FilterTemplate t : templates)
|
||||||
|
{
|
||||||
|
QMenu* menu = pathMap.value(t.getPath());
|
||||||
|
if(menu == NULL)
|
||||||
|
{
|
||||||
|
QMenu* parentMenu = rootMenu;
|
||||||
|
QStringList currentPath;
|
||||||
|
for(QString pathSegment : t.getPath())
|
||||||
|
{
|
||||||
|
currentPath.append(pathSegment);
|
||||||
|
menu = pathMap.value(currentPath);
|
||||||
|
if(menu == NULL)
|
||||||
|
{
|
||||||
|
menu = new QMenu(pathSegment);
|
||||||
|
pathMap.insert(currentPath, menu);
|
||||||
|
parentMenu->addMenu(menu);
|
||||||
|
}
|
||||||
|
parentMenu = menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction* action = menu->addAction(t.getName());
|
||||||
|
action->setData(QVariant::fromValue(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::cut()
|
||||||
|
{
|
||||||
|
copy();
|
||||||
|
deleteSelectedLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::copy()
|
||||||
|
{
|
||||||
|
QString text;
|
||||||
|
bool first = true;
|
||||||
|
for(Item* item : items)
|
||||||
|
{
|
||||||
|
if(selected.contains(item))
|
||||||
|
{
|
||||||
|
if(first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
text += "\n";
|
||||||
|
text += item->text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selected.size() > 0)
|
||||||
|
{
|
||||||
|
QMimeData* mimeData = new QMimeData;
|
||||||
|
mimeData->setText(text);
|
||||||
|
QClipboard* clipboard = QApplication::clipboard();
|
||||||
|
clipboard->setMimeData(mimeData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::paste()
|
||||||
|
{
|
||||||
|
QClipboard* clipboard = QApplication::clipboard();
|
||||||
|
const QMimeData* mimeData = clipboard->mimeData();
|
||||||
|
if(mimeData->hasText())
|
||||||
|
{
|
||||||
|
int dropRow = items.size();
|
||||||
|
for(int i = 0; i < items.size(); i++)
|
||||||
|
{
|
||||||
|
if(selected.contains(items[i]))
|
||||||
|
{
|
||||||
|
dropRow = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString text = mimeData->text();
|
||||||
|
QStringList textLines = text.split("\n");
|
||||||
|
selected.clear();
|
||||||
|
focused = NULL;
|
||||||
|
selectionStart = NULL;
|
||||||
|
for(QString line : textLines)
|
||||||
|
{
|
||||||
|
Item* item = new Item(line);
|
||||||
|
selected.insert(item);
|
||||||
|
items.insert(dropRow++, item);
|
||||||
|
if(focused == NULL)
|
||||||
|
{
|
||||||
|
focused = item;
|
||||||
|
selectionStart = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit linesChanged();
|
||||||
|
updateGuis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::deleteSelectedLines()
|
||||||
|
{
|
||||||
|
QList<Item*> newItems;
|
||||||
|
for(Item* item : items)
|
||||||
|
{
|
||||||
|
if(selected.contains(item))
|
||||||
|
{
|
||||||
|
if(item == focused)
|
||||||
|
focused = NULL;
|
||||||
|
if(item == selectionStart)
|
||||||
|
selectionStart = NULL;
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newItems.append(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selected.clear();
|
||||||
|
items = newItems;
|
||||||
|
emit linesChanged();
|
||||||
|
updateGuis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::updateModel()
|
||||||
|
{
|
||||||
|
emit linesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::updateChannels()
|
||||||
|
{
|
||||||
|
propagateChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::addActionTriggered()
|
||||||
|
{
|
||||||
|
QMenu* menu = createAddPopupMenu();
|
||||||
|
QAction* addAction = qobject_cast<QAction*>(QObject::sender());
|
||||||
|
QToolBar* toolBar = qobject_cast<QToolBar*>(addAction->parentWidget());
|
||||||
|
QRect rect = toolBar->actionGeometry(addAction);
|
||||||
|
QPoint p = toolBar->mapToGlobal(QPoint(rect.x(), rect.y() + rect.height()));
|
||||||
|
QAction* action = menu->exec(p);
|
||||||
|
addAction->setChecked(false);
|
||||||
|
if(action != NULL)
|
||||||
|
{
|
||||||
|
FilterTemplate t = action->data().value<FilterTemplate>();
|
||||||
|
QString line = t.getLine();
|
||||||
|
addLine(line);
|
||||||
|
updateGuis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::openConfig(QString path)
|
||||||
|
{
|
||||||
|
mainWindow->load(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::mousePressEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
if(event->buttons() & Qt::LeftButton )
|
||||||
|
{
|
||||||
|
int row = rowForPos(event->pos(), false);
|
||||||
|
if(row != -1)
|
||||||
|
{
|
||||||
|
Item* item = items[row];
|
||||||
|
|
||||||
|
if(event->modifiers() & Qt::ControlModifier)
|
||||||
|
{
|
||||||
|
if(!selected.remove(item))
|
||||||
|
selected.insert(item);
|
||||||
|
selectionStart = item;
|
||||||
|
}
|
||||||
|
else if(event->modifiers() & Qt::ShiftModifier)
|
||||||
|
{
|
||||||
|
int startRow = items.indexOf(selectionStart);
|
||||||
|
if(startRow != -1)
|
||||||
|
{
|
||||||
|
selected.clear();
|
||||||
|
for(int i = min(startRow, row); i <= max(startRow, row); i++)
|
||||||
|
{
|
||||||
|
selected.insert(items[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!selected.contains(item))
|
||||||
|
{
|
||||||
|
selected.clear();
|
||||||
|
selected.insert(item);
|
||||||
|
}
|
||||||
|
selectionStart = item;
|
||||||
|
}
|
||||||
|
focused = item;
|
||||||
|
ensureRowVisible(row);
|
||||||
|
update();
|
||||||
|
|
||||||
|
dragStartPos = event->pos();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selected.clear();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
if(event->buttons() & Qt::LeftButton)
|
||||||
|
{
|
||||||
|
if((event->pos() - dragStartPos).manhattanLength() >= QApplication::startDragDistance())
|
||||||
|
{
|
||||||
|
QString text;
|
||||||
|
bool first = true;
|
||||||
|
int i = 0;
|
||||||
|
bool dragPosInside = false;
|
||||||
|
for(Item* item : items)
|
||||||
|
{
|
||||||
|
if(selected.contains(item))
|
||||||
|
{
|
||||||
|
if(first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
text += "\n";
|
||||||
|
text += item->text;
|
||||||
|
|
||||||
|
if(!dragPosInside)
|
||||||
|
{
|
||||||
|
FilterTableRow* tableRow = qobject_cast<FilterTableRow*>(gridLayout->itemAtPosition(i, 0)->widget());
|
||||||
|
QRect rect = tableRow->getHeaderRect().translated(tableRow->pos());
|
||||||
|
if(rect.contains(dragStartPos))
|
||||||
|
dragPosInside = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selected.size() > 0 && dragPosInside)
|
||||||
|
{
|
||||||
|
QMimeData* mimeData = new QMimeData;
|
||||||
|
mimeData->setText(text);
|
||||||
|
|
||||||
|
QDrag* drag = new QDrag(this);
|
||||||
|
drag->setMimeData(mimeData);
|
||||||
|
QSet<Item*> selectedBefore = selected;
|
||||||
|
internalDrag = true;
|
||||||
|
Qt::DropAction action = drag->exec(Qt::MoveAction | Qt::CopyAction);
|
||||||
|
internalDrag = false;
|
||||||
|
if(action == Qt::MoveAction)
|
||||||
|
{
|
||||||
|
for(Item* item : selectedBefore)
|
||||||
|
{
|
||||||
|
items.removeOne(item);
|
||||||
|
if(focused == item)
|
||||||
|
focused = NULL;
|
||||||
|
if(selectionStart == item)
|
||||||
|
selectionStart = NULL;
|
||||||
|
selected.remove(item);
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(action != Qt::IgnoreAction)
|
||||||
|
{
|
||||||
|
emit linesChanged();
|
||||||
|
updateGuis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget::mouseMoveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::dragEnterEvent(QDragEnterEvent* event)
|
||||||
|
{
|
||||||
|
if(event->mimeData()->hasText())
|
||||||
|
{
|
||||||
|
if(event->keyboardModifiers() & Qt::ControlModifier)
|
||||||
|
event->setDropAction(Qt::CopyAction);
|
||||||
|
else
|
||||||
|
event->setDropAction(Qt::MoveAction);
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget::dragEnterEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::dragMoveEvent(QDragMoveEvent* event)
|
||||||
|
{
|
||||||
|
if(event->mimeData()->hasText())
|
||||||
|
{
|
||||||
|
if(event->keyboardModifiers() & Qt::ControlModifier)
|
||||||
|
event->setDropAction(Qt::CopyAction);
|
||||||
|
else
|
||||||
|
event->setDropAction(Qt::MoveAction);
|
||||||
|
|
||||||
|
int dropRow = rowForPos(event->pos(), true);
|
||||||
|
|
||||||
|
QRect rect = gridLayout->itemAtPosition(dropRow == -1 ? gridLayout->rowCount() - 2 : dropRow, 0)->geometry();
|
||||||
|
insertArrow->move(0, rect.top() - insertArrow->height() / 2 - gridLayout->verticalSpacing() / 2);
|
||||||
|
|
||||||
|
insertArrow->raise();
|
||||||
|
insertArrow->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget::dragMoveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::dragLeaveEvent(QDragLeaveEvent* event)
|
||||||
|
{
|
||||||
|
insertArrow->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::dropEvent(QDropEvent* event)
|
||||||
|
{
|
||||||
|
if(event->mimeData()->hasText())
|
||||||
|
{
|
||||||
|
if(event->keyboardModifiers() & Qt::ControlModifier)
|
||||||
|
event->setDropAction(Qt::CopyAction);
|
||||||
|
else
|
||||||
|
event->setDropAction(Qt::MoveAction);
|
||||||
|
|
||||||
|
QString text = event->mimeData()->text();
|
||||||
|
QStringList textLines = text.split("\n");
|
||||||
|
int dropRow = rowForPos(event->pos(), true);
|
||||||
|
if(dropRow == -1)
|
||||||
|
dropRow = items.size();
|
||||||
|
|
||||||
|
selected.clear();
|
||||||
|
focused = NULL;
|
||||||
|
selectionStart = NULL;
|
||||||
|
for(QString line : textLines)
|
||||||
|
{
|
||||||
|
Item* item = new Item(line);
|
||||||
|
selected.insert(item);
|
||||||
|
items.insert(dropRow++, item);
|
||||||
|
if(focused == NULL)
|
||||||
|
{
|
||||||
|
focused = item;
|
||||||
|
selectionStart = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event->accept();
|
||||||
|
|
||||||
|
if(!internalDrag)
|
||||||
|
{
|
||||||
|
emit linesChanged();
|
||||||
|
updateGuis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insertArrow->hide();
|
||||||
|
|
||||||
|
QWidget::dropEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::keyPressEvent(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
if(event->key() == Qt::Key_Down || event->key() == Qt::Key_Up)
|
||||||
|
{
|
||||||
|
if(focused != NULL)
|
||||||
|
{
|
||||||
|
int row = items.indexOf(focused);
|
||||||
|
if(row != -1)
|
||||||
|
{
|
||||||
|
int newRow = row;
|
||||||
|
if(event->key() == Qt::Key_Down && row + 1 < items.size())
|
||||||
|
newRow = row + 1;
|
||||||
|
else if(event->key() == Qt::Key_Up && row - 1 >= 0)
|
||||||
|
newRow = row - 1;
|
||||||
|
|
||||||
|
if(newRow != row)
|
||||||
|
{
|
||||||
|
focused = items[newRow];
|
||||||
|
if(event->modifiers() & Qt::ControlModifier)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if(event->modifiers() & Qt::ShiftModifier)
|
||||||
|
{
|
||||||
|
int startRow = items.indexOf(selectionStart);
|
||||||
|
if(startRow != -1)
|
||||||
|
{
|
||||||
|
selected.clear();
|
||||||
|
for(int i = min(startRow, newRow); i <= max(startRow, newRow); i++)
|
||||||
|
{
|
||||||
|
selected.insert(items[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selected.clear();
|
||||||
|
selected.insert(focused);
|
||||||
|
selectionStart = focused;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureRowVisible(newRow);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event->key() == Qt::Key_Space)
|
||||||
|
{
|
||||||
|
if(!(event->modifiers() & Qt::ControlModifier) || !selected.remove(focused))
|
||||||
|
selected.insert(focused);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event->key() == Qt::Key_F2)
|
||||||
|
{
|
||||||
|
if(focused != NULL)
|
||||||
|
{
|
||||||
|
int rowIndex = items.indexOf(focused);
|
||||||
|
if(rowIndex != -1)
|
||||||
|
{
|
||||||
|
QLayoutItem* layoutItem = gridLayout->itemAtPosition(rowIndex, 0);
|
||||||
|
FilterTableRow* tableRow = qobject_cast<FilterTableRow*>(layoutItem->widget());
|
||||||
|
if(tableRow != NULL)
|
||||||
|
tableRow->editText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event->key() == Qt::Key_Delete)
|
||||||
|
{
|
||||||
|
deleteSelectedLines();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::wheelEvent(QWheelEvent * event)
|
||||||
|
{
|
||||||
|
scrollingNow = true;
|
||||||
|
scrollStartPoint = event->globalPos();
|
||||||
|
|
||||||
|
QWidget::wheelEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FilterTable::eventFilter(QObject* obj, QEvent* event)
|
||||||
|
{
|
||||||
|
if(scrollingNow)
|
||||||
|
{
|
||||||
|
QEvent::Type type = event->type();
|
||||||
|
if(type == QEvent::Wheel)
|
||||||
|
{
|
||||||
|
QWidget* widget = qobject_cast<QWidget*>(obj);
|
||||||
|
if(widget != NULL)
|
||||||
|
{
|
||||||
|
if(isAncestorOf(widget))
|
||||||
|
{
|
||||||
|
QApplication::sendEvent(parent(), event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type == QEvent::MouseMove)
|
||||||
|
{
|
||||||
|
QMouseEvent* mouseEvent = (QMouseEvent*)event;
|
||||||
|
|
||||||
|
if((mouseEvent->globalPos() - scrollStartPoint).manhattanLength() > QApplication::startDragDistance())
|
||||||
|
scrollingNow = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::ensureRowVisible(int row)
|
||||||
|
{
|
||||||
|
QScrollBar* vScrollBar = scrollArea->verticalScrollBar();
|
||||||
|
if(vScrollBar != NULL)
|
||||||
|
{
|
||||||
|
QRect rect = rowRect(row).toAlignedRect();
|
||||||
|
if(rect.top() < vScrollBar->value())
|
||||||
|
vScrollBar->setValue(max(0, rect.top()));
|
||||||
|
else if(rect.bottom() + 1 > vScrollBar->value() + scrollArea->viewport()->height())
|
||||||
|
vScrollBar->setValue(min(vScrollBar->maximum(), rect.bottom() + 1 - scrollArea->viewport()->height()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int FilterTable::rowForPos(QPoint pos, bool insert)
|
||||||
|
{
|
||||||
|
int row = -1;
|
||||||
|
for(int i = 0; i < gridLayout->rowCount() - 2; i++)
|
||||||
|
{
|
||||||
|
QRect rect = gridLayout->itemAtPosition(i, 0)->geometry();
|
||||||
|
int y;
|
||||||
|
if(insert)
|
||||||
|
y = rect.center().y();
|
||||||
|
else
|
||||||
|
y = rect.bottom();
|
||||||
|
|
||||||
|
if(pos.y() <= y)
|
||||||
|
{
|
||||||
|
row = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF FilterTable::rowRect(int row)
|
||||||
|
{
|
||||||
|
QRectF rect = gridLayout->itemAtPosition(row, 0)->geometry();
|
||||||
|
rect = rect.marginsAdded(QMarginsF(-1.5, -1.5, -1.5, -0.5));
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::disableWheelForWidgets()
|
||||||
|
{
|
||||||
|
QList<QWidget*> widgets = findChildren<QWidget*>();
|
||||||
|
for(QWidget* widget : widgets)
|
||||||
|
{
|
||||||
|
if(qobject_cast<QComboBox*>(widget) || qobject_cast<QAbstractSpinBox*>(widget) || qobject_cast<QDial*>(widget))
|
||||||
|
{
|
||||||
|
widget->installEventFilter(new DisableWheelFilter(this, widget));
|
||||||
|
if(widget->focusPolicy() == Qt::WheelFocus)
|
||||||
|
widget->setFocusPolicy(Qt::StrongFocus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FilterTable::getConfigPath() const
|
||||||
|
{
|
||||||
|
return configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTable::setConfigPath(const QString& value)
|
||||||
|
{
|
||||||
|
configPath = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTable::Item* FilterTable::getFocusedItem() const
|
||||||
|
{
|
||||||
|
return focused;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSet<FilterTable::Item*>& FilterTable::getSelectedItems() const
|
||||||
|
{
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<DeviceAPOInfo>& FilterTable::getOutputDevices() const
|
||||||
|
{
|
||||||
|
return outputDevices;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<DeviceAPOInfo>& FilterTable::getInputDevices() const
|
||||||
|
{
|
||||||
|
return inputDevices;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceAPOInfo* FilterTable::getSelectedDevice() const
|
||||||
|
{
|
||||||
|
return selectedDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FilterTable::getSelectedChannelMask() const
|
||||||
|
{
|
||||||
|
return selectedChannelMask;
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
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 <QLabel>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
#include "Editor/helpers/DisableWheelFilter.h"
|
||||||
|
#include "DeviceAPOInfo.h"
|
||||||
|
#include "IFilterGUI.h"
|
||||||
|
#include "IFilterGUIFactory.h"
|
||||||
|
|
||||||
|
class MainWindow;
|
||||||
|
|
||||||
|
class FilterTable : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
struct Item {
|
||||||
|
Item()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Item(const QString& text)
|
||||||
|
{
|
||||||
|
this->text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit FilterTable(MainWindow* mainWindow, QWidget *parent = 0);
|
||||||
|
void initialize(QScrollArea* scrollArea, const QList<DeviceAPOInfo>& outputDevices, const QList<DeviceAPOInfo>& inputDevices);
|
||||||
|
void updateDeviceAndChannelMask(DeviceAPOInfo* selectedDevice, int selectedChannelMask);
|
||||||
|
void updateGuis();
|
||||||
|
void propagateChannels();
|
||||||
|
QList<QString> getLines();
|
||||||
|
void setLines(const QString& configPath, const QList<QString>& lines);
|
||||||
|
Item* addLine(const QString& line, Item* before = NULL);
|
||||||
|
void removeItem(Item* item);
|
||||||
|
QMenu* createAddPopupMenu();
|
||||||
|
void cut();
|
||||||
|
void copy();
|
||||||
|
void paste();
|
||||||
|
void deleteSelectedLines();
|
||||||
|
|
||||||
|
const QList<DeviceAPOInfo>& getOutputDevices() const;
|
||||||
|
const QList<DeviceAPOInfo>& getInputDevices() const;
|
||||||
|
DeviceAPOInfo* getSelectedDevice() const;
|
||||||
|
int getSelectedChannelMask() const;
|
||||||
|
|
||||||
|
const QSet<Item*>& getSelectedItems() const;
|
||||||
|
Item* getFocusedItem() const;
|
||||||
|
|
||||||
|
QString getConfigPath() const;
|
||||||
|
void setConfigPath(const QString& value);
|
||||||
|
|
||||||
|
void openConfig(QString path);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void linesChanged();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateModel();
|
||||||
|
void updateChannels();
|
||||||
|
void addActionTriggered();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||||
|
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||||
|
void dragLeaveEvent(QDragLeaveEvent* event) override;
|
||||||
|
void dropEvent(QDropEvent *event) override;
|
||||||
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
void wheelEvent(QWheelEvent* event) override;
|
||||||
|
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ensureRowVisible(int row);
|
||||||
|
int rowForPos(QPoint pos, bool insert);
|
||||||
|
QRectF rowRect(int row);
|
||||||
|
void disableWheelForWidgets();
|
||||||
|
|
||||||
|
MainWindow* mainWindow;
|
||||||
|
QScrollArea* scrollArea;
|
||||||
|
QGridLayout* gridLayout;
|
||||||
|
QLabel* insertArrow;
|
||||||
|
QPoint dragStartPos;
|
||||||
|
bool internalDrag = false;
|
||||||
|
QList<Item*> items;
|
||||||
|
QSet<Item*> selected;
|
||||||
|
Item* focused = NULL;
|
||||||
|
Item* selectionStart = NULL;
|
||||||
|
QList<IFilterGUIFactory*> factories;
|
||||||
|
QList<IFilterGUI*> guis;
|
||||||
|
bool scrollingNow = false;
|
||||||
|
QPoint scrollStartPoint;
|
||||||
|
QList<DeviceAPOInfo> outputDevices;
|
||||||
|
QList<DeviceAPOInfo> inputDevices;
|
||||||
|
DeviceAPOInfo* selectedDevice;
|
||||||
|
int selectedChannelMask;
|
||||||
|
QString configPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> inline uint qHash(QList<T> list)
|
||||||
|
{
|
||||||
|
uint hashValue = 0;
|
||||||
|
|
||||||
|
for(T t : list)
|
||||||
|
hashValue = 31 * hashValue + qHash(t);
|
||||||
|
|
||||||
|
return hashValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(FilterTable::Item*)
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
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 <QToolBar>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
|
#include "FilterTableRow.h"
|
||||||
|
#include "ui_FilterTableRow.h"
|
||||||
|
|
||||||
|
FilterTableRow::FilterTableRow(FilterTable* table, int number, FilterTable::Item* item, IFilterGUI* gui) :
|
||||||
|
QWidget(table),
|
||||||
|
ui(new Ui::FilterTableRow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
this->table = table;
|
||||||
|
this->item = item;
|
||||||
|
this->gui = gui;
|
||||||
|
|
||||||
|
ui->labelNumber->setText(QString("%0").arg(number));
|
||||||
|
|
||||||
|
ui->toolBar->addAction(ui->actionAdd);
|
||||||
|
ui->toolBar->addAction(ui->actionRemove);
|
||||||
|
ui->toolBar->addAction(ui->actionEditText);
|
||||||
|
ui->toolBar->updateMaximumHeight();
|
||||||
|
|
||||||
|
ui->stackedWidget->setContentsMargins(0, 5, 0, 5);
|
||||||
|
|
||||||
|
if(gui != NULL)
|
||||||
|
{
|
||||||
|
connect(gui, SIGNAL(updateModel()), this, SLOT(updateModel()));
|
||||||
|
ui->stackedWidget->addWidget(gui);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->stackedWidget->addWidget(new QLabel(item->text));
|
||||||
|
}
|
||||||
|
ui->stackedWidget->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTableRow::~FilterTableRow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect FilterTableRow::getHeaderRect()
|
||||||
|
{
|
||||||
|
QRect rect(0, 0, ui->labelNumber->geometry().right() + 1, height());
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::editText()
|
||||||
|
{
|
||||||
|
if(!ui->actionEditText->isChecked())
|
||||||
|
ui->actionEditText->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::mouseDoubleClickEvent(QMouseEvent*)
|
||||||
|
{
|
||||||
|
if(gui == NULL && ui->stackedWidget->currentIndex() == 1)
|
||||||
|
ui->actionEditText->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::paintEvent(QPaintEvent*)
|
||||||
|
{
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
QRectF r = rect();
|
||||||
|
r = r.marginsAdded(QMarginsF(-1.5, -1.5, -1.5, -0.5));
|
||||||
|
|
||||||
|
QColor color;
|
||||||
|
if(table->getSelectedItems().contains(item))
|
||||||
|
{
|
||||||
|
if(table->getFocusedItem() == item)
|
||||||
|
color = QColor(44, 111, 222);
|
||||||
|
else
|
||||||
|
color = QColor(64, 136, 255);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(table->getFocusedItem() == item)
|
||||||
|
color = QColor(160, 160, 160);
|
||||||
|
else
|
||||||
|
color = QColor(180, 180, 180);
|
||||||
|
}
|
||||||
|
painter.setPen(color);
|
||||||
|
|
||||||
|
QLinearGradient gradient(r.topLeft(), r.bottomLeft());
|
||||||
|
gradient.setColorAt(0, QColor(255, 255, 255));
|
||||||
|
gradient.setColorAt(1, QColor(230, 230, 230));
|
||||||
|
painter.setBrush(gradient);
|
||||||
|
painter.drawRoundedRect(r, 5, 5);
|
||||||
|
|
||||||
|
QRectF r2 = r;
|
||||||
|
r2.setRight(ui->labelNumber->geometry().right() - 0.5);
|
||||||
|
|
||||||
|
QLinearGradient gradient2(r2.topLeft(), r2.bottomLeft());
|
||||||
|
gradient2.setColorAt(0, color.darker(110));
|
||||||
|
gradient2.setColorAt(1, color.darker(150));
|
||||||
|
painter.setBrush(gradient2);
|
||||||
|
painter.drawRoundedRect(r2, 5, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::updateModel()
|
||||||
|
{
|
||||||
|
IFilterGUI* sender = qobject_cast<IFilterGUI*>(QObject::sender());
|
||||||
|
QString command;
|
||||||
|
QString parameters;
|
||||||
|
sender->store(command, parameters);
|
||||||
|
|
||||||
|
item->text = command + ": " + parameters;
|
||||||
|
|
||||||
|
qDebug("Updated item text to %s", item->text.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::on_actionAdd_triggered()
|
||||||
|
{
|
||||||
|
QMenu* menu = table->createAddPopupMenu();
|
||||||
|
QRect rect = ui->toolBar->actionGeometry(ui->actionAdd);
|
||||||
|
QPoint p = ui->toolBar->mapToGlobal(QPoint(rect.x(), rect.y() + rect.height()));
|
||||||
|
QAction* action = menu->exec(p);
|
||||||
|
ui->actionAdd->setChecked(false);
|
||||||
|
if(action != NULL)
|
||||||
|
{
|
||||||
|
FilterTemplate t = action->data().value<FilterTemplate>();
|
||||||
|
QString line = t.getLine();
|
||||||
|
table->addLine(line, item);
|
||||||
|
table->updateGuis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::on_actionRemove_triggered()
|
||||||
|
{
|
||||||
|
table->removeItem(item);
|
||||||
|
table->updateGuis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::on_actionEditText_triggered(bool checked)
|
||||||
|
{
|
||||||
|
if(checked)
|
||||||
|
{
|
||||||
|
if(!lastEditTime.isValid() || lastEditTime.elapsed() > 100)
|
||||||
|
{
|
||||||
|
ui->lineEdit->setText(item->text);
|
||||||
|
ui->stackedWidget->setCurrentIndex(0);
|
||||||
|
ui->lineEdit->setFocus();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->actionEditText->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::on_lineEdit_editingFinished()
|
||||||
|
{
|
||||||
|
if(ui->stackedWidget->currentIndex() == 0 && !editingDone)
|
||||||
|
{
|
||||||
|
if(ui->lineEdit->text() != item->text)
|
||||||
|
{
|
||||||
|
editingDone = true;
|
||||||
|
item->text = ui->lineEdit->text();
|
||||||
|
// set focus to table so that enter key does not cause scrolling down
|
||||||
|
table->setFocus();
|
||||||
|
table->updateGuis();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->stackedWidget->setCurrentIndex(1);
|
||||||
|
lastEditTime.start();
|
||||||
|
ui->actionEditText->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTableRow::on_lineEdit_editingCanceled()
|
||||||
|
{
|
||||||
|
if(ui->stackedWidget->currentIndex() == 0)
|
||||||
|
{
|
||||||
|
// will cause editingFinished to be called, so prevent committing
|
||||||
|
editingDone = true;
|
||||||
|
table->setFocus();
|
||||||
|
ui->stackedWidget->setCurrentIndex(1);
|
||||||
|
editingDone = false;
|
||||||
|
ui->actionEditText->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <QWidget>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
#include "FilterTable.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class FilterTableRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilterTableRow : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FilterTableRow(FilterTable* table, int index, FilterTable::Item* item, IFilterGUI* gui);
|
||||||
|
~FilterTableRow();
|
||||||
|
|
||||||
|
QRect getHeaderRect();
|
||||||
|
void editText();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mouseDoubleClickEvent(QMouseEvent*) override;
|
||||||
|
void paintEvent(QPaintEvent*) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateModel();
|
||||||
|
|
||||||
|
void on_actionAdd_triggered();
|
||||||
|
void on_actionRemove_triggered();
|
||||||
|
void on_actionEditText_triggered(bool checked);
|
||||||
|
|
||||||
|
void on_lineEdit_editingFinished();
|
||||||
|
void on_lineEdit_editingCanceled();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::FilterTableRow *ui;
|
||||||
|
FilterTable* table;
|
||||||
|
FilterTable::Item* item;
|
||||||
|
IFilterGUI* gui;
|
||||||
|
bool editingDone = false;
|
||||||
|
QTime lastEditTime;
|
||||||
|
};
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>FilterTableRow</class>
|
||||||
|
<widget class="QWidget" name="FilterTableRow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelNumber">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>25</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="palette">
|
||||||
|
<palette>
|
||||||
|
<active>
|
||||||
|
<colorrole role="WindowText">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>255</red>
|
||||||
|
<green>255</green>
|
||||||
|
<blue>255</blue>
|
||||||
|
</color>
|
||||||
|
</brush>
|
||||||
|
</colorrole>
|
||||||
|
</active>
|
||||||
|
<inactive>
|
||||||
|
<colorrole role="WindowText">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>255</red>
|
||||||
|
<green>255</green>
|
||||||
|
<blue>255</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="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>OpenHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">99</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="CompactToolBar" name="toolBar" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="page">
|
||||||
|
<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="2">
|
||||||
|
<widget class="EscapableLineEdit" name="lineEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<action name="actionAdd">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/list-add-green.png</normaloff>:/icons/16x16/list-add-green.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRemove">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/list-remove-red.png</normaloff>:/icons/16x16/list-remove-red.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionEditText">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/accessories-text-editor.png</normaloff>:/icons/16x16/accessories-text-editor.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit text</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>CompactToolBar</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>Editor/widgets/CompactToolBar.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>EscapableLineEdit</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>Editor/widgets/EscapableLineEdit.h</header>
|
||||||
|
<slots>
|
||||||
|
<signal>editingCanceled()</signal>
|
||||||
|
</slots>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="Editor.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
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 "FilterTemplate.h"
|
||||||
|
|
||||||
|
FilterTemplate::FilterTemplate(QString name, QString line, QStringList path)
|
||||||
|
: name(name), line(line), path(path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FilterTemplate::getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTemplate::setName(const QString& value)
|
||||||
|
{
|
||||||
|
name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FilterTemplate::getLine() const
|
||||||
|
{
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTemplate::setLine(const QString& value)
|
||||||
|
{
|
||||||
|
line = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList FilterTemplate::getPath() const
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterTemplate::setPath(const QStringList& value)
|
||||||
|
{
|
||||||
|
path = value;
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
class FilterTemplate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FilterTemplate() {}
|
||||||
|
FilterTemplate(QString name, QString line, QStringList path);
|
||||||
|
|
||||||
|
QString getName() const;
|
||||||
|
void setName(const QString& value);
|
||||||
|
|
||||||
|
virtual QString getLine() const;
|
||||||
|
void setLine(const QString& value);
|
||||||
|
|
||||||
|
QStringList getPath() const;
|
||||||
|
void setPath(const QStringList& value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString name;
|
||||||
|
QString line;
|
||||||
|
QStringList path;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(FilterTemplate)
|
||||||
@@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IFilterGUI.h"
|
||||||
|
|
||||||
|
IFilterGUI::IFilterGUI(QWidget* parent) :
|
||||||
|
QWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IFilterGUI::~IFilterGUI()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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 <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class IFilterGUI : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
IFilterGUI(QWidget* parent = 0);
|
||||||
|
virtual ~IFilterGUI();
|
||||||
|
|
||||||
|
virtual void configureChannels(std::vector<std::wstring>& channelNames) {}
|
||||||
|
|
||||||
|
virtual void store(QString& command, QString& parameters) = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void updateModel();
|
||||||
|
void updateChannels();
|
||||||
|
};
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
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 "IFilterGUIFactory.h"
|
||||||
|
|
||||||
|
IFilterGUIFactory::~IFilterGUIFactory()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
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 "FilterTemplate.h"
|
||||||
|
#include "IFilterGUI.h"
|
||||||
|
|
||||||
|
class FilterTable;
|
||||||
|
|
||||||
|
class IFilterGUIFactory : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~IFilterGUIFactory();
|
||||||
|
|
||||||
|
virtual void initialize(FilterTable* filterTable) {}
|
||||||
|
|
||||||
|
virtual QList<FilterTemplate> createFilterTemplates()
|
||||||
|
{
|
||||||
|
return QList<FilterTemplate>();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void startOfFile(const QString& configPath) {}
|
||||||
|
virtual IFilterGUI* createFilterGUI(QString& command, QString& parameters) = 0;
|
||||||
|
virtual IFilterGUI* decorateFilterGUI(IFilterGUI* gui)
|
||||||
|
{
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
virtual void endOfFile(const QString& configPath) {}
|
||||||
|
};
|
||||||
@@ -0,0 +1,632 @@
|
|||||||
|
/*
|
||||||
|
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 <sstream>
|
||||||
|
#include <QDrag>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <QProcess>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "helpers/StringHelper.h"
|
||||||
|
#include "helpers/LogHelper.h"
|
||||||
|
#include "helpers/ChannelHelper.h"
|
||||||
|
#include "Editor/helpers/GUIChannelHelper.h"
|
||||||
|
#include "version.h"
|
||||||
|
#include "FilterTable.h"
|
||||||
|
#include "MainWindow.h"
|
||||||
|
#include "ui_MainWindow.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QDir configDir, QWidget *parent) :
|
||||||
|
QMainWindow(parent), ui(new Ui::MainWindow), configDir(configDir)
|
||||||
|
{
|
||||||
|
outputDevices = QList<DeviceAPOInfo>::fromVector(QVector<DeviceAPOInfo>::fromStdVector(DeviceAPOInfo::loadAllInfos(false)));
|
||||||
|
inputDevices = QList<DeviceAPOInfo>::fromVector(QVector<DeviceAPOInfo>::fromStdVector(DeviceAPOInfo::loadAllInfos(true)));
|
||||||
|
|
||||||
|
defaultOutputDevice = NULL;
|
||||||
|
for(DeviceAPOInfo& apoInfo : outputDevices)
|
||||||
|
{
|
||||||
|
if(apoInfo.isDefaultDevice)
|
||||||
|
{
|
||||||
|
defaultOutputDevice = &apoInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
QString version = QString("%0.%1").arg(MAJOR).arg(MINOR);
|
||||||
|
if(REVISION != 0)
|
||||||
|
version += QString(".%0").arg(REVISION);
|
||||||
|
setWindowTitle(tr("Equalizer APO %0 Configuration Editor").arg(version));
|
||||||
|
|
||||||
|
QWidget* spacer = new QWidget;
|
||||||
|
spacer->setFixedWidth(10);
|
||||||
|
ui->mainToolBar->addWidget(spacer);
|
||||||
|
|
||||||
|
instantModeCheckBox = new QCheckBox(tr("Instant mode"));
|
||||||
|
instantModeCheckBox->setChecked(true);
|
||||||
|
instantModeCheckBox->setToolTip(tr("Changes are saved immediately"));
|
||||||
|
connect(instantModeCheckBox, SIGNAL(toggled(bool)), this, SLOT(instantModeEnabled(bool)));
|
||||||
|
ui->mainToolBar->addWidget(instantModeCheckBox);
|
||||||
|
|
||||||
|
spacer = new QWidget;
|
||||||
|
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
ui->mainToolBar->addWidget(spacer);
|
||||||
|
|
||||||
|
ui->mainToolBar->addWidget(new QLabel(tr("Device: ")));
|
||||||
|
|
||||||
|
deviceComboBox = new QComboBox;
|
||||||
|
connect(deviceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(deviceSelected(int)));
|
||||||
|
ui->mainToolBar->addWidget(deviceComboBox);
|
||||||
|
|
||||||
|
spacer = new QWidget;
|
||||||
|
spacer->setFixedWidth(10);
|
||||||
|
ui->mainToolBar->addWidget(spacer);
|
||||||
|
|
||||||
|
ui->mainToolBar->addWidget(new QLabel(tr("Channel configuration: ")));
|
||||||
|
|
||||||
|
channelConfigurationComboBox = new QComboBox;
|
||||||
|
channelConfigurationComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||||
|
ui->mainToolBar->addWidget(channelConfigurationComboBox);
|
||||||
|
|
||||||
|
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(deviceComboBox->model());
|
||||||
|
if(defaultOutputDevice != NULL)
|
||||||
|
deviceComboBox->addItem(tr("Default") + " (" + QString::fromStdWString(defaultOutputDevice->connectionName) + " - " + QString::fromStdWString(defaultOutputDevice->deviceName) + ")", NULL);
|
||||||
|
|
||||||
|
deviceComboBox->addItem(tr("Playback devices:"));
|
||||||
|
QStandardItem* item = model->item(model->rowCount() - 1);
|
||||||
|
QFont font = item->font();
|
||||||
|
font.setBold(true);
|
||||||
|
item->setFont(font);
|
||||||
|
item->setSelectable(false);
|
||||||
|
|
||||||
|
for(DeviceAPOInfo& apoInfo : outputDevices)
|
||||||
|
if(apoInfo.isInstalled)
|
||||||
|
deviceComboBox->addItem(QString::fromStdWString(apoInfo.connectionName) + " - " + QString::fromStdWString(apoInfo.deviceName), QVariant::fromValue(&apoInfo));
|
||||||
|
|
||||||
|
deviceComboBox->addItem(tr("Capture devices:"));
|
||||||
|
item = model->item(model->rowCount() - 1);
|
||||||
|
item->setFont(font);
|
||||||
|
item->setSelectable(false);
|
||||||
|
|
||||||
|
for(DeviceAPOInfo& apoInfo : inputDevices)
|
||||||
|
if(apoInfo.isInstalled)
|
||||||
|
deviceComboBox->addItem(QString::fromStdWString(apoInfo.connectionName) + " - " + QString::fromStdWString(apoInfo.deviceName), QVariant::fromValue(&apoInfo));
|
||||||
|
|
||||||
|
connect(channelConfigurationComboBox, SIGNAL(activated(int)), this, SLOT(channelConfigurationSelected(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::doChecks()
|
||||||
|
{
|
||||||
|
if(!DeviceAPOInfo::checkProtectedAudioDG(false))
|
||||||
|
{
|
||||||
|
if(QMessageBox::warning(this, tr("Registry problem"), tr("A registry value that is required for the operation of Equalizer APO is not set correctly.\nDo you want to run the Configurator application to fix the problem?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
QProcess::startDetached(QCoreApplication::applicationDirPath() + "/Configurator.exe", QStringList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!defaultOutputDevice->isInstalled)
|
||||||
|
{
|
||||||
|
if(QMessageBox::warning(this, tr("APO not installed to device"), tr("Equalizer APO has not been installed to the selected device.\nDo you want to run the Configurator application to fix the problem?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
QProcess::startDetached(QCoreApplication::applicationDirPath() + "/Configurator.exe", QStringList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceAPOInfo* disabledApoInfo = NULL;
|
||||||
|
for(DeviceAPOInfo& apoInfo : outputDevices)
|
||||||
|
{
|
||||||
|
if(apoInfo.isInstalled && apoInfo.isEnhancementsDisabled)
|
||||||
|
{
|
||||||
|
disabledApoInfo = &apoInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(disabledApoInfo == NULL)
|
||||||
|
{
|
||||||
|
for(DeviceAPOInfo& apoInfo : inputDevices)
|
||||||
|
{
|
||||||
|
if(apoInfo.isInstalled && apoInfo.isEnhancementsDisabled)
|
||||||
|
{
|
||||||
|
disabledApoInfo = &apoInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(disabledApoInfo != NULL)
|
||||||
|
{
|
||||||
|
if(QMessageBox::warning(this, tr("Audio enhancements disabled"), tr("Audio enhancements are not enabled for the device\n%0 %1.\nDo you want to run the Configurator application to fix the problem?").arg(QString::fromStdWString(disabledApoInfo->connectionName)).arg(QString::fromStdWString(disabledApoInfo->deviceName)), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
QProcess::startDetached(QCoreApplication::applicationDirPath() + "/Configurator.exe", QStringList());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::load(QString path)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ui->tabWidget->count(); i++)
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->widget(i));
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
|
||||||
|
if(filterTable->getConfigPath() == path)
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||||
|
while(hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hFile = CreateFile(path.toStdWString().c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if(hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
if(error != ERROR_SHARING_VIOLATION)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Error while reading configuration file: %0").arg(QString::fromStdWString(StringHelper::getSystemErrorString(error))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file is being written, so wait
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stringstream inputStream;
|
||||||
|
|
||||||
|
char buf[8192];
|
||||||
|
unsigned long bytesRead = -1;
|
||||||
|
while(ReadFile(hFile, buf, sizeof(buf), &bytesRead, NULL) && bytesRead != 0)
|
||||||
|
{
|
||||||
|
inputStream.write(buf, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
inputStream.seekg(0);
|
||||||
|
|
||||||
|
QList<QString> lines;
|
||||||
|
while(inputStream.good())
|
||||||
|
{
|
||||||
|
string encodedLine;
|
||||||
|
getline(inputStream, encodedLine);
|
||||||
|
if(encodedLine.size() > 0 && encodedLine[encodedLine.size() - 1] == '\r')
|
||||||
|
encodedLine.resize(encodedLine.size() - 1);
|
||||||
|
|
||||||
|
wstring line = StringHelper::toWString(encodedLine, CP_UTF8);
|
||||||
|
if(line.find(L'\uFFFD') != -1)
|
||||||
|
line = StringHelper::toWString(encodedLine, CP_ACP);
|
||||||
|
|
||||||
|
lines.append(QString::fromStdWString(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo fileInfo(path);
|
||||||
|
FilterTable* filterTable = addTab(fileInfo.fileName(), QDir::toNativeSeparators(fileInfo.absoluteFilePath()));
|
||||||
|
|
||||||
|
filterTable->setLines(path, lines);
|
||||||
|
|
||||||
|
connect(filterTable, SIGNAL(linesChanged()), this, SLOT(linesChanged()));
|
||||||
|
|
||||||
|
qDebug("Loading took %.1f ms", timer.nsecsElapsed() / 1e6);
|
||||||
|
|
||||||
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::save(FilterTable* filterTable, QString path)
|
||||||
|
{
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
QList<QString> lines = filterTable->getLines();
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
QByteArray byteArray;
|
||||||
|
for(QString line : lines)
|
||||||
|
{
|
||||||
|
if(first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
byteArray.append("\r\n");
|
||||||
|
byteArray.append(line.toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||||
|
while(hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hFile = CreateFile(path.toStdWString().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if(hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
if(error != ERROR_SHARING_VIOLATION)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Error while writing configuration file: %0").arg(QString::fromStdWString(StringHelper::getSystemErrorString(error))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file is being written, so wait
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long bytesWritten;
|
||||||
|
WriteFile(hFile, byteArray.constData(), byteArray.length(), &bytesWritten, NULL);
|
||||||
|
if(bytesWritten != byteArray.length())
|
||||||
|
{
|
||||||
|
// should never happen
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Only %0/%1 bytes have been written!").arg(bytesWritten).arg(byteArray.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
|
||||||
|
qDebug("Saving took %.1f ms", timer.nsecsElapsed() / 1e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::closeEvent(QCloseEvent* event)
|
||||||
|
{
|
||||||
|
while(ui->tabWidget->count() > 0)
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(0);
|
||||||
|
|
||||||
|
if(!on_tabWidget_tabCloseRequested(0))
|
||||||
|
{
|
||||||
|
event->ignore();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::deviceSelected(int index)
|
||||||
|
{
|
||||||
|
DeviceAPOInfo* apoInfo = deviceComboBox->itemData(index).value<DeviceAPOInfo*>();
|
||||||
|
if(apoInfo == NULL)
|
||||||
|
apoInfo = defaultOutputDevice;
|
||||||
|
|
||||||
|
channelConfigurationComboBox->clear();
|
||||||
|
|
||||||
|
const QList<GUIChannelHelper::ChannelConfigurationInfo>& infos = GUIChannelHelper::getInstance()->getChannelConfigurationInfos();
|
||||||
|
|
||||||
|
if(apoInfo != NULL)
|
||||||
|
{
|
||||||
|
const GUIChannelHelper::ChannelConfigurationInfo* selectedInfo = NULL;
|
||||||
|
for(const GUIChannelHelper::ChannelConfigurationInfo& info : infos)
|
||||||
|
{
|
||||||
|
if(info.channelMask == apoInfo->channelMask)
|
||||||
|
{
|
||||||
|
selectedInfo = &info;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selectedInfo != NULL)
|
||||||
|
channelConfigurationComboBox->addItem(tr("From device") + " (" + selectedInfo->name + ")", 0);
|
||||||
|
else
|
||||||
|
channelConfigurationComboBox->addItem(tr("From device") + " (" + apoInfo->channelCount + " channels)", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const GUIChannelHelper::ChannelConfigurationInfo& info : infos)
|
||||||
|
channelConfigurationComboBox->addItem(info.name, info.channelMask);
|
||||||
|
|
||||||
|
channelConfigurationSelected(channelConfigurationComboBox->currentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::channelConfigurationSelected(int index)
|
||||||
|
{
|
||||||
|
DeviceAPOInfo* selectedDevice;
|
||||||
|
int channelMask;
|
||||||
|
getDeviceAndChannelMask(&selectedDevice, &channelMask);
|
||||||
|
|
||||||
|
for(int i = 0; i < ui->tabWidget->count(); i++)
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->widget(i));
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
filterTable->updateDeviceAndChannelMask(selectedDevice, channelMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::linesChanged()
|
||||||
|
{
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(sender());
|
||||||
|
|
||||||
|
if(instantModeCheckBox->isChecked())
|
||||||
|
{
|
||||||
|
QString configPath = filterTable->getConfigPath();
|
||||||
|
if(configPath.length() > 0)
|
||||||
|
{
|
||||||
|
save(filterTable, configPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tabIndex = -1;
|
||||||
|
for(int i = 0; i < ui->tabWidget->count(); i++)
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->widget(i));
|
||||||
|
if(scrollArea->widget() == filterTable)
|
||||||
|
{
|
||||||
|
tabIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString tabText = ui->tabWidget->tabText(tabIndex);
|
||||||
|
if(!tabText.endsWith('*'))
|
||||||
|
{
|
||||||
|
tabText += '*';
|
||||||
|
ui->tabWidget->setTabText(tabIndex, tabText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::getDeviceAndChannelMask(DeviceAPOInfo** selectedDevice, int* channelMask)
|
||||||
|
{
|
||||||
|
*selectedDevice = deviceComboBox->currentData().value<DeviceAPOInfo*>();
|
||||||
|
if(*selectedDevice == NULL)
|
||||||
|
*selectedDevice = defaultOutputDevice;
|
||||||
|
|
||||||
|
*channelMask = channelConfigurationComboBox->currentData().toInt();
|
||||||
|
if(*channelMask == 0 && selectedDevice != NULL)
|
||||||
|
{
|
||||||
|
*channelMask = (*selectedDevice)->channelMask;
|
||||||
|
|
||||||
|
if(*channelMask == 0)
|
||||||
|
*channelMask = ChannelHelper::getDefaultChannelMask((*selectedDevice)->channelCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::on_tabWidget_tabCloseRequested(int index)
|
||||||
|
{
|
||||||
|
if(ui->tabWidget->tabText(index).endsWith('*'))
|
||||||
|
{
|
||||||
|
ui->tabWidget->setCurrentIndex(index);
|
||||||
|
QString configPath = ui->tabWidget->tabToolTip(index);
|
||||||
|
QMessageBox messageBox;
|
||||||
|
messageBox.setWindowTitle(tr("Unsaved changes"));
|
||||||
|
messageBox.setText(tr("The configuration file %0 has unsaved changes.").arg(configPath));
|
||||||
|
messageBox.setInformativeText(tr("Do you want to save the changes before closing the file?"));
|
||||||
|
messageBox.setIcon(QMessageBox::Question);
|
||||||
|
messageBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||||
|
messageBox.setDefaultButton(QMessageBox::Save);
|
||||||
|
messageBox.setEscapeButton(QMessageBox::Cancel);
|
||||||
|
messageBox.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
|
||||||
|
int result = messageBox.exec();
|
||||||
|
|
||||||
|
switch(result)
|
||||||
|
{
|
||||||
|
case QMessageBox::Save:
|
||||||
|
ui->actionSave->trigger();
|
||||||
|
if(ui->tabWidget->tabText(index).endsWith('*'))
|
||||||
|
// saving was canceled
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case QMessageBox::Discard:
|
||||||
|
break;
|
||||||
|
case QMessageBox::Cancel:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->tabWidget->removeTab(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionOpen_triggered()
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
|
||||||
|
QString path;
|
||||||
|
if(scrollArea != NULL)
|
||||||
|
{
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
if(filterTable->getConfigPath().length() > 0)
|
||||||
|
{
|
||||||
|
QFileInfo fileInfo(filterTable->getConfigPath());
|
||||||
|
path = fileInfo.absolutePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(path.length() == 0)
|
||||||
|
path = configDir.absolutePath();
|
||||||
|
|
||||||
|
QFileDialog dialog(this, tr("Open file"), path, "*.txt");
|
||||||
|
dialog.setFileMode(QFileDialog::ExistingFiles);
|
||||||
|
dialog.setNameFilter(tr("E-APO configurations (*.txt)"));
|
||||||
|
|
||||||
|
if(dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
for(QString file : dialog.selectedFiles())
|
||||||
|
load(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionSave_triggered()
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
|
||||||
|
if(scrollArea == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
|
||||||
|
if(filterTable->getConfigPath().length() == 0)
|
||||||
|
{
|
||||||
|
ui->actionSaveAs->trigger();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
save(filterTable, filterTable->getConfigPath());
|
||||||
|
|
||||||
|
QString tabText = ui->tabWidget->tabText(ui->tabWidget->currentIndex());
|
||||||
|
if(tabText.endsWith('*'))
|
||||||
|
ui->tabWidget->setTabText(ui->tabWidget->currentIndex(), tabText.left(tabText.length() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionSaveAs_triggered()
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
|
||||||
|
if(scrollArea == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
QString path;
|
||||||
|
QString filename;
|
||||||
|
if(filterTable->getConfigPath().length() == 0)
|
||||||
|
{
|
||||||
|
path = configDir.absolutePath();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QFileInfo fileInfo(filterTable->getConfigPath());
|
||||||
|
path = fileInfo.absolutePath();
|
||||||
|
filename = fileInfo.fileName();
|
||||||
|
}
|
||||||
|
QFileDialog dialog(this, tr("Save file as"), path, "*.txt");
|
||||||
|
dialog.setFileMode(QFileDialog::AnyFile);
|
||||||
|
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||||
|
dialog.setNameFilter(tr("E-APO configurations (*.txt)"));
|
||||||
|
dialog.setDefaultSuffix(".txt");
|
||||||
|
if(filename.length() > 0)
|
||||||
|
dialog.selectFile(filename);
|
||||||
|
|
||||||
|
if(dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
QString savePath = dialog.selectedFiles().first();
|
||||||
|
save(filterTable, savePath);
|
||||||
|
filterTable->setConfigPath(savePath);
|
||||||
|
|
||||||
|
QFileInfo fileInfo(savePath);
|
||||||
|
ui->tabWidget->setTabText(ui->tabWidget->currentIndex(), fileInfo.fileName());
|
||||||
|
ui->tabWidget->setTabToolTip(ui->tabWidget->currentIndex(), QDir::toNativeSeparators(fileInfo.absoluteFilePath()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionNew_triggered()
|
||||||
|
{
|
||||||
|
FilterTable* filterTable = addTab(tr("Unsaved"), "");
|
||||||
|
filterTable->setLines("", QList<QString>());
|
||||||
|
|
||||||
|
connect(filterTable, SIGNAL(linesChanged()), this, SLOT(linesChanged()));
|
||||||
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTable* MainWindow::addTab(QString title, QString tooltip)
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = new QScrollArea(ui->tabWidget);
|
||||||
|
scrollArea->setWidgetResizable(true);
|
||||||
|
FilterTable* filterTable = new FilterTable(this);
|
||||||
|
scrollArea->setWidget(filterTable);
|
||||||
|
filterTable->setAcceptDrops(true);
|
||||||
|
filterTable->setFocusPolicy(Qt::WheelFocus);
|
||||||
|
|
||||||
|
int tabIndex = ui->tabWidget->addTab(scrollArea, title);
|
||||||
|
ui->tabWidget->setTabToolTip(tabIndex, tooltip);
|
||||||
|
|
||||||
|
DeviceAPOInfo* selectedDevice;
|
||||||
|
int channelMask;
|
||||||
|
getDeviceAndChannelMask(&selectedDevice, &channelMask);
|
||||||
|
filterTable->updateDeviceAndChannelMask(selectedDevice, channelMask);
|
||||||
|
filterTable->initialize(scrollArea, outputDevices, inputDevices);
|
||||||
|
|
||||||
|
return filterTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionCut_triggered()
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
|
||||||
|
if(scrollArea == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
filterTable->cut();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionCopy_triggered()
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
|
||||||
|
if(scrollArea == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
filterTable->copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionPaste_triggered()
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
|
||||||
|
if(scrollArea == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
filterTable->paste();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionDelete_triggered()
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
|
||||||
|
if(scrollArea == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
filterTable->deleteSelectedLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::instantModeEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if(enabled)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ui->tabWidget->count(); i++)
|
||||||
|
{
|
||||||
|
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->widget(i));
|
||||||
|
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
|
||||||
|
|
||||||
|
if(filterTable->getConfigPath().length() > 0)
|
||||||
|
{
|
||||||
|
save(filterTable, filterTable->getConfigPath());
|
||||||
|
|
||||||
|
QString tabText = ui->tabWidget->tabText(i);
|
||||||
|
if(tabText.endsWith('*'))
|
||||||
|
ui->tabWidget->setTabText(i, tabText.left(tabText.length() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
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 <QMainWindow>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "FilterTable.h"
|
||||||
|
#include "DeviceAPOInfo.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QDir configDir, QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
void doChecks();
|
||||||
|
void load(QString path);
|
||||||
|
void save(FilterTable* filterTable, QString path);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void deviceSelected(int index);
|
||||||
|
void channelConfigurationSelected(int index);
|
||||||
|
void linesChanged();
|
||||||
|
|
||||||
|
bool on_tabWidget_tabCloseRequested(int index);
|
||||||
|
void on_actionOpen_triggered();
|
||||||
|
void on_actionSave_triggered();
|
||||||
|
void on_actionSaveAs_triggered();
|
||||||
|
void on_actionNew_triggered();
|
||||||
|
|
||||||
|
void on_actionCut_triggered();
|
||||||
|
void on_actionDelete_triggered();
|
||||||
|
void on_actionPaste_triggered();
|
||||||
|
void on_actionCopy_triggered();
|
||||||
|
|
||||||
|
void instantModeEnabled(bool enabled);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FilterTable* addTab(QString title, QString tooltip);
|
||||||
|
void getDeviceAndChannelMask(DeviceAPOInfo** selectedDevice, int* channelMask);
|
||||||
|
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
QDir configDir;
|
||||||
|
QCheckBox* instantModeCheckBox;
|
||||||
|
QComboBox* deviceComboBox;
|
||||||
|
QComboBox* channelConfigurationComboBox;
|
||||||
|
QList<DeviceAPOInfo> outputDevices;
|
||||||
|
QList<DeviceAPOInfo> inputDevices;
|
||||||
|
DeviceAPOInfo* defaultOutputDevice;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(DeviceAPOInfo*)
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1024</width>
|
||||||
|
<height>768</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralWidget">
|
||||||
|
<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="0">
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="documentMode">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="tabsClosable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="movable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menuBar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1024</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNew"/>
|
||||||
|
<addaction name="actionOpen"/>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="actionSaveAs"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionExit"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuEdit">
|
||||||
|
<property name="title">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionCut"/>
|
||||||
|
<addaction name="actionCopy"/>
|
||||||
|
<addaction name="actionPaste"/>
|
||||||
|
<addaction name="actionDelete"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuEdit"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="mainToolBar">
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="actionNew"/>
|
||||||
|
<addaction name="actionOpen"/>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
</widget>
|
||||||
|
<action name="actionNew">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/document-new.png</normaloff>:/icons/16x16/document-new.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+N</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionOpen">
|
||||||
|
<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>Open</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Open</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+O</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/document-save.png</normaloff>:/icons/16x16/document-save.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+S</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSaveAs">
|
||||||
|
<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>Save as...</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save as...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionExit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Alt+F4</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCut">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/edit-cut.png</normaloff>:/icons/16x16/edit-cut.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cut</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+X</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCopy">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/edit-copy.png</normaloff>:/icons/16x16/edit-copy.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Copy</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+C</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPaste">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/edit-paste.png</normaloff>:/icons/16x16/edit-paste.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Paste</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+V</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDelete">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Editor.qrc">
|
||||||
|
<normaloff>:/icons/16x16/edit-delete.png</normaloff>:/icons/16x16/edit-delete.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<resources>
|
||||||
|
<include location="Editor.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>actionExit</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>close()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>511</x>
|
||||||
|
<y>383</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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" : "");
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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*)
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
};
|
||||||
Loaded 100 of 284 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user