Signed-off-by: falkTX <falktx@falktx.com>fix-audiofile-buffering
@@ -32,7 +32,6 @@ typedef struct { | |||
} JackAppDialogResults; | |||
typedef struct { | |||
uint API; | |||
uint build; | |||
uint type; | |||
uint hints; | |||
@@ -48,14 +47,10 @@ typedef struct { | |||
uint cvOuts; | |||
uint midiIns; | |||
uint midiOuts; | |||
uint parametersIns; | |||
uint parametersOuts; | |||
uint parameterIns; | |||
uint parameterOuts; | |||
} PluginListDialogResults; | |||
typedef struct { | |||
char todo; | |||
} PluginListRefreshDialogResults; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
CARLA_API void | |||
@@ -67,9 +62,6 @@ carla_frontend_createAndExecJackAppDialog(void* parent, const char* projectFilen | |||
CARLA_API const PluginListDialogResults* | |||
carla_frontend_createAndExecPluginListDialog(void* parent/*, const HostSettings& hostSettings*/); | |||
CARLA_API const PluginListRefreshDialogResults* | |||
carla_frontend_createAndExecPluginListRefreshDialog(void* parent, bool useSystemIcons); | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
#ifdef __cplusplus | |||
@@ -73,8 +73,7 @@ CPP_FILES = \ | |||
carla_frontend.cpp \ | |||
dialogs/aboutjucedialog.cpp \ | |||
dialogs/jackappdialog.cpp \ | |||
pluginlist/pluginlistdialog.cpp \ | |||
pluginlist/pluginlistrefreshdialog.cpp | |||
pluginlist/pluginlistdialog.cpp | |||
OBJS = $(CPP_FILES:%=$(OBJDIR)/%.o) | |||
@@ -139,7 +138,6 @@ UIs = $(DIALOG_UI_FILES:dialogs/%.ui=dialogs/ui_%.h) | |||
UIs += $(PLUGINLIST_UI_FILES:pluginlist/%.ui=pluginlist/ui_%.h) | |||
UIs += $(DIALOG_UI_FILES:%.ui=%_ui.py) | |||
UIs += $(PLUGINLIST_UI_FILES:%.ui=%_ui.py) | |||
# old stuff, not yet converted | |||
UIs += \ | |||
@@ -23,7 +23,7 @@ | |||
# Imports (ctypes) | |||
from ctypes import ( | |||
c_bool, c_char, c_char_p, c_int, c_void_p, cast, | |||
c_bool, c_char, c_char_p, c_uint, c_uint64, c_void_p, cast, | |||
cdll, Structure, | |||
POINTER | |||
) | |||
@@ -55,15 +55,23 @@ class JackApplicationDialogResults(Structure): | |||
class PluginListDialogResults(Structure): | |||
_fields_ = [ | |||
("btype", c_int), | |||
("ptype", c_int), | |||
("binary", c_char_p), | |||
("label", c_char_p) | |||
] | |||
class PluginListRefreshDialogResults(Structure): | |||
_fields_ = [ | |||
("todo", c_char) | |||
("build", c_uint), | |||
("type", c_uint), | |||
("hints", c_uint), | |||
("category", c_char_p), | |||
("filename", c_char_p), | |||
("name", c_char_p), | |||
("label", c_char_p), | |||
("maker", c_char_p), | |||
("uniqueId", c_uint64), | |||
("audioIns", c_uint), | |||
("audioOuts", c_uint), | |||
("cvIns", c_uint), | |||
("cvOuts", c_uint), | |||
("midiIns", c_uint), | |||
("midiOuts", c_uint), | |||
("parametersIns", c_uint), | |||
("parametersOuts", c_uint), | |||
] | |||
# ------------------------------------------------------------------------------------------------------------ | |||
@@ -82,9 +90,6 @@ class CarlaFrontendLib(): | |||
self.lib.carla_frontend_createAndExecPluginListDialog.argtypes = (c_void_p,) # , c_bool) | |||
self.lib.carla_frontend_createAndExecPluginListDialog.restype = POINTER(PluginListDialogResults) | |||
self.lib.carla_frontend_createAndExecPluginListRefreshDialog.argtypes = (c_void_p, c_bool) | |||
self.lib.carla_frontend_createAndExecPluginListRefreshDialog.restype = POINTER(PluginListRefreshDialogResults) | |||
# -------------------------------------------------------------------------------------------------------- | |||
def createAndExecAboutJuceDialog(self, parent): | |||
@@ -97,8 +102,4 @@ class CarlaFrontendLib(): | |||
def createAndExecPluginListDialog(self, parent, useSystemIcons): | |||
return structToDictOrNull(self.lib.carla_frontend_createAndExecPluginListDialog(unwrapinstance(parent))) | |||
def createAndExecPluginListRefreshDialog(self, parent, useSystemIcons): | |||
return structToDictOrNull(self.lib.carla_frontend_createAndExecPluginListRefreshDialog(unwrapinstance(parent), | |||
useSystemIcons)) | |||
# ------------------------------------------------------------------------------------------------------------ |
@@ -62,7 +62,6 @@ from carla_utils import * | |||
from carla_widgets import * | |||
from patchcanvas import patchcanvas | |||
from pluginlist import PluginListDialog | |||
from widgets.digitalpeakmeter import DigitalPeakMeter | |||
from widgets.pixmapkeyboard import PixmapKeyboardHArea | |||
@@ -1208,25 +1207,14 @@ class HostWindow(QMainWindow): | |||
# Plugins (menu actions) | |||
def showAddPluginDialog(self): | |||
#ret = gCarla.felib.createAndExecPluginListDialog(self.fParentOrSelf, | |||
#self.fSavedSettings[CARLA_KEY_MAIN_SYSTEM_ICONS]) | |||
#print(ret) | |||
#return | |||
#ret = gCarla.felib.createAndExecPluginListRefreshDialog(self.fParentOrSelf, | |||
#self.fSavedSettings[CARLA_KEY_MAIN_SYSTEM_ICONS]) | |||
#print(ret) | |||
#return | |||
if self.fPluginDatabaseDialog is None: | |||
self.fPluginDatabaseDialog = PluginListDialog(self.fParentOrSelf, self.host, | |||
self.fSavedSettings[CARLA_KEY_MAIN_SYSTEM_ICONS]) | |||
dialog = self.fPluginDatabaseDialog | |||
dialog.hasLoadedLv2Plugins = self.fHasLoadedLv2Plugins | |||
ret = dialog.exec_() | |||
if dialog.fFavoritePluginsChanged: | |||
self.fFavoritePlugins = dialog.fFavoritePlugins | |||
# TODO self.fHasLoadedLv2Plugins | |||
ret = gCarla.felib.createAndExecPluginListDialog(self.fParentOrSelf, | |||
self.fSavedSettings[CARLA_KEY_MAIN_SYSTEM_ICONS]) | |||
print(ret) | |||
# TODO | |||
#if dialog.fFavoritePluginsChanged: | |||
#self.fFavoritePlugins = dialog.fFavoritePlugins | |||
if not ret: | |||
return | |||
@@ -1235,12 +1223,12 @@ class HostWindow(QMainWindow): | |||
QMessageBox.warning(self, self.tr("Warning"), self.tr("Cannot add new plugins while engine is stopped")) | |||
return | |||
btype = dialog.fRetPlugin['build'] | |||
ptype = dialog.fRetPlugin['type'] | |||
filename = dialog.fRetPlugin['filename'] | |||
label = dialog.fRetPlugin['label'] | |||
uniqueId = dialog.fRetPlugin['uniqueId'] | |||
extraPtr = self.getExtraPtr(dialog.fRetPlugin) | |||
btype = ret['build'] | |||
ptype = ret['type'] | |||
filename = ret['filename'] | |||
label = ret['label'] | |||
uniqueId = ret['uniqueId'] | |||
extraPtr = None | |||
return (btype, ptype, filename, label, uniqueId, extraPtr) | |||
@@ -1,19 +0,0 @@ | |||
#!/usr/bin/env python3 | |||
# -*- coding: utf-8 -*- | |||
# Carla plugin host | |||
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
# | |||
# 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 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. | |||
# | |||
# For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
from .pluginlistdialog import PluginListDialog |
@@ -1,411 +0,0 @@ | |||
#!/usr/bin/env python3 | |||
# -*- coding: utf-8 -*- | |||
# Carla plugin list code | |||
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
# | |||
# 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 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. | |||
# | |||
# For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Imports (Global) | |||
import os | |||
from copy import deepcopy | |||
from subprocess import Popen, PIPE | |||
from PyQt5.QtCore import qWarning | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Imports (Carla) | |||
from carla_backend import ( | |||
BINARY_NATIVE, | |||
BINARY_NONE, | |||
PLUGIN_AU, | |||
PLUGIN_DSSI, | |||
PLUGIN_LADSPA, | |||
PLUGIN_LV2, | |||
PLUGIN_NONE, | |||
PLUGIN_SF2, | |||
PLUGIN_SFZ, | |||
PLUGIN_VST2, | |||
PLUGIN_VST3, | |||
PLUGIN_CLAP, | |||
) | |||
from carla_shared import ( | |||
LINUX, | |||
MACOS, | |||
WINDOWS, | |||
) | |||
from carla_utils import getPluginCategoryAsString | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Plugin Query (helper functions) | |||
def findBinaries(binPath, pluginType, OS): | |||
binaries = [] | |||
if OS == "HAIKU": | |||
extensions = ("") if pluginType == PLUGIN_VST2 else (".so",) | |||
elif OS == "MACOS": | |||
extensions = (".dylib", ".so") | |||
elif OS == "WINDOWS": | |||
extensions = (".dll",) | |||
else: | |||
extensions = (".so",) | |||
for root, _, files in os.walk(binPath): | |||
for name in tuple(name for name in files if name.lower().endswith(extensions)): | |||
binaries.append(os.path.join(root, name)) | |||
return binaries | |||
def findVST3Binaries(binPath): | |||
binaries = [] | |||
for root, dirs, files in os.walk(binPath): | |||
for name in tuple(name for name in (files+dirs) if name.lower().endswith(".vst3")): | |||
binaries.append(os.path.join(root, name)) | |||
return binaries | |||
def findCLAPBinaries(binPath): | |||
binaries = [] | |||
for root, _, files in os.walk(binPath, followlinks=True): | |||
for name in tuple(name for name in files if name.lower().endswith(".clap")): | |||
binaries.append(os.path.join(root, name)) | |||
return binaries | |||
def findLV2Bundles(bundlePath): | |||
bundles = [] | |||
for root, _, _2 in os.walk(bundlePath, followlinks=True): | |||
if root == bundlePath: | |||
continue | |||
if os.path.exists(os.path.join(root, "manifest.ttl")): | |||
bundles.append(root) | |||
return bundles | |||
def findMacBundles(bundlePath, pluginType): | |||
bundles = [] | |||
if pluginType == PLUGIN_VST2: | |||
extension = ".vst" | |||
elif pluginType == PLUGIN_VST3: | |||
extension = ".vst3" | |||
elif pluginType == PLUGIN_CLAP: | |||
extension = ".clap" | |||
else: | |||
return bundles | |||
for root, dirs, _ in os.walk(bundlePath, followlinks=True): | |||
for name in tuple(name for name in dirs if name.lower().endswith(extension)): | |||
bundles.append(os.path.join(root, name)) | |||
return bundles | |||
def findFilenames(filePath, stype): | |||
filenames = [] | |||
if stype == "sf2": | |||
extensions = (".sf2",".sf3",) | |||
else: | |||
return [] | |||
for root, _, files in os.walk(filePath): | |||
for name in tuple(name for name in files if name.lower().endswith(extensions)): | |||
filenames.append(os.path.join(root, name)) | |||
return filenames | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Plugin Query | |||
# NOTE: this code is ugly, it is meant to be replaced, so let it be as-is for now | |||
PLUGIN_QUERY_API_VERSION = 12 | |||
PyPluginInfo = { | |||
'API': PLUGIN_QUERY_API_VERSION, | |||
'valid': False, | |||
'build': BINARY_NONE, | |||
'type': PLUGIN_NONE, | |||
'hints': 0x0, | |||
'category': "", | |||
'filename': "", | |||
'name': "", | |||
'label': "", | |||
'maker': "", | |||
'uniqueId': 0, | |||
'audio.ins': 0, | |||
'audio.outs': 0, | |||
'cv.ins': 0, | |||
'cv.outs': 0, | |||
'midi.ins': 0, | |||
'midi.outs': 0, | |||
'parameters.ins': 0, | |||
'parameters.outs': 0 | |||
} | |||
gDiscoveryProcess = None | |||
def findWinePrefix(filename, recursionLimit = 10): | |||
if recursionLimit == 0 or len(filename) < 5 or "/" not in filename: | |||
return "" | |||
path = filename[:filename.rfind("/")] | |||
if os.path.isdir(path + "/dosdevices"): | |||
return path | |||
return findWinePrefix(path, recursionLimit-1) | |||
def runCarlaDiscovery(itype, stype, filename, tool, wineSettings=None): | |||
if not os.path.exists(tool): | |||
qWarning(f"runCarlaDiscovery() - tool '{tool}' does not exist") | |||
return [] | |||
command = [] | |||
if LINUX or MACOS: | |||
command.append("env") | |||
command.append("LANG=C") | |||
command.append("LD_PRELOAD=") | |||
if wineSettings is not None: | |||
command.append("WINEDEBUG=-all") | |||
if wineSettings['autoPrefix']: | |||
winePrefix = findWinePrefix(filename) | |||
else: | |||
winePrefix = "" | |||
if not winePrefix: | |||
envWinePrefix = os.getenv("WINEPREFIX") | |||
if envWinePrefix: | |||
winePrefix = envWinePrefix | |||
elif wineSettings['fallbackPrefix']: | |||
winePrefix = os.path.expanduser(wineSettings['fallbackPrefix']) | |||
else: | |||
winePrefix = os.path.expanduser("~/.wine") | |||
wineCMD = wineSettings['executable'] if wineSettings['executable'] else "wine" | |||
if tool.endswith("64.exe") and os.path.exists(wineCMD + "64"): | |||
wineCMD += "64" | |||
command.append("WINEPREFIX=" + winePrefix) | |||
command.append(wineCMD) | |||
command.append(tool) | |||
command.append(stype) | |||
command.append(filename) | |||
# pylint: disable=global-statement | |||
global gDiscoveryProcess | |||
# pylint: enable=global-statement | |||
# pylint: disable=consider-using-with | |||
gDiscoveryProcess = Popen(command, stdout=PIPE) | |||
# pylint: enable=consider-using-with | |||
pinfo = None | |||
plugins = [] | |||
fakeLabel = os.path.basename(filename).rsplit(".", 1)[0] | |||
while True: | |||
try: | |||
line = gDiscoveryProcess.stdout.readline().decode("utf-8", errors="ignore") | |||
except: | |||
print("ERROR: discovery readline failed") | |||
break | |||
# line is valid, strip it | |||
if line: | |||
line = line.strip() | |||
# line is invalid, try poll() again | |||
elif gDiscoveryProcess.poll() is None: | |||
continue | |||
# line is invalid and poll() failed, stop here | |||
else: | |||
break | |||
if line == "carla-discovery::init::------------": | |||
pinfo = deepcopy(PyPluginInfo) | |||
pinfo['type'] = itype | |||
pinfo['filename'] = filename if filename != ":all" else "" | |||
elif line == "carla-discovery::end::------------": | |||
if pinfo is not None: | |||
plugins.append(pinfo) | |||
del pinfo | |||
pinfo = None | |||
elif line == "Segmentation fault": | |||
print(f"carla-discovery::crash::{filename} crashed during discovery") | |||
elif line.startswith("err:module:import_dll Library"): | |||
print(line) | |||
elif line.startswith("carla-discovery::info::"): | |||
print(f"{line} - {filename}") | |||
elif line.startswith("carla-discovery::warning::"): | |||
print(f"{line} - {filename}") | |||
elif line.startswith("carla-discovery::error::"): | |||
print(f"{line} - {filename}") | |||
elif line.startswith("carla-discovery::"): | |||
if pinfo is None: | |||
continue | |||
try: | |||
prop, value = line.replace("carla-discovery::", "").split("::", 1) | |||
except: | |||
continue | |||
# pylint: disable=unsupported-assignment-operation | |||
if prop == "build": | |||
if value.isdigit(): | |||
pinfo['build'] = int(value) | |||
elif prop == "name": | |||
pinfo['name'] = value if value else fakeLabel | |||
elif prop == "label": | |||
pinfo['label'] = value if value else fakeLabel | |||
elif prop == "filename": | |||
pinfo['filename'] = value | |||
elif prop == "maker": | |||
pinfo['maker'] = value | |||
elif prop == "category": | |||
pinfo['category'] = value | |||
elif prop == "uniqueId": | |||
if value.isdigit(): | |||
pinfo['uniqueId'] = int(value) | |||
elif prop == "hints": | |||
if value.isdigit(): | |||
pinfo['hints'] = int(value) | |||
elif prop == "audio.ins": | |||
if value.isdigit(): | |||
pinfo['audio.ins'] = int(value) | |||
elif prop == "audio.outs": | |||
if value.isdigit(): | |||
pinfo['audio.outs'] = int(value) | |||
elif prop == "cv.ins": | |||
if value.isdigit(): | |||
pinfo['cv.ins'] = int(value) | |||
elif prop == "cv.outs": | |||
if value.isdigit(): | |||
pinfo['cv.outs'] = int(value) | |||
elif prop == "midi.ins": | |||
if value.isdigit(): | |||
pinfo['midi.ins'] = int(value) | |||
elif prop == "midi.outs": | |||
if value.isdigit(): | |||
pinfo['midi.outs'] = int(value) | |||
elif prop == "parameters.ins": | |||
if value.isdigit(): | |||
pinfo['parameters.ins'] = int(value) | |||
elif prop == "parameters.outs": | |||
if value.isdigit(): | |||
pinfo['parameters.outs'] = int(value) | |||
elif prop == "uri": | |||
if value: | |||
pinfo['label'] = value | |||
else: | |||
# cannot use empty URIs | |||
del pinfo | |||
pinfo = None | |||
continue | |||
else: | |||
print(f"{line} - {filename} (unknown property)") | |||
# pylint: enable=unsupported-assignment-operation | |||
tmp = gDiscoveryProcess | |||
gDiscoveryProcess = None | |||
del tmp | |||
return plugins | |||
def killDiscovery(): | |||
# pylint: disable=global-variable-not-assigned | |||
global gDiscoveryProcess | |||
# pylint: enable=global-variable-not-assigned | |||
if gDiscoveryProcess is not None: | |||
gDiscoveryProcess.kill() | |||
def checkPluginCached(desc, ptype): | |||
pinfo = deepcopy(PyPluginInfo) | |||
pinfo['build'] = BINARY_NATIVE | |||
pinfo['type'] = ptype | |||
pinfo['hints'] = desc['hints'] | |||
pinfo['name'] = desc['name'] | |||
pinfo['label'] = desc['label'] | |||
pinfo['maker'] = desc['maker'] | |||
pinfo['category'] = getPluginCategoryAsString(desc['category']) | |||
pinfo['audio.ins'] = desc['audioIns'] | |||
pinfo['audio.outs'] = desc['audioOuts'] | |||
pinfo['cv.ins'] = desc['cvIns'] | |||
pinfo['cv.outs'] = desc['cvOuts'] | |||
pinfo['midi.ins'] = desc['midiIns'] | |||
pinfo['midi.outs'] = desc['midiOuts'] | |||
pinfo['parameters.ins'] = desc['parameterIns'] | |||
pinfo['parameters.outs'] = desc['parameterOuts'] | |||
if ptype == PLUGIN_LV2: | |||
pinfo['filename'], pinfo['label'] = pinfo['label'].split('\\' if WINDOWS else '/',1) | |||
elif ptype == PLUGIN_SFZ: | |||
pinfo['filename'] = pinfo['label'] | |||
pinfo['label'] = pinfo['name'] | |||
return pinfo | |||
def checkPluginLADSPA(filename, tool, wineSettings=None): | |||
return runCarlaDiscovery(PLUGIN_LADSPA, "LADSPA", filename, tool, wineSettings) | |||
def checkPluginDSSI(filename, tool, wineSettings=None): | |||
return runCarlaDiscovery(PLUGIN_DSSI, "DSSI", filename, tool, wineSettings) | |||
def checkPluginLV2(filename, tool, wineSettings=None): | |||
return runCarlaDiscovery(PLUGIN_LV2, "LV2", filename, tool, wineSettings) | |||
def checkPluginVST2(filename, tool, wineSettings=None): | |||
return runCarlaDiscovery(PLUGIN_VST2, "VST2", filename, tool, wineSettings) | |||
def checkPluginVST3(filename, tool, wineSettings=None): | |||
return runCarlaDiscovery(PLUGIN_VST3, "VST3", filename, tool, wineSettings) | |||
def checkPluginCLAP(filename, tool, wineSettings=None): | |||
return runCarlaDiscovery(PLUGIN_CLAP, "CLAP", filename, tool, wineSettings) | |||
def checkFileSF2(filename, tool): | |||
return runCarlaDiscovery(PLUGIN_SF2, "SF2", filename, tool) | |||
def checkFileSFZ(filename, tool): | |||
return runCarlaDiscovery(PLUGIN_SFZ, "SFZ", filename, tool) | |||
def checkAllPluginsAU(tool): | |||
return runCarlaDiscovery(PLUGIN_AU, "AU", ":all", tool) |
@@ -1,851 +0,0 @@ | |||
#!/usr/bin/env python3 | |||
# -*- coding: utf-8 -*- | |||
# Carla plugin host | |||
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
# | |||
# 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 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. | |||
# | |||
# For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Imports (Global) | |||
import os | |||
from PyQt5.QtCore import pyqtSignal, QThread | |||
from PyQt5.QtWidgets import QWidget | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Imports (Custom) | |||
from carla_backend import ( | |||
PLUGIN_AU, | |||
PLUGIN_DSSI, | |||
PLUGIN_JSFX, | |||
PLUGIN_LADSPA, | |||
PLUGIN_LV2, | |||
PLUGIN_SFZ, | |||
PLUGIN_VST2, | |||
PLUGIN_VST3, | |||
PLUGIN_CLAP, | |||
) | |||
from carla_shared import ( | |||
CARLA_DEFAULT_DSSI_PATH, | |||
CARLA_DEFAULT_JSFX_PATH, | |||
CARLA_DEFAULT_LADSPA_PATH, | |||
CARLA_DEFAULT_LV2_PATH, | |||
CARLA_DEFAULT_SF2_PATH, | |||
CARLA_DEFAULT_SFZ_PATH, | |||
CARLA_DEFAULT_VST2_PATH, | |||
CARLA_DEFAULT_VST3_PATH, | |||
CARLA_DEFAULT_CLAP_PATH, | |||
CARLA_DEFAULT_WINE_AUTO_PREFIX, | |||
CARLA_DEFAULT_WINE_EXECUTABLE, | |||
CARLA_DEFAULT_WINE_FALLBACK_PREFIX, | |||
CARLA_KEY_PATHS_DSSI, | |||
CARLA_KEY_PATHS_JSFX, | |||
CARLA_KEY_PATHS_LADSPA, | |||
CARLA_KEY_PATHS_LV2, | |||
CARLA_KEY_PATHS_SF2, | |||
CARLA_KEY_PATHS_SFZ, | |||
CARLA_KEY_PATHS_VST2, | |||
CARLA_KEY_PATHS_VST3, | |||
CARLA_KEY_PATHS_CLAP, | |||
CARLA_KEY_WINE_AUTO_PREFIX, | |||
CARLA_KEY_WINE_EXECUTABLE, | |||
CARLA_KEY_WINE_FALLBACK_PREFIX, | |||
HAIKU, | |||
LINUX, | |||
MACOS, | |||
WINDOWS, | |||
gCarla, | |||
splitter, | |||
) | |||
from utils import QSafeSettings | |||
from .discovery import ( | |||
checkAllPluginsAU, | |||
checkFileSF2, | |||
checkPluginCached, | |||
checkPluginDSSI, | |||
checkPluginLADSPA, | |||
checkPluginVST2, | |||
checkPluginVST3, | |||
checkPluginCLAP, | |||
findBinaries, | |||
findFilenames, | |||
findMacBundles, | |||
findVST3Binaries, | |||
findCLAPBinaries | |||
) | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Separate Thread for Plugin Search | |||
class SearchPluginsThread(QThread): | |||
pluginLook = pyqtSignal(float, str) | |||
def __init__(self, parent: QWidget, pathBinaries: str): | |||
QThread.__init__(self, parent) | |||
self.fContinueChecking = False | |||
self.fPathBinaries = pathBinaries | |||
self.fCheckNative = False | |||
self.fCheckPosix32 = False | |||
self.fCheckPosix64 = False | |||
self.fCheckWin32 = False | |||
self.fCheckWin64 = False | |||
self.fCheckLADSPA = False | |||
self.fCheckDSSI = False | |||
self.fCheckLV2 = False | |||
self.fCheckVST2 = False | |||
self.fCheckVST3 = False | |||
self.fCheckCLAP = False | |||
self.fCheckAU = False | |||
self.fCheckSF2 = False | |||
self.fCheckSFZ = False | |||
self.fCheckJSFX = False | |||
if WINDOWS: | |||
toolNative = "carla-discovery-native.exe" | |||
self.fWineSettings = None | |||
else: | |||
toolNative = "carla-discovery-native" | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
self.fWineSettings = { | |||
'executable' : settings.value(CARLA_KEY_WINE_EXECUTABLE, | |||
CARLA_DEFAULT_WINE_EXECUTABLE, str), | |||
'autoPrefix' : settings.value(CARLA_KEY_WINE_AUTO_PREFIX, | |||
CARLA_DEFAULT_WINE_AUTO_PREFIX, bool), | |||
'fallbackPrefix': settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX, | |||
CARLA_DEFAULT_WINE_FALLBACK_PREFIX, str), | |||
} | |||
del settings | |||
self.fToolNative = os.path.join(pathBinaries, toolNative) | |||
if not os.path.exists(self.fToolNative): | |||
self.fToolNative = "" | |||
self.fCurCount = 0 | |||
self.fCurPercentValue = 0 | |||
self.fLastCheckValue = 0 | |||
self.fSomethingChanged = False | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
# public methods | |||
def hasSomethingChanged(self): | |||
return self.fSomethingChanged | |||
def setSearchBinaryTypes(self, native: bool, posix32: bool, posix64: bool, win32: bool, win64: bool): | |||
self.fCheckNative = native | |||
self.fCheckPosix32 = posix32 | |||
self.fCheckPosix64 = posix64 | |||
self.fCheckWin32 = win32 | |||
self.fCheckWin64 = win64 | |||
def setSearchPluginTypes(self, ladspa: bool, dssi: bool, lv2: bool, vst2: bool, vst3: bool, clap: bool, | |||
au: bool, sf2: bool, sfz: bool, jsfx: bool): | |||
self.fCheckLADSPA = ladspa | |||
self.fCheckDSSI = dssi | |||
self.fCheckLV2 = lv2 | |||
self.fCheckVST2 = vst2 | |||
self.fCheckVST3 = vst3 | |||
self.fCheckCLAP = clap | |||
self.fCheckAU = au and MACOS | |||
self.fCheckSF2 = sf2 | |||
self.fCheckSFZ = sfz | |||
self.fCheckJSFX = jsfx | |||
def stop(self): | |||
self.fContinueChecking = False | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
# protected reimplemented methods | |||
def run(self): | |||
settingsDB = QSafeSettings("falkTX", "CarlaPlugins5") | |||
self.fContinueChecking = True | |||
self.fCurCount = 0 | |||
if self.fCheckNative and not self.fToolNative: | |||
self.fCheckNative = False | |||
# looking for plugins via external discovery | |||
pluginCount = 0 | |||
if self.fCheckLADSPA: | |||
pluginCount += 1 | |||
if self.fCheckDSSI: | |||
pluginCount += 1 | |||
if self.fCheckVST2: | |||
pluginCount += 1 | |||
if self.fCheckVST3: | |||
pluginCount += 1 | |||
if self.fCheckCLAP: | |||
pluginCount += 1 | |||
# Increase count by the number of externally discoverable plugin types | |||
if self.fCheckNative: | |||
self.fCurCount += pluginCount | |||
if self.fCheckPosix32: | |||
self.fCurCount += pluginCount | |||
if self.fCheckPosix64: | |||
self.fCurCount += pluginCount | |||
if self.fCheckWin32: | |||
self.fCurCount += pluginCount | |||
if self.fCheckWin64: | |||
self.fCurCount += pluginCount | |||
if self.fCheckLV2: | |||
if self.fCheckNative: | |||
self.fCurCount += 1 | |||
else: | |||
self.fCheckLV2 = False | |||
if self.fCheckAU: | |||
if self.fCheckNative or self.fCheckPosix32: | |||
self.fCurCount += int(self.fCheckNative) + int(self.fCheckPosix32) | |||
else: | |||
self.fCheckAU = False | |||
if self.fCheckSF2: | |||
if self.fCheckNative: | |||
self.fCurCount += 1 | |||
else: | |||
self.fCheckSF2 = False | |||
if self.fCheckSFZ: | |||
if self.fCheckNative: | |||
self.fCurCount += 1 | |||
else: | |||
self.fCheckSFZ = False | |||
if self.fCheckJSFX: | |||
if self.fCheckNative: | |||
self.fCurCount += 1 | |||
else: | |||
self.fCheckJSFX = False | |||
if self.fCurCount == 0: | |||
return | |||
self.fCurPercentValue = 100.0 / self.fCurCount | |||
self.fLastCheckValue = 0.0 | |||
del pluginCount | |||
if HAIKU: | |||
OS = "HAIKU" | |||
elif LINUX: | |||
OS = "LINUX" | |||
elif MACOS: | |||
OS = "MACOS" | |||
elif WINDOWS: | |||
OS = "WINDOWS" | |||
else: | |||
OS = "UNKNOWN" | |||
if not self.fContinueChecking: | |||
return | |||
self.fSomethingChanged = True | |||
if self.fCheckLADSPA: | |||
if self.fCheckNative: | |||
plugins = self._checkLADSPA(OS, self.fToolNative) | |||
settingsDB.setValue("Plugins/LADSPA_native", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix32: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-posix32") | |||
plugins = self._checkLADSPA(OS, tool) | |||
settingsDB.setValue("Plugins/LADSPA_posix32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix64: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-posix64") | |||
plugins = self._checkLADSPA(OS, tool) | |||
settingsDB.setValue("Plugins/LADSPA_posix64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin32: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe") | |||
plugins = self._checkLADSPA("WINDOWS", tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/LADSPA_win32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin64: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe") | |||
plugins = self._checkLADSPA("WINDOWS", tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/LADSPA_win64", plugins) | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckDSSI: | |||
if self.fCheckNative: | |||
plugins = self._checkDSSI(OS, self.fToolNative) | |||
settingsDB.setValue("Plugins/DSSI_native", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix32: | |||
plugins = self._checkDSSI(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32")) | |||
settingsDB.setValue("Plugins/DSSI_posix32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix64: | |||
plugins = self._checkDSSI(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64")) | |||
settingsDB.setValue("Plugins/DSSI_posix64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin32: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe") | |||
plugins = self._checkDSSI("WINDOWS", tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/DSSI_win32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin64: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe") | |||
plugins = self._checkDSSI("WINDOWS", tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/DSSI_win64", plugins) | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckLV2: | |||
plugins = self._checkCached(True) | |||
settingsDB.setValue("Plugins/LV2", plugins) | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckVST2: | |||
if self.fCheckNative: | |||
plugins = self._checkVST2(OS, self.fToolNative) | |||
settingsDB.setValue("Plugins/VST2_native", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix32: | |||
plugins = self._checkVST2(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix32")) | |||
settingsDB.setValue("Plugins/VST2_posix32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix64: | |||
plugins = self._checkVST2(OS, os.path.join(self.fPathBinaries, "carla-discovery-posix64")) | |||
settingsDB.setValue("Plugins/VST2_posix64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin32: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe") | |||
plugins = self._checkVST2("WINDOWS", tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/VST2_win32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin64: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe") | |||
plugins = self._checkVST2("WINDOWS", tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/VST2_win64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckVST3: | |||
if self.fCheckNative and (LINUX or MACOS or WINDOWS): | |||
plugins = self._checkVST3(self.fToolNative) | |||
settingsDB.setValue("Plugins/VST3_native", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix32: | |||
plugins = self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-posix32")) | |||
settingsDB.setValue("Plugins/VST3_posix32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix64: | |||
plugins = self._checkVST3(os.path.join(self.fPathBinaries, "carla-discovery-posix64")) | |||
settingsDB.setValue("Plugins/VST3_posix64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin32: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe") | |||
plugins = self._checkVST3(tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/VST3_win32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin64: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe") | |||
plugins = self._checkVST3(tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/VST3_win64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckCLAP: | |||
if self.fCheckNative: | |||
plugins = self._checkCLAP(self.fToolNative) | |||
settingsDB.setValue("Plugins/CLAP_native", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix32: | |||
plugins = self._checkCLAP(os.path.join(self.fPathBinaries, "carla-discovery-posix32")) | |||
settingsDB.setValue("Plugins/CLAP_posix32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix64: | |||
plugins = self._checkCLAP(os.path.join(self.fPathBinaries, "carla-discovery-posix64")) | |||
settingsDB.setValue("Plugins/CLAP_posix64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin32: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win32.exe") | |||
plugins = self._checkCLAP(tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/CLAP_win32", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckWin64: | |||
tool = os.path.join(self.fPathBinaries, "carla-discovery-win64.exe") | |||
plugins = self._checkCLAP(tool, not WINDOWS) | |||
settingsDB.setValue("Plugins/CLAP_win64", plugins) | |||
if not self.fContinueChecking: | |||
return | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckAU: | |||
if self.fCheckNative: | |||
plugins = self._checkCached(False) | |||
settingsDB.setValue("Plugins/AU", plugins) | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckPosix32: | |||
plugins = self._checkAU(os.path.join(self.fPathBinaries, "carla-discovery-posix32")) | |||
settingsDB.setValue("Plugins/AU_posix32", self.fAuPlugins) | |||
if not self.fContinueChecking: | |||
return | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckSF2: | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
SF2_PATH = settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list) | |||
del settings | |||
kits = self._checkKIT(SF2_PATH, "sf2") | |||
settingsDB.setValue("Plugins/SF2", kits) | |||
settingsDB.sync() | |||
if not self.fContinueChecking: | |||
return | |||
if self.fCheckSFZ: | |||
kits = self._checkSfzCached() | |||
settingsDB.setValue("Plugins/SFZ", kits) | |||
settingsDB.sync() | |||
if self.fCheckJSFX: | |||
kits = self._checkJsfxCached() | |||
settingsDB.setValue("Plugins/JSFX", kits) | |||
settingsDB.sync() | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
# private methods | |||
def _checkLADSPA(self, OS, tool, isWine=False): | |||
ladspaBinaries = [] | |||
ladspaPlugins = [] | |||
self._pluginLook(self.fLastCheckValue, "LADSPA plugins...") | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
LADSPA_PATH = settings.value(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH, list) | |||
del settings | |||
for iPATH in LADSPA_PATH: | |||
binaries = findBinaries(iPATH, PLUGIN_LADSPA, OS) | |||
for binary in binaries: | |||
if binary not in ladspaBinaries: | |||
ladspaBinaries.append(binary) | |||
ladspaBinaries.sort() | |||
if not self.fContinueChecking: | |||
return ladspaPlugins | |||
for i in range(len(ladspaBinaries)): | |||
ladspa = ladspaBinaries[i] | |||
percent = ( float(i) / len(ladspaBinaries) ) * self.fCurPercentValue | |||
self._pluginLook((self.fLastCheckValue + percent) * 0.9, ladspa) | |||
plugins = checkPluginLADSPA(ladspa, tool, self.fWineSettings if isWine else None) | |||
if plugins: | |||
ladspaPlugins.append(plugins) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return ladspaPlugins | |||
def _checkDSSI(self, OS, tool, isWine=False): | |||
dssiBinaries = [] | |||
dssiPlugins = [] | |||
self._pluginLook(self.fLastCheckValue, "DSSI plugins...") | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
DSSI_PATH = settings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH, list) | |||
del settings | |||
for iPATH in DSSI_PATH: | |||
binaries = findBinaries(iPATH, PLUGIN_DSSI, OS) | |||
for binary in binaries: | |||
if binary not in dssiBinaries: | |||
dssiBinaries.append(binary) | |||
dssiBinaries.sort() | |||
if not self.fContinueChecking: | |||
return dssiPlugins | |||
for i in range(len(dssiBinaries)): | |||
dssi = dssiBinaries[i] | |||
percent = ( float(i) / len(dssiBinaries) ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, dssi) | |||
plugins = checkPluginDSSI(dssi, tool, self.fWineSettings if isWine else None) | |||
if plugins: | |||
dssiPlugins.append(plugins) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return dssiPlugins | |||
def _checkVST2(self, OS, tool, isWine=False): | |||
vst2Binaries = [] | |||
vst2Plugins = [] | |||
if MACOS and not isWine: | |||
self._pluginLook(self.fLastCheckValue, "VST2 bundles...") | |||
else: | |||
self._pluginLook(self.fLastCheckValue, "VST2 plugins...") | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
VST2_PATH = settings.value(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH, list) | |||
del settings | |||
for iPATH in VST2_PATH: | |||
if MACOS and not isWine: | |||
binaries = findMacBundles(iPATH, PLUGIN_VST2) | |||
else: | |||
binaries = findBinaries(iPATH, PLUGIN_VST2, OS) | |||
for binary in binaries: | |||
if binary not in vst2Binaries: | |||
vst2Binaries.append(binary) | |||
vst2Binaries.sort() | |||
if not self.fContinueChecking: | |||
return vst2Plugins | |||
for i in range(len(vst2Binaries)): | |||
vst2 = vst2Binaries[i] | |||
percent = ( float(i) / len(vst2Binaries) ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, vst2) | |||
plugins = checkPluginVST2(vst2, tool, self.fWineSettings if isWine else None) | |||
if plugins: | |||
vst2Plugins.append(plugins) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return vst2Plugins | |||
def _checkVST3(self, tool, isWine=False): | |||
vst3Binaries = [] | |||
vst3Plugins = [] | |||
if MACOS and not isWine: | |||
self._pluginLook(self.fLastCheckValue, "VST3 bundles...") | |||
else: | |||
self._pluginLook(self.fLastCheckValue, "VST3 plugins...") | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
VST3_PATH = settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list) | |||
del settings | |||
for iPATH in VST3_PATH: | |||
if MACOS and not isWine: | |||
binaries = findMacBundles(iPATH, PLUGIN_VST3) | |||
else: | |||
binaries = findVST3Binaries(iPATH) | |||
for binary in binaries: | |||
if binary not in vst3Binaries: | |||
vst3Binaries.append(binary) | |||
vst3Binaries.sort() | |||
if not self.fContinueChecking: | |||
return vst3Plugins | |||
for i in range(len(vst3Binaries)): | |||
vst3 = vst3Binaries[i] | |||
percent = ( float(i) / len(vst3Binaries) ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, vst3) | |||
plugins = checkPluginVST3(vst3, tool, self.fWineSettings if isWine else None) | |||
if plugins: | |||
vst3Plugins.append(plugins) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return vst3Plugins | |||
def _checkCLAP(self, tool, isWine=False): | |||
clapBinaries = [] | |||
clapPlugins = [] | |||
self._pluginLook(self.fLastCheckValue, "CLAP plugins...") | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
CLAP_PATH = settings.value(CARLA_KEY_PATHS_CLAP, CARLA_DEFAULT_CLAP_PATH, list) | |||
del settings | |||
for iPATH in CLAP_PATH: | |||
if MACOS and not isWine: | |||
binaries = findMacBundles(iPATH, PLUGIN_CLAP) | |||
else: | |||
binaries = findCLAPBinaries(iPATH) | |||
for binary in binaries: | |||
if binary not in clapBinaries: | |||
clapBinaries.append(binary) | |||
clapBinaries.sort() | |||
if not self.fContinueChecking: | |||
return clapPlugins | |||
for i in range(len(clapBinaries)): | |||
clap = clapBinaries[i] | |||
percent = ( float(i) / len(clapBinaries) ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, clap) | |||
plugins = checkPluginCLAP(clap, tool, self.fWineSettings if isWine else None) | |||
if plugins: | |||
clapPlugins.append(plugins) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return clapPlugins | |||
def _checkAU(self, tool): | |||
auPlugins = [] | |||
plugins = checkAllPluginsAU(tool) | |||
if plugins: | |||
auPlugins.append(plugins) | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return auPlugins | |||
def _checkKIT(self, kitPATH, kitExtension): | |||
kitFiles = [] | |||
kitPlugins = [] | |||
for iPATH in kitPATH: | |||
files = findFilenames(iPATH, kitExtension) | |||
for file_ in files: | |||
if file_ not in kitFiles: | |||
kitFiles.append(file_) | |||
kitFiles.sort() | |||
if not self.fContinueChecking: | |||
return kitPlugins | |||
for i in range(len(kitFiles)): | |||
kit = kitFiles[i] | |||
percent = ( float(i) / len(kitFiles) ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, kit) | |||
if kitExtension == "sf2": | |||
plugins = checkFileSF2(kit, self.fToolNative) | |||
else: | |||
plugins = None | |||
if plugins: | |||
kitPlugins.append(plugins) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return kitPlugins | |||
def _checkCached(self, isLV2): | |||
if isLV2: | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
PLUG_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH, list)) | |||
del settings | |||
PLUG_TEXT = "LV2" | |||
PLUG_TYPE = PLUGIN_LV2 | |||
else: # AU | |||
PLUG_PATH = "" | |||
PLUG_TEXT = "AU" | |||
PLUG_TYPE = PLUGIN_AU | |||
plugins = [] | |||
self._pluginLook(self.fLastCheckValue, f"{PLUG_TEXT} plugins...") | |||
if not isLV2: | |||
gCarla.utils.juce_init() | |||
count = gCarla.utils.get_cached_plugin_count(PLUG_TYPE, PLUG_PATH) | |||
if not self.fContinueChecking: | |||
return plugins | |||
for i in range(count): | |||
descInfo = gCarla.utils.get_cached_plugin_info(PLUG_TYPE, i) | |||
percent = ( float(i) / count ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, descInfo['label']) | |||
if not descInfo['valid']: | |||
continue | |||
plugins.append(checkPluginCached(descInfo, PLUG_TYPE)) | |||
if not self.fContinueChecking: | |||
break | |||
if not isLV2: | |||
gCarla.utils.juce_cleanup() | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return plugins | |||
def _checkSfzCached(self): | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
PLUG_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list)) | |||
del settings | |||
sfzKits = [] | |||
self._pluginLook(self.fLastCheckValue, "SFZ kits...") | |||
count = gCarla.utils.get_cached_plugin_count(PLUGIN_SFZ, PLUG_PATH) | |||
if not self.fContinueChecking: | |||
return sfzKits | |||
for i in range(count): | |||
descInfo = gCarla.utils.get_cached_plugin_info(PLUGIN_SFZ, i) | |||
percent = ( float(i) / count ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, descInfo['label']) | |||
if not descInfo['valid']: | |||
continue | |||
sfzKits.append(checkPluginCached(descInfo, PLUGIN_SFZ)) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return sfzKits | |||
def _checkJsfxCached(self): | |||
settings = QSafeSettings("falkTX", "Carla2") | |||
PLUG_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list)) | |||
del settings | |||
jsfxPlugins = [] | |||
self._pluginLook(self.fLastCheckValue, "JSFX plugins...") | |||
count = gCarla.utils.get_cached_plugin_count(PLUGIN_JSFX, PLUG_PATH) | |||
if not self.fContinueChecking: | |||
return jsfxPlugins | |||
for i in range(count): | |||
descInfo = gCarla.utils.get_cached_plugin_info(PLUGIN_JSFX, i) | |||
percent = ( float(i) / count ) * self.fCurPercentValue | |||
self._pluginLook(self.fLastCheckValue + percent, descInfo['label']) | |||
if not descInfo['valid']: | |||
continue | |||
jsfxPlugins.append(checkPluginCached(descInfo, PLUGIN_JSFX)) | |||
if not self.fContinueChecking: | |||
break | |||
self.fLastCheckValue += self.fCurPercentValue | |||
return jsfxPlugins | |||
def _pluginLook(self, percent, plugin): | |||
self.pluginLook.emit(percent, plugin) | |||
# --------------------------------------------------------------------------------------------------------------------- |
@@ -1,18 +1,7 @@ | |||
/* | |||
* Carla plugin host | |||
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* 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 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. | |||
* | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
* SPDX-License-Identifier: GPL-2.0-or-later | |||
*/ | |||
#pragma once | |||
@@ -35,9 +24,7 @@ | |||
# pragma GCC diagnostic pop | |||
#endif | |||
#include "CarlaBackend.h" | |||
static constexpr const uint PLUGIN_QUERY_API_VERSION = 12; | |||
#include "ui_pluginlistdialog.h" | |||
struct HostSettings { | |||
bool showPluginBridges; | |||
@@ -45,73 +32,76 @@ struct HostSettings { | |||
bool useSystemIcons; | |||
}; | |||
struct PluginInfo { | |||
uint API; | |||
CARLA_BACKEND_NAMESPACE::BinaryType build; | |||
CARLA_BACKEND_NAMESPACE::PluginType type; | |||
uint hints; | |||
QString category; | |||
QString filename; | |||
QString name; | |||
QString label; | |||
QString maker; | |||
uint64_t uniqueId; | |||
uint audioIns; | |||
uint audioOuts; | |||
uint cvIns; | |||
uint cvOuts; | |||
uint midiIns; | |||
uint midiOuts; | |||
uint parametersIns; | |||
uint parametersOuts; | |||
}; | |||
class QSafeSettings; | |||
typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo; | |||
struct PluginInfo; | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Plugin List Dialog | |||
class PluginListDialog : public QDialog | |||
{ | |||
struct Self; | |||
Self& self; | |||
enum TableIndex { | |||
TW_FAVORITE, | |||
TW_NAME, | |||
TW_LABEL, | |||
TW_MAKER, | |||
TW_BINARY, | |||
}; | |||
enum UserRoles { | |||
UR_PLUGIN_INFO = 1, | |||
UR_SEARCH_TEXT, | |||
}; | |||
struct PrivateData; | |||
PrivateData *const p; | |||
Ui_PluginListDialog ui; | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// public methods | |||
public: | |||
explicit PluginListDialog(QWidget* parent, const HostSettings& hostSettings); | |||
~PluginListDialog() override; | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// public methods | |||
const PluginInfo& getSelectedPluginInfo() const; | |||
void addPluginInfo(const CarlaPluginDiscoveryInfo* info, const char* sha1sum); | |||
bool checkPluginCache(const char* filename, const char* sha1sum); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// protected methods | |||
protected: | |||
void done(int) override; | |||
void showEvent(QShowEvent*) override; | |||
void timerEvent(QTimerEvent*) override; | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// private methods | |||
private: | |||
void addPluginsToTable(); | |||
void loadSettings(); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// private slots | |||
private Q_SLOTS: | |||
void slot_cellClicked(int row, int column); | |||
void slot_cellDoubleClicked(int row, int column); | |||
void slot_focusSearchFieldAndSelectAll(); | |||
void slot_addPlugin(); | |||
void slot_checkPlugin(int row); | |||
void slot_checkFilters(); | |||
void slot_checkFiltersCategoryAll(bool clicked); | |||
void slot_checkFiltersCategorySpecific(bool clicked); | |||
void slot_refreshPlugins(); | |||
void slot_clearFilters(); | |||
void slot_saveSettings(); | |||
void cellClicked(int row, int column); | |||
void cellDoubleClicked(int row, int column); | |||
void focusSearchFieldAndSelectAll(); | |||
void checkFilters(); | |||
void checkFiltersCategoryAll(bool clicked); | |||
void checkFiltersCategorySpecific(bool clicked); | |||
void clearFilters(); | |||
void checkPlugin(int row); | |||
void refreshPlugins(); | |||
void refreshPluginsStart(); | |||
void refreshPluginsStop(); | |||
void refreshPluginsSkip(); | |||
void saveSettings(); | |||
}; | |||
// -------------------------------------------------------------------------------------------------------------------- |
@@ -35,7 +35,7 @@ | |||
<verstretch>0</verstretch> | |||
</sizepolicy> | |||
</property> | |||
<property name="tabBarAutoHide" stdset="0"> | |||
<property name="tabBarAutoHide"> | |||
<bool>true</bool> | |||
</property> | |||
<widget class="QWidget" name="tw_reqs"> | |||
@@ -133,7 +133,7 @@ | |||
<string>&Add Plugin</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<iconset resource="../../../resources/resources.qrc"> | |||
<normaloff>:/16x16/list-add.svgz</normaloff>:/16x16/list-add.svgz</iconset> | |||
</property> | |||
</widget> | |||
@@ -144,7 +144,7 @@ | |||
<string>Cancel</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<iconset resource="../../../resources/resources.qrc"> | |||
<normaloff>:/16x16/dialog-cancel.svgz</normaloff>:/16x16/dialog-cancel.svgz</iconset> | |||
</property> | |||
</widget> | |||
@@ -155,7 +155,7 @@ | |||
<layout class="QHBoxLayout" name="horizontalLayout"> | |||
<item> | |||
<widget class="QLineEdit" name="lineEdit"> | |||
<property name="clearButtonEnabled" stdset="0"> | |||
<property name="clearButtonEnabled"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
@@ -166,7 +166,7 @@ | |||
<string>Refresh</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<iconset resource="../../../resources/resources.qrc"> | |||
<normaloff>:/16x16/view-refresh.svgz</normaloff>:/16x16/view-refresh.svgz</iconset> | |||
</property> | |||
</widget> | |||
@@ -177,7 +177,7 @@ | |||
<string>Reset filters</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<iconset resource="../../../resources/resources.qrc"> | |||
<normaloff>:/16x16/edit-clear.svgz</normaloff>:/16x16/edit-clear.svgz</iconset> | |||
</property> | |||
</widget> | |||
@@ -186,7 +186,7 @@ | |||
</item> | |||
<item row="1" column="2" rowspan="3"> | |||
<widget class="QTabWidget" name="tab_info"> | |||
<property name="tabBarAutoHide" stdset="0"> | |||
<property name="tabBarAutoHide"> | |||
<bool>true</bool> | |||
</property> | |||
<widget class="QWidget" name="tw_info"> | |||
@@ -582,12 +582,12 @@ | |||
<attribute name="verticalHeaderVisible"> | |||
<bool>false</bool> | |||
</attribute> | |||
<attribute name="verticalHeaderDefaultSectionSize"> | |||
<number>22</number> | |||
</attribute> | |||
<attribute name="verticalHeaderMinimumSectionSize"> | |||
<number>12</number> | |||
</attribute> | |||
<attribute name="verticalHeaderDefaultSectionSize"> | |||
<number>22</number> | |||
</attribute> | |||
<column> | |||
<property name="text"> | |||
<string notr="true"/> | |||
@@ -599,7 +599,7 @@ | |||
<string notr="true"/> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<iconset resource="../../../resources/resources.qrc"> | |||
<normaloff>:/16x16/bookmarks.svgz</normaloff>:/16x16/bookmarks.svgz</iconset> | |||
</property> | |||
</column> | |||
@@ -635,8 +635,8 @@ | |||
<rect> | |||
<x>0</x> | |||
<y>0</y> | |||
<width>158</width> | |||
<height>237</height> | |||
<width>135</width> | |||
<height>282</height> | |||
</rect> | |||
</property> | |||
<attribute name="label"> | |||
@@ -733,8 +733,8 @@ | |||
<rect> | |||
<x>0</x> | |||
<y>0</y> | |||
<width>158</width> | |||
<height>156</height> | |||
<width>113</width> | |||
<height>120</height> | |||
</rect> | |||
</property> | |||
<attribute name="label"> | |||
@@ -785,6 +785,14 @@ | |||
</layout> | |||
</widget> | |||
<widget class="QWidget" name="p_category"> | |||
<property name="geometry"> | |||
<rect> | |||
<x>0</x> | |||
<y>0</y> | |||
<width>100</width> | |||
<height>282</height> | |||
</rect> | |||
</property> | |||
<attribute name="label"> | |||
<string>Category</string> | |||
</attribute> | |||
@@ -879,8 +887,8 @@ | |||
<rect> | |||
<x>0</x> | |||
<y>0</y> | |||
<width>158</width> | |||
<height>130</height> | |||
<width>124</width> | |||
<height>93</height> | |||
</rect> | |||
</property> | |||
<attribute name="label"> | |||
@@ -967,8 +975,7 @@ | |||
<tabstop>tab_info</tabstop> | |||
</tabstops> | |||
<resources> | |||
<include location="../resources.qrc"/> | |||
<include location="../../../resources/resources.qrc"/> | |||
</resources> | |||
<connections> | |||
</connections> | |||
<connections/> | |||
</ui> |
@@ -1,590 +0,0 @@ | |||
/* | |||
* Carla plugin host | |||
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* 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 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. | |||
* | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
*/ | |||
#include "pluginlistrefreshdialog.hpp" | |||
#ifdef __clang__ | |||
# pragma clang diagnostic push | |||
# pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" | |||
# pragma clang diagnostic ignored "-Wdeprecated-register" | |||
#elif defined(__GNUC__) && __GNUC__ >= 8 | |||
# pragma GCC diagnostic push | |||
# pragma GCC diagnostic ignored "-Wclass-memaccess" | |||
# pragma GCC diagnostic ignored "-Wdeprecated-copy" | |||
#endif | |||
#include "ui_pluginlistrefreshdialog.h" | |||
#include <QtCore/QFileInfo> | |||
#include <QtWidgets/QPushButton> | |||
#ifdef __clang__ | |||
# pragma clang diagnostic pop | |||
#elif defined(__GNUC__) && __GNUC__ >= 8 | |||
# pragma GCC diagnostic pop | |||
#endif | |||
#include "qsafesettings.hpp" | |||
#include "CarlaFrontend.h" | |||
#include "CarlaUtils.h" | |||
#include <cstring> | |||
static bool hasFeature(const char* const* const features, const char* const feature) | |||
{ | |||
if (features == nullptr) | |||
return false; | |||
for (int i=0; features[i] != nullptr; ++i) | |||
{ | |||
if (std::strcmp(features[i], feature) == 0) | |||
return true; | |||
} | |||
return false; | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Jack Application Dialog | |||
struct PluginListRefreshDialog::Self { | |||
Ui_PluginRefreshW ui; | |||
QPixmap fIconYes; | |||
QPixmap fIconNo; | |||
Self() {} | |||
static Self& create() | |||
{ | |||
Self* const self = new Self(); | |||
return *self; | |||
} | |||
}; | |||
PluginListRefreshDialog::PluginListRefreshDialog(QWidget* const parent, const bool useSystemIcons) | |||
: QDialog(parent), | |||
self(Self::create()) | |||
{ | |||
self.ui.setupUi(this); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// Internal stuff | |||
#ifdef CARLA_OS_WIN | |||
#define APP_EXT ".exe" | |||
#else | |||
#define APP_EXT "" | |||
#endif | |||
QString hostPathBinaries; | |||
const bool hasNative = QFileInfo::exists(QCarlaString(hostPathBinaries) + CARLA_OS_SEP_STR "carla-discovery-native" APP_EXT); | |||
const bool hasPosix32 = QFileInfo::exists(QCarlaString(hostPathBinaries) + CARLA_OS_SEP_STR "carla-discovery-posix32"); | |||
const bool hasPosix64 = QFileInfo::exists(QCarlaString(hostPathBinaries) + CARLA_OS_SEP_STR "carla-discovery-posix64"); | |||
const bool hasWin32 = QFileInfo::exists(QCarlaString(hostPathBinaries) + CARLA_OS_SEP_STR "carla-discovery-win32.exe"); | |||
const bool hasWin64 = QFileInfo::exists(QCarlaString(hostPathBinaries) + CARLA_OS_SEP_STR "carla-discovery-win64.exe"); | |||
// self.fThread = SearchPluginsThread(self, host.pathBinaries) | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// Set-up Icons | |||
if (useSystemIcons) | |||
{ | |||
// self.ui.b_start->setIcon(getIcon("arrow-right", 16, "svgz")); | |||
// self.ui.b_close->setIcon(getIcon("window-close", 16, "svgz")); | |||
// if QT_VERSION >= 0x50600: | |||
// size = int(16 * self.devicePixelRatioF()) | |||
// else: | |||
// size = 16 | |||
// self.fIconYes = QPixmap(getIcon('dialog-ok-apply', 16, 'svgz').pixmap(size)) | |||
// self.fIconNo = QPixmap(getIcon('dialog-error', 16, 'svgz').pixmap(size)) | |||
} | |||
else | |||
{ | |||
self.fIconYes = QPixmap(":/16x16/dialog-ok-apply.svgz"); | |||
self.fIconNo = QPixmap(":/16x16/dialog-error.svgz"); | |||
} | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// UI setup | |||
// FIXME remove LRDF | |||
self.ui.ico_rdflib->setPixmap(self.fIconNo); | |||
self.ui.b_skip->hide(); | |||
#if defined(CARLA_OS_HAIKU) | |||
self.ui.ch_posix32->setText("Haiku 32bit"); | |||
self.ui.ch_posix64->setText("Haiku 64bit"); | |||
#elif defined(CARLA_OS_LINUX) | |||
self.ui.ch_posix32->setText("Linux 32bit"); | |||
self.ui.ch_posix64->setText("Linux 64bit"); | |||
#elif defined(CARLA_OS_MAC) | |||
self.ui.ch_posix32->setText("MacOS 32bit"); | |||
self.ui.ch_posix64->setText("MacOS 64bit"); | |||
#endif | |||
#ifndef CARLA_OS_WIN | |||
if (hasPosix32) | |||
{ | |||
self.ui.ico_posix32->setPixmap(self.fIconYes); | |||
} | |||
else | |||
#endif | |||
{ | |||
self.ui.ico_posix32->setPixmap(self.fIconNo); | |||
self.ui.ch_posix32->setEnabled(false); | |||
} | |||
#ifndef CARLA_OS_WIN | |||
if (hasPosix64) | |||
{ | |||
self.ui.ico_posix64->setPixmap(self.fIconYes); | |||
} | |||
else | |||
#endif | |||
{ | |||
self.ui.ico_posix64->setPixmap(self.fIconNo); | |||
self.ui.ch_posix64->setEnabled(false); | |||
} | |||
if (hasWin32) | |||
{ | |||
self.ui.ico_win32->setPixmap(self.fIconYes); | |||
} | |||
else | |||
{ | |||
self.ui.ico_win32->setPixmap(self.fIconNo); | |||
self.ui.ch_win32->setEnabled(false); | |||
} | |||
if (hasWin64) | |||
{ | |||
self.ui.ico_win64->setPixmap(self.fIconYes); | |||
} | |||
else | |||
{ | |||
self.ui.ico_win64->setPixmap(self.fIconNo); | |||
self.ui.ch_win64->setEnabled(false); | |||
} | |||
bool hasNonNative; | |||
#if defined(CARLA_OS_WIN) | |||
#ifdef CARLA_OS_64BIT | |||
hasNonNative = hasWin32; | |||
self.ui.ch_win64->setEnabled(false); | |||
self.ui.ch_win64->setVisible(false); | |||
self.ui.ico_win64->setVisible(false); | |||
self.ui.label_win64->setVisible(false); | |||
#else | |||
hasNonNative = hasWin64; | |||
self.ui.ch_win32->setEnabled(false); | |||
self.ui.ch_win32->setVisible(false); | |||
self.ui.ico_win32->setVisible(false); | |||
self.ui.label_win32->setVisible(false); | |||
#endif | |||
self.ui.ch_posix32->setEnabled(false); | |||
self.ui.ch_posix32->setVisible(false); | |||
self.ui.ch_posix64->setEnabled(false); | |||
self.ui.ch_posix64->setVisible(false); | |||
self.ui.ico_posix32->hide(); | |||
self.ui.ico_posix64->hide(); | |||
self.ui.label_posix32->hide(); | |||
self.ui.label_posix64->hide(); | |||
self.ui.ico_rdflib->hide(); | |||
self.ui.label_rdflib->hide(); | |||
#elif defined(CARLA_OS_64BIT) | |||
hasNonNative = hasPosix32 || hasWin32 || hasWin64; | |||
self.ui.ch_posix64->setEnabled(false); | |||
self.ui.ch_posix64->setVisible(false); | |||
self.ui.ico_posix64->setVisible(false); | |||
self.ui.label_posix64->setVisible(false); | |||
#else | |||
hasNonNative = hasPosix64 || hasWin32 || hasWin64; | |||
self.ui.ch_posix32->setEnabled(false); | |||
self.ui.ch_posix32->setVisible(false); | |||
self.ui.ico_posix32->setVisible(false); | |||
self.ui.label_posix32->setVisible(false); | |||
#endif | |||
#ifdef CARLA_OS_MAC | |||
setWindowModality(Qt::WindowModal); | |||
#else | |||
self.ui.ch_au->setEnabled(false); | |||
self.ui.ch_au->setVisible(false); | |||
#endif | |||
if (hasNative) | |||
{ | |||
self.ui.ico_native->setPixmap(self.fIconYes); | |||
} | |||
else | |||
{ | |||
self.ui.ico_native->setPixmap(self.fIconNo); | |||
self.ui.ch_native->setEnabled(false); | |||
self.ui.ch_sf2->setEnabled(false); | |||
if (! hasNonNative) | |||
{ | |||
self.ui.ch_ladspa->setEnabled(false); | |||
self.ui.ch_dssi->setEnabled(false); | |||
self.ui.ch_vst->setEnabled(false); | |||
self.ui.ch_vst3->setEnabled(false); | |||
self.ui.ch_clap->setEnabled(false); | |||
} | |||
} | |||
// TODO | |||
// if (! hasLoadedLv2Plugins) | |||
self.ui.lv2_restart_notice->hide(); | |||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// Load settings | |||
loadSettings(); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// Hide bridges if disabled | |||
// TODO | |||
bool showPluginBridges = true; | |||
bool showWineBridges = true; | |||
#ifdef CARLA_OS_WIN | |||
#ifndef CARLA_OS_64BIT | |||
// NOTE: We Assume win32 carla build will not run win64 plugins | |||
showPluginBridges = false; | |||
#endif | |||
showWineBridges = false; | |||
#endif | |||
if (! showPluginBridges) | |||
{ | |||
self.ui.ch_native->setChecked(true); | |||
self.ui.ch_native->setEnabled(false); | |||
self.ui.ch_native->setVisible(false); | |||
self.ui.ch_posix32->setChecked(false); | |||
self.ui.ch_posix32->setEnabled(false); | |||
self.ui.ch_posix32->setVisible(false); | |||
self.ui.ch_posix64->setChecked(false); | |||
self.ui.ch_posix64->setEnabled(false); | |||
self.ui.ch_posix64->setVisible(false); | |||
self.ui.ch_win32->setChecked(false); | |||
self.ui.ch_win32->setEnabled(false); | |||
self.ui.ch_win32->setVisible(false); | |||
self.ui.ch_win64->setChecked(false); | |||
self.ui.ch_win64->setEnabled(false); | |||
self.ui.ch_win64->setVisible(false); | |||
self.ui.ico_posix32->hide(); | |||
self.ui.ico_posix64->hide(); | |||
self.ui.ico_win32->hide(); | |||
self.ui.ico_win64->hide(); | |||
self.ui.label_posix32->hide(); | |||
self.ui.label_posix64->hide(); | |||
self.ui.label_win32->hide(); | |||
self.ui.label_win64->hide(); | |||
self.ui.sep_format->hide(); | |||
} | |||
else if (! showWineBridges) | |||
{ | |||
self.ui.ch_win32->setChecked(false); | |||
self.ui.ch_win32->setEnabled(false); | |||
self.ui.ch_win32->setVisible(false); | |||
self.ui.ch_win64->setChecked(false); | |||
self.ui.ch_win64->setEnabled(false); | |||
self.ui.ch_win64->setVisible(false); | |||
self.ui.ico_win32->hide(); | |||
self.ui.ico_win64->hide(); | |||
self.ui.label_win32->hide(); | |||
self.ui.label_win64->hide(); | |||
} | |||
// Disable non-supported features | |||
const char* const* const features = carla_get_supported_features(); | |||
if (! hasFeature(features, "sf2")) | |||
{ | |||
self.ui.ch_sf2->setChecked(false); | |||
self.ui.ch_sf2->setEnabled(false); | |||
} | |||
#ifdef CARLA_OS_MAC | |||
if (! hasFeature(features, "juce")) | |||
{ | |||
self.ui.ch_au->setChecked(false); | |||
self.ui.ch_au->setEnabled(false); | |||
} | |||
#endif | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// Resize to minimum size, as it's very likely UI stuff was hidden | |||
resize(minimumSize()); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// Set-up connections | |||
connect(this, &QDialog::finished, | |||
this, &PluginListRefreshDialog::slot_saveSettings); | |||
// self.ui.b_start.clicked.connect(self.slot_start) | |||
// self.ui.b_skip.clicked.connect(self.slot_skip) | |||
// self.ui.ch_native.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_posix32.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_posix64.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_win32.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_win64.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_ladspa.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_dssi.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_lv2.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_vst.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_vst3.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_clap.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_au.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_sf2.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_sfz.clicked.connect(self.slot_checkTools) | |||
// self.ui.ch_jsfx.clicked.connect(self.slot_checkTools) | |||
// self.fThread.pluginLook.connect(self.slot_handlePluginLook) | |||
// self.fThread.finished.connect(self.slot_handlePluginThreadFinished) | |||
// connect(this, &QDialog::finished, | |||
// this, &JackAppDialog::slot_saveSettings); | |||
// connect(self.ui.cb_session_mgr, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), | |||
// this, &JackAppDialog::slot_sessionManagerChanged); | |||
// connect(self.ui.le_command, &QLineEdit::textChanged, | |||
// this, &JackAppDialog::slot_commandChanged); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// Post-connect setup | |||
slot_checkTools(); | |||
} | |||
PluginListRefreshDialog::~PluginListRefreshDialog() | |||
{ | |||
delete &self; | |||
} | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// public methods | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// protected methods | |||
void PluginListRefreshDialog::closeEvent(QCloseEvent* const event) | |||
{ | |||
/* | |||
if (self.fThread.isRunning()) | |||
{ | |||
self.fThread.stop(); | |||
killDiscovery(); | |||
#self.fThread.terminate(); | |||
self.fThread.wait(); | |||
} | |||
if (self.fThread.hasSomethingChanged()) | |||
accept(); | |||
else | |||
*/ | |||
reject(); | |||
QDialog::closeEvent(event); | |||
} | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// private methods | |||
void PluginListRefreshDialog::loadSettings() | |||
{ | |||
const QSafeSettings settings("falkTX", "CarlaRefresh2"); | |||
bool check; | |||
check = settings.valueBool("PluginDatabase/SearchLADSPA", true) and self.ui.ch_ladspa->isEnabled(); | |||
self.ui.ch_ladspa->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchDSSI", true) and self.ui.ch_dssi->isEnabled(); | |||
self.ui.ch_dssi->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchLV2", true) and self.ui.ch_lv2->isEnabled(); | |||
self.ui.ch_lv2->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchVST2", true) and self.ui.ch_vst->isEnabled(); | |||
self.ui.ch_vst->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchVST3", true) and self.ui.ch_vst3->isEnabled(); | |||
self.ui.ch_vst3->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchCLAP", true) and self.ui.ch_clap->isEnabled(); | |||
self.ui.ch_clap->setChecked(check); | |||
#ifdef CARLA_OS_MAC | |||
check = settings.valueBool("PluginDatabase/SearchAU", true) and self.ui.ch_au->isEnabled(); | |||
#else | |||
check = false; | |||
#endif | |||
self.ui.ch_au->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchSF2", false) and self.ui.ch_sf2->isEnabled(); | |||
self.ui.ch_sf2->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchSFZ", false) and self.ui.ch_sfz->isEnabled(); | |||
self.ui.ch_sfz->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchJSFX", true) and self.ui.ch_jsfx->isEnabled(); | |||
self.ui.ch_jsfx->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchNative", true) and self.ui.ch_native->isEnabled(); | |||
self.ui.ch_native->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchPOSIX32", false) and self.ui.ch_posix32->isEnabled(); | |||
self.ui.ch_posix32->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchPOSIX64", false) and self.ui.ch_posix64->isEnabled(); | |||
self.ui.ch_posix64->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchWin32", false) and self.ui.ch_win32->isEnabled(); | |||
self.ui.ch_win32->setChecked(check); | |||
check = settings.valueBool("PluginDatabase/SearchWin64", false) and self.ui.ch_win64->isEnabled(); | |||
self.ui.ch_win64->setChecked(check); | |||
self.ui.ch_do_checks->setChecked(settings.valueBool("PluginDatabase/DoChecks", false)); | |||
} | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// private slots | |||
void PluginListRefreshDialog::slot_saveSettings() | |||
{ | |||
QSafeSettings settings("falkTX", "CarlaRefresh2"); | |||
settings.setValue("PluginDatabase/SearchLADSPA", self.ui.ch_ladspa->isChecked()); | |||
settings.setValue("PluginDatabase/SearchDSSI", self.ui.ch_dssi->isChecked()); | |||
settings.setValue("PluginDatabase/SearchLV2", self.ui.ch_lv2->isChecked()); | |||
settings.setValue("PluginDatabase/SearchVST2", self.ui.ch_vst->isChecked()); | |||
settings.setValue("PluginDatabase/SearchVST3", self.ui.ch_vst3->isChecked()); | |||
settings.setValue("PluginDatabase/SearchCLAP", self.ui.ch_clap->isChecked()); | |||
settings.setValue("PluginDatabase/SearchAU", self.ui.ch_au->isChecked()); | |||
settings.setValue("PluginDatabase/SearchSF2", self.ui.ch_sf2->isChecked()); | |||
settings.setValue("PluginDatabase/SearchSFZ", self.ui.ch_sfz->isChecked()); | |||
settings.setValue("PluginDatabase/SearchJSFX", self.ui.ch_jsfx->isChecked()); | |||
settings.setValue("PluginDatabase/SearchNative", self.ui.ch_native->isChecked()); | |||
settings.setValue("PluginDatabase/SearchPOSIX32", self.ui.ch_posix32->isChecked()); | |||
settings.setValue("PluginDatabase/SearchPOSIX64", self.ui.ch_posix64->isChecked()); | |||
settings.setValue("PluginDatabase/SearchWin32", self.ui.ch_win32->isChecked()); | |||
settings.setValue("PluginDatabase/SearchWin64", self.ui.ch_win64->isChecked()); | |||
settings.setValue("PluginDatabase/DoChecks", self.ui.ch_do_checks->isChecked()); | |||
} | |||
void PluginListRefreshDialog::slot_start() | |||
{ | |||
self.ui.progressBar->setMinimum(0); | |||
self.ui.progressBar->setMaximum(100); | |||
self.ui.progressBar->setValue(0); | |||
self.ui.b_start->setEnabled(false); | |||
self.ui.b_skip->setVisible(true); | |||
self.ui.b_close->setVisible(false); | |||
self.ui.group_types->setEnabled(false); | |||
self.ui.group_options->setEnabled(false); | |||
// if gCarla.utils: | |||
// if self.ui.ch_do_checks.isChecked(): | |||
// gCarla.utils.unsetenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") | |||
// else: | |||
// gCarla.utils.setenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS", "true") | |||
// | |||
// native, posix32, posix64, win32, win64 = (self.ui.ch_native.isChecked(), | |||
// self.ui.ch_posix32.isChecked(), self.ui.ch_posix64.isChecked(), | |||
// self.ui.ch_win32.isChecked(), self.ui.ch_win64.isChecked()) | |||
// | |||
// ladspa, dssi, lv2, vst, vst3, clap, au, sf2, sfz, jsfx = (self.ui.ch_ladspa.isChecked(), self.ui.ch_dssi.isChecked(), | |||
// self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(), | |||
// self.ui.ch_vst3.isChecked(), self.ui.ch_clap.isChecked(), | |||
// self.ui.ch_au.isChecked(), self.ui.ch_sf2.isChecked(), | |||
// self.ui.ch_sfz.isChecked(), self.ui.ch_jsfx.isChecked()) | |||
// | |||
// self.fThread.setSearchBinaryTypes(native, posix32, posix64, win32, win64) | |||
// self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, vst3, clap, au, sf2, sfz, jsfx) | |||
// self.fThread.start() | |||
} | |||
void PluginListRefreshDialog::slot_skip() | |||
{ | |||
// killDiscovery(); | |||
} | |||
void PluginListRefreshDialog::slot_checkTools() | |||
{ | |||
const bool enabled1 = self.ui.ch_native->isChecked() | |||
|| self.ui.ch_posix32->isChecked() | |||
|| self.ui.ch_posix64->isChecked() | |||
|| self.ui.ch_win32->isChecked() | |||
|| self.ui.ch_win64->isChecked(); | |||
const bool enabled2 = self.ui.ch_ladspa->isChecked() | |||
|| self.ui.ch_dssi->isChecked() | |||
|| self.ui.ch_lv2->isChecked() | |||
|| self.ui.ch_vst->isChecked() | |||
|| self.ui.ch_vst3->isChecked() | |||
|| self.ui.ch_clap->isChecked() | |||
|| self.ui.ch_au->isChecked() | |||
|| self.ui.ch_sf2->isChecked() | |||
|| self.ui.ch_sfz->isChecked() | |||
|| self.ui.ch_jsfx->isChecked(); | |||
self.ui.b_start->setEnabled(enabled1 and enabled2); | |||
} | |||
void PluginListRefreshDialog::slot_handlePluginLook(const int percent, const QString plugin) | |||
{ | |||
self.ui.progressBar->setFormat(plugin); | |||
self.ui.progressBar->setValue(percent); | |||
} | |||
void PluginListRefreshDialog::slot_handlePluginThreadFinished() | |||
{ | |||
self.ui.progressBar->setMinimum(0); | |||
self.ui.progressBar->setMaximum(1); | |||
self.ui.progressBar->setValue(1); | |||
self.ui.progressBar->setFormat(tr("Done")); | |||
self.ui.b_start->setEnabled(true); | |||
self.ui.b_skip->setVisible(false); | |||
self.ui.b_close->setVisible(true); | |||
self.ui.group_types->setEnabled(true); | |||
self.ui.group_options->setEnabled(true); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
const PluginListRefreshDialogResults* | |||
carla_frontend_createAndExecPluginListRefreshDialog(void* const parent, const bool useSystemIcons) | |||
{ | |||
PluginListRefreshDialog gui(reinterpret_cast<QWidget*>(parent), useSystemIcons); | |||
if (gui.exec()) | |||
{ | |||
static PluginListRefreshDialogResults ret = {}; | |||
return &ret; | |||
} | |||
return nullptr; | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- |
@@ -1,81 +0,0 @@ | |||
/* | |||
* Carla plugin host | |||
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* 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 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. | |||
* | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
*/ | |||
#pragma once | |||
#ifdef __clang__ | |||
# pragma clang diagnostic push | |||
# pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" | |||
# pragma clang diagnostic ignored "-Wdeprecated-register" | |||
#elif defined(__GNUC__) && __GNUC__ >= 8 | |||
# pragma GCC diagnostic push | |||
# pragma GCC diagnostic ignored "-Wclass-memaccess" | |||
# pragma GCC diagnostic ignored "-Wdeprecated-copy" | |||
#endif | |||
#include <QtWidgets/QDialog> | |||
#ifdef __clang__ | |||
# pragma clang diagnostic pop | |||
#elif defined(__GNUC__) && __GNUC__ >= 8 | |||
# pragma GCC diagnostic pop | |||
#endif | |||
#include "qcarlastring.hpp" | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Jack Application Dialog | |||
class PluginListRefreshDialog : public QDialog | |||
{ | |||
struct Self; | |||
Self& self; | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
public: | |||
explicit PluginListRefreshDialog(QWidget* parent, bool useSystemIcons); | |||
~PluginListRefreshDialog() override; | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// public methods | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// protected methods | |||
protected: | |||
void closeEvent(QCloseEvent*) override; | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// private methods | |||
private: | |||
void loadSettings(); | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// private slots | |||
private slots: | |||
void slot_saveSettings(); | |||
void slot_start(); | |||
void slot_skip(); | |||
void slot_checkTools(); | |||
void slot_handlePluginLook(int percent, QString plugin); | |||
void slot_handlePluginThreadFinished(); | |||
}; | |||
// -------------------------------------------------------------------------------------------------------------------- |
@@ -1,473 +0,0 @@ | |||
#!/usr/bin/env python3 | |||
# -*- coding: utf-8 -*- | |||
# Carla plugin host | |||
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com> | |||
# | |||
# 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 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. | |||
# | |||
# For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Imports (Global) | |||
import os | |||
from PyQt5.QtCore import pyqtSlot, Qt, QT_VERSION | |||
from PyQt5.QtGui import QPixmap | |||
from PyQt5.QtWidgets import QDialog, QWidget | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Imports (Carla) | |||
from carla_shared import ( | |||
HAIKU, | |||
LINUX, | |||
MACOS, | |||
WINDOWS, | |||
gCarla, | |||
getIcon, | |||
kIs64bit, | |||
) | |||
from utils import QSafeSettings | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Imports (Local) | |||
from .discovery import killDiscovery | |||
from .discoverythread import SearchPluginsThread | |||
from .pluginlistrefreshdialog_ui import Ui_PluginRefreshW | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Plugin Refresh Dialog | |||
class PluginRefreshW(QDialog): | |||
def __init__(self, parent: QWidget, host, useSystemIcons: bool, hasLoadedLv2Plugins: bool): | |||
QDialog.__init__(self, parent) | |||
self.host = host | |||
self.ui = Ui_PluginRefreshW() | |||
self.ui.setupUi(self) | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Internal stuff | |||
toolNative = "carla-discovery-native.exe" if WINDOWS else "carla-discovery-native" | |||
hasNative = os.path.exists(os.path.join(host.pathBinaries, toolNative)) | |||
hasPosix32 = os.path.exists(os.path.join(host.pathBinaries, "carla-discovery-posix32")) | |||
hasPosix64 = os.path.exists(os.path.join(host.pathBinaries, "carla-discovery-posix64")) | |||
hasWin32 = os.path.exists(os.path.join(host.pathBinaries, "carla-discovery-win32.exe")) | |||
hasWin64 = os.path.exists(os.path.join(host.pathBinaries, "carla-discovery-win64.exe")) | |||
self.fThread = SearchPluginsThread(self, host.pathBinaries) | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Set-up Icons | |||
if useSystemIcons: | |||
self.ui.b_start.setIcon(getIcon('arrow-right', 16, 'svgz')) | |||
self.ui.b_close.setIcon(getIcon('window-close', 16, 'svgz')) | |||
if QT_VERSION >= 0x50600: | |||
size = int(16 * self.devicePixelRatioF()) | |||
else: | |||
size = 16 | |||
self.fIconYes = QPixmap(getIcon('dialog-ok-apply', 16, 'svgz').pixmap(size)) | |||
self.fIconNo = QPixmap(getIcon('dialog-error', 16, 'svgz').pixmap(size)) | |||
else: | |||
self.fIconYes = QPixmap(":/16x16/dialog-ok-apply.svgz") | |||
self.fIconNo = QPixmap(":/16x16/dialog-error.svgz") | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Set-up GUI | |||
# FIXME remove LRDF | |||
self.ui.ico_rdflib.setPixmap(self.fIconNo) | |||
self.ui.b_skip.setVisible(False) | |||
if HAIKU: | |||
self.ui.ch_posix32.setText("Haiku 32bit") | |||
self.ui.ch_posix64.setText("Haiku 64bit") | |||
elif LINUX: | |||
self.ui.ch_posix32.setText("Linux 32bit") | |||
self.ui.ch_posix64.setText("Linux 64bit") | |||
elif MACOS: | |||
self.ui.ch_posix32.setText("MacOS 32bit") | |||
self.ui.ch_posix64.setText("MacOS 64bit") | |||
if hasPosix32 and not WINDOWS: | |||
self.ui.ico_posix32.setPixmap(self.fIconYes) | |||
else: | |||
self.ui.ico_posix32.setPixmap(self.fIconNo) | |||
self.ui.ch_posix32.setEnabled(False) | |||
if hasPosix64 and not WINDOWS: | |||
self.ui.ico_posix64.setPixmap(self.fIconYes) | |||
else: | |||
self.ui.ico_posix64.setPixmap(self.fIconNo) | |||
self.ui.ch_posix64.setEnabled(False) | |||
if hasWin32: | |||
self.ui.ico_win32.setPixmap(self.fIconYes) | |||
else: | |||
self.ui.ico_win32.setPixmap(self.fIconNo) | |||
self.ui.ch_win32.setEnabled(False) | |||
if hasWin64: | |||
self.ui.ico_win64.setPixmap(self.fIconYes) | |||
else: | |||
self.ui.ico_win64.setPixmap(self.fIconNo) | |||
self.ui.ch_win64.setEnabled(False) | |||
if WINDOWS: | |||
if kIs64bit: | |||
hasNonNative = hasWin32 | |||
self.ui.ch_win64.setEnabled(False) | |||
self.ui.ch_win64.setVisible(False) | |||
self.ui.ico_win64.setVisible(False) | |||
self.ui.label_win64.setVisible(False) | |||
else: | |||
hasNonNative = hasWin64 | |||
self.ui.ch_win32.setEnabled(False) | |||
self.ui.ch_win32.setVisible(False) | |||
self.ui.ico_win32.setVisible(False) | |||
self.ui.label_win32.setVisible(False) | |||
self.ui.ch_posix32.setEnabled(False) | |||
self.ui.ch_posix32.setVisible(False) | |||
self.ui.ch_posix64.setEnabled(False) | |||
self.ui.ch_posix64.setVisible(False) | |||
self.ui.ico_posix32.hide() | |||
self.ui.ico_posix64.hide() | |||
self.ui.label_posix32.hide() | |||
self.ui.label_posix64.hide() | |||
self.ui.ico_rdflib.hide() | |||
self.ui.label_rdflib.hide() | |||
else: | |||
if kIs64bit: | |||
hasNonNative = bool(hasPosix32 or hasWin32 or hasWin64) | |||
self.ui.ch_posix64.setEnabled(False) | |||
self.ui.ch_posix64.setVisible(False) | |||
self.ui.ico_posix64.setVisible(False) | |||
self.ui.label_posix64.setVisible(False) | |||
else: | |||
hasNonNative = bool(hasPosix64 or hasWin32 or hasWin64) | |||
self.ui.ch_posix32.setEnabled(False) | |||
self.ui.ch_posix32.setVisible(False) | |||
self.ui.ico_posix32.setVisible(False) | |||
self.ui.label_posix32.setVisible(False) | |||
if MACOS: | |||
self.setWindowModality(Qt.WindowModal) | |||
else: | |||
self.ui.ch_au.setEnabled(False) | |||
self.ui.ch_au.setVisible(False) | |||
if hasNative: | |||
self.ui.ico_native.setPixmap(self.fIconYes) | |||
else: | |||
self.ui.ico_native.setPixmap(self.fIconNo) | |||
self.ui.ch_native.setEnabled(False) | |||
self.ui.ch_sf2.setEnabled(False) | |||
if not hasNonNative: | |||
self.ui.ch_ladspa.setEnabled(False) | |||
self.ui.ch_dssi.setEnabled(False) | |||
self.ui.ch_vst.setEnabled(False) | |||
self.ui.ch_vst3.setEnabled(False) | |||
self.ui.ch_clap.setEnabled(False) | |||
if not hasLoadedLv2Plugins: | |||
self.ui.lv2_restart_notice.hide() | |||
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Load settings | |||
self.loadSettings() | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Hide bridges if disabled | |||
# NOTE: We Assume win32 carla build will not run win64 plugins | |||
if (WINDOWS and not kIs64bit) or not host.showPluginBridges: | |||
self.ui.ch_native.setChecked(True) | |||
self.ui.ch_native.setEnabled(False) | |||
self.ui.ch_native.setVisible(False) | |||
self.ui.ch_posix32.setChecked(False) | |||
self.ui.ch_posix32.setEnabled(False) | |||
self.ui.ch_posix32.setVisible(False) | |||
self.ui.ch_posix64.setChecked(False) | |||
self.ui.ch_posix64.setEnabled(False) | |||
self.ui.ch_posix64.setVisible(False) | |||
self.ui.ch_win32.setChecked(False) | |||
self.ui.ch_win32.setEnabled(False) | |||
self.ui.ch_win32.setVisible(False) | |||
self.ui.ch_win64.setChecked(False) | |||
self.ui.ch_win64.setEnabled(False) | |||
self.ui.ch_win64.setVisible(False) | |||
self.ui.ico_posix32.hide() | |||
self.ui.ico_posix64.hide() | |||
self.ui.ico_win32.hide() | |||
self.ui.ico_win64.hide() | |||
self.ui.label_posix32.hide() | |||
self.ui.label_posix64.hide() | |||
self.ui.label_win32.hide() | |||
self.ui.label_win64.hide() | |||
self.ui.sep_format.hide() | |||
elif not (WINDOWS or host.showWineBridges): | |||
self.ui.ch_win32.setChecked(False) | |||
self.ui.ch_win32.setEnabled(False) | |||
self.ui.ch_win32.setVisible(False) | |||
self.ui.ch_win64.setChecked(False) | |||
self.ui.ch_win64.setEnabled(False) | |||
self.ui.ch_win64.setVisible(False) | |||
self.ui.ico_win32.hide() | |||
self.ui.ico_win64.hide() | |||
self.ui.label_win32.hide() | |||
self.ui.label_win64.hide() | |||
# Disable non-supported features | |||
features = gCarla.utils.get_supported_features() if gCarla.utils else () | |||
if "sf2" not in features: | |||
self.ui.ch_sf2.setChecked(False) | |||
self.ui.ch_sf2.setEnabled(False) | |||
if MACOS and "juce" not in features: | |||
self.ui.ch_au.setChecked(False) | |||
self.ui.ch_au.setEnabled(False) | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Resize to minimum size, as it's very likely UI stuff was hidden | |||
self.resize(self.minimumSize()) | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Set-up connections | |||
self.finished.connect(self.slot_saveSettings) | |||
self.ui.b_start.clicked.connect(self.slot_start) | |||
self.ui.b_skip.clicked.connect(self.slot_skip) | |||
self.ui.ch_native.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_posix32.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_posix64.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_win32.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_win64.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_ladspa.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_dssi.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_lv2.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_vst.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_vst3.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_clap.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_au.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_sf2.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_sfz.clicked.connect(self.slot_checkTools) | |||
self.ui.ch_jsfx.clicked.connect(self.slot_checkTools) | |||
self.fThread.pluginLook.connect(self.slot_handlePluginLook) | |||
self.fThread.finished.connect(self.slot_handlePluginThreadFinished) | |||
# ------------------------------------------------------------------------------------------------------------- | |||
# Post-connect setup | |||
self.slot_checkTools() | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
def loadSettings(self): | |||
settings = QSafeSettings("falkTX", "CarlaRefresh2") | |||
check = settings.value("PluginDatabase/SearchLADSPA", True, bool) and self.ui.ch_ladspa.isEnabled() | |||
self.ui.ch_ladspa.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchDSSI", True, bool) and self.ui.ch_dssi.isEnabled() | |||
self.ui.ch_dssi.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchLV2", True, bool) and self.ui.ch_lv2.isEnabled() | |||
self.ui.ch_lv2.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchVST2", True, bool) and self.ui.ch_vst.isEnabled() | |||
self.ui.ch_vst.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchVST3", True, bool) and self.ui.ch_vst3.isEnabled() | |||
self.ui.ch_vst3.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchCLAP", True, bool) and self.ui.ch_clap.isEnabled() | |||
self.ui.ch_clap.setChecked(check) | |||
if MACOS: | |||
check = settings.value("PluginDatabase/SearchAU", True, bool) and self.ui.ch_au.isEnabled() | |||
else: | |||
check = False | |||
self.ui.ch_au.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchSF2", False, bool) and self.ui.ch_sf2.isEnabled() | |||
self.ui.ch_sf2.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchSFZ", False, bool) and self.ui.ch_sfz.isEnabled() | |||
self.ui.ch_sfz.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchJSFX", True, bool) and self.ui.ch_jsfx.isEnabled() | |||
self.ui.ch_jsfx.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchNative", True, bool) and self.ui.ch_native.isEnabled() | |||
self.ui.ch_native.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchPOSIX32", False, bool) and self.ui.ch_posix32.isEnabled() | |||
self.ui.ch_posix32.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchPOSIX64", False, bool) and self.ui.ch_posix64.isEnabled() | |||
self.ui.ch_posix64.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchWin32", False, bool) and self.ui.ch_win32.isEnabled() | |||
self.ui.ch_win32.setChecked(check) | |||
check = settings.value("PluginDatabase/SearchWin64", False, bool) and self.ui.ch_win64.isEnabled() | |||
self.ui.ch_win64.setChecked(check) | |||
self.ui.ch_do_checks.setChecked(settings.value("PluginDatabase/DoChecks", False, bool)) | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
@pyqtSlot() | |||
def slot_saveSettings(self): | |||
settings = QSafeSettings("falkTX", "CarlaRefresh2") | |||
settings.setValue("PluginDatabase/SearchLADSPA", self.ui.ch_ladspa.isChecked()) | |||
settings.setValue("PluginDatabase/SearchDSSI", self.ui.ch_dssi.isChecked()) | |||
settings.setValue("PluginDatabase/SearchLV2", self.ui.ch_lv2.isChecked()) | |||
settings.setValue("PluginDatabase/SearchVST2", self.ui.ch_vst.isChecked()) | |||
settings.setValue("PluginDatabase/SearchVST3", self.ui.ch_vst3.isChecked()) | |||
settings.setValue("PluginDatabase/SearchCLAP", self.ui.ch_clap.isChecked()) | |||
settings.setValue("PluginDatabase/SearchAU", self.ui.ch_au.isChecked()) | |||
settings.setValue("PluginDatabase/SearchSF2", self.ui.ch_sf2.isChecked()) | |||
settings.setValue("PluginDatabase/SearchSFZ", self.ui.ch_sfz.isChecked()) | |||
settings.setValue("PluginDatabase/SearchJSFX", self.ui.ch_jsfx.isChecked()) | |||
settings.setValue("PluginDatabase/SearchNative", self.ui.ch_native.isChecked()) | |||
settings.setValue("PluginDatabase/SearchPOSIX32", self.ui.ch_posix32.isChecked()) | |||
settings.setValue("PluginDatabase/SearchPOSIX64", self.ui.ch_posix64.isChecked()) | |||
settings.setValue("PluginDatabase/SearchWin32", self.ui.ch_win32.isChecked()) | |||
settings.setValue("PluginDatabase/SearchWin64", self.ui.ch_win64.isChecked()) | |||
settings.setValue("PluginDatabase/DoChecks", self.ui.ch_do_checks.isChecked()) | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
@pyqtSlot() | |||
def slot_start(self): | |||
self.ui.progressBar.setMinimum(0) | |||
self.ui.progressBar.setMaximum(100) | |||
self.ui.progressBar.setValue(0) | |||
self.ui.b_start.setEnabled(False) | |||
self.ui.b_skip.setVisible(True) | |||
self.ui.b_close.setVisible(False) | |||
self.ui.group_types.setEnabled(False) | |||
self.ui.group_options.setEnabled(False) | |||
if gCarla.utils: | |||
if self.ui.ch_do_checks.isChecked(): | |||
gCarla.utils.unsetenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") | |||
else: | |||
gCarla.utils.setenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS", "true") | |||
native, posix32, posix64, win32, win64 = (self.ui.ch_native.isChecked(), | |||
self.ui.ch_posix32.isChecked(), self.ui.ch_posix64.isChecked(), | |||
self.ui.ch_win32.isChecked(), self.ui.ch_win64.isChecked()) | |||
ladspa, dssi, lv2, vst, vst3, clap, au, sf2, sfz, jsfx = (self.ui.ch_ladspa.isChecked(), self.ui.ch_dssi.isChecked(), | |||
self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(), | |||
self.ui.ch_vst3.isChecked(), self.ui.ch_clap.isChecked(), | |||
self.ui.ch_au.isChecked(), self.ui.ch_sf2.isChecked(), | |||
self.ui.ch_sfz.isChecked(), self.ui.ch_jsfx.isChecked()) | |||
self.fThread.setSearchBinaryTypes(native, posix32, posix64, win32, win64) | |||
self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, vst3, clap, au, sf2, sfz, jsfx) | |||
self.fThread.start() | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
@pyqtSlot() | |||
def slot_skip(self): | |||
killDiscovery() | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
@pyqtSlot() | |||
def slot_checkTools(self): | |||
enabled1 = bool(self.ui.ch_native.isChecked() or | |||
self.ui.ch_posix32.isChecked() or self.ui.ch_posix64.isChecked() or | |||
self.ui.ch_win32.isChecked() or self.ui.ch_win64.isChecked()) | |||
enabled2 = bool(self.ui.ch_ladspa.isChecked() or self.ui.ch_dssi.isChecked() or | |||
self.ui.ch_lv2.isChecked() or self.ui.ch_vst.isChecked() or | |||
self.ui.ch_vst3.isChecked() or self.ui.ch_clap.isChecked() or | |||
self.ui.ch_au.isChecked() or self.ui.ch_sf2.isChecked() or | |||
self.ui.ch_sfz.isChecked() or self.ui.ch_jsfx.isChecked()) | |||
self.ui.b_start.setEnabled(enabled1 and enabled2) | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
@pyqtSlot(float, str) | |||
def slot_handlePluginLook(self, percent, plugin): | |||
self.ui.progressBar.setFormat(plugin) | |||
self.ui.progressBar.setValue(int(percent)) | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
@pyqtSlot() | |||
def slot_handlePluginThreadFinished(self): | |||
self.ui.progressBar.setMinimum(0) | |||
self.ui.progressBar.setMaximum(1) | |||
self.ui.progressBar.setValue(1) | |||
self.ui.progressBar.setFormat(self.tr("Done")) | |||
self.ui.b_start.setEnabled(True) | |||
self.ui.b_skip.setVisible(False) | |||
self.ui.b_close.setVisible(True) | |||
self.ui.group_types.setEnabled(True) | |||
self.ui.group_options.setEnabled(True) | |||
# ----------------------------------------------------------------------------------------------------------------- | |||
def closeEvent(self, event): | |||
if self.fThread.isRunning(): | |||
self.fThread.stop() | |||
killDiscovery() | |||
#self.fThread.terminate() | |||
self.fThread.wait() | |||
if self.fThread.hasSomethingChanged(): | |||
self.accept() | |||
else: | |||
self.reject() | |||
QDialog.closeEvent(self, event) | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Testing | |||
if __name__ == '__main__': | |||
import sys | |||
# pylint: disable=ungrouped-imports | |||
from PyQt5.QtWidgets import QApplication | |||
# pylint: enable=ungrouped-imports | |||
class _host: | |||
pathBinaries = "" | |||
showPluginBridges = False | |||
showWineBridges = False | |||
_host = _host() | |||
_app = QApplication(sys.argv) | |||
_gui = PluginRefreshW(None, _host, True, False) | |||
_app.exec_() | |||
# --------------------------------------------------------------------------------------------------------------------- |
@@ -1,610 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<ui version="4.0"> | |||
<class>PluginRefreshW</class> | |||
<widget class="QDialog" name="PluginRefreshW"> | |||
<property name="geometry"> | |||
<rect> | |||
<x>0</x> | |||
<y>0</y> | |||
<width>613</width> | |||
<height>369</height> | |||
</rect> | |||
</property> | |||
<property name="windowTitle"> | |||
<string>Carla - Refresh</string> | |||
</property> | |||
<layout class="QVBoxLayout" name="verticalLayout_5"> | |||
<item> | |||
<layout class="QHBoxLayout" name="horizontalLayout_3"> | |||
<item> | |||
<spacer name="horizontalSpacer"> | |||
<property name="orientation"> | |||
<enum>Qt::Horizontal</enum> | |||
</property> | |||
<property name="sizeType"> | |||
<enum>QSizePolicy::Preferred</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>30</width> | |||
<height>20</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
<item> | |||
<widget class="QGroupBox" name="group_types"> | |||
<property name="title"> | |||
<string>Search for new...</string> | |||
</property> | |||
<property name="alignment"> | |||
<set>Qt::AlignCenter</set> | |||
</property> | |||
<layout class="QHBoxLayout" name="horizontalLayout_2"> | |||
<item> | |||
<layout class="QVBoxLayout" name="verticalLayout"> | |||
<item> | |||
<widget class="QCheckBox" name="ch_ladspa"> | |||
<property name="text"> | |||
<string>LADSPA</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_dssi"> | |||
<property name="text"> | |||
<string>DSSI</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_lv2"> | |||
<property name="text"> | |||
<string>LV2</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_vst"> | |||
<property name="text"> | |||
<string>VST2</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_vst3"> | |||
<property name="text"> | |||
<string>VST3</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_clap"> | |||
<property name="text"> | |||
<string>CLAP</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_au"> | |||
<property name="text"> | |||
<string>AU</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_jsfx"> | |||
<property name="text"> | |||
<string>JSFX</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="Line" name="line_3"> | |||
<property name="lineWidth"> | |||
<number>0</number> | |||
</property> | |||
<property name="midLineWidth"> | |||
<number>1</number> | |||
</property> | |||
<property name="orientation"> | |||
<enum>Qt::Horizontal</enum> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_sf2"> | |||
<property name="text"> | |||
<string>SF2/3</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_sfz"> | |||
<property name="text"> | |||
<string>SFZ</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<spacer name="horizontalSpacer_4"> | |||
<property name="orientation"> | |||
<enum>Qt::Horizontal</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>40</width> | |||
<height>5</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
<item> | |||
<spacer name="verticalSpacer_3"> | |||
<property name="orientation"> | |||
<enum>Qt::Vertical</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>40</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
</layout> | |||
</item> | |||
<item> | |||
<widget class="Line" name="sep_format"> | |||
<property name="lineWidth"> | |||
<number>0</number> | |||
</property> | |||
<property name="midLineWidth"> | |||
<number>1</number> | |||
</property> | |||
<property name="orientation"> | |||
<enum>Qt::Vertical</enum> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<layout class="QVBoxLayout" name="verticalLayout_2"> | |||
<item> | |||
<widget class="QCheckBox" name="ch_native"> | |||
<property name="text"> | |||
<string>Native</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_posix32"> | |||
<property name="text"> | |||
<string>POSIX 32bit</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_posix64"> | |||
<property name="text"> | |||
<string>POSIX 64bit</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_win32"> | |||
<property name="text"> | |||
<string>Windows 32bit</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_win64"> | |||
<property name="text"> | |||
<string>Windows 64bit</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<spacer name="verticalSpacer_2"> | |||
<property name="orientation"> | |||
<enum>Qt::Vertical</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>40</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
</layout> | |||
</item> | |||
</layout> | |||
</widget> | |||
</item> | |||
<item> | |||
<spacer name="horizontalSpacer_3"> | |||
<property name="orientation"> | |||
<enum>Qt::Horizontal</enum> | |||
</property> | |||
<property name="sizeType"> | |||
<enum>QSizePolicy::Fixed</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>20</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
<item> | |||
<layout class="QVBoxLayout" name="verticalLayout_3"> | |||
<item> | |||
<widget class="QGroupBox" name="group_tools"> | |||
<property name="title"> | |||
<string>Available tools:</string> | |||
</property> | |||
<property name="alignment"> | |||
<set>Qt::AlignCenter</set> | |||
</property> | |||
<property name="flat"> | |||
<bool>true</bool> | |||
</property> | |||
<layout class="QGridLayout" name="gridLayout"> | |||
<item row="0" column="0"> | |||
<widget class="QLabel" name="ico_native"> | |||
<property name="maximumSize"> | |||
<size> | |||
<width>16</width> | |||
<height>16</height> | |||
</size> | |||
</property> | |||
<property name="text"> | |||
<string/> | |||
</property> | |||
<property name="pixmap"> | |||
<pixmap resource="../resources.qrc">:/16x16/dialog-ok-apply.svgz</pixmap> | |||
</property> | |||
<property name="scaledContents"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="1" column="0"> | |||
<widget class="QLabel" name="ico_posix32"> | |||
<property name="maximumSize"> | |||
<size> | |||
<width>16</width> | |||
<height>16</height> | |||
</size> | |||
</property> | |||
<property name="text"> | |||
<string/> | |||
</property> | |||
<property name="pixmap"> | |||
<pixmap resource="../resources.qrc">:/16x16/dialog-ok-apply.svgz</pixmap> | |||
</property> | |||
<property name="scaledContents"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="5" column="1"> | |||
<widget class="QLabel" name="label_rdflib"> | |||
<property name="text"> | |||
<string>python3-rdflib (LADSPA-RDF support)</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="4" column="1"> | |||
<widget class="QLabel" name="label_win64"> | |||
<property name="text"> | |||
<string>carla-discovery-win64</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="0" column="1"> | |||
<widget class="QLabel" name="label_native"> | |||
<property name="text"> | |||
<string>carla-discovery-native</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="2" column="0"> | |||
<widget class="QLabel" name="ico_posix64"> | |||
<property name="maximumSize"> | |||
<size> | |||
<width>16</width> | |||
<height>16</height> | |||
</size> | |||
</property> | |||
<property name="text"> | |||
<string/> | |||
</property> | |||
<property name="pixmap"> | |||
<pixmap resource="../resources.qrc">:/16x16/dialog-ok-apply.svgz</pixmap> | |||
</property> | |||
<property name="scaledContents"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="5" column="0"> | |||
<widget class="QLabel" name="ico_rdflib"> | |||
<property name="maximumSize"> | |||
<size> | |||
<width>16</width> | |||
<height>16</height> | |||
</size> | |||
</property> | |||
<property name="text"> | |||
<string/> | |||
</property> | |||
<property name="pixmap"> | |||
<pixmap resource="../resources.qrc">:/16x16/dialog-ok-apply.svgz</pixmap> | |||
</property> | |||
<property name="scaledContents"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="1" column="1"> | |||
<widget class="QLabel" name="label_posix32"> | |||
<property name="text"> | |||
<string>carla-discovery-posix32</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="3" column="0"> | |||
<widget class="QLabel" name="ico_win32"> | |||
<property name="maximumSize"> | |||
<size> | |||
<width>16</width> | |||
<height>16</height> | |||
</size> | |||
</property> | |||
<property name="text"> | |||
<string/> | |||
</property> | |||
<property name="pixmap"> | |||
<pixmap resource="../resources.qrc">:/16x16/dialog-ok-apply.svgz</pixmap> | |||
</property> | |||
<property name="scaledContents"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="4" column="0"> | |||
<widget class="QLabel" name="ico_win64"> | |||
<property name="maximumSize"> | |||
<size> | |||
<width>16</width> | |||
<height>16</height> | |||
</size> | |||
</property> | |||
<property name="text"> | |||
<string/> | |||
</property> | |||
<property name="pixmap"> | |||
<pixmap resource="../resources.qrc">:/16x16/dialog-ok-apply.svgz</pixmap> | |||
</property> | |||
<property name="scaledContents"> | |||
<bool>true</bool> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="2" column="1"> | |||
<widget class="QLabel" name="label_posix64"> | |||
<property name="text"> | |||
<string>carla-discovery-posix64</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item row="3" column="1"> | |||
<widget class="QLabel" name="label_win32"> | |||
<property name="text"> | |||
<string>carla-discovery-win32</string> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
</item> | |||
<item> | |||
<spacer name="verticalSpacer_5"> | |||
<property name="orientation"> | |||
<enum>Qt::Vertical</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>40</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
<item> | |||
<widget class="QGroupBox" name="group_options"> | |||
<property name="title"> | |||
<string>Options:</string> | |||
</property> | |||
<property name="alignment"> | |||
<set>Qt::AlignCenter</set> | |||
</property> | |||
<property name="flat"> | |||
<bool>true</bool> | |||
</property> | |||
<layout class="QVBoxLayout" name="verticalLayout_4"> | |||
<item> | |||
<widget class="QCheckBox" name="ch_do_checks"> | |||
<property name="toolTip"> | |||
<string>Carla will run small processing checks when scanning the plugins (to make sure they won't crash). | |||
You can disable these checks to get a faster scanning time (at your own risk).</string> | |||
</property> | |||
<property name="text"> | |||
<string>Run processing checks while scanning</string> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
</item> | |||
<item> | |||
<spacer name="verticalSpacer_4"> | |||
<property name="orientation"> | |||
<enum>Qt::Vertical</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>40</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
</layout> | |||
</item> | |||
<item> | |||
<spacer name="horizontalSpacer_2"> | |||
<property name="orientation"> | |||
<enum>Qt::Horizontal</enum> | |||
</property> | |||
<property name="sizeType"> | |||
<enum>QSizePolicy::Preferred</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>30</width> | |||
<height>20</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
</layout> | |||
</item> | |||
<item> | |||
<spacer name="verticalSpacer"> | |||
<property name="orientation"> | |||
<enum>Qt::Vertical</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>6</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
<item> | |||
<widget class="QWidget" name="lv2_restart_notice" native="true"> | |||
<layout class="QHBoxLayout" name="horizontalLayout_4"> | |||
<item> | |||
<widget class="QLabel" name="label_4"> | |||
<property name="maximumSize"> | |||
<size> | |||
<width>22</width> | |||
<height>22</height> | |||
</size> | |||
</property> | |||
<property name="text"> | |||
<string/> | |||
</property> | |||
<property name="pixmap"> | |||
<pixmap resource="../resources.qrc">:/16x16/dialog-information.svgz</pixmap> | |||
</property> | |||
<property name="scaledContents"> | |||
<bool>true</bool> | |||
</property> | |||
<property name="alignment"> | |||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QLabel" name="label_5"> | |||
<property name="text"> | |||
<string>Restart Carla to list the new LV2 plugins</string> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</widget> | |||
</item> | |||
<item> | |||
<layout class="QHBoxLayout" name="horizontalLayout"> | |||
<item> | |||
<widget class="QProgressBar" name="progressBar"> | |||
<property name="sizePolicy"> | |||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | |||
<horstretch>0</horstretch> | |||
<verstretch>0</verstretch> | |||
</sizepolicy> | |||
</property> | |||
<property name="maximum"> | |||
<number>100</number> | |||
</property> | |||
<property name="value"> | |||
<number>0</number> | |||
</property> | |||
<property name="format"> | |||
<string>Press 'Scan' to begin the search</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QPushButton" name="b_start"> | |||
<property name="text"> | |||
<string>Scan</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<normaloff>:/16x16/arrow-right.svgz</normaloff>:/16x16/arrow-right.svgz</iconset> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QPushButton" name="b_skip"> | |||
<property name="text"> | |||
<string>>> Skip</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QPushButton" name="b_close"> | |||
<property name="text"> | |||
<string>Close</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../resources.qrc"> | |||
<normaloff>:/16x16/window-close.svgz</normaloff>:/16x16/window-close.svgz</iconset> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</item> | |||
</layout> | |||
</widget> | |||
<resources> | |||
<include location="../resources.qrc"/> | |||
<include location="../resources.qrc"/> | |||
</resources> | |||
<connections> | |||
<connection> | |||
<sender>b_close</sender> | |||
<signal>clicked()</signal> | |||
<receiver>PluginRefreshW</receiver> | |||
<slot>close()</slot> | |||
<hints> | |||
<hint type="sourcelabel"> | |||
<x>426</x> | |||
<y>231</y> | |||
</hint> | |||
<hint type="destinationlabel"> | |||
<x>236</x> | |||
<y>125</y> | |||
</hint> | |||
</hints> | |||
</connection> | |||
</connections> | |||
</ui> |
@@ -0,0 +1,65 @@ | |||
/* | |||
* Carla plugin host | |||
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com> | |||
* SPDX-License-Identifier: GPL-2.0-or-later | |||
*/ | |||
#pragma once | |||
#include "ui_pluginrefreshdialog.h" | |||
#include "qsafesettings.hpp" | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
// Plugin Refresh Dialog | |||
struct PluginRefreshDialog : QDialog, Ui_PluginRefreshDialog { | |||
explicit PluginRefreshDialog(QWidget* const parent) | |||
: QDialog(parent) | |||
{ | |||
setupUi(this); | |||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | |||
#ifdef CARLA_OS_MAC | |||
setWindowModality(Qt::WindowModal); | |||
#endif | |||
b_skip->setEnabled(false); | |||
ch_invalid->setEnabled(false); | |||
// ------------------------------------------------------------------------------------------------------------ | |||
// Load settings | |||
{ | |||
const QSafeSettings settings; | |||
restoreGeometry(settings.valueByteArray("PluginRefreshDialog/Geometry")); | |||
if (settings.valueBool("PluginRefreshDialog/RefreshAll", false)) | |||
ch_all->setChecked(true); | |||
else | |||
ch_updated->setChecked(true); | |||
ch_invalid->setChecked(settings.valueBool("PluginRefreshDialog/CheckInvalid", false)); | |||
} | |||
// ------------------------------------------------------------------------------------------------------------ | |||
// Set-up connections | |||
QObject::connect(this, &QDialog::finished, this, &PluginRefreshDialog::saveSettings); | |||
} | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// private slots | |||
private Q_SLOTS: | |||
void saveSettings() | |||
{ | |||
QSafeSettings settings; | |||
settings.setValue("PluginRefreshDialog/Geometry", saveGeometry()); | |||
settings.setValue("PluginRefreshDialog/RefreshAll", ch_all->isChecked()); | |||
settings.setValue("PluginRefreshDialog/CheckInvalid", ch_invalid->isChecked()); | |||
} | |||
}; | |||
// -------------------------------------------------------------------------------------------------------------------- |
@@ -0,0 +1,190 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<ui version="4.0"> | |||
<class>PluginRefreshDialog</class> | |||
<widget class="QDialog" name="PluginRefreshDialog"> | |||
<property name="geometry"> | |||
<rect> | |||
<x>0</x> | |||
<y>0</y> | |||
<width>873</width> | |||
<height>179</height> | |||
</rect> | |||
</property> | |||
<property name="windowTitle"> | |||
<string>Plugin Refresh</string> | |||
</property> | |||
<layout class="QVBoxLayout" name="verticalLayout_5"> | |||
<item> | |||
<layout class="QHBoxLayout" name="horizontalLayout_3"> | |||
<item> | |||
<spacer name="horizontalSpacer"> | |||
<property name="orientation"> | |||
<enum>Qt::Horizontal</enum> | |||
</property> | |||
<property name="sizeType"> | |||
<enum>QSizePolicy::Preferred</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>30</width> | |||
<height>20</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
<item> | |||
<widget class="QGroupBox" name="group"> | |||
<property name="title"> | |||
<string>Search for:</string> | |||
</property> | |||
<property name="alignment"> | |||
<set>Qt::AlignCenter</set> | |||
</property> | |||
<layout class="QHBoxLayout" name="horizontalLayout_2"> | |||
<item> | |||
<layout class="QVBoxLayout" name="verticalLayout"> | |||
<item> | |||
<widget class="QRadioButton" name="ch_all"> | |||
<property name="text"> | |||
<string>All plugins, ignoring cache</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QRadioButton" name="ch_updated"> | |||
<property name="text"> | |||
<string>Updated plugins only</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QCheckBox" name="ch_invalid"> | |||
<property name="text"> | |||
<string>Check previously invalid plugins</string> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</item> | |||
</layout> | |||
</widget> | |||
</item> | |||
<item> | |||
<spacer name="horizontalSpacer_3"> | |||
<property name="orientation"> | |||
<enum>Qt::Horizontal</enum> | |||
</property> | |||
<property name="sizeType"> | |||
<enum>QSizePolicy::Preferred</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>20</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
</layout> | |||
</item> | |||
<item> | |||
<spacer name="verticalSpacer"> | |||
<property name="orientation"> | |||
<enum>Qt::Vertical</enum> | |||
</property> | |||
<property name="sizeHint" stdset="0"> | |||
<size> | |||
<width>20</width> | |||
<height>6</height> | |||
</size> | |||
</property> | |||
</spacer> | |||
</item> | |||
<item> | |||
<layout class="QHBoxLayout" name="horizontalLayout"> | |||
<item> | |||
<widget class="QProgressBar" name="progressBar"> | |||
<property name="sizePolicy"> | |||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | |||
<horstretch>0</horstretch> | |||
<verstretch>0</verstretch> | |||
</sizepolicy> | |||
</property> | |||
<property name="maximum"> | |||
<number>100</number> | |||
</property> | |||
<property name="value"> | |||
<number>0</number> | |||
</property> | |||
<property name="format"> | |||
<string>Press 'Scan' to begin the search</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QPushButton" name="b_start"> | |||
<property name="text"> | |||
<string>Scan</string> | |||
</property> | |||
<property name="icon"> | |||
<iconset resource="../../../resources/resources.qrc"> | |||
<normaloff>:/16x16/arrow-right.svgz</normaloff>:/16x16/arrow-right.svgz</iconset> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QPushButton" name="b_skip"> | |||
<property name="text"> | |||
<string>>> Skip</string> | |||
</property> | |||
</widget> | |||
</item> | |||
<item> | |||
<widget class="QPushButton" name="b_close"> | |||
<property name="text"> | |||
<string>Close</string> | |||
</property> | |||
</widget> | |||
</item> | |||
</layout> | |||
</item> | |||
</layout> | |||
</widget> | |||
<resources> | |||
<include location="../../../resources/resources.qrc"/> | |||
</resources> | |||
<connections> | |||
<connection> | |||
<sender>b_close</sender> | |||
<signal>clicked()</signal> | |||
<receiver>PluginRefreshDialog</receiver> | |||
<slot>close()</slot> | |||
<hints> | |||
<hint type="sourcelabel"> | |||
<x>426</x> | |||
<y>231</y> | |||
</hint> | |||
<hint type="destinationlabel"> | |||
<x>236</x> | |||
<y>125</y> | |||
</hint> | |||
</hints> | |||
</connection> | |||
<connection> | |||
<sender>ch_updated</sender> | |||
<signal>toggled(bool)</signal> | |||
<receiver>ch_invalid</receiver> | |||
<slot>setEnabled(bool)</slot> | |||
<hints> | |||
<hint type="sourcelabel"> | |||
<x>436</x> | |||
<y>78</y> | |||
</hint> | |||
<hint type="destinationlabel"> | |||
<x>436</x> | |||
<y>105</y> | |||
</hint> | |||
</hints> | |||
</connection> | |||
</connections> | |||
</ui> |
@@ -49,6 +49,11 @@ public: | |||
explicit inline QCarlaString(const char* const str) | |||
: QString(fromUtf8(str)) {} | |||
#if QT_VERSION < 0x60000 | |||
explicit inline QCarlaString(const QChar* const str, const qsizetype size) | |||
: QString(str, size) {} | |||
#endif | |||
inline QCarlaString(const QString& s) | |||
: QString(s) {} | |||
@@ -66,6 +71,36 @@ public: | |||
{ | |||
return simplified().remove(' '); | |||
} | |||
#if QT_VERSION < 0x60000 | |||
inline QCarlaString sliced(const qsizetype pos) const | |||
{ | |||
return QCarlaString(data() + pos, size() - pos); | |||
} | |||
#endif | |||
}; | |||
//--------------------------------------------------------------------------------------------------------------------- | |||
// Custom QByteArray class with a few extra methods | |||
class QCarlaByteArray : public QByteArray | |||
{ | |||
public: | |||
explicit inline QCarlaByteArray() | |||
: QByteArray() {} | |||
explicit inline QCarlaByteArray(const char* const data, const qsizetype size) | |||
: QByteArray(data, size) {} | |||
inline QCarlaByteArray(const QByteArray& b) | |||
: QByteArray(b) {} | |||
#if QT_VERSION < 0x60000 | |||
inline QCarlaByteArray sliced(const qsizetype pos) const | |||
{ | |||
return QCarlaByteArray(data() + pos, size() - pos); | |||
} | |||
#endif | |||
}; | |||
//--------------------------------------------------------------------------------------------------------------------- |