|
|
@@ -17,18 +17,104 @@ |
|
|
|
|
|
|
|
#include "carla_database.hpp" |
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------- |
|
|
|
// Imports (Global) |
|
|
|
|
|
|
|
#include <QtCore/QDir> |
|
|
|
#include <QtCore/QFileInfo> |
|
|
|
|
|
|
|
#include <QtWidgets/QPushButton> |
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------- |
|
|
|
// Imports (Custom) |
|
|
|
|
|
|
|
#include "ui_carla_add_jack.hpp" |
|
|
|
#include "ui_carla_database.hpp" |
|
|
|
#include "ui_carla_refresh.hpp" |
|
|
|
|
|
|
|
#include "carla_host.hpp" |
|
|
|
|
|
|
|
#include "CarlaHost.h" |
|
|
|
#include "CarlaLibJackHints.h" |
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------- |
|
|
|
// Separate Thread for Plugin Search |
|
|
|
|
|
|
|
struct WineSettings { |
|
|
|
QString executable; |
|
|
|
bool autoPrefix; |
|
|
|
QString fallbackPrefix; |
|
|
|
|
|
|
|
WineSettings() |
|
|
|
: executable(), |
|
|
|
autoPrefix(false), |
|
|
|
fallbackPrefix() |
|
|
|
{ |
|
|
|
const QSafeSettings settings("falkTX", "Carla2"); |
|
|
|
|
|
|
|
executable = settings.valueString(CARLA_KEY_WINE_EXECUTABLE, CARLA_DEFAULT_WINE_EXECUTABLE); |
|
|
|
autoPrefix = settings.valueBool(CARLA_KEY_WINE_AUTO_PREFIX, CARLA_DEFAULT_WINE_AUTO_PREFIX); |
|
|
|
fallbackPrefix = settings.valueString(CARLA_KEY_WINE_FALLBACK_PREFIX, CARLA_DEFAULT_WINE_FALLBACK_PREFIX); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
struct SearchPluginsThread::PrivateData { |
|
|
|
PrivateData(void*) |
|
|
|
bool fContinueChecking; |
|
|
|
QString fPathBinaries; |
|
|
|
|
|
|
|
bool fCheckNative; |
|
|
|
bool fCheckPosix32; |
|
|
|
bool fCheckPosix64; |
|
|
|
bool fCheckWin32; |
|
|
|
bool fCheckWin64; |
|
|
|
|
|
|
|
bool fCheckLADSPA; |
|
|
|
bool fCheckDSSI; |
|
|
|
bool fCheckLV2; |
|
|
|
bool fCheckVST2; |
|
|
|
bool fCheckVST3; |
|
|
|
bool fCheckAU; |
|
|
|
bool fCheckSF2; |
|
|
|
bool fCheckSFZ; |
|
|
|
|
|
|
|
WineSettings fWineSettings; |
|
|
|
|
|
|
|
QString fToolNative; |
|
|
|
|
|
|
|
uint fCurCount; |
|
|
|
uint fCurPercentValue; |
|
|
|
uint fLastCheckValue; |
|
|
|
bool fSomethingChanged; |
|
|
|
|
|
|
|
PrivateData(void*, const QString pathBinaries) |
|
|
|
: fContinueChecking(false), |
|
|
|
fPathBinaries(pathBinaries), |
|
|
|
fCheckNative(false), |
|
|
|
fCheckPosix32(false), |
|
|
|
fCheckPosix64(false), |
|
|
|
fCheckWin32(false), |
|
|
|
fCheckWin64(false), |
|
|
|
fCheckLADSPA(false), |
|
|
|
fCheckDSSI(false), |
|
|
|
fCheckLV2(false), |
|
|
|
fCheckVST2(false), |
|
|
|
fCheckVST3(false), |
|
|
|
fCheckAU(false), |
|
|
|
fCheckSF2(false), |
|
|
|
fCheckSFZ(false), |
|
|
|
fWineSettings(), |
|
|
|
fToolNative(), |
|
|
|
fCurCount(0), |
|
|
|
fCurPercentValue(0), |
|
|
|
fLastCheckValue(0), |
|
|
|
fSomethingChanged(false) |
|
|
|
{ |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
SearchPluginsThread::SearchPluginsThread(QObject* parent, QString pathBinaries) |
|
|
|
SearchPluginsThread::SearchPluginsThread(QObject* parent, const QString pathBinaries) |
|
|
|
: QThread(parent), |
|
|
|
self(new PrivateData(this)) |
|
|
|
self(new PrivateData(this, pathBinaries)) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
@@ -37,24 +123,82 @@ SearchPluginsThread::~SearchPluginsThread() |
|
|
|
delete self; |
|
|
|
} |
|
|
|
|
|
|
|
void SearchPluginsThread::run() |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------- |
|
|
|
// Plugin Refresh Dialog |
|
|
|
|
|
|
|
struct PluginRefreshW::PrivateData { |
|
|
|
PrivateData(void*) |
|
|
|
Ui::PluginRefreshW ui; |
|
|
|
|
|
|
|
SearchPluginsThread fThread; |
|
|
|
QPixmap fIconYes; |
|
|
|
QPixmap fIconNo; |
|
|
|
|
|
|
|
PrivateData(PluginRefreshW* const refreshDialog, const CarlaHost& host) |
|
|
|
: fThread(refreshDialog, host.pathBinaries), |
|
|
|
fIconYes(":/16x16/dialog-ok-apply.svgz"), |
|
|
|
fIconNo(":/16x16/dialog-error.svgz") |
|
|
|
{ |
|
|
|
ui.setupUi(refreshDialog); |
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------------------ |
|
|
|
// Internal stuff |
|
|
|
|
|
|
|
const bool hasNative = QFileInfo::exists(host.pathBinaries + CARLA_OS_SEP_STR "carla-discovery-native"); |
|
|
|
const bool hasPosix32 = QFileInfo::exists(host.pathBinaries + CARLA_OS_SEP_STR "carla-discovery-posix32"); |
|
|
|
const bool hasPosix64 = QFileInfo::exists(host.pathBinaries + CARLA_OS_SEP_STR "carla-discovery-posix64"); |
|
|
|
const bool hasWin32 = QFileInfo::exists(host.pathBinaries + CARLA_OS_SEP_STR "carla-discovery-win32.exe"); |
|
|
|
const bool hasWin64 = QFileInfo::exists(host.pathBinaries + CARLA_OS_SEP_STR "carla-discovery-win64.exe"); |
|
|
|
} |
|
|
|
|
|
|
|
void loadSettings() |
|
|
|
{ |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
PluginRefreshW::PluginRefreshW(QWidget* parent) |
|
|
|
PluginRefreshW::PluginRefreshW(QWidget* const parent, const CarlaHost& host) |
|
|
|
: QDialog(parent), |
|
|
|
self(new PrivateData(this)) |
|
|
|
self(new PrivateData(this, host)) |
|
|
|
{ |
|
|
|
delete self; |
|
|
|
// ---------------------------------------------------------------------------------------------------------------- |
|
|
|
// Resize to minimum size, as it's very likely UI stuff was hidden |
|
|
|
|
|
|
|
resize(minimumSize()); |
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------- |
|
|
|
// Set-up connections |
|
|
|
|
|
|
|
connect(this, SIGNAL(finished(int)), SLOT(slot_saveSettings())); |
|
|
|
connect(self->ui.b_start, SIGNAL(clicked()), SLOT(slot_start())); |
|
|
|
connect(self->ui.b_skip, SIGNAL(clicked()), SLOT(slot_skip())); |
|
|
|
connect(self->ui.ch_native, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_posix32, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_posix64, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_win32, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_win64, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_ladspa, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_dssi, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_lv2, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_vst, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_vst3, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_au, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_sf2, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(self->ui.ch_sfz, SIGNAL(clicked()), SLOT(slot_checkTools())); |
|
|
|
connect(&self->fThread, SIGNAL(pluginLook(float, QString)), SLOT(slot_handlePluginLook(float, QString))); |
|
|
|
connect(&self->fThread, SIGNAL(finished(int)), SLOT(slot_handlePluginThreadFinished())); |
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------- |
|
|
|
// Post-connect setup |
|
|
|
|
|
|
|
slot_checkTools(); |
|
|
|
} |
|
|
|
|
|
|
|
PluginRefreshW::~PluginRefreshW() |
|
|
|
{ |
|
|
|
delete self; |
|
|
|
} |
|
|
|
|
|
|
|
void PluginRefreshW::getValues(QString& audioDevice, uint& bufferSize, double& sampleRate) |
|
|
@@ -148,9 +292,81 @@ void PluginDatabaseW::slot_saveSettings() |
|
|
|
// -------------------------------------------------------------------------------------------------------------------- |
|
|
|
// Jack Application Dialog |
|
|
|
|
|
|
|
// NOTE: index matches the one in the UI |
|
|
|
enum UiSessionManager { |
|
|
|
UI_SESSION_NONE, |
|
|
|
UI_SESSION_LADISH, |
|
|
|
UI_SESSION_NSM |
|
|
|
}; |
|
|
|
|
|
|
|
struct JackApplicationW::PrivateData { |
|
|
|
PrivateData(void*) |
|
|
|
Ui::Dialog ui; |
|
|
|
|
|
|
|
PrivateData(JackApplicationW* const dialog) |
|
|
|
: ui() |
|
|
|
{ |
|
|
|
ui.setupUi(dialog); |
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------------------ |
|
|
|
// Load settings |
|
|
|
|
|
|
|
loadSettings(); |
|
|
|
} |
|
|
|
|
|
|
|
void checkIfButtonBoxShouldBeEnabled(int index, const QString text) |
|
|
|
{ |
|
|
|
static QList<QChar> badFirstChars = { '.', '/' }; |
|
|
|
|
|
|
|
bool enabled = text.length() > 0; |
|
|
|
|
|
|
|
// NSM applications must not be abstract or absolute paths, and must not contain arguments |
|
|
|
if (enabled && index == UI_SESSION_NSM) |
|
|
|
enabled = ! (badFirstChars.contains(text[0]) || text.contains(' ')); |
|
|
|
|
|
|
|
if (QPushButton* const button = ui.buttonBox->button(QDialogButtonBox::Ok)) |
|
|
|
button->setEnabled(enabled); |
|
|
|
} |
|
|
|
|
|
|
|
void loadSettings() |
|
|
|
{ |
|
|
|
const QSafeSettings settings("falkTX", "CarlaAddJackApp"); |
|
|
|
|
|
|
|
const QString smName = settings.valueString("SessionManager", ""); |
|
|
|
|
|
|
|
if (smName == "LADISH (SIGUSR1)") |
|
|
|
ui.cb_session_mgr->setCurrentIndex(UI_SESSION_LADISH); |
|
|
|
else if (smName == "NSM") |
|
|
|
ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NSM); |
|
|
|
else |
|
|
|
ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NONE); |
|
|
|
|
|
|
|
ui.le_command->setText(settings.valueString("Command", "")); |
|
|
|
ui.le_name->setText(settings.valueString("Name", "")); |
|
|
|
ui.sb_audio_ins->setValue(settings.valueUInt("NumAudioIns", 2)); |
|
|
|
ui.sb_audio_ins->setValue(settings.valueUInt("NumAudioIns", 2)); |
|
|
|
ui.sb_audio_outs->setValue(settings.valueUInt("NumAudioOuts", 2)); |
|
|
|
ui.sb_midi_ins->setValue(settings.valueUInt("NumMidiIns", 0)); |
|
|
|
ui.sb_midi_outs->setValue(settings.valueUInt("NumMidiOuts", 0)); |
|
|
|
ui.cb_manage_window->setChecked(settings.valueBool("ManageWindow", true)); |
|
|
|
ui.cb_capture_first_window->setChecked(settings.valueBool("CaptureFirstWindow", false)); |
|
|
|
ui.cb_out_midi_mixdown->setChecked(settings.valueBool("MidiOutMixdown", false)); |
|
|
|
|
|
|
|
checkIfButtonBoxShouldBeEnabled(ui.cb_session_mgr->currentIndex(), ui.le_command->text()); |
|
|
|
} |
|
|
|
|
|
|
|
void saveSettings() |
|
|
|
{ |
|
|
|
QSafeSettings settings("falkTX", "CarlaAddJackApp"); |
|
|
|
settings.setValue("Command", ui.le_command->text()); |
|
|
|
settings.setValue("Name", ui.le_name->text()); |
|
|
|
settings.setValue("SessionManager", ui.cb_session_mgr->currentText()); |
|
|
|
settings.setValue("NumAudioIns", ui.sb_audio_ins->value()); |
|
|
|
settings.setValue("NumAudioOuts", ui.sb_audio_outs->value()); |
|
|
|
settings.setValue("NumMidiIns", ui.sb_midi_ins->value()); |
|
|
|
settings.setValue("NumMidiOuts", ui.sb_midi_outs->value()); |
|
|
|
settings.setValue("ManageWindow", ui.cb_manage_window->isChecked()); |
|
|
|
settings.setValue("CaptureFirstWindow", ui.cb_capture_first_window->isChecked()); |
|
|
|
settings.setValue("MidiOutMixdown", ui.cb_out_midi_mixdown->isChecked()); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
@@ -158,6 +374,14 @@ JackApplicationW::JackApplicationW(QWidget* parent) |
|
|
|
: QDialog(parent), |
|
|
|
self(new PrivateData(this)) |
|
|
|
{ |
|
|
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); |
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------- |
|
|
|
// Set-up connections |
|
|
|
|
|
|
|
connect(this, SIGNAL(finished(int)), SLOT(slot_saveSettings())); |
|
|
|
connect(self->ui.cb_session_mgr, SIGNAL(currentIndexChanged(int)), SLOT(slot_sessionManagerChanged(int))); |
|
|
|
connect(self->ui.le_command, SIGNAL(textChanged(QString)), SLOT(slot_commandChanged(QString))); |
|
|
|
} |
|
|
|
|
|
|
|
JackApplicationW::~JackApplicationW() |
|
|
@@ -167,18 +391,63 @@ JackApplicationW::~JackApplicationW() |
|
|
|
|
|
|
|
void JackApplicationW::getCommandAndFlags(QString& command, QString& name, QString& labelSetup) |
|
|
|
{ |
|
|
|
name = self->ui.le_name->text(); |
|
|
|
command = self->ui.le_command->text(); |
|
|
|
|
|
|
|
if (name.isEmpty()) |
|
|
|
{ |
|
|
|
name = QFileInfo(command.split(' ').first()).baseName(); |
|
|
|
// FIXME |
|
|
|
name[0] = name[0].toTitleCase(); |
|
|
|
} |
|
|
|
|
|
|
|
SessionManager smgr; |
|
|
|
switch (self->ui.cb_session_mgr->currentIndex()) |
|
|
|
{ |
|
|
|
case UI_SESSION_LADISH: |
|
|
|
smgr = LIBJACK_SESSION_MANAGER_LADISH; |
|
|
|
break; |
|
|
|
case UI_SESSION_NSM: |
|
|
|
smgr = LIBJACK_SESSION_MANAGER_NSM; |
|
|
|
break; |
|
|
|
default: |
|
|
|
smgr = LIBJACK_SESSION_MANAGER_NONE; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
uint flags = 0x0; |
|
|
|
if (self->ui.cb_manage_window->isChecked()) |
|
|
|
flags |= LIBJACK_FLAG_CONTROL_WINDOW; |
|
|
|
if (self->ui.cb_capture_first_window->isChecked()) |
|
|
|
flags |= LIBJACK_FLAG_CAPTURE_FIRST_WINDOW; |
|
|
|
if (self->ui.cb_buffers_addition_mode->isChecked()) |
|
|
|
flags |= LIBJACK_FLAG_AUDIO_BUFFERS_ADDITION; |
|
|
|
if (self->ui.cb_out_midi_mixdown->isChecked()) |
|
|
|
flags |= LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN; |
|
|
|
if (self->ui.cb_external_start->isChecked()) |
|
|
|
flags |= LIBJACK_FLAG_EXTERNAL_START; |
|
|
|
|
|
|
|
labelSetup = QString("%1%2%3%4%5%6").arg(QChar('0' + self->ui.sb_audio_ins->value())) |
|
|
|
.arg(QChar('0' + self->ui.sb_audio_outs->value())) |
|
|
|
.arg(QChar('0' + self->ui.sb_midi_ins->value())) |
|
|
|
.arg(QChar('0' + self->ui.sb_midi_outs->value())) |
|
|
|
.arg(QChar('0' + smgr)) |
|
|
|
.arg(QChar('0' + flags)); |
|
|
|
} |
|
|
|
|
|
|
|
void JackApplicationW::slot_commandChanged(QString text) |
|
|
|
void JackApplicationW::slot_commandChanged(const QString text) |
|
|
|
{ |
|
|
|
self->checkIfButtonBoxShouldBeEnabled(self->ui.cb_session_mgr->currentIndex(), text); |
|
|
|
} |
|
|
|
|
|
|
|
void JackApplicationW::slot_sessionManagerChanged(int index) |
|
|
|
void JackApplicationW::slot_sessionManagerChanged(const int index) |
|
|
|
{ |
|
|
|
self->checkIfButtonBoxShouldBeEnabled(index, self->ui.le_command->text()); |
|
|
|
} |
|
|
|
|
|
|
|
void JackApplicationW::slot_saveSettings() |
|
|
|
{ |
|
|
|
self->saveSettings(); |
|
|
|
} |
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------- |