Improved: The Configuration Editor now saves most of its state (window positions, open files, etc.) when closing and restores it when run again.

Fixed: The GUI for the Copy command was behaving incorrectly when channels were selected by number instead of name.
Fixed: When the processing caused delay (e.g. via Delay command), the remaining audio was not output when the input signal became silence (e.g. pausing a music player), but only when the silence ended.
Fixed: The checks for missing registry values in Configuration Editor/Configurator should now be sufficient to reanimate E-APO after an OS upgrade. Also the Configurator did not launch when accepting the question in the Configuration Editor with UAC enabled.
This commit is contained in:
jthedering committed 2015-11-22 20:16:39 +00:00
1 parent 0895d84055
commit a1be4cc70f
32 files changed
+1111 -205

No files matched your search

+7 -3
View File
@@ -61,7 +61,7 @@ void Configurator::onInitDialog(HWND hDlg)
expandTroubleShooting(false);
wchar_t stringBuf[255];
wchar_t stringBuf[512];
TCITEM tci;
tci.pszText = stringBuf;
@@ -206,10 +206,13 @@ void Configurator::onInitDialog(HWND hDlg)
ListView_SetColumnWidth(deviceList, 2, LVSCW_AUTOSIZE);
}
if (!DeviceAPOInfo::checkProtectedAudioDG(true))
bool fixedAudioDG = !DeviceAPOInfo::checkProtectedAudioDG(true);
bool fixedRegistration = !DeviceAPOInfo::checkAPORegistration(true);
if (fixedAudioDG || fixedRegistration)
{
LoadStringW(hInstance, IDS_REGISTRY_VALUE_FIXED, stringBuf, sizeof(stringBuf) / sizeof(wchar_t));
MessageBoxW(hDlg, stringBuf, L"Info", MB_ICONINFORMATION | MB_OK);
askForReboot = true;
}
}
@@ -377,7 +380,8 @@ bool Configurator::onButtonClicked(unsigned sourceId)
LoadStringW(hInstance, IDS_AFTERINSTALL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t));
MessageBoxW(hDlg, stringBuf, L"Info", MB_ICONINFORMATION | MB_OK);
}
else if(sourceId == IDOK && RegistryHelper::isWindowsVersionAtLeast(6, 3)) // Windows 8.1
else if(sourceId == IDOK && RegistryHelper::isWindowsVersionAtLeast(6, 3) // Windows 8.1
|| askForReboot)
{
wchar_t captionBuf[255];
LoadStringW(hInstance, IDS_SHOULD_REBOOT_CAPTION, captionBuf, sizeof(captionBuf)/sizeof(wchar_t));
+1
View File
@@ -63,4 +63,5 @@ private:
void updateButtons(int listIndex);
std::vector<DeviceAPOInfo> apoInfos[2];
bool askForReboot = false;
};
Binary file not shown.
+4 -4
View File
@@ -138,7 +138,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>audioeng.lib;version.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -151,7 +151,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -168,7 +168,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>audioeng.lib;version.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -185,7 +185,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>audioeng.lib;version.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+29
View File
@@ -20,6 +20,7 @@
#include "stdafx.h"
#include <mmdeviceapi.h>
#include <mmreg.h>
#include <shellapi.h>
#include "DeviceAPOInfo.h"
@@ -30,6 +31,8 @@ using namespace std;
#define protectedDGKeyPath L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Audio"
#define protectedDGValueName L"DisableProtectedAudioDG"
#define apoRegistrationKeyPath L"HKEY_CLASSES_ROOT\\AudioEngine\\AudioProcessingObjects"
#define clsidKeyPath L"HKEY_CLASSES_ROOT\\CLSID"
#define commonKeyPath L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio"
#define renderKeyPath commonKeyPath L"\\Render"
#define captureKeyPath commonKeyPath L"\\Capture"
@@ -134,6 +137,32 @@ bool DeviceAPOInfo::checkProtectedAudioDG(bool fix)
return result;
}
bool DeviceAPOInfo::checkAPORegistration(bool fix)
{
bool result = true;
if (!RegistryHelper::keyExists(apoRegistrationKeyPath L"\\" + RegistryHelper::getGuidString(EQUALIZERAPO_PRE_MIX_GUID))
|| !RegistryHelper::keyExists(apoRegistrationKeyPath L"\\" + RegistryHelper::getGuidString(EQUALIZERAPO_POST_MIX_GUID))
|| !RegistryHelper::keyExists(clsidKeyPath L"\\" + RegistryHelper::getGuidString(EQUALIZERAPO_PRE_MIX_GUID))
|| !RegistryHelper::keyExists(clsidKeyPath L"\\" + RegistryHelper::getGuidString(EQUALIZERAPO_POST_MIX_GUID)))
{
result = false;
if (fix)
{
wchar_t path[MAX_PATH];
if(GetModuleFileNameW(NULL, path, MAX_PATH) != 0)
{
PathRemoveFileSpecW(path);
wstring params = wstring(L"/s \"") + path + L"\\EqualizerAPO.dll\"";
ShellExecuteW(NULL, L"open", L"regsvr32.exe", params.c_str(), NULL, SW_SHOWNORMAL);
}
}
}
return result;
}
bool DeviceAPOInfo::load(const wstring& deviceGuid, wstring defaultDeviceGuid)
{
wstring keyPath;
+1
View File
@@ -62,6 +62,7 @@ public:
static std::vector<DeviceAPOInfo> loadAllInfos(bool input);
static std::wstring getDefaultDevice(bool input, int role = 1);
static bool checkProtectedAudioDG(bool fix);
static bool checkAPORegistration(bool fix);
bool load(const std::wstring& deviceGuid, std::wstring defaultDeviceGuid = L"");
bool canBeUpgraded();
bool hasChanges();
+4 -2
View File
@@ -111,7 +111,8 @@ SOURCES += main.cpp\
../parser/RegistryFunctions.cpp \
../parser/StringOperators.cpp \
AnalysisThread.cpp \
widgets/ExponentialSpinBox.cpp
widgets/ExponentialSpinBox.cpp \
FilterTableMimeData.cpp
HEADERS += \
../helpers/LogHelper.h \
@@ -211,7 +212,8 @@ HEADERS += \
../parser/RegistryFunctions.h \
../parser/StringOperators.h \
AnalysisThread.h \
widgets/ExponentialSpinBox.h
widgets/ExponentialSpinBox.h \
FilterTableMimeData.h
FORMS += \
guis/PreampFilterGUI.ui \
+154 -11
View File
@@ -30,9 +30,12 @@
#include <QComboBox>
#include <QAbstractSpinBox>
#include <QDial>
#include <QJsonDocument>
#include <QSettings>
#include "MainWindow.h"
#include "FilterTableRow.h"
#include "FilterTableMimeData.h"
#include "guis/ExpressionFilterGUIFactory.h"
#include "guis/CommentFilterGUIFactory.h"
#include "guis/DeviceFilterGUIFactory.h"
@@ -48,6 +51,7 @@
#include "helpers/StringHelper.h"
#include "helpers/LogHelper.h"
#include "helpers/ChannelHelper.h"
#include "helpers/RegistryHelper.h"
#include "FilterTable.h"
using namespace std;
@@ -102,7 +106,15 @@ void FilterTable::updateGuis()
QElapsedTimer timer;
timer.start();
guis.clear();
for(Item* item : items)
{
if(item->gui != NULL)
{
item->prefs.clear();
item->gui->storePreferences(item->prefs);
}
}
delete layout();
for(QObject* object : children())
@@ -133,7 +145,7 @@ void FilterTable::updateGuis()
{
QString line = item->text;
IFilterGUI* gui = NULL;
int pos = line.indexOf(L':');
int pos = line.indexOf(':');
if(pos != -1)
{
QString key = line.mid(0, pos);
@@ -164,9 +176,12 @@ void FilterTable::updateGuis()
FilterTableRow* rowWidget = new FilterTableRow(this, row + 1, item, gui);
gridLayout->addWidget(rowWidget, row, 0);
item->gui = gui;
if(gui != NULL)
{
guis.append(gui);
gui->loadPreferences(item->prefs);
connect(gui, SIGNAL(updateModel()), this, SLOT(updateModel()));
connect(gui, SIGNAL(updateChannels()), this, SLOT(updateChannels()));
}
@@ -208,9 +223,10 @@ void FilterTable::propagateChannels()
{
vector<wstring> channelNames = ChannelHelper::getChannelNames(selectedDevice->channelCount, selectedChannelMask);
for(IFilterGUI* gui : guis)
for(Item* item : items)
{
gui->configureChannels(channelNames);
if(item->gui != NULL)
item->gui->configureChannels(channelNames);
}
}
@@ -231,7 +247,50 @@ void FilterTable::setLines(const QString& configPath, const QList<QString>& line
items.clear();
for(QString line : lines)
{
items.append(new Item(line));
}
QSettings settings(QString::fromWCharArray(EDITOR_PER_FILE_REGPATH), QSettings::NativeFormat);
settings.beginGroup(QString(configPath).replace('\\', '|'));
QVariant prefsValue = settings.value("rowPrefs");
QStringList prefLines;
if(prefsValue.isValid())
prefLines = prefsValue.toStringList();
for(QString prefLine : prefLines)
{
int index = prefLine.indexOf(':');
int lineNumber;
if(index != -1)
lineNumber = prefLine.left(index).toInt();
QString prefCommand;
QString prefString;
if(lineNumber > 0)
{
int index2 = prefLine.indexOf(':', index + 1);
if(index2 != -1)
{
prefCommand = prefLine.mid(index + 1, index2 - index - 1);
prefString = prefLine.mid(index2 + 1);
if(lineNumber <= items.size())
{
Item* item = items[lineNumber - 1];
QString command;
int index = item->text.indexOf(':');
if(index != -1)
command = item->text.left(index).trimmed();
if(command == prefCommand)
item->prefs = QJsonDocument::fromJson(prefString.toUtf8()).toVariant().toMap();
}
}
}
}
setScrollOffsets(settings.value("scrollX", 0).toInt(), settings.value("scrollY", 0).toInt());
settings.endGroup();
if(!items.isEmpty())
{
@@ -319,6 +378,7 @@ void FilterTable::cut()
void FilterTable::copy()
{
QString text;
QList<QVariantMap> prefsList;
bool first = true;
for(Item* item : items)
{
@@ -329,13 +389,15 @@ void FilterTable::copy()
else
text += "\n";
text += item->text;
prefsList.append(item->prefs);
}
}
if(selected.size() > 0)
{
QMimeData* mimeData = new QMimeData;
FilterTableMimeData* mimeData = new FilterTableMimeData;
mimeData->setText(text);
mimeData->setPrefsList(prefsList);
QClipboard* clipboard = QApplication::clipboard();
clipboard->setMimeData(mimeData);
}
@@ -359,12 +421,20 @@ void FilterTable::paste()
QString text = mimeData->text();
QStringList textLines = text.split("\n");
QList<QVariantMap> prefsList;
const FilterTableMimeData* filterTableMimeData = qobject_cast<const FilterTableMimeData*>(mimeData);
if(filterTableMimeData != NULL)
prefsList = filterTableMimeData->getPrefsList();
selected.clear();
focused = NULL;
selectionStart = NULL;
for(QString line : textLines)
for(int i = 0; i < textLines.size(); i++)
{
QString line = textLines[i];
Item* item = new Item(line);
if(!prefsList.isEmpty())
item->prefs = prefsList[i];
selected.insert(item);
items.insert(dropRow++, item);
if(focused == NULL)
@@ -468,6 +538,50 @@ void FilterTable::setMinimumHeightHint(int height)
updateGeometry();
}
void FilterTable::savePreferences()
{
if(!configPath.isEmpty())
{
QStringList prefLines;
for(int i = 0; i < items.size(); i++)
{
Item* item = items[i];
if(item->gui != NULL)
{
item->prefs.clear();
item->gui->storePreferences(item->prefs);
}
if(!item->prefs.isEmpty())
{
QString command;
int index = item->text.indexOf(':');
if(index != -1)
command = item->text.left(index).trimmed();
QByteArray byteArray = QJsonDocument::fromVariant(item->prefs).toJson(QJsonDocument::Compact);
QString string = QString("%0:%1:%2").arg(i + 1).arg(command).arg(QString::fromUtf8(byteArray));
prefLines.append(string);
}
}
QSettings settings(QString::fromWCharArray(EDITOR_PER_FILE_REGPATH), QSettings::NativeFormat);
settings.beginGroup(QString(configPath).replace('\\', '|'));
settings.setValue("rowPrefs", prefLines);
settings.setValue("scrollX", scrollArea->horizontalScrollBar()->value());
settings.setValue("scrollY", scrollArea->verticalScrollBar()->value());
settings.endGroup();
}
}
void FilterTable::setScrollOffsets(int x, int y)
{
presetScrollX = x;
presetScrollY = y;
}
void FilterTable::mousePressEvent(QMouseEvent* event)
{
if(event->buttons() & Qt::LeftButton )
@@ -525,6 +639,7 @@ void FilterTable::mouseMoveEvent(QMouseEvent* event)
if((event->pos() - dragStartPos).manhattanLength() >= QApplication::startDragDistance())
{
QString text;
QList<QVariantMap> prefsList;
bool first = true;
int i = 0;
bool dragPosInside = false;
@@ -537,6 +652,9 @@ void FilterTable::mouseMoveEvent(QMouseEvent* event)
else
text += "\n";
text += item->text;
if(item->gui != NULL)
item->gui->storePreferences(item->prefs);
prefsList.append(item->prefs);
if(!dragPosInside)
{
@@ -551,8 +669,9 @@ void FilterTable::mouseMoveEvent(QMouseEvent* event)
if(selected.size() > 0 && dragPosInside)
{
QMimeData* mimeData = new QMimeData;
FilterTableMimeData* mimeData = new FilterTableMimeData;
mimeData->setText(text);
mimeData->setPrefsList(prefsList);
QDrag* drag = new QDrag(this);
drag->setMimeData(mimeData);
@@ -628,15 +747,21 @@ void FilterTable::dragLeaveEvent(QDragLeaveEvent* event)
void FilterTable::dropEvent(QDropEvent* event)
{
if(event->mimeData()->hasText())
const QMimeData* mimeData = event->mimeData();
if(mimeData->hasText())
{
if(event->keyboardModifiers() & Qt::ControlModifier)
event->setDropAction(Qt::CopyAction);
else
event->setDropAction(Qt::MoveAction);
QString text = event->mimeData()->text();
QString text = mimeData->text();
QStringList textLines = text.split("\n");
QList<QVariantMap> prefsList;
const FilterTableMimeData* filterTableMimeData = qobject_cast<const FilterTableMimeData*>(mimeData);
if(filterTableMimeData != NULL)
prefsList = filterTableMimeData->getPrefsList();
int dropRow = rowForPos(event->pos(), true);
if(dropRow == -1)
dropRow = items.size();
@@ -644,9 +769,12 @@ void FilterTable::dropEvent(QDropEvent* event)
selected.clear();
focused = NULL;
selectionStart = NULL;
for(QString line : textLines)
for(int i = 0; i < textLines.size(); i++)
{
QString line = textLines[i];
Item* item = new Item(line);
if(!prefsList.isEmpty())
item->prefs = prefsList[i];
selected.insert(item);
items.insert(dropRow++, item);
if(focused == NULL)
@@ -787,6 +915,21 @@ bool FilterTable::eventFilter(QObject* obj, QEvent* event)
return false;
}
void FilterTable::showEvent(QShowEvent*)
{
if(presetScrollX != -1)
{
scrollArea->horizontalScrollBar()->setValue(presetScrollX);
presetScrollX = -1;
}
if(presetScrollY != -1)
{
scrollArea->verticalScrollBar()->setValue(presetScrollY);
presetScrollY = -1;
}
}
void FilterTable::ensureRowVisible(int row)
{
QScrollBar* vScrollBar = scrollArea->verticalScrollBar();
+9 -1
View File
@@ -26,6 +26,7 @@
#include <QGridLayout>
#include <QScrollArea>
#include <QMenu>
#include <QJsonObject>
#include "Editor/helpers/DisableWheelFilter.h"
#include "DeviceAPOInfo.h"
@@ -49,6 +50,8 @@ public:
}
QString text;
QVariantMap prefs;
IFilterGUI* gui = NULL;
};
explicit FilterTable(MainWindow* mainWindow, QWidget *parent = 0);
@@ -85,6 +88,9 @@ public:
QSize minimumSizeHint() const override;
void setMinimumHeightHint(int height);
void savePreferences();
void setScrollOffsets(int x, int y);
signals:
void linesChanged();
@@ -103,6 +109,7 @@ protected:
void keyPressEvent(QKeyEvent* event) override;
void wheelEvent(QWheelEvent* event) override;
bool eventFilter(QObject* obj, QEvent* event) override;
void showEvent(QShowEvent*) override;
private:
void ensureRowVisible(int row);
@@ -121,7 +128,6 @@ private:
Item* focused = NULL;
Item* selectionStart = NULL;
QList<IFilterGUIFactory*> factories;
QList<IFilterGUI*> guis;
bool scrollingNow = false;
QPoint scrollStartPoint;
QList<DeviceAPOInfo> outputDevices;
@@ -130,6 +136,8 @@ private:
int selectedChannelMask;
QString configPath;
int minimumHeightHint = 0;
int presetScrollX = -1;
int presetScrollY = -1;
};
template<typename T> inline uint qHash(QList<T> list)
+35
View File
@@ -0,0 +1,35 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 Jonas Thedering
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "FilterTableMimeData.h"
FilterTableMimeData::FilterTableMimeData()
{
}
QList<QVariantMap> FilterTableMimeData::getPrefsList() const
{
return prefsList;
}
void FilterTableMimeData::setPrefsList(const QList<QVariantMap>& value)
{
prefsList = value;
}
+36
View File
@@ -0,0 +1,36 @@
/*
This file is part of EqualizerAPO, a system-wide equalizer.
Copyright (C) 2015 Jonas Thedering
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include <QMimeData>
class FilterTableMimeData : public QMimeData
{
Q_OBJECT
public:
FilterTableMimeData();
QList<QVariantMap> getPrefsList() const;
void setPrefsList(const QList<QVariantMap>& value);
private:
QList<QVariantMap> prefsList;
};
+4
View File
@@ -22,6 +22,7 @@
#include <string>
#include <vector>
#include <QWidget>
#include <QVariantMap>
class IFilterGUI : public QWidget
{
@@ -35,6 +36,9 @@ public:
virtual void store(QString& command, QString& parameters) = 0;
virtual void loadPreferences(const QVariantMap& prefs) {}
virtual void storePreferences(QVariantMap& prefs) {}
signals:
void updateModel();
void updateChannels();
+329 -42
View File
@@ -30,9 +30,11 @@
#include <QFileDialog>
#include <QMessageBox>
#include <QProcess>
#include <QSettings>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include "helpers/StringHelper.h"
#include "helpers/LogHelper.h"
@@ -132,6 +134,33 @@ MainWindow::MainWindow(QDir configDir, QWidget *parent) :
analysisThread = new AnalysisThread;
analysisThread->start();
connect(analysisThread, SIGNAL(analysisFinished()), this, SLOT(updateAnalysisPanel()));
QLocale autoLocale = QLocale::system();
if(autoLocale.language() != QLocale::German)
autoLocale = QLocale("en");
QLocale::Language languages[] = {QLocale::AnyLanguage, QLocale::English, QLocale::German};
for(int i = 0; i < sizeof(languages) / sizeof(QLocale::Language); i++)
{
QLocale::Language language = languages[i];
QString languageName;
if(language == QLocale::AnyLanguage)
languageName = autoLocale.nativeLanguageName();
else
languageName = QLocale(language).nativeLanguageName();
if(languageName == "American English")
languageName = "English";
QString text;
if(language == QLocale::AnyLanguage)
text = tr("Automatic (%0)").arg(languageName);
else
text = languageName;
QAction* action = ui->menuLanguage->addAction(text);
action->setData(language);
action->setCheckable(true);
connect(action, SIGNAL(triggered(bool)), this, SLOT(languageSelected(bool)));
}
loadPreferences();
}
MainWindow::~MainWindow()
@@ -143,11 +172,11 @@ MainWindow::~MainWindow()
void MainWindow::doChecks()
{
if(!DeviceAPOInfo::checkProtectedAudioDG(false))
if(!DeviceAPOInfo::checkProtectedAudioDG(false) || !DeviceAPOInfo::checkAPORegistration(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());
runConfigurator();
return;
}
}
@@ -156,7 +185,7 @@ void MainWindow::doChecks()
{
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());
runConfigurator();
return;
}
}
@@ -187,14 +216,25 @@ void MainWindow::doChecks()
{
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());
runConfigurator();
return;
}
}
}
void MainWindow::runConfigurator()
{
// cannot use QProcess::startDetached because of UAC
wstring file = (QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/Configurator.exe")).toStdWString();
int result = (int)ShellExecuteW(NULL, L"open", file.c_str(), NULL, NULL, SW_SHOWNORMAL);
if(result == SE_ERR_ACCESSDENIED)
ShellExecuteW(NULL, L"runas", file.c_str(), NULL, NULL, SW_SHOWNORMAL);
}
void MainWindow::load(QString path)
{
path = QDir::toNativeSeparators(path);
for(int i = 0; i < ui->tabWidget->count(); i++)
{
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->widget(i));
@@ -266,6 +306,12 @@ void MainWindow::load(QString path)
qDebug("Loading took %.1f ms", timer.nsecsElapsed() / 1e6);
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
recentFiles.removeAll(path);
recentFiles.prepend(path);
if(recentFiles.size() > 10)
recentFiles.removeLast();
updateRecentFiles();
}
void MainWindow::save(FilterTable* filterTable, QString path)
@@ -319,18 +365,39 @@ void MainWindow::save(FilterTable* filterTable, QString path)
startAnalysis();
}
bool MainWindow::isEmpty()
{
return ui->tabWidget->count() == 0;
}
bool MainWindow::shouldRestart()
{
return restart;
}
void MainWindow::closeEvent(QCloseEvent* event)
{
while(ui->tabWidget->count() > 0)
bool canceled = false;
for(int i = 0; i < ui->tabWidget->count(); i++)
{
ui->tabWidget->setCurrentIndex(0);
if(!on_tabWidget_tabCloseRequested(0))
if(!askForClose(i))
{
event->ignore();
canceled = true;
break;
}
}
if(canceled)
{
event->ignore();
restart = false;
noSavePreferences = false;
noSaveFilePreferences = false;
}
else
{
savePreferences();
}
}
void MainWindow::deviceSelected(int index)
@@ -438,37 +505,8 @@ void MainWindow::linesChanged()
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);
if(askForClose(index))
ui->tabWidget->removeTab(index);
return true;
}
@@ -552,7 +590,7 @@ void MainWindow::on_actionSaveAs_triggered()
{
QString savePath = dialog.selectedFiles().first();
save(filterTable, savePath);
filterTable->setConfigPath(savePath);
filterTable->setConfigPath(QDir::toNativeSeparators(savePath));
QFileInfo fileInfo(savePath);
ui->tabWidget->setTabText(ui->tabWidget->currentIndex(), fileInfo.fileName());
@@ -569,6 +607,12 @@ void MainWindow::on_actionNew_triggered()
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
}
void MainWindow::recentFileSelected()
{
QAction* action = qobject_cast<QAction*>(sender());
load(action->text());
}
void MainWindow::on_actionCut_triggered()
{
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->currentWidget());
@@ -661,7 +705,7 @@ void MainWindow::updateAnalysisPanel()
ui->peakGainValueLabel->setText(tr("%0 dB").arg(peakGain, 0, 'f', 1));
ui->peakGainValueLabel->setForegroundRole(peakGain > 0 ? QPalette::Dark : QPalette::WindowText);
ui->latencyValueLabel->setText(tr("%0 ms (%1 samples)").arg(latency * 1000.0 / sampleRate).arg(latency));
ui->latencyValueLabel->setText(tr("%0 ms (%1 s.)").arg(latency * 1000.0 / sampleRate, 0, 'f', 1).arg(latency));
ui->initTimeValueLabel->setText(tr("%0 ms").arg(analysisThread->getInitializationTime(), 0, 'f', 1));
@@ -692,6 +736,78 @@ void MainWindow::on_actionAnalysisPanel_triggered(bool checked)
ui->analysisDockWidget->setVisible(checked);
}
void MainWindow::languageSelected(bool selected)
{
QAction* action = qobject_cast<QAction*>(sender());
if(!selected)
{
action->setChecked(true);
return;
}
QLocale::Language language = (QLocale::Language)action->data().toInt();
if(QMessageBox::question(this, tr("Restart required"), tr("Configuration Editor will be restarted to apply the changed settings. Proceed?")) == QMessageBox::Yes)
{
QSettings settings(QString::fromWCharArray(EDITOR_REGPATH), QSettings::NativeFormat);
if(language == QLocale::AnyLanguage)
{
settings.remove("language");
}
else
{
QString name = QLocale(language).name();
int index = name.indexOf('_');
if(index != -1)
name = name.left(index);
settings.setValue("language", name);
}
restart = true;
close();
}
else
{
action->setChecked(false);
}
}
void MainWindow::on_actionResetAllGlobalPreferences_triggered()
{
if(QMessageBox::question(this, tr("Restart required"), tr("Configuration Editor will be restarted to apply the changed settings. Proceed?")) == QMessageBox::Yes)
{
QSettings settings(QString::fromWCharArray(EDITOR_REGPATH), QSettings::NativeFormat);
for(QString key : settings.childGroups())
{
if(key != "file-specific")
settings.remove(key);
}
for(QString key : settings.childKeys())
settings.remove(key);
restart = true;
noSavePreferences = true;
close();
}
}
void MainWindow::on_actionResetAllFileSpecificPreferences_triggered()
{
if(QMessageBox::question(this, tr("Restart required"), tr("Configuration Editor will be restarted to apply the changed settings. Proceed?")) == QMessageBox::Yes)
{
QSettings settings(QString::fromWCharArray(EDITOR_PER_FILE_REGPATH), QSettings::NativeFormat);
for(QString key : settings.childGroups())
settings.remove(key);
for(QString key : settings.childKeys())
settings.remove(key);
restart = true;
noSaveFilePreferences = true;
close();
}
}
FilterTable* MainWindow::addTab(QString title, QString tooltip)
{
QScrollArea* scrollArea = new QScrollArea(ui->tabWidget);
@@ -729,6 +845,53 @@ void MainWindow::getDeviceAndChannelMask(DeviceAPOInfo** selectedDevice, int* ch
}
}
bool MainWindow::askForClose(int tabIndex)
{
bool discarded = false;
if(ui->tabWidget->tabText(tabIndex).endsWith('*'))
{
ui->tabWidget->setCurrentIndex(tabIndex);
QString configPath = ui->tabWidget->tabToolTip(tabIndex);
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(tabIndex).endsWith('*'))
// saving was canceled
return false;
break;
case QMessageBox::Discard:
discarded = true;
break;
case QMessageBox::Cancel:
return false;
}
}
if(!discarded && !noSaveFilePreferences)
{
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->widget(tabIndex));
if(scrollArea != NULL)
{
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
filterTable->savePreferences();
}
}
return true;
}
void MainWindow::startAnalysis()
{
DeviceAPOInfo* selectedDevice;
@@ -759,3 +922,127 @@ void MainWindow::startAnalysis()
analysisThread->setParameters(selectedDevice, channelMask, ui->analysisChannelComboBox->currentIndex(), configPath, ui->resolutionSpinBox->value());
}
}
void MainWindow::loadPreferences()
{
QSettings settings(QString::fromWCharArray(EDITOR_REGPATH), QSettings::NativeFormat);
QVariant geometryValue = settings.value("geometry");
if(geometryValue.isValid())
restoreGeometry(geometryValue.toByteArray());
QVariant stateValue = settings.value("windowState");
if(stateValue.isValid())
restoreState(stateValue.toByteArray());
instantModeCheckBox->setChecked(settings.value("instantMode", true).toBool());
ui->startFromComboBox->setCurrentIndex(settings.value("analysis/startFrom").toInt());
ui->analysisChannelComboBox->setCurrentText(settings.value("analysis/channel").toString());
ui->resolutionSpinBox->setValue(settings.value("analysis/resolution", 65536).toInt());
double zoomX = settings.value("analysis/zoomX", 1.0).toDouble();
double zoomY = settings.value("analysis/zoomY", 1.0).toDouble();
if(zoomX != 1.0 || zoomY != 1.0)
analysisPlotScene->setZoom(zoomX, zoomY);
int scrollX = settings.value("analysis/scrollX", round(analysisPlotScene->hzToX(20))).toInt();
int scrollY = settings.value("analysis/scrollY", round(analysisPlotScene->dbToY(22))).toInt();
ui->graphicsView->setScrollOffsets(scrollX, scrollY);
QVariant openFilesValue = settings.value("openFiles");
int tabIndex = settings.value("tabIndex").toInt();
if(openFilesValue.isValid())
{
QStringList fileList = openFilesValue.toStringList();
for(int i = 0; i < fileList.size(); i++)
{
load(fileList[i]);
if(i == tabIndex)
tabIndex = ui->tabWidget->currentIndex();
}
}
ui->tabWidget->setCurrentIndex(tabIndex);
recentFiles = settings.value("recentFiles").toStringList();
updateRecentFiles();
QVariant languageValue = settings.value("language");
QLocale::Language language;
if(languageValue.isValid())
language = QLocale(languageValue.toString()).language();
else
language = QLocale::AnyLanguage;
for(QAction* action : ui->menuLanguage->actions())
action->setChecked(action->data().toInt() == language);
}
void MainWindow::savePreferences()
{
if(noSavePreferences)
return;
QSettings settings(QString::fromWCharArray(EDITOR_REGPATH), QSettings::NativeFormat);
settings.setValue("geometry", saveGeometry());
settings.setValue("windowState", saveState());
settings.setValue("instantMode", instantModeCheckBox->isChecked());
settings.setValue("analysis/startFrom", ui->startFromComboBox->currentIndex());
settings.setValue("analysis/channel", ui->analysisChannelComboBox->currentText());
settings.setValue("analysis/resolution", ui->resolutionSpinBox->value());
settings.setValue("analysis/zoomX", analysisPlotScene->getZoomX());
settings.setValue("analysis/zoomY", analysisPlotScene->getZoomY());
QScrollBar* hScrollBar = ui->graphicsView->horizontalScrollBar();
int value = hScrollBar->value();
settings.setValue("analysis/scrollX", value);
QScrollBar* vScrollBar = ui->graphicsView->verticalScrollBar();
value = vScrollBar->value();
settings.setValue("analysis/scrollY", value);
QStringList fileList;
for(int i = 0; i < ui->tabWidget->count(); i++)
{
QScrollArea* scrollArea = qobject_cast<QScrollArea*>(ui->tabWidget->widget(i));
if(scrollArea == NULL)
continue;
FilterTable* filterTable = qobject_cast<FilterTable*>(scrollArea->widget());
if(filterTable->getConfigPath().length() > 0)
{
fileList.append(filterTable->getConfigPath());
}
}
settings.setValue("openFiles", fileList);
settings.setValue("tabIndex", ui->tabWidget->currentIndex());
settings.setValue("recentFiles", recentFiles);
settings.sync();
}
void MainWindow::updateRecentFiles()
{
QList<QAction*> actions = ui->menuFile->actions();
int separatorsFound = 0;
for(int i = actions.size() - 1; i >= 0; i--)
{
QAction* action = actions[i];
if(action->isSeparator())
{
separatorsFound++;
if(separatorsFound == 1)
{
QList<QAction*> newActions;
for(QString recentFile : recentFiles)
{
QAction* newAction = new QAction(recentFile, ui->menuFile);
connect(newAction, SIGNAL(triggered(bool)), this, SLOT(recentFileSelected()));
newActions.append(newAction);
}
ui->menuFile->insertActions(action, newActions);
}
else
{
break;
}
}
else if(separatorsFound >= 1)
{
ui->menuFile->removeAction(action);
}
}
}
+20
View File
@@ -30,6 +30,10 @@
#include "DeviceAPOInfo.h"
#include "Editor/AnalysisPlotScene.h"
#include "Editor/AnalysisThread.h"
#include "helpers/RegistryHelper.h"
#define EDITOR_REGPATH USER_REGPATH L"\\Configuration Editor"
#define EDITOR_PER_FILE_REGPATH EDITOR_REGPATH L"\\file-specific"
namespace Ui {
class MainWindow;
@@ -43,8 +47,11 @@ public:
explicit MainWindow(QDir configDir, QWidget *parent = 0);
~MainWindow();
void doChecks();
void runConfigurator();
void load(QString path);
void save(FilterTable* filterTable, QString path);
bool isEmpty();
bool shouldRestart();
protected:
void closeEvent(QCloseEvent* event) override;
@@ -59,6 +66,7 @@ private slots:
void on_actionSave_triggered();
void on_actionSaveAs_triggered();
void on_actionNew_triggered();
void recentFileSelected();
void on_actionCut_triggered();
void on_actionDelete_triggered();
@@ -77,10 +85,18 @@ private slots:
void on_actionToolbar_triggered(bool checked);
void on_actionAnalysisPanel_triggered(bool checked);
void languageSelected(bool selected);
void on_actionResetAllGlobalPreferences_triggered();
void on_actionResetAllFileSpecificPreferences_triggered();
private:
FilterTable* addTab(QString title, QString tooltip);
void getDeviceAndChannelMask(DeviceAPOInfo** selectedDevice, int* channelMask);
bool askForClose(int tabIndex);
void startAnalysis();
void loadPreferences();
void savePreferences();
void updateRecentFiles();
Ui::MainWindow *ui;
@@ -93,6 +109,10 @@ private:
DeviceAPOInfo* defaultOutputDevice;
AnalysisPlotScene* analysisPlotScene;
AnalysisThread* analysisThread;
bool restart = false;
bool noSavePreferences = false;
bool noSaveFilePreferences = false;
QStringList recentFiles;
};
Q_DECLARE_METATYPE(DeviceAPOInfo*)
+29 -2
View File
@@ -60,6 +60,7 @@
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuEdit">
@@ -78,9 +79,25 @@
<addaction name="actionToolbar"/>
<addaction name="actionAnalysisPanel"/>
</widget>
<widget class="QMenu" name="menuSettings">
<property name="title">
<string>Settings</string>
</property>
<widget class="QMenu" name="menuLanguage">
<property name="title">
<string>Language</string>
</property>
<addaction name="separator"/>
</widget>
<addaction name="menuLanguage"/>
<addaction name="separator"/>
<addaction name="actionResetAllGlobalPreferences"/>
<addaction name="actionResetAllFileSpecificPreferences"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuView"/>
<addaction name="menuSettings"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<property name="windowTitle">
@@ -141,7 +158,7 @@
<item row="3" column="0">
<widget class="QLabel" name="resolutionLabel">
<property name="text">
<string>FFT resolution:</string>
<string>Resolution:</string>
</property>
</widget>
</item>
@@ -185,7 +202,7 @@
<widget class="QComboBox" name="startFromComboBox">
<item>
<property name="text">
<string>config.txt</string>
<string notr="true">config.txt</string>
</property>
</item>
<item>
@@ -665,6 +682,16 @@
<string>Analysis panel</string>
</property>
</action>
<action name="actionResetAllGlobalPreferences">
<property name="text">
<string>Reset all global preferences</string>
</property>
</action>
<action name="actionResetAllFileSpecificPreferences">
<property name="text">
<string>Reset all file-specific preferences</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
+10
View File
@@ -69,6 +69,16 @@ void CommentFilterGUI::store(QString& command, QString& parameters)
command = "# " + command;
}
void CommentFilterGUI::loadPreferences(const QVariantMap& prefs)
{
child->loadPreferences(prefs);
}
void CommentFilterGUI::storePreferences(QVariantMap& prefs)
{
child->storePreferences(prefs);
}
void CommentFilterGUI::on_actionPowerOn_toggled(bool checked)
{
child->setEnabled(checked);
+3
View File
@@ -36,6 +36,9 @@ public:
void configureChannels(std::vector<std::wstring>& channelNames) override;
void store(QString& command, QString& parameters) override;
void loadPreferences(const QVariantMap& prefs) override;
void storePreferences(QVariantMap& prefs) override;
private slots:
void on_actionPowerOn_toggled(bool checked);
+17 -1
View File
@@ -23,6 +23,8 @@
#include "CopyFilterGUI.h"
#include "ui_CopyFilterGUI.h"
static const int DEFAULT_HEIGHT = 88;
using namespace std;
CopyFilterGUI::CopyFilterGUI(CopyFilter* filter, FilterTable* filterTable) :
@@ -42,7 +44,7 @@ CopyFilterGUI::CopyFilterGUI(CopyFilter* filter, FilterTable* filterTable) :
return QSize(0, ui->scrollArea->height());
},
[this](QSize size) {
ui->scrollArea->setMinimumHeight(size.height());
ui->scrollArea->setFixedHeight(size.height());
}, ui->scrollArea);
cornerWidget->setCursor(Qt::SizeVerCursor);
cornerWidget->setAutoFillBackground(true);
@@ -162,3 +164,17 @@ void CopyFilterGUI::store(QString& command, QString& parameters)
scene->load(inputChannelNames, assignments);
}
}
void CopyFilterGUI::loadPreferences(const QVariantMap& prefs)
{
ui->scrollArea->setFixedHeight(prefs.value("height", DEFAULT_HEIGHT).toInt());
ui->tabWidget->setCurrentIndex(prefs.value("tabIndex", 0).toInt());
}
void CopyFilterGUI::storePreferences(QVariantMap& prefs)
{
if(ui->scrollArea->height() != DEFAULT_HEIGHT)
prefs.insert("height", ui->scrollArea->height());
if(ui->tabWidget->currentIndex() != 0)
prefs.insert("tabIndex", ui->tabWidget->currentIndex());
}
+3
View File
@@ -40,6 +40,9 @@ public:
void store(QString& command, QString& parameters) override;
void loadPreferences(const QVariantMap& prefs) override;
void storePreferences(QVariantMap& prefs) override;
private:
Ui::CopyFilterGUI *ui;
CopyFilterGUIScene* scene;
+6 -4
View File
@@ -48,7 +48,7 @@ void CopyFilterGUIScene::load(const vector<wstring>& channelNames, vector<Assign
addItem(inputItem);
inputChannelMap.insert(c, inputItem);
inputChannelMap.insert(QString().setNum(i), inputItem);
inputChannelMap.insert(QString().setNum(i + 1), inputItem);
lastInputItem = inputItem;
CopyFilterGUIChannelItem* outputItem = new CopyFilterGUIChannelItem(c, true);
@@ -56,7 +56,7 @@ void CopyFilterGUIScene::load(const vector<wstring>& channelNames, vector<Assign
addItem(outputItem);
outputChannelMap.insert(c, outputItem);
outputChannelMap.insert(QString().setNum(i), outputItem);
outputChannelMap.insert(QString().setNum(i + 1), outputItem);
lastOutputItem = outputItem;
}
@@ -212,6 +212,8 @@ void CopyFilterGUIScene::keyPressEvent(QKeyEvent* event)
emit updateModel();
emit updateChannels();
}
QGraphicsScene::keyPressEvent(event);
else
{
QGraphicsScene::keyPressEvent(event);
}
}
+36 -1
View File
@@ -29,6 +29,9 @@
#include "GraphicEQFilterGUI.h"
#include "ui_GraphicEQFilterGUI.h"
static const int DEFAULT_TABLE_WIDTH = 119;
static const int DEFAULT_VIEW_HEIGHT = 150;
using namespace std;
QRegularExpression GraphicEQFilterGUI::numberRegEx("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
@@ -51,7 +54,6 @@ GraphicEQFilterGUI::GraphicEQFilterGUI(GraphicEQFilter* filter, QString configPa
ui->graphicsView->setFixedHeight(size.height());
}, ui->graphicsView);
ui->graphicsView->setCornerWidget(cornerWidget);
ui->graphicsView->setFixedHeight(150);
ui->toolBar->addAction(ui->actionImport);
ui->toolBar->addAction(ui->actionExport);
@@ -105,6 +107,39 @@ void GraphicEQFilterGUI::store(QString & command, QString & parameters)
}
}
void GraphicEQFilterGUI::loadPreferences(const QVariantMap& prefs)
{
ui->tableWidget->setFixedWidth(prefs.value("tableWidth", DEFAULT_TABLE_WIDTH).toInt());
ui->graphicsView->setFixedHeight(prefs.value("viewHeight", DEFAULT_VIEW_HEIGHT).toInt());
double zoomX = prefs.value("zoomX", 1.0).toDouble();
double zoomY = prefs.value("zoomY", 1.0).toDouble();
if(zoomX != 1.0 || zoomY != 1.0)
scene->setZoom(zoomX, zoomY);
int scrollX = prefs.value("scrollX", round(scene->hzToX(20))).toInt();
int scrollY = prefs.value("scrollY", round(scene->dbToY(22))).toInt();
ui->graphicsView->setScrollOffsets(scrollX, scrollY);
}
void GraphicEQFilterGUI::storePreferences(QVariantMap& prefs)
{
if(ui->tableWidget->width() != DEFAULT_TABLE_WIDTH)
prefs.insert("tableWidth", ui->tableWidget->width());
if(ui->graphicsView->height() != DEFAULT_VIEW_HEIGHT)
prefs.insert("viewHeight", ui->graphicsView->height());
if(scene->getZoomX() != 1.0)
prefs.insert("zoomX", scene->getZoomX());
if(scene->getZoomY() != 1.0)
prefs.insert("zoomY", scene->getZoomY());
QScrollBar* hScrollBar = ui->graphicsView->horizontalScrollBar();
int value = hScrollBar->value();
if(value != round(scene->hzToX(20)))
prefs.insert("scrollX", value);
QScrollBar* vScrollBar = ui->graphicsView->verticalScrollBar();
value = vScrollBar->value();
if(value != round(scene->dbToY(22)))
prefs.insert("scrollY", value);
}
void GraphicEQFilterGUI::insertRow(int index, double hz, double db)
{
ui->tableWidget->blockSignals(true);
+3
View File
@@ -41,6 +41,9 @@ public:
void store(QString& command, QString& parameters) override;
void loadPreferences(const QVariantMap& prefs) override;
void storePreferences(QVariantMap& prefs) override;
private slots:
void insertRow(int index, double hz, double db);
void removeRow(int index);
+27 -5
View File
@@ -21,6 +21,7 @@
#include <QApplication>
#include <QDir>
#include <QCommandLineParser>
#include <QSettings>
#include "MainWindow.h"
#include "helpers/RegistryHelper.h"
@@ -34,17 +35,26 @@ int main(int argc, char *argv[])
//_CrtSetBreakAlloc(3318);
#endif
{
QCoreApplication::addLibraryPath("qt");
QCoreApplication::addLibraryPath("qt");
bool restart;
do
{
QApplication application(argc, argv);
QSettings settings(QString::fromWCharArray(EDITOR_REGPATH), QSettings::NativeFormat);
QVariant languageValue = settings.value("language");
if(languageValue.isValid())
QLocale::setDefault(languageValue.toString());
else
QLocale::setDefault(QLocale::system());
QTranslator qtTranslator;
qtTranslator.load(QLocale::system(), ":/translations/qtbase", "_");
qtTranslator.load(QLocale(), ":/translations/qtbase", "_");
application.installTranslator(&qtTranslator);
QTranslator editorTranslator;
editorTranslator.load(QLocale::system(), ":/translations/Editor", "_");
editorTranslator.load(QLocale(), ":/translations/Editor", "_");
application.installTranslator(&editorTranslator);
QString configPath = QDir::currentPath();
@@ -52,13 +62,22 @@ int main(int argc, char *argv[])
configPath = QString::fromStdWString(RegistryHelper::readValue(APP_REGPATH, L"ConfigPath"));
QDir configDir(configPath);
if(!RegistryHelper::keyExists(USER_REGPATH))
RegistryHelper::createKey(USER_REGPATH);
if(!RegistryHelper::keyExists(EDITOR_REGPATH))
RegistryHelper::createKey(EDITOR_REGPATH);
if(!RegistryHelper::keyExists(EDITOR_PER_FILE_REGPATH))
RegistryHelper::createKey(EDITOR_PER_FILE_REGPATH);
MainWindow w(configDir);
w.show();
QCommandLineParser parser;
parser.process(application);
QStringList args = parser.positionalArguments();
if(args.isEmpty())
if(args.isEmpty() && w.isEmpty())
args = QStringList("config.txt");
for(QString arg : args)
@@ -67,7 +86,10 @@ int main(int argc, char *argv[])
w.doChecks();
result = application.exec();
restart = w.shouldRestart();
}
while(restart);
return result;
}
Binary file not shown.
+221 -83
View File
@@ -381,12 +381,12 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<translation>Graph</translation>
</message>
<message>
<location filename="../guis/CopyFilterGUI.ui" line="107"/>
<location filename="../guis/CopyFilterGUI.ui" line="110"/>
<source>Assignments</source>
<translation>Zuweisungen</translation>
</message>
<message>
<location filename="../guis/CopyFilterGUI.ui" line="152"/>
<location filename="../guis/CopyFilterGUI.ui" line="161"/>
<source>Selected channels:</source>
<translation>Gewählte Kanäle:</translation>
</message>
@@ -402,12 +402,12 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<translation type="vanished">Steuerung</translation>
</message>
<message>
<location filename="../guis/CopyFilterGUIFactory.cpp" line="32"/>
<location filename="../guis/CopyFilterGUIFactory.cpp" line="37"/>
<source>Copy (Copy between channels)</source>
<translation>Copy (Kopieren zwischen Kanälen)</translation>
</message>
<message>
<location filename="../guis/CopyFilterGUIFactory.cpp" line="32"/>
<location filename="../guis/CopyFilterGUIFactory.cpp" line="37"/>
<source>Basic filters</source>
<translation>Einfache Filter</translation>
</message>
@@ -647,7 +647,7 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<context>
<name>FilterTable</name>
<message>
<location filename="../FilterTable.cpp" line="189"/>
<location filename="../FilterTable.cpp" line="203"/>
<source>Add filter</source>
<translation>Filter hinzufügen</translation>
</message>
@@ -659,17 +659,17 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<translation type="obsolete">99</translation>
</message>
<message>
<location filename="../FilterTableRow.ui" line="147"/>
<location filename="../FilterTableRow.ui" line="153"/>
<source>Add</source>
<translation>Hinzufügen</translation>
</message>
<message>
<location filename="../FilterTableRow.ui" line="156"/>
<location filename="../FilterTableRow.ui" line="162"/>
<source>Remove</source>
<translation>Entfernen</translation>
</message>
<message>
<location filename="../FilterTableRow.ui" line="168"/>
<location filename="../FilterTableRow.ui" line="174"/>
<source>Edit text</source>
<translation>Text bearbeiten</translation>
</message>
@@ -715,79 +715,83 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<context>
<name>GraphicEQFilterGUI</name>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="44"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="46"/>
<source>Graphic EQ:</source>
<translation>Grafischer EQ:</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="122"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="189"/>
<source>Freq.</source>
<translation>Freq.</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="127"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="194"/>
<source>Gain</source>
<translation>Verst.</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="160"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="53"/>
<source>15-band</source>
<translation>15-Band</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="167"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="60"/>
<source>31-band</source>
<translation>31-Band</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="174"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="67"/>
<source>variable</source>
<translation>variabel</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="190"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="218"/>
<source>Import</source>
<translation>Importieren</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="199"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="227"/>
<source>Export</source>
<translation>Exportieren</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="208"/>
<source>Mirror response</source>
<translation>Frequenzgang spiegeln</translation>
<location filename="../guis/GraphicEQFilterGUI.ui" line="236"/>
<source>Invert response</source>
<translation>Frequenzgang invertieren</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="217"/>
<source>Mirror response</source>
<translation type="vanished">Frequenzgang spiegeln</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="245"/>
<source>Normalize response</source>
<translation>Frequenzgang normalisieren</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.ui" line="226"/>
<location filename="../guis/GraphicEQFilterGUI.ui" line="254"/>
<source>Reset response</source>
<translation>Frequenzgang zurücksetzen</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="248"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="295"/>
<source>Import frequency response</source>
<translation>Frequenzgang importieren</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="251"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="320"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="298"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="365"/>
<source>Frequency response (*.csv)</source>
<translation>Frequenzgang (*.csv)</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="252"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="321"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="299"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="366"/>
<source>All files (*.*)</source>
<translation>Alle Dateien (*.*)</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="316"/>
<location filename="../guis/GraphicEQFilterGUI.cpp" line="361"/>
<source>Export frequency response</source>
<translation>Frequenzgang exportieren</translation>
</message>
@@ -795,24 +799,24 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<context>
<name>GraphicEQFilterGUIFactory</name>
<message>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="32"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="37"/>
<source>15-band graphic equalizer</source>
<translation>Grafischer Equalizer mit 15 Bändern</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="32"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="33"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="34"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="37"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="38"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="39"/>
<source>Graphic equalizers</source>
<translation>Grafische Equalizer</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="33"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="38"/>
<source>31-band graphic equalizer</source>
<translation>Grafischer Equalizer mit 31 Bändern</translation>
</message>
<message>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="34"/>
<location filename="../guis/GraphicEQFilterGUIFactory.cpp" line="39"/>
<source>Graphic equalizer with variable bands</source>
<translation>Grafischer Equalizer mit variablen Bändern</translation>
</message>
@@ -874,120 +878,207 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<translation>Datei</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="67"/>
<location filename="../MainWindow.ui" line="68"/>
<source>Edit</source>
<translation>Bearbeiten</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="95"/>
<location filename="../MainWindow.ui" line="77"/>
<source>View</source>
<translation>Ansicht</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="84"/>
<location filename="../MainWindow.ui" line="146"/>
<source>Settings</source>
<translation>Einstellungen</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="88"/>
<source>Language</source>
<translation>Sprache</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="104"/>
<location filename="../MainWindow.ui" line="674"/>
<source>Toolbar</source>
<translation>Werkzeugleiste</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="118"/>
<location filename="../MainWindow.ui" line="682"/>
<source>Analysis panel</source>
<translation>Analysepanel</translation>
</message>
<message>
<source>FFT resolution:</source>
<translation type="vanished">FFT-Auflösung:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="161"/>
<source>Resolution:</source>
<translation>Auflösung:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="168"/>
<source>Channel:</source>
<translation>Kanal:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="197"/>
<source>Start from:</source>
<translation>Beginne bei:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="210"/>
<source>Current file</source>
<translation>Aktuelle Datei</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="221"/>
<source>Estimated properties</source>
<translation>Geschätzte Eigenschaften</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="237"/>
<source>CPU usage:</source>
<translation>CPU-Last:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="244"/>
<source>Init. time:</source>
<translation>Init.-Zeit:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="410"/>
<source>Latency: </source>
<translation>Latenz:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="417"/>
<source>Peak gain:</source>
<translation>Maximum:</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="568"/>
<source>New</source>
<translation>Neu</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="98"/>
<location filename="../MainWindow.ui" line="571"/>
<source>Ctrl+N</source>
<translation>Ctrl+N</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="107"/>
<location filename="../MainWindow.ui" line="110"/>
<location filename="../MainWindow.ui" line="580"/>
<location filename="../MainWindow.ui" line="583"/>
<source>Open</source>
<translation>Öffnen</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="113"/>
<location filename="../MainWindow.ui" line="586"/>
<source>Ctrl+O</source>
<translation>Ctrl+O</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="122"/>
<location filename="../MainWindow.ui" line="125"/>
<location filename="../MainWindow.ui" line="595"/>
<location filename="../MainWindow.ui" line="598"/>
<source>Save</source>
<translation>Speichern</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="128"/>
<location filename="../MainWindow.ui" line="601"/>
<source>Ctrl+S</source>
<translation>Ctrl+S</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="137"/>
<location filename="../MainWindow.ui" line="140"/>
<location filename="../MainWindow.ui" line="610"/>
<location filename="../MainWindow.ui" line="613"/>
<source>Save as...</source>
<translation>Speichern unter...</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="145"/>
<location filename="../MainWindow.ui" line="618"/>
<source>Exit</source>
<translation>Beenden</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="148"/>
<location filename="../MainWindow.ui" line="621"/>
<source>Alt+F4</source>
<translation>Alt+F4</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="157"/>
<location filename="../MainWindow.ui" line="630"/>
<source>Cut</source>
<translation>Ausschneiden</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="160"/>
<location filename="../MainWindow.ui" line="633"/>
<source>Ctrl+X</source>
<translation>Ctrl+X</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="169"/>
<location filename="../MainWindow.ui" line="642"/>
<source>Copy</source>
<translation>Kopieren</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="172"/>
<location filename="../MainWindow.ui" line="645"/>
<source>Ctrl+C</source>
<translation>Ctrl+C</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="181"/>
<location filename="../MainWindow.ui" line="654"/>
<source>Paste</source>
<translation>Einfügen</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="184"/>
<location filename="../MainWindow.ui" line="657"/>
<source>Ctrl+V</source>
<translation>Ctrl+V</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="193"/>
<location filename="../MainWindow.ui" line="666"/>
<source>Delete</source>
<translation>Löschen</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="69"/>
<location filename="../MainWindow.ui" line="687"/>
<source>Reset all global preferences</source>
<translation>Alle globalen Einstellungen zurücksetzen</translation>
</message>
<message>
<location filename="../MainWindow.ui" line="692"/>
<source>Reset all file-specific preferences</source>
<translation>Alle dateispezifischen Einstellungen zurücksetzen</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="73"/>
<source>Equalizer APO %0 Configuration Editor</source>
<translation>Equalizer APO %0 Konfigurationseditor</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="75"/>
<location filename="../MainWindow.cpp" line="79"/>
<source>Instant mode</source>
<translation>Sofort-Modus</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="77"/>
<location filename="../MainWindow.cpp" line="81"/>
<source>Changes are saved immediately</source>
<translation>Änderungen werden sofort gespeichert</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="85"/>
<location filename="../MainWindow.cpp" line="89"/>
<source>Device: </source>
<translation>Gerät: </translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="95"/>
<location filename="../MainWindow.cpp" line="99"/>
<source>Channel configuration: </source>
<translation>Kanalkonfiguration: </translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="103"/>
<location filename="../MainWindow.cpp" line="107"/>
<source>Default</source>
<translation>Standard</translation>
</message>
@@ -1000,17 +1091,17 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<translation type="vanished">Eingabegeräte:</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="105"/>
<location filename="../MainWindow.cpp" line="109"/>
<source>Playback devices:</source>
<translation>Wiedergabegeräte:</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="116"/>
<location filename="../MainWindow.cpp" line="120"/>
<source>Capture devices:</source>
<translation>Aufnahmegeräte:</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="137"/>
<location filename="../MainWindow.cpp" line="177"/>
<source>Registry problem</source>
<translation>Registry-Problem</translation>
</message>
@@ -1019,31 +1110,31 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.</tra
<translation type="vanished">Ein Registrywert, der für den Betrieb von Equalizer APO erforderlich ist, ist nicht korrekt gesetzt. Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="137"/>
<location filename="../MainWindow.cpp" line="177"/>
<source>A registry value that is required for the operation of Equalizer APO is not set correctly.
Do you want to run the Configurator application to fix the problem?</source>
<translation>Ein Registrywert, der für den Betrieb von Equalizer APO erforderlich ist, ist nicht korrekt gesetzt.
Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="146"/>
<location filename="../MainWindow.cpp" line="186"/>
<source>APO not installed to device</source>
<translation>APO nicht für das Gerät installiert</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="146"/>
<location filename="../MainWindow.cpp" line="186"/>
<source>Equalizer APO has not been installed to the selected device.
Do you want to run the Configurator application to fix the problem?</source>
<translation>Equalizer APO wurde nicht für das gewählte Gerät installiert.
Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="177"/>
<location filename="../MainWindow.cpp" line="217"/>
<source>Audio enhancements disabled</source>
<translation>Signalverbesserungen deaktiviert</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="177"/>
<location filename="../MainWindow.cpp" line="217"/>
<source>Audio enhancements are not enabled for the device
%0 %1.
Do you want to run the Configurator application to fix the problem?</source>
@@ -1052,66 +1143,113 @@ Do you want to run the Configurator application to fix the problem?</source>
Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="211"/>
<location filename="../MainWindow.cpp" line="287"/>
<location filename="../MainWindow.cpp" line="301"/>
<location filename="../MainWindow.cpp" line="262"/>
<location filename="../MainWindow.cpp" line="344"/>
<location filename="../MainWindow.cpp" line="358"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="211"/>
<location filename="../MainWindow.cpp" line="262"/>
<source>Error while reading configuration file: %0</source>
<translation>Fehler beim Lesen der Konfigurationsdatei: %0</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="287"/>
<location filename="../MainWindow.cpp" line="344"/>
<source>Error while writing configuration file: %0</source>
<translation>Fehler beim Schreiben der Konfigurationsdatei: %0</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="301"/>
<location filename="../MainWindow.cpp" line="358"/>
<source>Only %0/%1 bytes have been written!</source>
<translation>Nur %0/%1 Bytes wurden geschrieben!</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="346"/>
<location filename="../MainWindow.cpp" line="348"/>
<location filename="../MainWindow.cpp" line="426"/>
<location filename="../MainWindow.cpp" line="428"/>
<source>From device</source>
<translation>Von Gerät</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="426"/>
<location filename="../MainWindow.cpp" line="705"/>
<source>%0 dB</source>
<translation>%0 dB</translation>
</message>
<message>
<source>%0 ms (%1 samp.)</source>
<translation type="vanished">%0 ms (%1 Samp.)</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="708"/>
<source>%0 ms (%1 s.)</source>
<translation>%0 ms (%1 S.)</translation>
</message>
<message>
<source>%0 ms (%1 samples)</source>
<translation type="vanished">%0 ms (%1 Samples)</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="710"/>
<source>%0 ms</source>
<translation>%0 ms</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="713"/>
<source>%0 % (one core)</source>
<translation>%0 % (ein Kern)</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="751"/>
<location filename="../MainWindow.cpp" line="778"/>
<location filename="../MainWindow.cpp" line="797"/>
<source>Restart required</source>
<translation>Neustart erforderlich</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="751"/>
<location filename="../MainWindow.cpp" line="778"/>
<location filename="../MainWindow.cpp" line="797"/>
<source>Configuration Editor will be restarted to apply the changed settings. Proceed?</source>
<translation>Konfigurationseditor wird neugestartet, um die geänderten Einstellungen zu übernehmen. Fortsetzen?</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="856"/>
<source>Unsaved changes</source>
<translation>Ungespeicherte Änderungen</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="427"/>
<location filename="../MainWindow.cpp" line="857"/>
<source>The configuration file %0 has unsaved changes.</source>
<translation>Die Konfigurationsdatei %0 hat ungespeicherte Änderungen.</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="428"/>
<location filename="../MainWindow.cpp" line="858"/>
<source>Do you want to save the changes before closing the file?</source>
<translation>Möchten Sie die Änderungen speichern, bevor die Datei geschlossen wird?</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="471"/>
<location filename="../MainWindow.cpp" line="529"/>
<source>Open file</source>
<translation>Datei öffnen</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="473"/>
<location filename="../MainWindow.cpp" line="526"/>
<location filename="../MainWindow.cpp" line="154"/>
<source>Automatic (%0)</source>
<translation>Automatisch (%0)</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="531"/>
<location filename="../MainWindow.cpp" line="584"/>
<source>E-APO configurations (*.txt)</source>
<translation>E-APO-Konfigurationen (*.txt)</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="523"/>
<location filename="../MainWindow.cpp" line="581"/>
<source>Save file as</source>
<translation>Datei speichern unter</translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="545"/>
<location filename="../MainWindow.cpp" line="603"/>
<source>Unsaved</source>
<translation>Ungespeichert</translation>
</message>
+17 -1
View File
@@ -168,6 +168,12 @@ void FrequencyPlotView::zoom(int deltaX, int deltaY, int mouseX, int mouseY)
vRuler->update();
}
void FrequencyPlotView::setScrollOffsets(int x, int y)
{
presetScrollX = x;
presetScrollY = y;
}
void FrequencyPlotView::wheelEvent(QWheelEvent* event)
{
int delta = event->angleDelta().y();
@@ -224,5 +230,15 @@ void FrequencyPlotView::showEvent(QShowEvent* event)
{
QGraphicsView::showEvent(event);
horizontalScrollBar()->setValue(scene()->hzToX(20));
if(presetScrollX != -1)
{
horizontalScrollBar()->setValue(presetScrollX);
presetScrollX = -1;
}
if(presetScrollY != -1)
{
verticalScrollBar()->setValue(presetScrollY);
presetScrollY = -1;
}
}
+3
View File
@@ -43,6 +43,7 @@ public:
using QGraphicsView::viewportMargins;
void zoom(int deltaX, int deltaY, int mouseX, int mouseY);
void setScrollOffsets(int x, int y);
protected:
void wheelEvent(QWheelEvent* event) override;
@@ -57,4 +58,6 @@ private:
FrequencyPlotHRuler* hRuler;
FrequencyPlotVRuler* vRuler;
QPoint lastMousePos;
int presetScrollX = -1;
int presetScrollY = -1;
};
+5 -8
View File
@@ -404,10 +404,14 @@ void EqualizerAPO::APOProcess(UINT32 u32NumInputConnections,
switch( ppInputConnections[0]->u32BufferFlags )
{
case BUFFER_VALID:
case BUFFER_SILENT:
{
float* inputFrames = reinterpret_cast<float*>(ppInputConnections[0]->pBuffer);
float* outputFrames = reinterpret_cast<float*>(ppOutputConnections[0]->pBuffer);
if(ppInputConnections[0]->u32BufferFlags == BUFFER_SILENT)
memset(inputFrames, 0, ppInputConnections[0]->u32ValidFrameCount * engine.getInputChannelCount() * sizeof(float));
if(childRT)
{
childRT->APOProcess(u32NumInputConnections, ppInputConnections, u32NumOutputConnections, ppOutputConnections);
@@ -418,14 +422,7 @@ void EqualizerAPO::APOProcess(UINT32 u32NumInputConnections,
engine.process(outputFrames, inputFrames, ppInputConnections[0]->u32ValidFrameCount);
ppOutputConnections[0]->u32ValidFrameCount = ppInputConnections[0]->u32ValidFrameCount;
ppOutputConnections[0]->u32BufferFlags = ppInputConnections[0]->u32BufferFlags;
break;
}
case BUFFER_SILENT:
{
ppOutputConnections[0]->u32ValidFrameCount = ppInputConnections[0]->u32ValidFrameCount;
ppOutputConnections[0]->u32BufferFlags = ppInputConnections[0]->u32BufferFlags;
ppOutputConnections[0]->u32BufferFlags = BUFFER_VALID;
break;
}
-27
View File
@@ -365,33 +365,6 @@ void FilterEngine::watchRegistryKey(const std::wstring& key)
#pragma AVRT_CODE_BEGIN
void FilterEngine::process(float *output, float *input, unsigned frameCount)
{
bool inputSilent = true;
for (unsigned i = 0; i < frameCount * realChannelCount; i++)
{
if(input[i] != 0)
{
inputSilent = false;
break;
}
}
if(inputSilent)
{
if(lastInputWasSilent)
{
//Avoid processing cost if silence would be output anyway
if(input != output)
memset(output, 0, frameCount * outputChannelCount * sizeof(float));
return;
}
else
lastInputWasSilent = true;
}
else
lastInputWasSilent = false;
if(currentConfig->isEmpty() && nextConfig == NULL)
{
// avoid (de-)interleaving cost if no processing will happen anyway
+1
View File
@@ -197,6 +197,7 @@ Section /o un.$(SecRemoveName)
Delete "$INSTDIR\*.reg"
RMDir /REBOOTOK /r "$INSTDIR\config"
DeleteRegKey HKCU ${REGPATH}
SectionEnd
+94 -10
View File
@@ -66,7 +66,7 @@ wstring RegistryHelper::readValue(wstring key, wstring valuename)
//Remove zero-termination
if(buf[bufSize / sizeof(wchar_t) - 1] == L'\0')
bufSize -= sizeof(wchar_t);
result = wstring((wchar_t*)buf, (wstring::size_type)bufSize/sizeof(wchar_t));
result = wstring((wchar_t*)buf, (wstring::size_type)bufSize / sizeof(wchar_t));
delete buf;
return result;
@@ -111,6 +111,62 @@ unsigned long RegistryHelper::readDWORDValue(wstring key, wstring valuename)
return result;
}
vector<wstring> RegistryHelper::readMultiValue(wstring key, wstring valuename)
{
vector<wstring> result;
HKEY keyHandle = openKey(key, KEY_QUERY_VALUE | KEY_WOW64_64KEY);
LSTATUS status;
DWORD type;
DWORD bufSize;
status = RegQueryValueExW(keyHandle, valuename.c_str(), NULL, &type, NULL, &bufSize);
if(status != ERROR_SUCCESS)
{
RegCloseKey(keyHandle);
throw RegistryException(L"Error while reading registry value " + key + L"\\" + valuename + L": " + StringHelper::getSystemErrorString(status));
}
if(type != REG_MULTI_SZ)
{
RegCloseKey(keyHandle);
throw RegistryException(L"Registry value " + key + L"\\" + valuename + L" has wrong type");
}
wchar_t* buf = new wchar_t[bufSize / sizeof(wchar_t) + 1];
status = RegQueryValueExW(keyHandle, valuename.c_str(), NULL, NULL, (LPBYTE)buf, &bufSize);
RegCloseKey(keyHandle);
if(status != ERROR_SUCCESS)
{
delete buf;
throw RegistryException(L"Error while reading registry value " + key + L"\\" + valuename + L": " + StringHelper::getSystemErrorString(status));
}
size_t length = bufSize / sizeof(wchar_t);
//Remove zero-termination
while(length > 0 && buf[length - 1] == L'\0')
length--;
size_t start = 0;
for(size_t i = 0; i < length; i++)
{
if(buf[i] == L'\0')
{
result.push_back(wstring(buf + start, i - start));
start = i + 1;
}
}
if(length > start)
result.push_back(wstring(buf + start, length - start));
delete buf;
return result;
}
vector<unsigned char> RegistryHelper::readBinaryValue(wstring key, wstring valuename)
{
HKEY keyHandle = openKey(key, KEY_QUERY_VALUE | KEY_WOW64_64KEY);
@@ -148,7 +204,7 @@ void RegistryHelper::writeValue(wstring key, wstring valuename, wstring value)
{
HKEY keyHandle = openKey(key, KEY_SET_VALUE | KEY_WOW64_64KEY);
LSTATUS status = RegSetValueExW(keyHandle, valuename.c_str(), 0, REG_SZ, (const BYTE*)value.c_str(), (DWORD)((value.size()+1)*sizeof(wchar_t)));
LSTATUS status = RegSetValueExW(keyHandle, valuename.c_str(), 0, REG_SZ, (const BYTE*)value.c_str(), (DWORD)((value.size() + 1) * sizeof(wchar_t)));
RegCloseKey(keyHandle);
@@ -173,11 +229,39 @@ void RegistryHelper::writeMultiValue(wstring key, wstring valuename, wstring val
HKEY keyHandle = openKey(key, KEY_SET_VALUE | KEY_WOW64_64KEY);
wchar_t* data = new wchar_t[value.size() + 2];
value._Copy_s(data, (value.size()+2)*sizeof(wchar_t), value.size());
value._Copy_s(data, (value.size() + 2)*sizeof(wchar_t), value.size());
data[value.size()] = L'\0';
data[value.size()+1] = L'\0';
data[value.size() + 1] = L'\0';
LSTATUS status = RegSetValueExW(keyHandle, valuename.c_str(), 0, REG_MULTI_SZ, (const BYTE*)data, (DWORD)((value.size()+2)*sizeof(wchar_t)));
LSTATUS status = RegSetValueExW(keyHandle, valuename.c_str(), 0, REG_MULTI_SZ, (const BYTE*)data, (DWORD)((value.size() + 2) * sizeof(wchar_t)));
delete data;
RegCloseKey(keyHandle);
if(status != ERROR_SUCCESS)
throw RegistryException(L"Error while writing to registry value " + key + L"\\" + valuename + L": " + StringHelper::getSystemErrorString(status));
}
void RegistryHelper::writeMultiValue(wstring key, wstring valuename, vector<wstring> values)
{
HKEY keyHandle = openKey(key, KEY_SET_VALUE | KEY_WOW64_64KEY);
size_t size = 1;
for(wstring value : values)
size += value.size() + 1;
wchar_t* data = new wchar_t[size];
size_t offset = 0;
for(wstring value : values)
{
value._Copy_s(data + offset, size * sizeof(wchar_t), value.size());
offset += value.size();
data[offset++] = L'\0';
}
data[offset] = L'\0';
LSTATUS status = RegSetValueExW(keyHandle, valuename.c_str(), 0, REG_MULTI_SZ, (const BYTE*)data, (DWORD)(size * sizeof(wchar_t)));
delete data;
@@ -242,13 +326,13 @@ void RegistryHelper::makeWritable(wstring key)
PSID sid = NULL;
SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
if(!AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &sid))
0, 0, 0, 0, 0, 0, &sid))
throw RegistryException(L"Error in AllocateAndInitializeSid while ensuring writability");
EXPLICIT_ACCESS ea;
ea.grfAccessPermissions = KEY_ALL_ACCESS;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea.Trustee.ptstrName = (LPWSTR)sid;
@@ -307,7 +391,7 @@ void RegistryHelper::takeOwnership(wstring key)
PSID sid = NULL;
SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
if(!AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &sid))
0, 0, 0, 0, 0, 0, &sid))
throw RegistryException(L"Error in AllocateAndInitializeSid while taking ownership");
if(!SetSecurityDescriptorOwner(sd, sid, FALSE))
@@ -361,7 +445,7 @@ vector<wstring> RegistryHelper::enumSubKeys(wstring key)
wchar_t keyName[256];
DWORD keyLength = sizeof(keyName) / sizeof(wchar_t);
int i=0;
int i = 0;
LSTATUS status;
while((status = RegEnumKeyExW(keyHandle, i++, keyName, &keyLength, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
@@ -472,7 +556,7 @@ wstring RegistryHelper::splitKey(const wstring& key, HKEY* rootKey)
throw RegistryException(L"Key " + key + L" has invalid format");
wstring rootPart = key.substr(0, pos);
wstring pathPart = key.substr(pos+1);
wstring pathPart = key.substr(pos + 1);
wstring p = StringHelper::toUpperCase(rootPart);
if(p == L"HKEY_CLASSES_ROOT")
+3
View File
@@ -31,16 +31,19 @@ const GUID EQUALIZERAPO_PRE_MIX_GUID = { 0xeacd2258, 0xfcac, 0x4ff4, { 0xb3, 0x6
const GUID EQUALIZERAPO_POST_MIX_GUID = { 0xec1cc9ce, 0xfaed, 0x4822, { 0x82, 0x8a, 0x82, 0xa8, 0x1a, 0x6f, 0x01, 0x8f } };
#define APP_REGPATH L"HKEY_LOCAL_MACHINE\\SOFTWARE\\EqualizerAPO"
#define USER_REGPATH L"HKEY_CURRENT_USER\\SOFTWARE\\EqualizerAPO"
class RegistryHelper
{
public:
static std::wstring readValue(std::wstring key, std::wstring valuename);
static unsigned long readDWORDValue(std::wstring key, std::wstring valuename);
static std::vector<std::wstring> readMultiValue(std::wstring key, std::wstring valuename);
static std::vector<unsigned char> readBinaryValue(std::wstring key, std::wstring valuename);
static void writeValue(std::wstring key, std::wstring valuename, std::wstring value);
static void writeDWORDValue(std::wstring key, std::wstring valuename, unsigned long value);
static void writeMultiValue(std::wstring key, std::wstring valuename, std::wstring value);
static void writeMultiValue(std::wstring key, std::wstring valuename, std::vector<std::wstring> values);
static void deleteValue(std::wstring key, std::wstring valuename);
static void createKey(std::wstring key);
static void deleteKey(std::wstring key);