| @@ -35,9 +35,9 @@ NON_STATIC_LINK_FLAGS = $(LINK_FLAGS) | |||||
| endif | endif | ||||
| ifeq ($(WINDOWS),true) | ifeq ($(WINDOWS),true) | ||||
| QT_LINK_FLAGS += -L$(BINDIR) $(BINDIR)/libcarla_utils.dll | |||||
| QT_LINK_FLAGS += -L$(BINDIR) $(BINDIR)/libcarla_standalone2.dll $(BINDIR)/libcarla_utils.dll | |||||
| else | else | ||||
| QT_LINK_FLAGS += -L$(BINDIR) -lcarla_utils | |||||
| QT_LINK_FLAGS += -L$(BINDIR) -lcarla_standalone2 -lcarla_utils | |||||
| endif | endif | ||||
| ifeq ($(MACOS),true) | ifeq ($(MACOS),true) | ||||
| @@ -58,6 +58,7 @@ QMs = $(patsubst %,translations/carla_%.qm,$(I18N_LANGUAGES)) | |||||
| CPP_FILES = \ | CPP_FILES = \ | ||||
| carla_frontend.cpp \ | carla_frontend.cpp \ | ||||
| dialogs/aboutdialog.cpp \ | |||||
| dialogs/jackappdialog.cpp \ | dialogs/jackappdialog.cpp \ | ||||
| pluginlist/pluginlistdialog.cpp | pluginlist/pluginlistdialog.cpp | ||||
| @@ -89,7 +90,6 @@ RES = \ | |||||
| $(BINDIR)/resources/notes-ui \ | $(BINDIR)/resources/notes-ui \ | ||||
| $(BINDIR)/resources/xycontroller-ui \ | $(BINDIR)/resources/xycontroller-ui \ | ||||
| $(BINDIR)/resources/resources_rc.py \ | $(BINDIR)/resources/resources_rc.py \ | ||||
| $(BINDIR)/resources/ui_carla_about.py \ | |||||
| $(BINDIR)/resources/ui_carla_edit.py \ | $(BINDIR)/resources/ui_carla_edit.py \ | ||||
| $(BINDIR)/resources/ui_carla_host.py \ | $(BINDIR)/resources/ui_carla_host.py \ | ||||
| $(BINDIR)/resources/ui_carla_osc_connect.py \ | $(BINDIR)/resources/ui_carla_osc_connect.py \ | ||||
| @@ -122,11 +122,8 @@ PLUGINLIST_UI_FILES = $(wildcard pluginlist/*.ui) | |||||
| UIs = $(DIALOG_UI_FILES:dialogs/%.ui=dialogs/ui_%.h) | UIs = $(DIALOG_UI_FILES:dialogs/%.ui=dialogs/ui_%.h) | ||||
| UIs += $(PLUGINLIST_UI_FILES:pluginlist/%.ui=pluginlist/ui_%.h) | UIs += $(PLUGINLIST_UI_FILES:pluginlist/%.ui=pluginlist/ui_%.h) | ||||
| UIs += $(DIALOG_UI_FILES:%.ui=%_ui.py) | |||||
| # old stuff, not yet converted | # old stuff, not yet converted | ||||
| UIs += \ | UIs += \ | ||||
| ui_carla_about.py \ | |||||
| ui_carla_edit.py \ | ui_carla_edit.py \ | ||||
| ui_carla_host.py \ | ui_carla_host.py \ | ||||
| ui_carla_osc_connect.py \ | ui_carla_osc_connect.py \ | ||||
| @@ -1531,6 +1531,7 @@ class CarlaHostMeta(): | |||||
| self.isPlugin = False | self.isPlugin = False | ||||
| self.isRemote = False | self.isRemote = False | ||||
| self.nsmOK = False | self.nsmOK = False | ||||
| self.handle = None | |||||
| # settings | # settings | ||||
| self.processMode = ENGINE_PROCESS_MODE_PATCHBAY | self.processMode = ENGINE_PROCESS_MODE_PATCHBAY | ||||
| @@ -1,23 +1,136 @@ | |||||
| /* | |||||
| * 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. | |||||
| */ | |||||
| // SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-License-Identifier: GPL-2.0-or-later | |||||
| #include "carla_frontend.h" | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| // common files | // common files | ||||
| #include "utils/qsafesettings.cpp" | #include "utils/qsafesettings.cpp" | ||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // aboutdialog | |||||
| #include "dialogs/aboutdialog.hpp" | |||||
| void carla_frontend_createAndExecAboutDialog(QWidget* const parent, | |||||
| const CarlaHostHandle hostHandle, | |||||
| const bool isControl, | |||||
| const bool isPlugin) | |||||
| { | |||||
| AboutDialog(parent, hostHandle, isControl, isPlugin).exec(); | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // jackappdialog | |||||
| #include "dialogs/jackappdialog.hpp" | |||||
| #include "distrho/extra/String.hpp" | |||||
| const JackAppDialogResults* | |||||
| carla_frontend_createAndExecJackAppDialog(QWidget* const parent, const char* const projectFilename) | |||||
| { | |||||
| JackAppDialog gui(parent, projectFilename); | |||||
| if (gui.exec()) | |||||
| { | |||||
| static JackAppDialogResults ret = {}; | |||||
| static String retCommand; | |||||
| static String retName; | |||||
| static String retLabelSetup; | |||||
| const JackAppDialog::CommandAndFlags cafs = gui.getCommandAndFlags(); | |||||
| retCommand = cafs.command.toUtf8().constData(); | |||||
| retName = cafs.name.toUtf8().constData(); | |||||
| retLabelSetup = cafs.labelSetup.toUtf8().constData(); | |||||
| ret.command = retCommand; | |||||
| ret.name = retName; | |||||
| ret.labelSetup = retLabelSetup; | |||||
| return &ret; | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // pluginlistdialog | |||||
| #include "pluginlist/pluginlistdialog.hpp" | |||||
| #include "CarlaUtils.h" | |||||
| PluginListDialog* | |||||
| carla_frontend_createPluginListDialog(QWidget* const parent, const HostSettings* const hostSettings) | |||||
| { | |||||
| return new PluginListDialog(parent, hostSettings); | |||||
| } | |||||
| void | |||||
| carla_frontend_destroyPluginListDialog(PluginListDialog* const dialog) | |||||
| { | |||||
| dialog->close(); | |||||
| delete dialog; | |||||
| } | |||||
| void | |||||
| carla_frontend_setPluginListDialogPath(PluginListDialog* const dialog, const int ptype, const char* const path) | |||||
| { | |||||
| dialog->setPluginPath(static_cast<PluginType>(ptype), path); | |||||
| } | |||||
| const PluginListDialogResults* | |||||
| carla_frontend_execPluginListDialog(PluginListDialog* const dialog) | |||||
| { | |||||
| if (dialog->exec()) | |||||
| { | |||||
| static PluginListDialogResults ret; | |||||
| static String category; | |||||
| static String filename; | |||||
| static String name; | |||||
| static String label; | |||||
| static String maker; | |||||
| const PluginInfo& plugin(dialog->getSelectedPluginInfo()); | |||||
| category = plugin.category.toUtf8(); | |||||
| filename = plugin.filename.toUtf8(); | |||||
| name = plugin.name.toUtf8(); | |||||
| label = plugin.label.toUtf8(); | |||||
| maker = plugin.maker.toUtf8(); | |||||
| ret.build = plugin.build; | |||||
| ret.type = plugin.type; | |||||
| ret.hints = plugin.hints; | |||||
| ret.category = category; | |||||
| ret.filename = filename; | |||||
| ret.name = name; | |||||
| ret.label = label; | |||||
| ret.maker = maker; | |||||
| ret.uniqueId = plugin.uniqueId; | |||||
| ret.audioIns = plugin.audioIns; | |||||
| ret.audioOuts = plugin.audioOuts; | |||||
| ret.cvIns = plugin.cvIns; | |||||
| ret.cvOuts = plugin.cvOuts; | |||||
| ret.midiIns = plugin.midiIns; | |||||
| ret.midiOuts = plugin.midiOuts; | |||||
| ret.parameterIns = plugin.parameterIns; | |||||
| ret.parameterOuts = plugin.parameterOuts; | |||||
| return &ret; | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // const PluginListDialogResults* | |||||
| // carla_frontend_createAndExecPluginListDialog(void* const parent, const HostSettings* const hostSettings) | |||||
| // { | |||||
| // PluginListDialog gui(reinterpret_cast<QWidget*>(parent), hostSettings); | |||||
| // | |||||
| // return carla_frontend_execPluginListDialog(&gui); | |||||
| // } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -1,4 +1,4 @@ | |||||
| // SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-License-Identifier: GPL-2.0-or-later | // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| #pragma once | #pragma once | ||||
| @@ -10,6 +10,8 @@ using CARLA_BACKEND_NAMESPACE::PluginType; | |||||
| extern "C" { | extern "C" { | ||||
| #endif | #endif | ||||
| typedef struct _CarlaHostHandle* CarlaHostHandle; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| typedef struct { | typedef struct { | ||||
| @@ -49,17 +51,26 @@ typedef struct { | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| class PluginListDialog; | class PluginListDialog; | ||||
| class QWidget; | |||||
| #else | #else | ||||
| struct PluginListDialog; | struct PluginListDialog; | ||||
| struct QWidget; | |||||
| #endif | #endif | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| CARLA_PLUGIN_EXPORT void | |||||
| carla_frontend_createAndExecAboutDialog(QWidget* parent, CarlaHostHandle hostHandle, bool isControl, bool isPlugin); | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| CARLA_PLUGIN_EXPORT const JackAppDialogResults* | CARLA_PLUGIN_EXPORT const JackAppDialogResults* | ||||
| carla_frontend_createAndExecJackAppDialog(void* parent, const char* projectFilename); | |||||
| carla_frontend_createAndExecJackAppDialog(QWidget* parent, const char* projectFilename); | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| CARLA_PLUGIN_EXPORT PluginListDialog* | CARLA_PLUGIN_EXPORT PluginListDialog* | ||||
| carla_frontend_createPluginListDialog(void* parent, const HostSettings* hostSettings); | |||||
| carla_frontend_createPluginListDialog(QWidget* parent, const HostSettings* hostSettings); | |||||
| CARLA_PLUGIN_EXPORT void | CARLA_PLUGIN_EXPORT void | ||||
| carla_frontend_destroyPluginListDialog(PluginListDialog* dialog); | carla_frontend_destroyPluginListDialog(PluginListDialog* dialog); | ||||
| @@ -81,6 +81,9 @@ class CarlaFrontendLib(): | |||||
| def __init__(self, filename): | def __init__(self, filename): | ||||
| self.lib = cdll.LoadLibrary(filename) | self.lib = cdll.LoadLibrary(filename) | ||||
| self.lib.carla_frontend_createAndExecAboutDialog.argtypes = (c_void_p, c_void_p, c_bool, c_bool) | |||||
| self.lib.carla_frontend_createAndExecAboutDialog.restype = None | |||||
| self.lib.carla_frontend_createAndExecJackAppDialog.argtypes = (c_void_p, c_char_p) | self.lib.carla_frontend_createAndExecJackAppDialog.argtypes = (c_void_p, c_char_p) | ||||
| self.lib.carla_frontend_createAndExecJackAppDialog.restype = POINTER(JackApplicationDialogResults) | self.lib.carla_frontend_createAndExecJackAppDialog.restype = POINTER(JackApplicationDialogResults) | ||||
| @@ -98,9 +101,16 @@ class CarlaFrontendLib(): | |||||
| # -------------------------------------------------------------------------------------------------------- | # -------------------------------------------------------------------------------------------------------- | ||||
| def createAndExecAboutDialog(self, parent, hostHandle, isControl, isPlugin): | |||||
| return structToDictOrNull(self.lib.carla_frontend_createAndExecAboutDialog(unwrapinstance(parent), | |||||
| hostHandle, | |||||
| isControl, | |||||
| isPlugin)) | |||||
| def createAndExecJackAppDialog(self, parent, projectFilename): | def createAndExecJackAppDialog(self, parent, projectFilename): | ||||
| return structToDictOrNull(self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent), | |||||
| projectFilename.encode("utf-8"))) | |||||
| return structToDictOrNull( | |||||
| self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent), | |||||
| projectFilename.encode("utf-8"))) | |||||
| def createPluginListDialog(self, parent, hostSettings): | def createPluginListDialog(self, parent, hostSettings): | ||||
| hostSettingsC = HostSettings() | hostSettingsC = HostSettings() | ||||
| @@ -2215,7 +2215,10 @@ class HostWindow(QMainWindow): | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_aboutCarla(self): | def slot_aboutCarla(self): | ||||
| CarlaAboutW(self.fParentOrSelf, self.host).exec_() | |||||
| gCarla.felib.createAndExecAboutDialog(self.fParentOrSelf, | |||||
| self.host.handle, | |||||
| self.host.isControl, | |||||
| self.host.isPlugin) | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_aboutQt(self): | def slot_aboutQt(self): | ||||
| @@ -42,7 +42,6 @@ elif qt_config == 6: | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Imports (Custom) | # Imports (Custom) | ||||
| import ui_carla_about | |||||
| import ui_carla_edit | import ui_carla_edit | ||||
| import ui_carla_parameter | import ui_carla_parameter | ||||
| @@ -113,135 +112,6 @@ ICON_STATE_WAIT = 2 # nothing, sets as off | |||||
| ICON_STATE_OFF = 1 # turns off, sets as null | ICON_STATE_OFF = 1 # turns off, sets as null | ||||
| ICON_STATE_NULL = 0 # nothing | ICON_STATE_NULL = 0 # nothing | ||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Carla About dialog | |||||
| class CarlaAboutW(QDialog): | |||||
| def __init__(self, parent, host): | |||||
| QDialog.__init__(self, parent) | |||||
| self.ui = ui_carla_about.Ui_CarlaAboutW() | |||||
| self.ui.setupUi(self) | |||||
| if host.isControl: | |||||
| extraInfo = " - <b>%s</b>" % self.tr("OSC Bridge Version") | |||||
| elif host.isPlugin: | |||||
| extraInfo = " - <b>%s</b>" % self.tr("Plugin Version") | |||||
| else: | |||||
| extraInfo = "" | |||||
| self.ui.l_about.setText(self.tr("" | |||||
| "<br>Version %s" | |||||
| "<br>Carla is a fully-featured audio plugin host%s.<br>" | |||||
| "<br>Copyright (C) 2011-2025 falkTX<br>" | |||||
| "" % (CARLA_VERSION_STRING, extraInfo))) | |||||
| if self.ui.about.palette().color(QPalette.Background).blackF() < 0.5: | |||||
| self.ui.l_icons.setPixmap(QPixmap(":/bitmaps/carla_about_black.png")) | |||||
| self.ui.ico_example_edit.setPixmap(QPixmap(":/bitmaps/button_file-black.png")) | |||||
| self.ui.ico_example_file.setPixmap(QPixmap(":/scalable/button_edit-black.svg")) | |||||
| self.ui.ico_example_gui.setPixmap(QPixmap(":/bitmaps/button_gui-black.png")) | |||||
| if host.isControl: | |||||
| self.ui.l_extended.hide() | |||||
| self.ui.tabWidget.removeTab(3) | |||||
| self.ui.tabWidget.removeTab(2) | |||||
| self.ui.l_extended.setText(gCarla.utils.get_complete_license_text()) | |||||
| if host.is_engine_running() and not host.isControl: | |||||
| self.ui.le_osc_url_tcp.setText(host.get_host_osc_url_tcp()) | |||||
| self.ui.le_osc_url_udp.setText(host.get_host_osc_url_udp()) | |||||
| else: | |||||
| self.ui.le_osc_url_tcp.setText(self.tr("(Engine not running)")) | |||||
| self.ui.le_osc_url_udp.setText(self.tr("(Engine not running)")) | |||||
| # pylint: disable=line-too-long | |||||
| self.ui.l_osc_cmds.setText("<table>" | |||||
| "<tr><td>" "/set_active" " </td><td><i-value></td></tr>" | |||||
| "<tr><td>" "/set_drywet" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_volume" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_balance_left" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_balance_right" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_panning" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_parameter_value" " </td><td><i-index> <f-value></td></tr>" | |||||
| "<tr><td>" "/set_parameter_midi_cc" " </td><td><i-index> <i-cc></td></tr>" | |||||
| "<tr><td>" "/set_parameter_midi_channel" " </td><td><i-index> <i-channel></td></tr>" | |||||
| "<tr><td>" "/set_program" " </td><td><i-index></td></tr>" | |||||
| "<tr><td>" "/set_midi_program" " </td><td><i-index></td></tr>" | |||||
| "<tr><td>" "/note_on" " </td><td><i-channel> <i-note> <i-velo></td></tr>" | |||||
| "<tr><td>" "/note_off" " </td><td><i-channel> <i-note</td></tr>" | |||||
| "</table>" | |||||
| ) | |||||
| self.ui.l_example.setText("/Carla/2/set_parameter_value 5 1.0") | |||||
| self.ui.l_example_help.setText("<i>(as in this example, \"2\" is the plugin number and \"5\" the parameter)</i>") | |||||
| # pylint: enable=line-too-long | |||||
| self.ui.l_ladspa.setText(self.tr("Everything! (Including LRDF)")) | |||||
| self.ui.l_dssi.setText(self.tr("Everything! (Including CustomData/Chunks)")) | |||||
| self.ui.l_lv2.setText(self.tr("About 110% complete (using custom extensions)<br/>" | |||||
| "Implemented Feature/Extensions:" | |||||
| "<ul>" | |||||
| "<li>http://lv2plug.in/ns/ext/atom</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/buf-size</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/data-access</li>" | |||||
| #"<li>http://lv2plug.in/ns/ext/dynmanifest</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/event</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/instance-access</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/log</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/midi</li>" | |||||
| #"<li>http://lv2plug.in/ns/ext/morph</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/options</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/parameters</li>" | |||||
| #"<li>http://lv2plug.in/ns/ext/patch</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/port-props</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/presets</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/resize-port</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/state</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/time</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/uri-map</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/urid</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/worker</li>" | |||||
| "<li>http://lv2plug.in/ns/extensions/ui</li>" | |||||
| "<li>http://lv2plug.in/ns/extensions/units</li>" | |||||
| "<li>http://home.gna.org/lv2dynparam/rtmempool/v1</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/external-ui</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/programs</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/props</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/rtmempool</li>" | |||||
| "<li>http://ll-plugins.nongnu.org/lv2/ext/midimap</li>" | |||||
| "<li>http://ll-plugins.nongnu.org/lv2/ext/miditype</li>" | |||||
| "</ul>")) | |||||
| self.ui.l_vst2.setText(self.tr("About 85% complete (missing vst bank/presets and some minor stuff)")) | |||||
| self.ui.l_vst3.setText(self.tr("About 66% complete")) | |||||
| if CARLA_OS_MAC: | |||||
| self.ui.l_au.setText(self.tr("About 20% complete")) | |||||
| else: | |||||
| self.ui.line_vst3.hide() | |||||
| self.ui.l_au.hide() | |||||
| self.ui.lid_au.hide() | |||||
| # 3rd tab is usually longer than the 1st | |||||
| # adjust appropriately | |||||
| self.ui.tabWidget.setCurrentIndex(2) | |||||
| self.adjustSize() | |||||
| self.ui.tabWidget.setCurrentIndex(0) | |||||
| self.setFixedSize(self.size()) | |||||
| flags = self.windowFlags() | |||||
| flags &= ~Qt.WindowContextHelpButtonHint | |||||
| if CARLA_OS_WIN: | |||||
| flags |= Qt.MSWindowsFixedSizeDialogHint | |||||
| self.setWindowFlags(flags) | |||||
| if CARLA_OS_MAC: | |||||
| self.setWindowModality(Qt.WindowModal) | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Plugin Parameter | # Plugin Parameter | ||||
| @@ -1852,9 +1722,6 @@ if __name__ == '__main__': | |||||
| _host.add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/karplong.so", "karplong", "karplong", 0, None, 0x0) | _host.add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/karplong.so", "karplong", "karplong", 0, None, 0x0) | ||||
| _host.set_active(0, True) | _host.set_active(0, True) | ||||
| gui1 = CarlaAboutW(None, _host) | |||||
| gui1.show() | |||||
| gui2 = PluginEdit(None, _host, 0) | gui2 = PluginEdit(None, _host, 0) | ||||
| gui2.testTimer() | gui2.testTimer() | ||||
| gui2.show() | gui2.show() | ||||
| @@ -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 .jackappdialog import JackAppDialog | |||||
| @@ -0,0 +1,165 @@ | |||||
| // SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-License-Identifier: GPL-2.0-or-later | |||||
| #include "aboutdialog.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 <QtCore/QFileInfo> | |||||
| // #include <QtCore/QVector> | |||||
| // #include <QtWidgets/QPushButton> | |||||
| #ifdef __clang__ | |||||
| # pragma clang diagnostic pop | |||||
| #elif defined(__GNUC__) && __GNUC__ >= 8 | |||||
| # pragma GCC diagnostic pop | |||||
| #endif | |||||
| #include "CarlaHost.h" | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // About Dialog | |||||
| AboutDialog::AboutDialog(QWidget* const parent, | |||||
| const CarlaHostHandle hostHandle, | |||||
| const bool isControl, | |||||
| const bool isPlugin) | |||||
| : QDialog(parent) | |||||
| { | |||||
| ui.setupUi(this); | |||||
| QString extraInfo; | |||||
| if (isControl) | |||||
| extraInfo = QString(" - <b>%1</b>").arg(tr("OSC Bridge Version")); | |||||
| else if (isPlugin) | |||||
| extraInfo = QString(" - <b>%1</b>").arg(tr("Plugin Version")); | |||||
| ui.l_about->setText(tr("" | |||||
| "<br>Version %1" | |||||
| "<br>Carla is a fully-featured audio plugin host%2.<br>" | |||||
| "<br>Copyright (C) 2011-2025 falkTX<br>" | |||||
| "").arg(CARLA_VERSION_STRING).arg(extraInfo)); | |||||
| if (ui.about->palette().color(QPalette::Background).blackF() < 0.5) | |||||
| { | |||||
| ui.l_icons->setPixmap(QPixmap(":/bitmaps/carla_about_black.png")); | |||||
| ui.ico_example_edit->setPixmap(QPixmap(":/bitmaps/button_file-black.png")); | |||||
| ui.ico_example_file->setPixmap(QPixmap(":/scalable/button_edit-black.svg")); | |||||
| ui.ico_example_gui->setPixmap(QPixmap(":/bitmaps/button_gui-black.png")); | |||||
| } | |||||
| if (isControl || isPlugin) | |||||
| { | |||||
| ui.l_extended->hide(); | |||||
| ui.tabWidget->removeTab(3); | |||||
| ui.tabWidget->removeTab(2); | |||||
| } | |||||
| else if (carla_is_engine_running(hostHandle)) | |||||
| { | |||||
| ui.le_osc_url_tcp->setText(carla_get_host_osc_url_tcp(hostHandle)); | |||||
| ui.le_osc_url_udp->setText(carla_get_host_osc_url_udp(hostHandle)); | |||||
| } | |||||
| else | |||||
| { | |||||
| ui.le_osc_url_tcp->setText(tr("(Engine not running)")); | |||||
| ui.le_osc_url_udp->setText(tr("(Engine not running)")); | |||||
| } | |||||
| ui.l_extended->setText(carla_get_complete_license_text()); | |||||
| ui.l_osc_cmds->setText("<table>" | |||||
| "<tr><td>" "/set_active" " </td><td><i-value></td></tr>" | |||||
| "<tr><td>" "/set_drywet" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_volume" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_balance_left" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_balance_right" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_panning" " </td><td><f-value></td></tr>" | |||||
| "<tr><td>" "/set_parameter_value" " </td><td><i-index> <f-value></td></tr>" | |||||
| "<tr><td>" "/set_parameter_midi_cc" " </td><td><i-index> <i-cc></td></tr>" | |||||
| "<tr><td>" "/set_parameter_midi_channel" " </td><td><i-index> <i-channel></td></tr>" | |||||
| "<tr><td>" "/set_program" " </td><td><i-index></td></tr>" | |||||
| "<tr><td>" "/set_midi_program" " </td><td><i-index></td></tr>" | |||||
| "<tr><td>" "/note_on" " </td><td><i-channel> <i-note> <i-velo></td></tr>" | |||||
| "<tr><td>" "/note_off" " </td><td><i-channel> <i-note</td></tr>" | |||||
| "</table>"); | |||||
| ui.l_example->setText("/Carla/2/set_parameter_value 5 1.0"); | |||||
| ui.l_example_help->setText("<i>(as in this example, \"2\" is the plugin number and \"5\" the parameter)</i>"); | |||||
| ui.l_ladspa->setText(tr("Everything! (Including LRDF)")); | |||||
| ui.l_dssi->setText(tr("Everything! (Including CustomData/Chunks)")); | |||||
| ui.l_lv2->setText(tr("About 110% complete (using custom extensions)<br/>" | |||||
| "Implemented Feature/Extensions:" | |||||
| "<ul>" | |||||
| "<li>http://lv2plug.in/ns/ext/atom</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/buf-size</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/data-access</li>" | |||||
| // "<li>http://lv2plug.in/ns/ext/dynmanifest</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/event</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/instance-access</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/log</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/midi</li>" | |||||
| // "<li>http://lv2plug.in/ns/ext/morph</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/options</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/parameters</li>" | |||||
| // "<li>http://lv2plug.in/ns/ext/patch</li>" | |||||
| // "<li>http://lv2plug.in/ns/ext/port-groups</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/port-props</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/presets</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/resize-port</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/state</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/time</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/uri-map</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/urid</li>" | |||||
| "<li>http://lv2plug.in/ns/ext/worker</li>" | |||||
| "<li>http://lv2plug.in/ns/extensions/ui</li>" | |||||
| "<li>http://lv2plug.in/ns/extensions/units</li>" | |||||
| "<li>http://home.gna.org/lv2dynparam/rtmempool/v1</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/external-ui</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/programs</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/props</li>" | |||||
| "<li>http://kxstudio.sf.net/ns/lv2ext/rtmempool</li>" | |||||
| "<li>http://ll-plugins.nongnu.org/lv2/ext/midimap</li>" | |||||
| "<li>http://ll-plugins.nongnu.org/lv2/ext/miditype</li>" | |||||
| "</ul>")); | |||||
| ui.l_vst2->setText(tr("About 85% complete (missing vst bank/presets and some minor stuff)")); | |||||
| ui.l_vst3->setText(tr("About 66% complete")); | |||||
| #ifdef CARLA_OS_MAC | |||||
| ui.l_au->setText(tr("About 20% complete")); | |||||
| #else | |||||
| ui.line_vst3->hide(); | |||||
| ui.l_au->hide(); | |||||
| ui.lid_au->hide(); | |||||
| #endif | |||||
| // 3rd tab is usually longer than the 1st, adjust appropriately | |||||
| ui.tabWidget->setCurrentIndex(2); | |||||
| adjustSize(); | |||||
| ui.tabWidget->setCurrentIndex(0); | |||||
| setFixedSize(size()); | |||||
| Qt::WindowFlags flags = windowFlags(); | |||||
| flags &= ~Qt::WindowContextHelpButtonHint; | |||||
| #ifdef CARLA_OS_WIN | |||||
| flags |= ~Qt::MSWindowsFixedSizeDialogHint; | |||||
| #endif | |||||
| setWindowFlags(flags); | |||||
| #ifdef CARLA_OS_MAC | |||||
| if (parent != nullptr) | |||||
| setWindowModality(Qt::WindowModal); | |||||
| #endif | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -0,0 +1,39 @@ | |||||
| // SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-License-Identifier: GPL-2.0-or-later | |||||
| #pragma once | |||||
| #include "carla_frontend.h" | |||||
| #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_aboutdialog.h" | |||||
| #ifdef __clang__ | |||||
| # pragma clang diagnostic pop | |||||
| #elif defined(__GNUC__) && __GNUC__ >= 8 | |||||
| # pragma GCC diagnostic pop | |||||
| #endif | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // About Dialog | |||||
| class AboutDialog : public QDialog | |||||
| { | |||||
| Ui_AboutDialog ui; | |||||
| // ---------------------------------------------------------------------------------------------------------------- | |||||
| public: | |||||
| explicit AboutDialog(QWidget* parent, CarlaHostHandle hostHandle, bool isControl, bool isPlugin); | |||||
| }; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -1,7 +1,7 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | <ui version="4.0"> | ||||
| <class>CarlaAboutW</class> | |||||
| <widget class="QDialog" name="CarlaAboutW"> | |||||
| <class>AboutDialog</class> | |||||
| <widget class="QDialog" name="AboutDialog"> | |||||
| <property name="geometry"> | <property name="geometry"> | ||||
| <rect> | <rect> | ||||
| <x>0</x> | <x>0</x> | ||||
| @@ -1425,7 +1425,7 @@ POSSIBILITY OF SUCH DAMAGES. | |||||
| <connection> | <connection> | ||||
| <sender>buttonBox</sender> | <sender>buttonBox</sender> | ||||
| <signal>accepted()</signal> | <signal>accepted()</signal> | ||||
| <receiver>CarlaAboutW</receiver> | |||||
| <receiver>AboutDialog</receiver> | |||||
| <slot>accept()</slot> | <slot>accept()</slot> | ||||
| <hints> | <hints> | ||||
| <hint type="sourcelabel"> | <hint type="sourcelabel"> | ||||
| @@ -1441,7 +1441,7 @@ POSSIBILITY OF SUCH DAMAGES. | |||||
| <connection> | <connection> | ||||
| <sender>buttonBox</sender> | <sender>buttonBox</sender> | ||||
| <signal>rejected()</signal> | <signal>rejected()</signal> | ||||
| <receiver>CarlaAboutW</receiver> | |||||
| <receiver>AboutDialog</receiver> | |||||
| <slot>reject()</slot> | <slot>reject()</slot> | ||||
| <hints> | <hints> | ||||
| <hint type="sourcelabel"> | <hint type="sourcelabel"> | ||||
| @@ -1,19 +1,5 @@ | |||||
| /* | |||||
| * 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-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-License-Identifier: GPL-2.0-or-later | |||||
| #include "jackappdialog.hpp" | #include "jackappdialog.hpp" | ||||
| @@ -27,9 +13,7 @@ | |||||
| # pragma GCC diagnostic ignored "-Wdeprecated-copy" | # pragma GCC diagnostic ignored "-Wdeprecated-copy" | ||||
| #endif | #endif | ||||
| #include "ui_jackappdialog.h" | |||||
| #include <QtCore/QFileInfo> | #include <QtCore/QFileInfo> | ||||
| #include <QtCore/QVector> | |||||
| #include <QtWidgets/QPushButton> | #include <QtWidgets/QPushButton> | ||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| @@ -40,43 +24,29 @@ | |||||
| #include "qsafesettings.hpp" | #include "qsafesettings.hpp" | ||||
| #include "CarlaFrontend.h" | |||||
| #include "CarlaLibJackHints.h" | #include "CarlaLibJackHints.h" | ||||
| #include "CarlaString.hpp" | #include "CarlaString.hpp" | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // Jack Application Dialog | // Jack Application Dialog | ||||
| enum { | |||||
| UI_SESSION_NONE = 0, | |||||
| UI_SESSION_LADISH = 1, | |||||
| UI_SESSION_NSM = 2, | |||||
| }; | |||||
| struct JackAppDialog::Self { | |||||
| Ui_JackAppDialog ui; | |||||
| struct JackAppDialog::PrivateData { | |||||
| const QString fProjectFilename; | const QString fProjectFilename; | ||||
| Self(const char* const projectFilename) | |||||
| PrivateData(const char* const projectFilename) | |||||
| : fProjectFilename(projectFilename) {} | : fProjectFilename(projectFilename) {} | ||||
| static Self& create(const char* const projectFilename) | |||||
| { | |||||
| Self* const self = new Self(projectFilename); | |||||
| return *self; | |||||
| } | |||||
| }; | }; | ||||
| JackAppDialog::JackAppDialog(QWidget* const parent, const char* const projectFilename) | JackAppDialog::JackAppDialog(QWidget* const parent, const char* const projectFilename) | ||||
| : QDialog(parent), | : QDialog(parent), | ||||
| self(Self::create(projectFilename)) | |||||
| p(new PrivateData(projectFilename)) | |||||
| { | { | ||||
| self.ui.setupUi(this); | |||||
| ui.setupUi(this); | |||||
| // ------------------------------------------------------------------------------------------------------------- | |||||
| // ---------------------------------------------------------------------------------------------------------------- | |||||
| // UI setup | // UI setup | ||||
| self.ui.group_error->setVisible(false); | |||||
| ui.group_error->setVisible(false); | |||||
| adjustSize(); | adjustSize(); | ||||
| setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | ||||
| @@ -86,34 +56,34 @@ JackAppDialog::JackAppDialog(QWidget* const parent, const char* const projectFil | |||||
| setWindowModality(Qt::WindowModal); | setWindowModality(Qt::WindowModal); | ||||
| #endif | #endif | ||||
| // ------------------------------------------------------------------------------------------------------------- | |||||
| // ---------------------------------------------------------------------------------------------------------------- | |||||
| // Load settings | // Load settings | ||||
| loadSettings(); | loadSettings(); | ||||
| // ------------------------------------------------------------------------------------------------------------- | |||||
| // ---------------------------------------------------------------------------------------------------------------- | |||||
| // Set-up connections | // Set-up connections | ||||
| connect(this, &QDialog::finished, | connect(this, &QDialog::finished, | ||||
| this, &JackAppDialog::slot_saveSettings); | this, &JackAppDialog::slot_saveSettings); | ||||
| connect(self.ui.cb_session_mgr, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), | |||||
| connect(ui.cb_session_mgr, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), | |||||
| this, &JackAppDialog::slot_sessionManagerChanged); | this, &JackAppDialog::slot_sessionManagerChanged); | ||||
| connect(self.ui.le_command, &QLineEdit::textChanged, | |||||
| connect(ui.le_command, &QLineEdit::textChanged, | |||||
| this, &JackAppDialog::slot_commandChanged); | this, &JackAppDialog::slot_commandChanged); | ||||
| } | } | ||||
| JackAppDialog::~JackAppDialog() | JackAppDialog::~JackAppDialog() | ||||
| { | { | ||||
| delete &self; | |||||
| delete p; | |||||
| } | } | ||||
| // ----------------------------------------------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // public methods | // public methods | ||||
| JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const | JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const | ||||
| { | { | ||||
| const QString command = self.ui.le_command->text(); | |||||
| QString name = self.ui.le_name->text(); | |||||
| const QString command = ui.le_command->text(); | |||||
| QString name = ui.le_name->text(); | |||||
| if (name.isEmpty()) | if (name.isEmpty()) | ||||
| { | { | ||||
| @@ -122,7 +92,7 @@ JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const | |||||
| } | } | ||||
| SessionManager smgr; | SessionManager smgr; | ||||
| switch (self.ui.cb_session_mgr->currentIndex()) | |||||
| switch (ui.cb_session_mgr->currentIndex()) | |||||
| { | { | ||||
| case UI_SESSION_LADISH: | case UI_SESSION_LADISH: | ||||
| smgr = LIBJACK_SESSION_MANAGER_LADISH; | smgr = LIBJACK_SESSION_MANAGER_LADISH; | ||||
| @@ -136,28 +106,28 @@ JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const | |||||
| } | } | ||||
| uint flags = 0x0; | uint flags = 0x0; | ||||
| if (self.ui.cb_manage_window->isChecked()) | |||||
| if (ui.cb_manage_window->isChecked()) | |||||
| flags |= LIBJACK_FLAG_CONTROL_WINDOW; | flags |= LIBJACK_FLAG_CONTROL_WINDOW; | ||||
| if (self.ui.cb_capture_first_window->isChecked()) | |||||
| if (ui.cb_capture_first_window->isChecked()) | |||||
| flags |= LIBJACK_FLAG_CAPTURE_FIRST_WINDOW; | flags |= LIBJACK_FLAG_CAPTURE_FIRST_WINDOW; | ||||
| if (self.ui.cb_buffers_addition_mode->isChecked()) | |||||
| if (ui.cb_buffers_addition_mode->isChecked()) | |||||
| flags |= LIBJACK_FLAG_AUDIO_BUFFERS_ADDITION; | flags |= LIBJACK_FLAG_AUDIO_BUFFERS_ADDITION; | ||||
| if (self.ui.cb_out_midi_mixdown->isChecked()) | |||||
| if (ui.cb_out_midi_mixdown->isChecked()) | |||||
| flags |= LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN; | flags |= LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN; | ||||
| if (self.ui.cb_external_start->isChecked()) | |||||
| if (ui.cb_external_start->isChecked()) | |||||
| flags |= LIBJACK_FLAG_EXTERNAL_START; | flags |= LIBJACK_FLAG_EXTERNAL_START; | ||||
| const QString labelSetup(QString("%1%2%3%4%5%6").arg(QChar('0' + self.ui.sb_audio_ins->value())) | |||||
| .arg(QChar('0' + self.ui.sb_audio_outs->value())) | |||||
| .arg(QChar('0' + self.ui.sb_midi_ins->value())) | |||||
| .arg(QChar('0' + self.ui.sb_midi_outs->value())) | |||||
| const QString labelSetup(QString("%1%2%3%4%5%6").arg(QChar('0' + ui.sb_audio_ins->value())) | |||||
| .arg(QChar('0' + ui.sb_audio_outs->value())) | |||||
| .arg(QChar('0' + ui.sb_midi_ins->value())) | |||||
| .arg(QChar('0' + ui.sb_midi_outs->value())) | |||||
| .arg(QChar('0' + smgr)) | .arg(QChar('0' + smgr)) | ||||
| .arg(QChar('0' + flags))); | .arg(QChar('0' + flags))); | ||||
| return {command, name, labelSetup}; | return {command, name, labelSetup}; | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // private methods | // private methods | ||||
| void JackAppDialog::checkIfButtonBoxShouldBeEnabled(const int index, const QCarlaString& command) | void JackAppDialog::checkIfButtonBoxShouldBeEnabled(const int index, const QCarlaString& command) | ||||
| @@ -166,28 +136,28 @@ void JackAppDialog::checkIfButtonBoxShouldBeEnabled(const int index, const QCarl | |||||
| QCarlaString showErr; | QCarlaString showErr; | ||||
| // NSM applications must not be abstract or absolute paths, and must not contain arguments | // NSM applications must not be abstract or absolute paths, and must not contain arguments | ||||
| if (enabled and index == UI_SESSION_NSM) | |||||
| if (enabled && index == UI_SESSION_NSM) | |||||
| { | { | ||||
| if (QVector<QChar>{'.', '/'}.contains(command[0])) | |||||
| if (command[0] == '.' || command[0] == '/') | |||||
| showErr = tr("NSM applications cannot use abstract or absolute paths"); | showErr = tr("NSM applications cannot use abstract or absolute paths"); | ||||
| else if (command.contains(' ') or command.contains(';') or command.contains('&')) | else if (command.contains(' ') or command.contains(';') or command.contains('&')) | ||||
| showErr = tr("NSM applications cannot use CLI arguments"); | showErr = tr("NSM applications cannot use CLI arguments"); | ||||
| else if (self.fProjectFilename.isEmpty()) | |||||
| else if (p->fProjectFilename.isEmpty()) | |||||
| showErr = tr("You need to save the current Carla project before NSM can be used"); | showErr = tr("You need to save the current Carla project before NSM can be used"); | ||||
| } | } | ||||
| if (showErr.isNotEmpty()) | if (showErr.isNotEmpty()) | ||||
| { | { | ||||
| enabled = false; | enabled = false; | ||||
| self.ui.l_error->setText(showErr); | |||||
| self.ui.group_error->setVisible(true); | |||||
| ui.l_error->setText(showErr); | |||||
| ui.group_error->setVisible(true); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| self.ui.group_error->setVisible(false); | |||||
| ui.group_error->setVisible(false); | |||||
| } | } | ||||
| if (QPushButton* const button = self.ui.buttonBox->button(QDialogButtonBox::Ok)) | |||||
| if (QPushButton* const button = ui.buttonBox->button(QDialogButtonBox::Ok)) | |||||
| button->setEnabled(enabled); | button->setEnabled(enabled); | ||||
| } | } | ||||
| @@ -198,104 +168,53 @@ void JackAppDialog::loadSettings() | |||||
| const QString smName = settings.valueString("SessionManager", ""); | const QString smName = settings.valueString("SessionManager", ""); | ||||
| if (smName == "LADISH (SIGUSR1)") | if (smName == "LADISH (SIGUSR1)") | ||||
| self.ui.cb_session_mgr->setCurrentIndex(UI_SESSION_LADISH); | |||||
| ui.cb_session_mgr->setCurrentIndex(UI_SESSION_LADISH); | |||||
| else if (smName == "NSM") | else if (smName == "NSM") | ||||
| self.ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NSM); | |||||
| ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NSM); | |||||
| else | else | ||||
| self.ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NONE); | |||||
| self.ui.le_command->setText(settings.valueString("Command", "")); | |||||
| self.ui.le_name->setText(settings.valueString("Name", "")); | |||||
| self.ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); | |||||
| self.ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); | |||||
| self.ui.sb_audio_outs->setValue(settings.valueIntPositive("NumAudioOuts", 2)); | |||||
| self.ui.sb_midi_ins->setValue(settings.valueIntPositive("NumMidiIns", 0)); | |||||
| self.ui.sb_midi_outs->setValue(settings.valueIntPositive("NumMidiOuts", 0)); | |||||
| self.ui.cb_manage_window->setChecked(settings.valueBool("ManageWindow", true)); | |||||
| self.ui.cb_capture_first_window->setChecked(settings.valueBool("CaptureFirstWindow", false)); | |||||
| self.ui.cb_out_midi_mixdown->setChecked(settings.valueBool("MidiOutMixdown", false)); | |||||
| checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr->currentIndex(), | |||||
| self.ui.le_command->text()); | |||||
| ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NONE); | |||||
| ui.le_command->setText(settings.valueString("Command", "")); | |||||
| ui.le_name->setText(settings.valueString("Name", "")); | |||||
| ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); | |||||
| ui.sb_audio_ins->setValue(settings.valueIntPositive("NumAudioIns", 2)); | |||||
| ui.sb_audio_outs->setValue(settings.valueIntPositive("NumAudioOuts", 2)); | |||||
| ui.sb_midi_ins->setValue(settings.valueIntPositive("NumMidiIns", 0)); | |||||
| ui.sb_midi_outs->setValue(settings.valueIntPositive("NumMidiOuts", 0)); | |||||
| ui.cb_manage_window->setChecked(settings.valueBool("ManageWindow", true)); | |||||
| ui.cb_capture_first_window->setChecked(settings.valueBool("CaptureFirstWindow", false)); | |||||
| ui.cb_out_midi_mixdown->setChecked(settings.valueBool("MidiOutMixdown", false)); | |||||
| checkIfButtonBoxShouldBeEnabled(ui.cb_session_mgr->currentIndex(), | |||||
| ui.le_command->text()); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // private slots | // private slots | ||||
| void JackAppDialog::slot_commandChanged(const QString& command) | void JackAppDialog::slot_commandChanged(const QString& command) | ||||
| { | { | ||||
| checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr->currentIndex(), command); | |||||
| checkIfButtonBoxShouldBeEnabled(ui.cb_session_mgr->currentIndex(), command); | |||||
| } | } | ||||
| void JackAppDialog::slot_sessionManagerChanged(const int index) | void JackAppDialog::slot_sessionManagerChanged(const int index) | ||||
| { | { | ||||
| checkIfButtonBoxShouldBeEnabled(index, self.ui.le_command->text()); | |||||
| checkIfButtonBoxShouldBeEnabled(index, ui.le_command->text()); | |||||
| } | } | ||||
| void JackAppDialog::slot_saveSettings() | void JackAppDialog::slot_saveSettings() | ||||
| { | { | ||||
| QSafeSettings settings("falkTX", "CarlaAddJackApp"); | QSafeSettings settings("falkTX", "CarlaAddJackApp"); | ||||
| settings.setValue("Command", self.ui.le_command->text()); | |||||
| settings.setValue("Name", self.ui.le_name->text()); | |||||
| settings.setValue("SessionManager", self.ui.cb_session_mgr->currentText()); | |||||
| settings.setValue("NumAudioIns", self.ui.sb_audio_ins->value()); | |||||
| settings.setValue("NumAudioOuts", self.ui.sb_audio_outs->value()); | |||||
| settings.setValue("NumMidiIns", self.ui.sb_midi_ins->value()); | |||||
| settings.setValue("NumMidiOuts", self.ui.sb_midi_outs->value()); | |||||
| settings.setValue("ManageWindow", self.ui.cb_manage_window->isChecked()); | |||||
| settings.setValue("CaptureFirstWindow", self.ui.cb_capture_first_window->isChecked()); | |||||
| settings.setValue("MidiOutMixdown", self.ui.cb_out_midi_mixdown->isChecked()); | |||||
| settings.setValue("Command", ui.le_command->text()); | |||||
| settings.setValue("Name", ui.le_name->text()); | |||||
| settings.setValue("SessionManager", ui.cb_session_mgr->currentText()); | |||||
| settings.setValue("NumAudioIns", ui.sb_audio_ins->value()); | |||||
| settings.setValue("NumAudioOuts", ui.sb_audio_outs->value()); | |||||
| settings.setValue("NumMidiIns", ui.sb_midi_ins->value()); | |||||
| settings.setValue("NumMidiOuts", ui.sb_midi_outs->value()); | |||||
| settings.setValue("ManageWindow", ui.cb_manage_window->isChecked()); | |||||
| settings.setValue("CaptureFirstWindow", ui.cb_capture_first_window->isChecked()); | |||||
| settings.setValue("MidiOutMixdown", ui.cb_out_midi_mixdown->isChecked()); | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| const JackAppDialogResults* | |||||
| carla_frontend_createAndExecJackAppDialog(void* const parent, const char* const projectFilename) | |||||
| { | |||||
| JackAppDialog gui(reinterpret_cast<QWidget*>(parent), projectFilename); | |||||
| if (gui.exec()) | |||||
| { | |||||
| static JackAppDialogResults ret = {}; | |||||
| static CarlaString retCommand; | |||||
| static CarlaString retName; | |||||
| static CarlaString retLabelSetup; | |||||
| const JackAppDialog::CommandAndFlags cafs = gui.getCommandAndFlags(); | |||||
| retCommand = cafs.command.toUtf8().constData(); | |||||
| retName = cafs.name.toUtf8().constData(); | |||||
| retLabelSetup = cafs.labelSetup.toUtf8().constData(); | |||||
| ret.command = retCommand; | |||||
| ret.name = retName; | |||||
| ret.labelSetup = retLabelSetup; | |||||
| return &ret; | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| #if 0 | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // Testing | |||||
| #include "../utils/qsafesettings.cpp" | |||||
| int main(int argc, char* argv[]) | |||||
| { | |||||
| QApplication app(argc, argv); | |||||
| if (JackAppDialogResults* const res = carla_frontend_createAndExecJackAppDialog(nullptr, "")) | |||||
| { | |||||
| printf("Results:\n"); | |||||
| printf("\tCommand: %s\n", res->command); | |||||
| printf("\tName: %s\n", res->name); | |||||
| printf("\tLabelSetup: %s\n", res->labelSetup); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| #endif | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -1,22 +1,10 @@ | |||||
| /* | |||||
| * 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. | |||||
| */ | |||||
| // SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-License-Identifier: GPL-2.0-or-later | |||||
| #pragma once | #pragma once | ||||
| #include "carla_frontend.h" | |||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| # pragma clang diagnostic push | # pragma clang diagnostic push | ||||
| # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" | # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" | ||||
| @@ -27,7 +15,7 @@ | |||||
| # pragma GCC diagnostic ignored "-Wdeprecated-copy" | # pragma GCC diagnostic ignored "-Wdeprecated-copy" | ||||
| #endif | #endif | ||||
| #include <QtWidgets/QDialog> | |||||
| #include "ui_jackappdialog.h" | |||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| # pragma clang diagnostic pop | # pragma clang diagnostic pop | ||||
| @@ -42,8 +30,16 @@ | |||||
| class JackAppDialog : public QDialog | class JackAppDialog : public QDialog | ||||
| { | { | ||||
| struct Self; | |||||
| Self& self; | |||||
| enum { | |||||
| UI_SESSION_NONE, | |||||
| UI_SESSION_LADISH, | |||||
| UI_SESSION_NSM, | |||||
| }; | |||||
| struct PrivateData; | |||||
| PrivateData* const p; | |||||
| Ui_JackAppDialog ui; | |||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| @@ -1,221 +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 | |||||
| from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QWidget | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # Imports (Carla) | |||||
| from utils import QSafeSettings | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # Imports (Local) | |||||
| from jackappdialog_ui import Ui_JackAppDialog | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # Imports (API) | |||||
| SESSION_MGR_NONE = 0 | |||||
| SESSION_MGR_AUTO = 1 | |||||
| SESSION_MGR_JACK = 2 | |||||
| SESSION_MGR_LADISH = 3 | |||||
| SESSION_MGR_NSM = 4 | |||||
| FLAG_CONTROL_WINDOW = 0x01 | |||||
| FLAG_CAPTURE_FIRST_WINDOW = 0x02 | |||||
| FLAG_BUFFERS_ADDITION_MODE = 0x10 | |||||
| FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN = 0x20 | |||||
| FLAG_EXTERNAL_START = 0x40 | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # Jack Application Dialog | |||||
| UI_SESSION_NONE = 0 | |||||
| UI_SESSION_LADISH = 1 | |||||
| UI_SESSION_NSM = 2 | |||||
| class JackAppDialog(QDialog): | |||||
| def __init__(self, parent: QWidget, projectFilename: str): | |||||
| QDialog.__init__(self, parent) | |||||
| self.ui = Ui_JackAppDialog() | |||||
| self.ui.setupUi(self) | |||||
| self.fProjectFilename = projectFilename | |||||
| # -------------------------------------------------------------------------------------------------------------- | |||||
| # UI setup | |||||
| self.ui.group_error.setVisible(False) | |||||
| self.adjustSize() | |||||
| self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) | |||||
| # -------------------------------------------------------------------------------------------------------------- | |||||
| # Load settings | |||||
| self._loadSettings() | |||||
| # -------------------------------------------------------------------------------------------------------------- | |||||
| # Set-up connections | |||||
| self.finished.connect(self._slot_saveSettings) | |||||
| self.ui.cb_session_mgr.currentIndexChanged.connect(self._slot_sessionManagerChanged) | |||||
| self.ui.le_command.textChanged.connect(self._slot_commandChanged) | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # public methods | |||||
| def getCommandAndFlags(self): | |||||
| name = self.ui.le_name.text() | |||||
| command = self.ui.le_command.text() | |||||
| smgr = SESSION_MGR_NONE | |||||
| flags = 0x0 | |||||
| if not name: | |||||
| name = os.path.basename(command.split(" ",1)[0]).title() | |||||
| uiSessionMgrIndex = self.ui.cb_session_mgr.currentIndex() | |||||
| if uiSessionMgrIndex == UI_SESSION_LADISH: | |||||
| smgr = SESSION_MGR_LADISH | |||||
| elif uiSessionMgrIndex == UI_SESSION_NSM: | |||||
| smgr = SESSION_MGR_NSM | |||||
| if self.ui.cb_manage_window.isChecked(): | |||||
| flags |= FLAG_CONTROL_WINDOW | |||||
| if self.ui.cb_capture_first_window.isChecked(): | |||||
| flags |= FLAG_CAPTURE_FIRST_WINDOW | |||||
| if self.ui.cb_buffers_addition_mode.isChecked(): | |||||
| flags |= FLAG_BUFFERS_ADDITION_MODE | |||||
| if self.ui.cb_out_midi_mixdown.isChecked(): | |||||
| flags |= FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN | |||||
| if self.ui.cb_external_start.isChecked(): | |||||
| flags |= FLAG_EXTERNAL_START | |||||
| bv = ord('0') | |||||
| v1 = chr(bv + self.ui.sb_audio_ins.value()) | |||||
| v2 = chr(bv + self.ui.sb_audio_outs.value()) | |||||
| v3 = chr(bv + self.ui.sb_midi_ins.value()) | |||||
| v4 = chr(bv + self.ui.sb_midi_outs.value()) | |||||
| v5 = chr(bv + smgr) | |||||
| v6 = chr(bv + flags) | |||||
| labelSetup = f"{v1}{v2}{v3}{v4}{v5}{v6}" | |||||
| return (command, name, labelSetup) | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # private methods | |||||
| def _checkIfButtonBoxShouldBeEnabled(self, index: int, command: str): | |||||
| enabled = len(command) > 0 | |||||
| showErr = "" | |||||
| # NSM applications must not be abstract or absolute paths, and must not contain arguments | |||||
| if enabled and index == UI_SESSION_NSM: | |||||
| if command[0] in (".", "/"): | |||||
| showErr = self.tr("NSM applications cannot use abstract or absolute paths") | |||||
| elif " " in command or ";" in command or "&" in command: | |||||
| showErr = self.tr("NSM applications cannot use CLI arguments") | |||||
| elif not self.fProjectFilename: | |||||
| showErr = self.tr("You need to save the current Carla project before NSM can be used") | |||||
| if showErr: | |||||
| enabled = False | |||||
| self.ui.l_error.setText(showErr) | |||||
| self.ui.group_error.setVisible(True) | |||||
| else: | |||||
| self.ui.group_error.setVisible(False) | |||||
| self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled) | |||||
| def _loadSettings(self): | |||||
| settings = QSafeSettings("falkTX", "CarlaAddJackApp") | |||||
| smName = settings.value("SessionManager", "", str) | |||||
| if smName == "LADISH (SIGUSR1)": | |||||
| self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_LADISH) | |||||
| elif smName == "NSM": | |||||
| self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_NSM) | |||||
| else: | |||||
| self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_NONE) | |||||
| self.ui.le_command.setText(settings.value("Command", "", str)) | |||||
| self.ui.le_name.setText(settings.value("Name", "", str)) | |||||
| self.ui.sb_audio_ins.setValue(settings.value("NumAudioIns", 2, int)) | |||||
| self.ui.sb_audio_ins.setValue(settings.value("NumAudioIns", 2, int)) | |||||
| self.ui.sb_audio_outs.setValue(settings.value("NumAudioOuts", 2, int)) | |||||
| self.ui.sb_midi_ins.setValue(settings.value("NumMidiIns", 0, int)) | |||||
| self.ui.sb_midi_outs.setValue(settings.value("NumMidiOuts", 0, int)) | |||||
| self.ui.cb_manage_window.setChecked(settings.value("ManageWindow", True, bool)) | |||||
| self.ui.cb_capture_first_window.setChecked(settings.value("CaptureFirstWindow", False, bool)) | |||||
| self.ui.cb_out_midi_mixdown.setChecked(settings.value("MidiOutMixdown", False, bool)) | |||||
| self._checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr.currentIndex(), | |||||
| self.ui.le_command.text()) | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # private slots | |||||
| @pyqtSlot(str) | |||||
| def _slot_commandChanged(self, command: str): | |||||
| self._checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr.currentIndex(), command) | |||||
| @pyqtSlot(int) | |||||
| def _slot_sessionManagerChanged(self, index: int): | |||||
| self._checkIfButtonBoxShouldBeEnabled(index, self.ui.le_command.text()) | |||||
| @pyqtSlot() | |||||
| def _slot_saveSettings(self): | |||||
| settings = QSafeSettings("falkTX", "CarlaAddJackApp") | |||||
| settings.setValue("Command", self.ui.le_command.text()) | |||||
| settings.setValue("Name", self.ui.le_name.text()) | |||||
| settings.setValue("SessionManager", self.ui.cb_session_mgr.currentText()) | |||||
| settings.setValue("NumAudioIns", self.ui.sb_audio_ins.value()) | |||||
| settings.setValue("NumAudioOuts", self.ui.sb_audio_outs.value()) | |||||
| settings.setValue("NumMidiIns", self.ui.sb_midi_ins.value()) | |||||
| settings.setValue("NumMidiOuts", self.ui.sb_midi_outs.value()) | |||||
| settings.setValue("ManageWindow", self.ui.cb_manage_window.isChecked()) | |||||
| settings.setValue("CaptureFirstWindow", self.ui.cb_capture_first_window.isChecked()) | |||||
| settings.setValue("MidiOutMixdown", self.ui.cb_out_midi_mixdown.isChecked()) | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # Testing | |||||
| if __name__ == '__main__': | |||||
| import sys | |||||
| # pylint: disable=ungrouped-imports | |||||
| from PyQt5.QtWidgets import QApplication | |||||
| # pylint: enable=ungrouped-imports | |||||
| _app = QApplication(sys.argv) | |||||
| _gui = JackAppDialog(None, "") | |||||
| if _gui.exec_(): | |||||
| _command, _name, _labelSetup = _gui.getCommandAndFlags() | |||||
| print("Results:") | |||||
| print(f"\tCommand: {_command}") | |||||
| print(f"\tName: {_name}") | |||||
| print(f"\tLabelSetup: {_labelSetup}") | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -382,31 +382,6 @@ int fontMetricsHorizontalAdvance(const QFontMetrics& fontMetrics, const QString& | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // Qt-compatible plugin info | // Qt-compatible plugin info | ||||
| // base details, nicely packed and POD-only so we can directly use as binary | |||||
| struct PluginInfoHeader { | |||||
| uint16_t build; | |||||
| uint16_t type; | |||||
| uint32_t hints; | |||||
| uint64_t uniqueId; | |||||
| uint16_t audioIns; | |||||
| uint16_t audioOuts; | |||||
| uint16_t cvIns; | |||||
| uint16_t cvOuts; | |||||
| uint16_t midiIns; | |||||
| uint16_t midiOuts; | |||||
| uint16_t parameterIns; | |||||
| uint16_t parameterOuts; | |||||
| }; | |||||
| // full details, now with non-POD types | |||||
| struct PluginInfo : PluginInfoHeader { | |||||
| QString category; | |||||
| QString filename; | |||||
| QString name; | |||||
| QString label; | |||||
| QString maker; | |||||
| }; | |||||
| // convert PluginInfo to Qt types | // convert PluginInfo to Qt types | ||||
| static QVariant asByteArray(const PluginInfo& info) | static QVariant asByteArray(const PluginInfo& info) | ||||
| { | { | ||||
| @@ -2090,78 +2065,3 @@ void PluginListDialog::saveSettings() | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| PluginListDialog* | |||||
| carla_frontend_createPluginListDialog(void* const parent, const HostSettings* const hostSettings) | |||||
| { | |||||
| return new PluginListDialog(reinterpret_cast<QWidget*>(parent), hostSettings); | |||||
| } | |||||
| void | |||||
| carla_frontend_destroyPluginListDialog(PluginListDialog* const dialog) | |||||
| { | |||||
| dialog->close(); | |||||
| delete dialog; | |||||
| } | |||||
| void | |||||
| carla_frontend_setPluginListDialogPath(PluginListDialog* const dialog, const int ptype, const char* const path) | |||||
| { | |||||
| dialog->setPluginPath(static_cast<PluginType>(ptype), path); | |||||
| } | |||||
| const PluginListDialogResults* | |||||
| carla_frontend_execPluginListDialog(PluginListDialog* const dialog) | |||||
| { | |||||
| if (dialog->exec()) | |||||
| { | |||||
| static PluginListDialogResults ret; | |||||
| static CarlaString category; | |||||
| static CarlaString filename; | |||||
| static CarlaString name; | |||||
| static CarlaString label; | |||||
| static CarlaString maker; | |||||
| const PluginInfo& plugin(dialog->getSelectedPluginInfo()); | |||||
| category = plugin.category.toUtf8(); | |||||
| filename = plugin.filename.toUtf8(); | |||||
| name = plugin.name.toUtf8(); | |||||
| label = plugin.label.toUtf8(); | |||||
| maker = plugin.maker.toUtf8(); | |||||
| ret.build = plugin.build; | |||||
| ret.type = plugin.type; | |||||
| ret.hints = plugin.hints; | |||||
| ret.category = category; | |||||
| ret.filename = filename; | |||||
| ret.name = name; | |||||
| ret.label = label; | |||||
| ret.maker = maker; | |||||
| ret.uniqueId = plugin.uniqueId; | |||||
| ret.audioIns = plugin.audioIns; | |||||
| ret.audioOuts = plugin.audioOuts; | |||||
| ret.cvIns = plugin.cvIns; | |||||
| ret.cvOuts = plugin.cvOuts; | |||||
| ret.midiIns = plugin.midiIns; | |||||
| ret.midiOuts = plugin.midiOuts; | |||||
| ret.parameterIns = plugin.parameterIns; | |||||
| ret.parameterOuts = plugin.parameterOuts; | |||||
| return &ret; | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // const PluginListDialogResults* | |||||
| // carla_frontend_createAndExecPluginListDialog(void* const parent, const HostSettings* const hostSettings) | |||||
| // { | |||||
| // PluginListDialog gui(reinterpret_cast<QWidget*>(parent), hostSettings); | |||||
| // | |||||
| // return carla_frontend_execPluginListDialog(&gui); | |||||
| // } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -1,9 +1,9 @@ | |||||
| // SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com> | |||||
| // SPDX-License-Identifier: GPL-2.0-or-later | // SPDX-License-Identifier: GPL-2.0-or-later | ||||
| #pragma once | #pragma once | ||||
| #include "CarlaFrontend.h" | |||||
| #include "carla_frontend.h" | |||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| # pragma clang diagnostic push | # pragma clang diagnostic push | ||||
| @@ -15,7 +15,6 @@ | |||||
| # pragma GCC diagnostic ignored "-Wdeprecated-copy" | # pragma GCC diagnostic ignored "-Wdeprecated-copy" | ||||
| #endif | #endif | ||||
| #include <QtWidgets/QDialog> | |||||
| #include "ui_pluginlistdialog.h" | #include "ui_pluginlistdialog.h" | ||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| @@ -24,10 +23,35 @@ | |||||
| # pragma GCC diagnostic pop | # pragma GCC diagnostic pop | ||||
| #endif | #endif | ||||
| class QSafeSettings; | |||||
| typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo; | typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo; | ||||
| typedef struct _HostSettings HostSettings; | typedef struct _HostSettings HostSettings; | ||||
| struct PluginInfo; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // base details, nicely packed and POD-only so we can directly use as binary | |||||
| struct PluginInfoHeader { | |||||
| uint16_t build; | |||||
| uint16_t type; | |||||
| uint32_t hints; | |||||
| uint64_t uniqueId; | |||||
| uint16_t audioIns; | |||||
| uint16_t audioOuts; | |||||
| uint16_t cvIns; | |||||
| uint16_t cvOuts; | |||||
| uint16_t midiIns; | |||||
| uint16_t midiOuts; | |||||
| uint16_t parameterIns; | |||||
| uint16_t parameterOuts; | |||||
| }; | |||||
| // full details, now with non-POD types | |||||
| struct PluginInfo : PluginInfoHeader { | |||||
| QString category; | |||||
| QString filename; | |||||
| QString name; | |||||
| QString label; | |||||
| QString maker; | |||||
| }; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // Plugin List Dialog | // Plugin List Dialog | ||||