Added: VST Plugin support. Add and configure plugins via Configuration Editor. The plugin's architecture has to match the OS architecture, so most people will need 64-bit plugins. The subdirectory plugins is offered to put plugins into, but they can be opened from any directory with sufficient permissions.
Fixed: When trying to add a high-pass filter in the Configuration Editor, it was instead configured to be a low-pass filter.
This commit is contained in:
1 parent
989812ba36
commit
a24eaa0cd9
58 files changed
+3334
-151
No files matched your search
+27
-14
@@ -109,7 +109,7 @@ double AnalysisThread::getProcessingTime() const
|
||||
return processingTime;
|
||||
}
|
||||
|
||||
int AnalysisThread::getProcessedFrames() const
|
||||
unsigned AnalysisThread::getProcessedFrames() const
|
||||
{
|
||||
return processedFrames;
|
||||
}
|
||||
@@ -153,6 +153,7 @@ void AnalysisThread::run()
|
||||
unsigned sampleRate = device->getSampleRate();
|
||||
|
||||
qint64 startTime = timer.nsecsElapsed();
|
||||
|
||||
FilterEngine engine;
|
||||
engine.setDeviceInfo(device->isInput(), true, device->getDeviceName(), device->getConnectionName(), device->getDeviceGuid(), device->getDeviceString());
|
||||
engine.initialize(sampleRate, channelCount, channelCount, channelCount, channelMask, frameCount, configPath.toStdWString());
|
||||
@@ -193,8 +194,9 @@ void AnalysisThread::run()
|
||||
int latency = 0;
|
||||
int startFrame = -1;
|
||||
double processingTime = 0.0;
|
||||
int processedFrames = 0;
|
||||
while (true)
|
||||
unsigned processedFrames = 0;
|
||||
// stop searching for startFrame after 10 seconds of audio data
|
||||
while (processedFrames < 10 * sampleRate)
|
||||
{
|
||||
qint64 startTime = timer.nsecsElapsed();
|
||||
engine.process(buf2, buf, frameCount);
|
||||
@@ -240,20 +242,31 @@ void AnalysisThread::run()
|
||||
if (startFrame == -1)
|
||||
latency += frameCount;
|
||||
}
|
||||
latency += startFrame;
|
||||
|
||||
fftwf_execute(planForward);
|
||||
|
||||
double peakGain = -DBL_MAX;
|
||||
|
||||
for (int i = 0; i < frameCount / 2; i++)
|
||||
double peakGain;
|
||||
if (startFrame != -1)
|
||||
{
|
||||
float sqrGain = freqData[i][0] * freqData[i][0] + freqData[i][1] * freqData[i][1];
|
||||
if (sqrGain > peakGain)
|
||||
peakGain = sqrGain;
|
||||
latency += startFrame;
|
||||
|
||||
fftwf_execute(planForward);
|
||||
|
||||
peakGain = -DBL_MAX;
|
||||
|
||||
for (int i = 0; i < frameCount / 2; i++)
|
||||
{
|
||||
float sqrGain = freqData[i][0] * freqData[i][0] + freqData[i][1] * freqData[i][1];
|
||||
if (sqrGain > peakGain)
|
||||
peakGain = sqrGain;
|
||||
}
|
||||
peakGain = sqrt(peakGain);
|
||||
peakGain = log10(peakGain) * 20.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
latency = 0;
|
||||
peakGain = -numeric_limits<double>::infinity();
|
||||
memset(freqData, 0, frameCount * sizeof(fftwf_complex));
|
||||
}
|
||||
peakGain = sqrt(peakGain);
|
||||
peakGain = log10(peakGain) * 20.0;
|
||||
|
||||
mutex.lock();
|
||||
if (this->freqDataLength != frameCount)
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
int getLatency() const;
|
||||
double getInitializationTime() const;
|
||||
double getProcessingTime() const;
|
||||
int getProcessedFrames() const;
|
||||
unsigned getProcessedFrames() const;
|
||||
|
||||
signals:
|
||||
void analysisFinished();
|
||||
|
||||
+22
-4
@@ -116,7 +116,15 @@ SOURCES += main.cpp\
|
||||
helpers/DPIHelper.cpp \
|
||||
CustomStyle.cpp \
|
||||
../AbstractAPOInfo.cpp \
|
||||
../VoicemeeterAPOInfo.cpp
|
||||
../VoicemeeterAPOInfo.cpp \
|
||||
../helpers/AbstractLibrary.cpp \
|
||||
../helpers/VSTPluginLibrary.cpp \
|
||||
guis/VSTPluginFilterGUI.cpp \
|
||||
guis/VSTPluginFilterGUIFactory.cpp \
|
||||
guis/VSTPluginFilterGUIDialog.cpp \
|
||||
../filters/VSTPluginFilter.cpp \
|
||||
../filters/VSTPluginFilterFactory.cpp \
|
||||
../helpers/VSTPluginInstance.cpp
|
||||
|
||||
HEADERS += \
|
||||
../helpers/LogHelper.h \
|
||||
@@ -221,7 +229,15 @@ HEADERS += \
|
||||
helpers/DPIHelper.h \
|
||||
CustomStyle.h \
|
||||
../AbstractAPOInfo.h \
|
||||
../VoicemeeterAPOInfo.h
|
||||
../VoicemeeterAPOInfo.h \
|
||||
../helpers/AbstractLibrary.h \
|
||||
../helpers/VSTPluginLibrary.h \
|
||||
guis/VSTPluginFilterGUI.h \
|
||||
guis/VSTPluginFilterGUIFactory.h \
|
||||
guis/VSTPluginFilterGUIDialog.h \
|
||||
../filters/VSTPluginFilter.h \
|
||||
../filters/VSTPluginFilterFactory.h \
|
||||
../helpers/VSTPluginInstance.h
|
||||
|
||||
FORMS += \
|
||||
guis/PreampFilterGUI.ui \
|
||||
@@ -239,10 +255,12 @@ FORMS += \
|
||||
guis/GraphicEQFilterGUI.ui \
|
||||
guis/ConvolutionFilterGUI.ui \
|
||||
MainWindow.ui \
|
||||
guis/StageFilterGUI.ui
|
||||
guis/StageFilterGUI.ui \
|
||||
guis/VSTPluginFilterGUI.ui \
|
||||
guis/VSTPluginFilterGUIDialog.ui
|
||||
|
||||
INCLUDEPATH += $$PWD/.. "C:/Program Files/libsndfile/include" "C:/Program Files/fftw3" "C:/Program Files/muparserx_v3_0_1/parser"
|
||||
LIBS += user32.lib advapi32.lib version.lib ole32.lib Shlwapi.lib authz.lib libsndfile-1.lib libfftw3f-3.lib
|
||||
LIBS += user32.lib advapi32.lib version.lib ole32.lib Shlwapi.lib authz.lib crypt32.lib dbghelp.lib libsndfile-1.lib libfftw3f-3.lib
|
||||
|
||||
build_pass:CONFIG(debug, debug|release) {
|
||||
LIBS += muparserxd.lib
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "guis/IncludeFilterGUIFactory.h"
|
||||
#include "guis/GraphicEQFilterGUIFactory.h"
|
||||
#include "guis/ConvolutionFilterGUIFactory.h"
|
||||
#include "guis/VSTPluginFilterGUIFactory.h"
|
||||
#include "Editor/helpers/DPIHelper.h"
|
||||
#include "helpers/StringHelper.h"
|
||||
#include "helpers/LogHelper.h"
|
||||
@@ -79,10 +80,18 @@ FilterTable::FilterTable(MainWindow* mainWindow, QWidget* parent)
|
||||
factories.append(new CopyFilterGUIFactory);
|
||||
factories.append(new GraphicEQFilterGUIFactory);
|
||||
factories.append(new ConvolutionFilterGUIFactory);
|
||||
factories.append(new VSTPluginFilterGUIFactory);
|
||||
|
||||
QApplication::instance()->installEventFilter(this);
|
||||
}
|
||||
|
||||
FilterTable::~FilterTable()
|
||||
{
|
||||
for (IFilterGUIFactory* factory : factories)
|
||||
delete factory;
|
||||
factories.clear();
|
||||
}
|
||||
|
||||
void FilterTable::initialize(QScrollArea* scrollArea, const QList<shared_ptr<AbstractAPOInfo> >& outputDevices, const QList<shared_ptr<AbstractAPOInfo> >& inputDevices)
|
||||
{
|
||||
this->scrollArea = scrollArea;
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
};
|
||||
|
||||
explicit FilterTable(MainWindow* mainWindow, QWidget* parent = 0);
|
||||
~FilterTable();
|
||||
void initialize(QScrollArea* scrollArea, const QList<std::shared_ptr<AbstractAPOInfo> >& outputDevices, const QList<std::shared_ptr<AbstractAPOInfo> >& inputDevices);
|
||||
void updateDeviceAndChannelMask(std::shared_ptr<AbstractAPOInfo> selectedDevice, int selectedChannelMask);
|
||||
void updateGuis();
|
||||
|
||||
+13
-1
@@ -427,6 +427,10 @@ void MainWindow::deviceSelected(int index)
|
||||
else
|
||||
channelConfigurationComboBox->addItem(tr("From device") + " (" + apoInfo->getChannelCount() + " channels)", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
channelConfigurationComboBox->addItem(tr("From device") + " (?)", 0);
|
||||
}
|
||||
|
||||
for (const GUIChannelHelper::ChannelConfigurationInfo& info : infos)
|
||||
channelConfigurationComboBox->addItem(info.name, info.channelMask);
|
||||
@@ -469,6 +473,8 @@ void MainWindow::channelConfigurationSelected(int index)
|
||||
ui->analysisChannelComboBox->addItem(QString::fromStdWString(channelName));
|
||||
}
|
||||
}
|
||||
|
||||
startAnalysis();
|
||||
}
|
||||
|
||||
void MainWindow::linesChanged()
|
||||
@@ -723,6 +729,9 @@ void MainWindow::on_mainToolBar_visibilityChanged(bool visible)
|
||||
void MainWindow::on_analysisDockWidget_visibilityChanged(bool visible)
|
||||
{
|
||||
ui->actionAnalysisPanel->setChecked(visible);
|
||||
|
||||
if (visible)
|
||||
startAnalysis();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionToolbar_triggered(bool checked)
|
||||
@@ -836,7 +845,7 @@ void MainWindow::getDeviceAndChannelMask(shared_ptr<AbstractAPOInfo>* selectedDe
|
||||
*selectedDevice = defaultOutputDevice;
|
||||
|
||||
*channelMask = channelConfigurationComboBox->currentData().toInt();
|
||||
if (*channelMask == 0 && selectedDevice != NULL)
|
||||
if (*channelMask == 0 && selectedDevice->get() != NULL)
|
||||
{
|
||||
*channelMask = (*selectedDevice)->getChannelMask();
|
||||
|
||||
@@ -894,6 +903,9 @@ bool MainWindow::askForClose(int tabIndex)
|
||||
|
||||
void MainWindow::startAnalysis()
|
||||
{
|
||||
if (!ui->analysisDockWidget->isVisible())
|
||||
return;
|
||||
|
||||
shared_ptr<AbstractAPOInfo> selectedDevice;
|
||||
|
||||
int channelMask;
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ private:
|
||||
QList<std::shared_ptr<AbstractAPOInfo> > inputDevices;
|
||||
std::shared_ptr<AbstractAPOInfo> defaultOutputDevice;
|
||||
AnalysisPlotScene* analysisPlotScene;
|
||||
AnalysisThread* analysisThread;
|
||||
AnalysisThread* analysisThread = NULL;
|
||||
bool restart = false;
|
||||
bool noSavePreferences = false;
|
||||
bool noSaveFilePreferences = false;
|
||||
|
||||
@@ -32,7 +32,7 @@ QList<FilterTemplate> BiQuadFilterGUIFactory::createFilterTemplates()
|
||||
QList<FilterTemplate> list;
|
||||
list.append(FilterTemplate(tr("Peaking filter"), "Filter: ON PK Fc 100 Hz Gain 0 dB Q 10", path));
|
||||
list.append(FilterTemplate(tr("Low-pass filter"), "Filter: ON LP Fc 100 Hz", path));
|
||||
list.append(FilterTemplate(tr("High-pass filter"), "Filter: ON LP Fc 100 Hz", path));
|
||||
list.append(FilterTemplate(tr("High-pass filter"), "Filter: ON HP Fc 100 Hz", path));
|
||||
list.append(FilterTemplate(tr("Band-pass filter"), "Filter: ON BP Fc 100 Hz Q 10", path));
|
||||
list.append(FilterTemplate(tr("Low-shelf filter"), "Filter: ON LS Fc 100 Hz Gain 0 dB", path));
|
||||
list.append(FilterTemplate(tr("High-shelf filter"), "Filter: ON HS Fc 100 Hz Gain 0 dB", path));
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>652</width>
|
||||
<height>65</height>
|
||||
<width>665</width>
|
||||
<height>79</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -58,7 +58,14 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ResizingLineEdit" name="pathLineEdit"/>
|
||||
<widget class="ResizingLineEdit" name="pathLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
|
||||
@@ -175,8 +175,9 @@ void CopyFilterGUIConnectionItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent
|
||||
if (isDecibel)
|
||||
text += " dB";
|
||||
|
||||
ResizingLineEdit* lineEdit = new ResizingLineEdit("");
|
||||
ResizingLineEdit* lineEdit = new ResizingLineEdit(text, true);
|
||||
connect(lineEdit, SIGNAL(editingFinished()), this, SLOT(lineEditEditingFinished()));
|
||||
connect(lineEdit, SIGNAL(editingCanceled()), this, SLOT(lineEditEditingCanceled()));
|
||||
QGraphicsProxyWidget* proxyItem = scene()->addWidget(lineEdit);
|
||||
QLineF l = line();
|
||||
QPointF center = (l.p1() + l.p2()) / 2;
|
||||
@@ -233,6 +234,14 @@ void CopyFilterGUIConnectionItem::lineEditEditingFinished()
|
||||
emit((CopyFilterGUIScene*)scene())->updateModel();
|
||||
}
|
||||
|
||||
void CopyFilterGUIConnectionItem::lineEditEditingCanceled()
|
||||
{
|
||||
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(QObject::sender());
|
||||
|
||||
lineEdit->setVisible(false);
|
||||
lineEdit->deleteLater();
|
||||
}
|
||||
|
||||
CopyFilterGUIChannelItem* CopyFilterGUIConnectionItem::getSource() const
|
||||
{
|
||||
return source;
|
||||
|
||||
@@ -55,6 +55,7 @@ protected:
|
||||
|
||||
private slots:
|
||||
void lineEditEditingFinished();
|
||||
void lineEditEditingCanceled();
|
||||
|
||||
private:
|
||||
CopyFilterGUIChannelItem* source = NULL;
|
||||
|
||||
@@ -162,8 +162,9 @@ std::vector<Assignment> CopyFilterGUIScene::buildAssignments()
|
||||
|
||||
void CopyFilterGUIScene::addOutputChannel()
|
||||
{
|
||||
ResizingLineEdit* lineEdit = new ResizingLineEdit("");
|
||||
ResizingLineEdit* lineEdit = new ResizingLineEdit("", true);
|
||||
connect(lineEdit, SIGNAL(editingFinished()), this, SLOT(lineEditEditingFinished()));
|
||||
connect(lineEdit, SIGNAL(editingCanceled()), this, SLOT(lineEditEditingCanceled()));
|
||||
QGraphicsProxyWidget* proxyItem = addWidget(lineEdit);
|
||||
QPointF point = getNextChannelPoint(lastOutputItem, true);
|
||||
QRectF rect;
|
||||
@@ -183,13 +184,25 @@ void CopyFilterGUIScene::lineEditEditingFinished()
|
||||
return;
|
||||
|
||||
QString text = lineEdit->text();
|
||||
if (text != "")
|
||||
{
|
||||
CopyFilterGUIChannelItem* item = new CopyFilterGUIChannelItem(text, true);
|
||||
item->setPos(getNextChannelPoint(lastOutputItem, true));
|
||||
addItem(item);
|
||||
lastOutputItem = item;
|
||||
|
||||
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::lineEditEditingCanceled()
|
||||
{
|
||||
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(QObject::sender());
|
||||
|
||||
addProxyItem->setPos(getNextChannelPoint(lastOutputItem, true));
|
||||
addProxyItem->setVisible(true);
|
||||
|
||||
lineEdit->setVisible(false);
|
||||
|
||||
@@ -43,6 +43,7 @@ protected:
|
||||
private slots:
|
||||
void addOutputChannel();
|
||||
void lineEditEditingFinished();
|
||||
void lineEditEditingCanceled();
|
||||
|
||||
private:
|
||||
QGraphicsItem* lastOutputItem;
|
||||
|
||||
@@ -51,7 +51,14 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ResizingLineEdit" name="pathLineEdit"/>
|
||||
<widget class="ResizingLineEdit" name="pathLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="selectFileToolButton">
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 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 <QFileInfo>
|
||||
#include <QFileDialog>
|
||||
#include <QSettings>
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QStringList>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include "helpers/aeffectx.h"
|
||||
#include "helpers/StringHelper.h"
|
||||
#include "Editor/helpers/DPIHelper.h"
|
||||
#include "Editor/MainWindow.h"
|
||||
#include "VSTPluginFilterGUIDialog.h"
|
||||
#include "VSTPluginFilterGUI.h"
|
||||
#include "ui_VSTPluginFilterGUI.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
VSTPluginFilterGUI::VSTPluginFilterGUI(std::shared_ptr<VSTPluginLibrary> library, const std::wstring& chunkData, const std::unordered_map<std::wstring, float>& paramMap)
|
||||
: ui(new Ui::VSTPluginFilterGUI), library(library), chunkData(chunkData), paramMap(paramMap)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->frame->setVisible(false);
|
||||
updatePermissionWarning();
|
||||
|
||||
QString absolutePath = QString::fromStdWString(library->getLibPath());
|
||||
QDir pluginsDir(QString::fromStdWString(VSTPluginLibrary::getDefaultPluginPath()));
|
||||
QString relativePath = QDir::toNativeSeparators(pluginsDir.relativeFilePath(absolutePath));
|
||||
if (relativePath.startsWith(QDir::toNativeSeparators("../../")))
|
||||
relativePath = absolutePath;
|
||||
ui->pathLineEdit->setText(relativePath);
|
||||
|
||||
QMenu* menu = new QMenu(ui->optionsButton);
|
||||
menu->addAction(ui->embedAction);
|
||||
ui->optionsButton->setMenu(menu);
|
||||
}
|
||||
|
||||
VSTPluginFilterGUI::~VSTPluginFilterGUI()
|
||||
{
|
||||
if (effect != NULL)
|
||||
{
|
||||
if (ui->embedAction->isChecked())
|
||||
on_embedAction_toggled(false);
|
||||
delete effect;
|
||||
effect = NULL;
|
||||
}
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::store(QString& command, QString& parameters)
|
||||
{
|
||||
command = "VSTPlugin";
|
||||
|
||||
QString absolutePath = QString::fromStdWString(library->getLibPath());
|
||||
QDir pluginsDir(QString::fromStdWString(VSTPluginLibrary::getDefaultPluginPath()));
|
||||
QString relativePath = QDir::toNativeSeparators(pluginsDir.relativeFilePath(absolutePath));
|
||||
if (relativePath.startsWith(QDir::toNativeSeparators("../../")))
|
||||
relativePath = absolutePath;
|
||||
|
||||
if (relativePath.contains(" "))
|
||||
relativePath = "\"" + relativePath + "\"";
|
||||
parameters = "Library " + relativePath;
|
||||
|
||||
if (chunkData != L"")
|
||||
{
|
||||
parameters += " ChunkData \"" + QString::fromStdWString(chunkData) + "\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto it : paramMap)
|
||||
{
|
||||
QString name = QString::fromStdWString(it.first);
|
||||
if (name.contains(" ") || name.contains("\""))
|
||||
name = "\"" + name.replace("\"", "\"\"") + "\"";
|
||||
parameters += " " + name + " " + QString("%1").arg(it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::loadPreferences(const QVariantMap& prefs)
|
||||
{
|
||||
autoApplyDialog = prefs.value("autoApplyDialog").toBool();
|
||||
|
||||
if (prefs.value("embed").toBool())
|
||||
// will also call initPlugin
|
||||
ui->embedAction->setChecked(true);
|
||||
else
|
||||
initPlugin();
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::storePreferences(QVariantMap& prefs)
|
||||
{
|
||||
prefs.insert("embed", ui->embedAction->isChecked());
|
||||
prefs.insert("autoApplyDialog", autoApplyDialog);
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::on_openPanelButton_clicked()
|
||||
{
|
||||
initPlugin();
|
||||
|
||||
if (effect != NULL)
|
||||
{
|
||||
effect->writeToEffect(chunkData, paramMap);
|
||||
|
||||
VSTPluginFilterGUIDialog dialog(this, effect, autoApplyDialog);
|
||||
connect(dialog.getApplyButton(), SIGNAL(pressed()), SLOT(applyDialog()));
|
||||
connect(dialog.getAutoApplyCheckBox(), SIGNAL(toggled(bool)), SLOT(autoApplyToggled(bool)));
|
||||
connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), SLOT(on_idle()));
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
effect->readFromEffect(chunkData, paramMap);
|
||||
updateModel();
|
||||
updatePermissionWarning();
|
||||
}
|
||||
disconnect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(on_idle()));
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::applyDialog()
|
||||
{
|
||||
effect->readFromEffect(chunkData, paramMap);
|
||||
updateModel();
|
||||
updatePermissionWarning();
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::autoApplyToggled(bool checked)
|
||||
{
|
||||
autoApplyDialog = checked;
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::initPlugin()
|
||||
{
|
||||
if (effect != NULL)
|
||||
return;
|
||||
|
||||
QColor color;
|
||||
QString text;
|
||||
if (library->getLibPath() == L"")
|
||||
{
|
||||
text = tr("No file selected.");
|
||||
color = Qt::red;
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = library->initialize();
|
||||
if (result < 0)
|
||||
{
|
||||
color = Qt::red;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case AbstractLibrary::FILE_NOT_FOUND:
|
||||
text = tr("File not found.");
|
||||
break;
|
||||
case AbstractLibrary::LOADING_FAILED:
|
||||
text = tr("Library could not be loaded.");
|
||||
break;
|
||||
case AbstractLibrary::FUNCTIONS_MISSING:
|
||||
text = tr("Library does not contain needed functions.");
|
||||
break;
|
||||
case AbstractLibrary::WRONG_ARCHITECTURE:
|
||||
#ifdef _WIN64
|
||||
int bitDepth = 64;
|
||||
#else
|
||||
int bitDepth = 32;
|
||||
#endif
|
||||
text = tr("Library has the wrong architecture. Only %1-bit libraries are supported.").arg(bitDepth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
effect = new VSTPluginInstance(library, 1);
|
||||
if (effect->initialize())
|
||||
{
|
||||
effect->setLanguage(QLocale().language() == QLocale::German ? 2 : 1);
|
||||
effect->setAutomateFunc(bind(&VSTPluginFilterGUI::onAutomate, this));
|
||||
|
||||
color = Qt::black;
|
||||
text = QString::fromStdWString(effect->getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
delete effect;
|
||||
effect = NULL;
|
||||
|
||||
color = Qt::red;
|
||||
text = tr("Plugin crashed during initialization.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPalette palette = ui->statusLabel->palette();
|
||||
palette.setColor(QPalette::Active, QPalette::WindowText, color);
|
||||
palette.setColor(QPalette::Inactive, QPalette::WindowText, color);
|
||||
ui->statusLabel->setPalette(palette);
|
||||
ui->statusLabel->setText(text);
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::on_pathLineEdit_editingFinished()
|
||||
{
|
||||
if (QString::fromStdWString(library->getLibPath()) != ui->pathLineEdit->text())
|
||||
{
|
||||
int oldId = 0;
|
||||
if (effect != NULL)
|
||||
{
|
||||
oldId = effect->uniqueID();
|
||||
if (ui->embedAction->isChecked())
|
||||
on_embedAction_toggled(false);
|
||||
delete effect;
|
||||
effect = NULL;
|
||||
}
|
||||
|
||||
QDir pluginsDir(QString::fromStdWString(VSTPluginLibrary::getDefaultPluginPath()));
|
||||
QString path = ui->pathLineEdit->text();
|
||||
if (path.length() > 0)
|
||||
path = QDir::toNativeSeparators(QFileInfo(pluginsDir, ui->pathLineEdit->text()).absoluteFilePath());
|
||||
library = VSTPluginLibrary::getInstance(path.toStdWString());
|
||||
initPlugin();
|
||||
|
||||
if (effect == NULL || oldId == 0 || effect->uniqueID() != oldId)
|
||||
{
|
||||
chunkData = L"";
|
||||
paramMap.clear();
|
||||
}
|
||||
|
||||
updateModel();
|
||||
updatePermissionWarning();
|
||||
|
||||
if (ui->embedAction->isChecked())
|
||||
on_embedAction_toggled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::on_selectButton_clicked()
|
||||
{
|
||||
QDir pluginsDir(QString::fromStdWString(VSTPluginLibrary::getDefaultPluginPath()));
|
||||
|
||||
QSettings settings(QString::fromWCharArray(EDITOR_REGPATH), QSettings::NativeFormat);
|
||||
QString lastDir = settings.value("vst/lastDir", "").toString();
|
||||
if (lastDir == "")
|
||||
lastDir = pluginsDir.absolutePath();
|
||||
|
||||
QFileInfo fileInfo(lastDir);
|
||||
QString path = ui->pathLineEdit->text();
|
||||
if (path.length() > 0)
|
||||
fileInfo.setFile(pluginsDir, path);
|
||||
|
||||
QFileDialog dialog(this, tr("Select VST plugin"), fileInfo.absoluteFilePath(), "*.dll");
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
dialog.setNameFilter(tr("VST plugins (*.dll)"));
|
||||
if (path.length() > 0)
|
||||
dialog.selectFile(fileInfo.fileName());
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
QString absolutePath = dialog.selectedFiles().first();
|
||||
settings.setValue("vst/lastDir", QDir::toNativeSeparators(QFileInfo(absolutePath).absolutePath()));
|
||||
QString relativePath = pluginsDir.relativeFilePath(absolutePath);
|
||||
if (relativePath.startsWith("../../"))
|
||||
relativePath = absolutePath;
|
||||
ui->pathLineEdit->setText(QDir::toNativeSeparators(relativePath));
|
||||
on_pathLineEdit_editingFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::on_embedAction_toggled(bool checked)
|
||||
{
|
||||
initPlugin();
|
||||
|
||||
ui->openPanelButton->setVisible(!checked);
|
||||
|
||||
bool enable = checked;
|
||||
if (effect == NULL)
|
||||
enable = false;
|
||||
|
||||
bool wasEnabled = ui->frame->isVisible();
|
||||
if (enable != wasEnabled)
|
||||
{
|
||||
ui->frame->setVisible(enable);
|
||||
ui->statusLabel->setVisible(!enable);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
if (embedPlugin())
|
||||
{
|
||||
effect->setSizeWindowFunc(bind(&VSTPluginFilterGUI::onSizeWindow, this, _1, _2));
|
||||
connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), SLOT(on_idle()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->frame->setVisible(false);
|
||||
ui->statusLabel->setVisible(true);
|
||||
|
||||
QPalette palette = ui->statusLabel->palette();
|
||||
palette.setColor(QPalette::Active, QPalette::WindowText, Qt::red);
|
||||
palette.setColor(QPalette::Inactive, QPalette::WindowText, Qt::red);
|
||||
ui->statusLabel->setPalette(palette);
|
||||
ui->statusLabel->setText(tr("Plugin crashed when opening panel."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (effect != NULL)
|
||||
{
|
||||
effect->stopEditing();
|
||||
effect->setSizeWindowFunc(nullptr);
|
||||
}
|
||||
|
||||
disconnect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(on_idle()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::on_idle()
|
||||
{
|
||||
if (effect != NULL)
|
||||
{
|
||||
effect->doIdle();
|
||||
|
||||
if (ui->frame->isVisible() || autoApplyDialog)
|
||||
{
|
||||
if (!lastReadTimer.isValid() || lastReadTimer.elapsed() > 1000)
|
||||
{
|
||||
wstring newChunkData;
|
||||
unordered_map<std::wstring, float> newParamMap;
|
||||
effect->readFromEffect(newChunkData, newParamMap);
|
||||
if (newChunkData != chunkData || newParamMap != paramMap)
|
||||
{
|
||||
chunkData = newChunkData;
|
||||
paramMap = newParamMap;
|
||||
updateModel();
|
||||
updatePermissionWarning();
|
||||
}
|
||||
lastReadTimer.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::onAutomate()
|
||||
{
|
||||
if (ui->frame->isVisible() || autoApplyDialog)
|
||||
{
|
||||
effect->readFromEffect(chunkData, paramMap);
|
||||
updateModel();
|
||||
updatePermissionWarning();
|
||||
}
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::onSizeWindow(int w, int h)
|
||||
{
|
||||
if (ui->frame->isVisible())
|
||||
ui->frame->setFixedSize(w, h);
|
||||
}
|
||||
|
||||
bool VSTPluginFilterGUI::embedPlugin()
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
__try
|
||||
{
|
||||
effect->writeToEffect(chunkData, paramMap);
|
||||
|
||||
HWND hwnd = (HWND)ui->frame->winId();
|
||||
short width, height;
|
||||
|
||||
effect->startEditing(hwnd, &width, &height);
|
||||
|
||||
ui->frame->setFixedSize(width, height);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUI::updatePermissionWarning()
|
||||
{
|
||||
if (effect == NULL)
|
||||
{
|
||||
ui->warningTextEdit->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ACCESS_MASK mask = GENERIC_READ;
|
||||
try
|
||||
{
|
||||
mask = RegistryHelper::getFileAccessForUser(library->getLibPath(), SECURITY_LOCAL_SERVICE_RID);
|
||||
}
|
||||
catch (RegistryException e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
if ((mask & GENERIC_READ) != GENERIC_READ && (mask & FILE_GENERIC_READ) != FILE_GENERIC_READ)
|
||||
{
|
||||
QString text = tr("The library is not readable by the audio service.\nChange the file permissions or copy the file to the plugins directory.");
|
||||
|
||||
ui->warningTextEdit->setPlainText(text);
|
||||
QSize textSize = ui->warningTextEdit->fontMetrics().size(0, text);
|
||||
ui->warningTextEdit->setFixedSize(textSize + DPIHelper::scale(QSize(40, 15)));
|
||||
ui->warningTextEdit->setVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList files;
|
||||
if (chunkData != L"" && chunkData.length() < 100000)
|
||||
{
|
||||
QByteArray bytes = QByteArray::fromBase64(QString::fromStdWString(chunkData).toUtf8());
|
||||
QString string = QString::fromUtf8(bytes.data(), bytes.length());
|
||||
QRegExp regexp("[A-Za-z]:(?:\\\\[\\w \\(\\)-]+)+\\.[A-Za-z]{3}");
|
||||
int offset = 0;
|
||||
while (offset >= 0)
|
||||
{
|
||||
offset = regexp.indexIn(string, offset);
|
||||
if (offset >= 0)
|
||||
{
|
||||
QString path = regexp.cap();
|
||||
QFile file(path);
|
||||
if (file.exists())
|
||||
{
|
||||
ACCESS_MASK mask = GENERIC_READ;
|
||||
try
|
||||
{
|
||||
mask = RegistryHelper::getFileAccessForUser(path.toStdWString(), SECURITY_LOCAL_SERVICE_RID);
|
||||
}
|
||||
catch (RegistryException e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
if ((mask & GENERIC_READ) != GENERIC_READ && (mask & FILE_GENERIC_READ) != FILE_GENERIC_READ)
|
||||
files.append(path);
|
||||
}
|
||||
offset += regexp.matchedLength();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (files.isEmpty())
|
||||
{
|
||||
ui->warningTextEdit->setVisible(false);
|
||||
ui->warningTextEdit->setPlainText("");
|
||||
}
|
||||
else
|
||||
{
|
||||
files.removeDuplicates();
|
||||
QString text = tr("The plugin seemingly accesses these files not readable by the audio service:\n"
|
||||
"%0\n"
|
||||
"Change the file permissions or copy the files to the config directory.").arg(files.join("\n"));
|
||||
ui->warningTextEdit->setPlainText(text);
|
||||
QSize textSize = ui->warningTextEdit->fontMetrics().size(0, text);
|
||||
ui->warningTextEdit->setFixedSize(textSize + DPIHelper::scale(QSize(40, 15)));
|
||||
ui->warningTextEdit->setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 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 <memory>
|
||||
#include <QElapsedTimer>
|
||||
#include "Editor/IFilterGUI.h"
|
||||
#include "helpers/VSTPluginLibrary.h"
|
||||
|
||||
namespace Ui {
|
||||
class VSTPluginFilterGUI;
|
||||
}
|
||||
|
||||
class VSTPluginFilterGUI : public IFilterGUI
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VSTPluginFilterGUI(std::shared_ptr<VSTPluginLibrary> library, const std::wstring& chunkData, const std::unordered_map<std::wstring, float>& paramMap);
|
||||
~VSTPluginFilterGUI();
|
||||
|
||||
void store(QString& command, QString& parameters) override;
|
||||
void loadPreferences(const QVariantMap& prefs) override;
|
||||
void storePreferences(QVariantMap& prefs) override;
|
||||
void onAutomate();
|
||||
void onSizeWindow(int w, int h);
|
||||
|
||||
private slots:
|
||||
void on_openPanelButton_clicked();
|
||||
void applyDialog();
|
||||
void autoApplyToggled(bool checked);
|
||||
void on_pathLineEdit_editingFinished();
|
||||
void on_selectButton_clicked();
|
||||
void on_embedAction_toggled(bool checked);
|
||||
void on_idle();
|
||||
|
||||
private:
|
||||
void initPlugin();
|
||||
bool embedPlugin();
|
||||
void updatePermissionWarning();
|
||||
|
||||
Ui::VSTPluginFilterGUI* ui;
|
||||
std::shared_ptr<VSTPluginLibrary> library;
|
||||
VSTPluginInstance* effect = NULL;
|
||||
std::wstring chunkData;
|
||||
std::unordered_map<std::wstring, float> paramMap;
|
||||
bool autoApplyDialog = false;
|
||||
QElapsedTimer lastReadTimer;
|
||||
};
|
||||
@@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>VSTPluginFilterGUI</class>
|
||||
<widget class="QWidget" name="VSTPluginFilterGUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>542</width>
|
||||
<height>166</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3" 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>
|
||||
<property name="verticalSpacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="ResizingLineEdit" name="pathLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="openPanelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open panel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VST plugin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</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>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="optionsButton">
|
||||
<property name="text">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::MenuButtonPopup</enum>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextOnly</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="selectButton">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Editor.qrc">
|
||||
<normaloff>:/icons/document-open.ico</normaloff>:/icons/document-open.ico</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<widget class="QPlainTextEdit" name="warningTextEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="Base">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>127</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="Base">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>127</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="Base">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>240</red>
|
||||
<green>240</green>
|
||||
<blue>240</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="embedAction">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Embed</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ResizingLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Editor/widgets/ResizingLineEdit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../Editor.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>optionsButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>optionsButton</receiver>
|
||||
<slot>showMenu()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>288</x>
|
||||
<y>12</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>288</x>
|
||||
<y>12</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 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 <QPushButton>
|
||||
#include "VSTPluginFilterGUIDialog.h"
|
||||
#include "ui_VSTPluginFilterGUIDialog.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
VSTPluginFilterGUIDialog::VSTPluginFilterGUIDialog(QWidget* parent, VSTPluginInstance* effect, bool autoApply)
|
||||
: QDialog(parent, Qt::WindowCloseButtonHint),
|
||||
ui(new Ui::VSTPluginFilterGUIDialog),
|
||||
effect(effect)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->autoApplyCheckBox->setChecked(autoApply);
|
||||
|
||||
QString name = QString::fromStdWString(effect->getName());
|
||||
setWindowTitle(name);
|
||||
|
||||
HWND hwnd = (HWND)ui->frame->winId();
|
||||
|
||||
short width, height;
|
||||
|
||||
effect->startEditing(hwnd, &width, &height);
|
||||
|
||||
ui->frame->setFixedSize(width, height);
|
||||
effect->setSizeWindowFunc(bind(&VSTPluginFilterGUIDialog::onSizeWindow, this, _1, _2));
|
||||
}
|
||||
|
||||
VSTPluginFilterGUIDialog::~VSTPluginFilterGUIDialog()
|
||||
{
|
||||
effect->stopEditing();
|
||||
effect->setSizeWindowFunc(nullptr);
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QPushButton* VSTPluginFilterGUIDialog::getApplyButton()
|
||||
{
|
||||
return ui->buttonBox->button(QDialogButtonBox::Apply);
|
||||
}
|
||||
|
||||
QCheckBox* VSTPluginFilterGUIDialog::getAutoApplyCheckBox()
|
||||
{
|
||||
return ui->autoApplyCheckBox;
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUIDialog::onSizeWindow(int w, int h)
|
||||
{
|
||||
ui->frame->setFixedSize(w, h);
|
||||
}
|
||||
|
||||
void VSTPluginFilterGUIDialog::on_autoApplyCheckBox_clicked(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
getApplyButton()->click();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 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 <QCheckBox>
|
||||
#include "helpers/VSTPluginInstance.h"
|
||||
|
||||
namespace Ui {
|
||||
class VSTPluginFilterGUIDialog;
|
||||
}
|
||||
|
||||
class VSTPluginFilterGUIDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VSTPluginFilterGUIDialog(QWidget* parent, VSTPluginInstance* effect, bool autoApply);
|
||||
~VSTPluginFilterGUIDialog();
|
||||
|
||||
QPushButton* getApplyButton();
|
||||
QCheckBox* getAutoApplyCheckBox();
|
||||
|
||||
void onSizeWindow(int w, int h);
|
||||
|
||||
private slots:
|
||||
void on_autoApplyCheckBox_clicked(bool checked);
|
||||
|
||||
private:
|
||||
Ui::VSTPluginFilterGUIDialog* ui;
|
||||
VSTPluginInstance* effect;
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>VSTPluginFilterGUIDialog</class>
|
||||
<widget class="QDialog" name="VSTPluginFilterGUIDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>459</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="autoApplyCheckBox">
|
||||
<property name="text">
|
||||
<string>Apply automatically</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>VSTPluginFilterGUIDialog</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>VSTPluginFilterGUIDialog</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,62 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 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/VSTPluginLibrary.h"
|
||||
#include "helpers/StringHelper.h"
|
||||
#include "filters/VSTPluginFilterFactory.h"
|
||||
#include "filters/VSTPluginFilter.h"
|
||||
#include "VSTPluginFilterGUI.h"
|
||||
#include "VSTPluginFilterGUIFactory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
QList<FilterTemplate> VSTPluginFilterGUIFactory::createFilterTemplates()
|
||||
{
|
||||
QList<FilterTemplate> list;
|
||||
list.append(FilterTemplate(tr("VST plugin"), "VSTPlugin:", QStringList(tr("Plugins"))));
|
||||
return list;
|
||||
}
|
||||
|
||||
IFilterGUI* VSTPluginFilterGUIFactory::createFilterGUI(QString& command, QString& parameters)
|
||||
{
|
||||
VSTPluginFilterGUI* result = NULL;
|
||||
|
||||
if (command == "VSTPlugin")
|
||||
{
|
||||
VSTPluginFilterFactory factory;
|
||||
std::vector<IFilter*> filters = factory.createFilter(L"", command.toStdWString(), parameters.toStdWString());
|
||||
if (!filters.empty())
|
||||
{
|
||||
VSTPluginFilter* filter = (VSTPluginFilter*)filters[0];
|
||||
result = new VSTPluginFilterGUI(filter->getLibrary(), filter->getChunkData(), filter->getParamMap());
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new VSTPluginFilterGUI(VSTPluginLibrary::getInstance(L""), L"", unordered_map<wstring, float>());
|
||||
}
|
||||
|
||||
for (IFilter* f : filters)
|
||||
{
|
||||
f->~IFilter();
|
||||
MemoryHelper::free(f);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of Equalizer APO, a system-wide equalizer.
|
||||
Copyright (C) 2017 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 VSTPluginFilterGUIFactory : public IFilterGUIFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QList<FilterTemplate> createFilterTemplates() override;
|
||||
IFilterGUI* createFilterGUI(QString& command, QString& parameters) override;
|
||||
};
|
||||
Binary file not shown.
@@ -281,24 +281,24 @@
|
||||
<translation>Faltung mit Impulsantwort:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="66"/>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="73"/>
|
||||
<source>File information</source>
|
||||
<translation>Dateiinformationen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="72"/>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="79"/>
|
||||
<source>Sample rate:</source>
|
||||
<translation>Abtastrate:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="79"/>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="137"/>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="86"/>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="144"/>
|
||||
<location filename="../guis/ConvolutionFilterGUI.cpp" line="91"/>
|
||||
<source>No file selected</source>
|
||||
<translation>Keine Datei gewählt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="130"/>
|
||||
<location filename="../guis/ConvolutionFilterGUI.ui" line="137"/>
|
||||
<source>Length:</source>
|
||||
<translation>Länge:</translation>
|
||||
</message>
|
||||
@@ -661,7 +661,7 @@ Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.</t
|
||||
<context>
|
||||
<name>FilterTable</name>
|
||||
<message>
|
||||
<location filename="../FilterTable.cpp" line="205"/>
|
||||
<location filename="../FilterTable.cpp" line="214"/>
|
||||
<source>Add filter</source>
|
||||
<translation>Filter hinzufügen</translation>
|
||||
</message>
|
||||
@@ -838,12 +838,12 @@ Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.</t
|
||||
<context>
|
||||
<name>IncludeFilterGUI</name>
|
||||
<message>
|
||||
<location filename="../guis/IncludeFilterGUI.ui" line="70"/>
|
||||
<location filename="../guis/IncludeFilterGUI.ui" line="77"/>
|
||||
<source>Include:</source>
|
||||
<translation>Einbinden:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/IncludeFilterGUI.ui" line="59"/>
|
||||
<location filename="../guis/IncludeFilterGUI.ui" line="66"/>
|
||||
<source>Select file</source>
|
||||
<translation>Datei auswählen</translation>
|
||||
</message>
|
||||
@@ -1198,11 +1198,12 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</tra
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="426"/>
|
||||
<location filename="../MainWindow.cpp" line="428"/>
|
||||
<location filename="../MainWindow.cpp" line="432"/>
|
||||
<source>From device</source>
|
||||
<translation>Von Gerät</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="704"/>
|
||||
<location filename="../MainWindow.cpp" line="710"/>
|
||||
<source>%0 dB</source>
|
||||
<translation>%0 dB</translation>
|
||||
</message>
|
||||
@@ -1211,7 +1212,7 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</tra
|
||||
<translation type="vanished">%0 ms (%1 Samp.)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="707"/>
|
||||
<location filename="../MainWindow.cpp" line="713"/>
|
||||
<source>%0 ms (%1 s.)</source>
|
||||
<translation>%0 ms (%1 S.)</translation>
|
||||
</message>
|
||||
@@ -1220,46 +1221,46 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</tra
|
||||
<translation type="vanished">%0 ms (%1 Samples)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="709"/>
|
||||
<location filename="../MainWindow.cpp" line="715"/>
|
||||
<source>%0 ms</source>
|
||||
<translation>%0 ms</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="712"/>
|
||||
<location filename="../MainWindow.cpp" line="718"/>
|
||||
<source>%0 % (one core)</source>
|
||||
<translation>%0 % (ein Kern)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="750"/>
|
||||
<location filename="../MainWindow.cpp" line="777"/>
|
||||
<location filename="../MainWindow.cpp" line="796"/>
|
||||
<location filename="../MainWindow.cpp" line="759"/>
|
||||
<location filename="../MainWindow.cpp" line="786"/>
|
||||
<location filename="../MainWindow.cpp" line="805"/>
|
||||
<source>Restart required</source>
|
||||
<translation>Neustart erforderlich</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="750"/>
|
||||
<location filename="../MainWindow.cpp" line="777"/>
|
||||
<location filename="../MainWindow.cpp" line="796"/>
|
||||
<location filename="../MainWindow.cpp" line="759"/>
|
||||
<location filename="../MainWindow.cpp" line="786"/>
|
||||
<location filename="../MainWindow.cpp" line="805"/>
|
||||
<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"/>
|
||||
<location filename="../MainWindow.cpp" line="865"/>
|
||||
<source>Unsaved changes</source>
|
||||
<translation>Ungespeicherte Änderungen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="857"/>
|
||||
<location filename="../MainWindow.cpp" line="866"/>
|
||||
<source>The configuration file %0 has unsaved changes.</source>
|
||||
<translation>Die Konfigurationsdatei %0 hat ungespeicherte Änderungen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="858"/>
|
||||
<location filename="../MainWindow.cpp" line="867"/>
|
||||
<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="529"/>
|
||||
<location filename="../MainWindow.cpp" line="535"/>
|
||||
<source>Open file</source>
|
||||
<translation>Datei öffnen</translation>
|
||||
</message>
|
||||
@@ -1269,22 +1270,110 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</tra
|
||||
<translation>Automatisch (%0)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="531"/>
|
||||
<location filename="../MainWindow.cpp" line="584"/>
|
||||
<location filename="../MainWindow.cpp" line="537"/>
|
||||
<location filename="../MainWindow.cpp" line="590"/>
|
||||
<source>E-APO configurations (*.txt)</source>
|
||||
<translation>E-APO-Konfigurationen (*.txt)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="581"/>
|
||||
<location filename="../MainWindow.cpp" line="587"/>
|
||||
<source>Save file as</source>
|
||||
<translation>Datei speichern unter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../MainWindow.cpp" line="603"/>
|
||||
<location filename="../MainWindow.cpp" line="609"/>
|
||||
<source>Unsaved</source>
|
||||
<translation>Ungespeichert</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MathAudioFilterGUI</name>
|
||||
<message>
|
||||
<source>Open panel</source>
|
||||
<translation type="vanished">Panel öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Status information</source>
|
||||
<translation type="vanished">Statusinformationen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File %1 not found.</source>
|
||||
<translation type="vanished">Datei %1 nicht gefunden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Library %1 could not be loaded.</source>
|
||||
<translation type="vanished">Bibliothek %1 konnte nicht geladen werden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Library %1 does not contain needed functions.</source>
|
||||
<translation type="vanished">Bibliothek %1 enthält nicht die benötigten Funktionen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Library %1 could not be initialized.</source>
|
||||
<translation type="vanished">Bibliothek %1 konnte nicht initialisiert werden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Get library from <a href="%1">download page</a> and<br>extract %2-bit version of %3 into <a href="%4">plugins</a> directory.</source>
|
||||
<translation type="vanished">Bibliothek von der <a href="%1">Downloadseite</a> laden und<br>die %2-bit-Version von %3 in das Verzeichnis <a href="%4">plugins</a> extrahieren.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Library loaded successfully. Version: %1</source>
|
||||
<translation type="vanished">Bibliothek erfolgreich geladen. Version: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>For updates, get new version from <a href="%1">download page</a>, close Configuration Editor and<br>extract %2-bit version of %3 into <a href="%4">plugins</a> directory.</source>
|
||||
<translation type="vanished">Für Updates, neue Version von der <a href="%1">Downloadseite</a> laden, den Konfigurationseditor schließen und<br>die %2-bit-Version von %3 in das Verzeichnis <a href="%4">plugins</a> extrahieren.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MathAudioFilterGUIFactory</name>
|
||||
<message>
|
||||
<source>Plugins</source>
|
||||
<translation type="vanished">Plugins</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MathAudioHeadphoneEQFilterGUI</name>
|
||||
<message>
|
||||
<source>Open panel</source>
|
||||
<translation type="vanished">Panel öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Status information</source>
|
||||
<translation type="vanished">Statusinformationen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File %1 not found.</source>
|
||||
<translation type="vanished">Datei %1 nicht gefunden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Library %1 could not be loaded.</source>
|
||||
<translation type="vanished">Bibliothek %1 konnte nicht geladen werden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Library %1 does not contain needed functions.</source>
|
||||
<translation type="vanished">Bibliothek %1 enthält nicht die benötigten Funktionen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Get library from <a href="%1">download page</a> and<br>extract %2-bit version of %3 into <a href="%4">plugins</a> directory.</source>
|
||||
<translation type="vanished">Bibliothek von der <a href="%1">Downloadseite</a> laden und<br>die %2-bit-Version von %3 in das Verzeichnis <a href="%4">plugins</a> extrahieren.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Library loaded successfully.</source>
|
||||
<translation type="vanished">Bibliothek erfolgreich geladen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>For updates, get new version from <a href="%1">download page</a>, close Configuration Editor and<br>extract %2-bit version of %3 into <a href="%4">plugins</a> directory.</source>
|
||||
<translation type="vanished">Für Updates, neue Version von der <a href="%1">Downloadseite</a> laden, den Konfigurationseditor schließen und<br>die %2-bit-Version von %3 in das Verzeichnis <a href="%4">plugins</a> extrahieren.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MathAudioHeadphoneEQFilterGUIFactory</name>
|
||||
<message>
|
||||
<source>Plugins</source>
|
||||
<translation type="vanished">Plugins</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PreampFilterGUI</name>
|
||||
<message>
|
||||
@@ -1374,4 +1463,113 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?</tra
|
||||
<translation>Steuerung</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VSTPluginFilterGUI</name>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.ui" line="84"/>
|
||||
<source>Options</source>
|
||||
<translation>Optionen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.ui" line="44"/>
|
||||
<source>Open panel</source>
|
||||
<translation>Panel öffnen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.ui" line="57"/>
|
||||
<source>VST plugin:</source>
|
||||
<translation>VST-Plugin:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.ui" line="171"/>
|
||||
<source>Embed</source>
|
||||
<translation>Einbetten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No file selected</source>
|
||||
<translation type="vanished">Keine Datei gewählt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="162"/>
|
||||
<source>No file selected.</source>
|
||||
<translation>Keine Datei gewählt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="175"/>
|
||||
<source>File not found.</source>
|
||||
<translation>Datei nicht gefunden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="178"/>
|
||||
<source>Library could not be loaded.</source>
|
||||
<translation>Bibliothek konnte nicht geladen werden.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="181"/>
|
||||
<source>Library does not contain needed functions.</source>
|
||||
<translation>Bibliothek enthält benötigte Funktionen nicht.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="189"/>
|
||||
<source>Library has the wrong architecture. Only %1-bit libraries are supported.</source>
|
||||
<translation>Bibliothek hat die falsche Architektur. Nur %1-bit-Bibliotheken werden unterstützt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="210"/>
|
||||
<source>Plugin crashed during initialization.</source>
|
||||
<translation>Plugin ist bei der Initialisierung abgestürzt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="271"/>
|
||||
<source>Select VST plugin</source>
|
||||
<translation>VST-Plugin wählen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="273"/>
|
||||
<source>VST plugins (*.dll)</source>
|
||||
<translation>VST-Plugins (*.dll)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="320"/>
|
||||
<source>Plugin crashed when opening panel.</source>
|
||||
<translation>Plugin ist beim Öffnen des Panels abgestürzt.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="418"/>
|
||||
<source>The library is not readable by the audio service.
|
||||
Change the file permissions or copy the file to the plugins directory.</source>
|
||||
<translation>Die Bibliothek ist für den Audiodienst nicht lesbar.
|
||||
Ändern Sie die Dateiberechtigungen oder kopieren Sie die Datei in das plugins-Verzeichnis.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUI.cpp" line="469"/>
|
||||
<source>The plugin seemingly accesses these files not readable by the audio service:
|
||||
%0
|
||||
Change the file permissions or copy the files to the config directory.</source>
|
||||
<translation>Das Plugin scheint auf diese für den Audiodienst nicht lesbaren Dateien zuzugreifen:
|
||||
%0
|
||||
Ändern Sie die Dateiberechtigungen oder kopieren Sie die Dateien in das config-Verzeichnis.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VSTPluginFilterGUIDialog</name>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUIDialog.ui" line="20"/>
|
||||
<source>Apply automatically</source>
|
||||
<translation>Automatisch anwenden</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>VSTPluginFilterGUIFactory</name>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUIFactory.cpp" line="32"/>
|
||||
<source>VST plugin</source>
|
||||
<translation>VST-Plugin</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../guis/VSTPluginFilterGUIFactory.cpp" line="32"/>
|
||||
<source>Plugins</source>
|
||||
<translation>Plugins</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
@@ -26,9 +26,13 @@ EscapableLineEdit::EscapableLineEdit(QWidget* parent)
|
||||
{
|
||||
}
|
||||
|
||||
EscapableLineEdit::EscapableLineEdit(const QString& text, QWidget* parent)
|
||||
: QLineEdit(text, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void EscapableLineEdit::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
|
||||
if (event->key() == Qt::Key_Escape)
|
||||
emit editingCanceled();
|
||||
else
|
||||
|
||||
@@ -26,6 +26,7 @@ class EscapableLineEdit : public QLineEdit
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EscapableLineEdit(QWidget* parent = 0);
|
||||
explicit EscapableLineEdit(const QString& text, QWidget* parent = 0);
|
||||
|
||||
signals:
|
||||
void editingCanceled();
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
#include "ResizingLineEdit.h"
|
||||
|
||||
ResizingLineEdit::ResizingLineEdit(QWidget* parent)
|
||||
: QLineEdit(parent)
|
||||
: EscapableLineEdit(parent)
|
||||
{
|
||||
connect(this, SIGNAL(textChanged(QString)), this, SLOT(readjustSize()));
|
||||
|
||||
readjustSize();
|
||||
}
|
||||
|
||||
ResizingLineEdit::ResizingLineEdit(const QString& text, QWidget* parent)
|
||||
: QLineEdit(text, parent)
|
||||
ResizingLineEdit::ResizingLineEdit(const QString& text, bool forceWidth, QWidget* parent)
|
||||
: EscapableLineEdit(text, parent), forceWidth(forceWidth)
|
||||
{
|
||||
connect(this, SIGNAL(textChanged(QString)), this, SLOT(readjustSize()));
|
||||
|
||||
@@ -50,5 +50,8 @@ QSize ResizingLineEdit::sizeHint() const
|
||||
|
||||
void ResizingLineEdit::readjustSize()
|
||||
{
|
||||
setFixedWidth(sizeHint().width());
|
||||
if (forceWidth)
|
||||
setFixedWidth(sizeHint().width());
|
||||
else
|
||||
setMinimumWidth(sizeHint().width());
|
||||
}
|
||||
@@ -19,17 +19,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLineEdit>
|
||||
#include "EscapableLineEdit.h"
|
||||
|
||||
class ResizingLineEdit : public QLineEdit
|
||||
class ResizingLineEdit : public EscapableLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ResizingLineEdit(QWidget* parent = 0);
|
||||
explicit ResizingLineEdit(const QString& text, QWidget* parent = 0);
|
||||
explicit ResizingLineEdit(const QString& text, bool forceWidth, QWidget* parent = 0);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
|
||||
private slots:
|
||||
void readjustSize();
|
||||
|
||||
private:
|
||||
bool forceWidth = false;
|
||||
};
|
||||
Reference in new issue
Block a user