diff --git a/source/frontend/Makefile b/source/frontend/Makefile index b1029ba08..d3699dd24 100644 --- a/source/frontend/Makefile +++ b/source/frontend/Makefile @@ -35,9 +35,9 @@ NON_STATIC_LINK_FLAGS = $(LINK_FLAGS) endif 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 -QT_LINK_FLAGS += -L$(BINDIR) -lcarla_utils +QT_LINK_FLAGS += -L$(BINDIR) -lcarla_standalone2 -lcarla_utils endif ifeq ($(MACOS),true) @@ -58,6 +58,7 @@ QMs = $(patsubst %,translations/carla_%.qm,$(I18N_LANGUAGES)) CPP_FILES = \ carla_frontend.cpp \ + dialogs/aboutdialog.cpp \ dialogs/jackappdialog.cpp \ pluginlist/pluginlistdialog.cpp @@ -89,7 +90,6 @@ RES = \ $(BINDIR)/resources/notes-ui \ $(BINDIR)/resources/xycontroller-ui \ $(BINDIR)/resources/resources_rc.py \ - $(BINDIR)/resources/ui_carla_about.py \ $(BINDIR)/resources/ui_carla_edit.py \ $(BINDIR)/resources/ui_carla_host.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 += $(PLUGINLIST_UI_FILES:pluginlist/%.ui=pluginlist/ui_%.h) -UIs += $(DIALOG_UI_FILES:%.ui=%_ui.py) - # old stuff, not yet converted UIs += \ - ui_carla_about.py \ ui_carla_edit.py \ ui_carla_host.py \ ui_carla_osc_connect.py \ diff --git a/source/frontend/carla_backend.py b/source/frontend/carla_backend.py index 5447030df..49c41f2ae 100644 --- a/source/frontend/carla_backend.py +++ b/source/frontend/carla_backend.py @@ -1531,6 +1531,7 @@ class CarlaHostMeta(): self.isPlugin = False self.isRemote = False self.nsmOK = False + self.handle = None # settings self.processMode = ENGINE_PROCESS_MODE_PATCHBAY diff --git a/source/frontend/carla_frontend.cpp b/source/frontend/carla_frontend.cpp index de2dc26ec..b05efc2f3 100644 --- a/source/frontend/carla_frontend.cpp +++ b/source/frontend/carla_frontend.cpp @@ -1,23 +1,136 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2022 Filipe Coelho - * - * 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 +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "carla_frontend.h" // ------------------------------------------------------------------------------------------------------------------- // common files #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(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(parent), hostSettings); +// +// return carla_frontend_execPluginListDialog(&gui); +// } + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/CarlaFrontend.h b/source/frontend/carla_frontend.h similarity index 73% rename from source/frontend/CarlaFrontend.h rename to source/frontend/carla_frontend.h index 4d2500bcd..98ddcaeab 100644 --- a/source/frontend/CarlaFrontend.h +++ b/source/frontend/carla_frontend.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -10,6 +10,8 @@ using CARLA_BACKEND_NAMESPACE::PluginType; extern "C" { #endif +typedef struct _CarlaHostHandle* CarlaHostHandle; + // -------------------------------------------------------------------------------------------------------------------- typedef struct { @@ -49,17 +51,26 @@ typedef struct { #ifdef __cplusplus class PluginListDialog; +class QWidget; #else struct PluginListDialog; +struct QWidget; #endif // -------------------------------------------------------------------------------------------------------------------- +CARLA_PLUGIN_EXPORT void +carla_frontend_createAndExecAboutDialog(QWidget* parent, CarlaHostHandle hostHandle, bool isControl, bool isPlugin); + +// -------------------------------------------------------------------------------------------------------------------- + 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_frontend_createPluginListDialog(void* parent, const HostSettings* hostSettings); +carla_frontend_createPluginListDialog(QWidget* parent, const HostSettings* hostSettings); CARLA_PLUGIN_EXPORT void carla_frontend_destroyPluginListDialog(PluginListDialog* dialog); diff --git a/source/frontend/carla_frontend.py b/source/frontend/carla_frontend.py index f741a1a6a..8167cf055 100644 --- a/source/frontend/carla_frontend.py +++ b/source/frontend/carla_frontend.py @@ -81,6 +81,9 @@ class CarlaFrontendLib(): def __init__(self, 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.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): - 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): hostSettingsC = HostSettings() diff --git a/source/frontend/carla_host.py b/source/frontend/carla_host.py index bbe2c3000..2c0007a3f 100644 --- a/source/frontend/carla_host.py +++ b/source/frontend/carla_host.py @@ -2215,7 +2215,10 @@ class HostWindow(QMainWindow): @pyqtSlot() 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() def slot_aboutQt(self): diff --git a/source/frontend/carla_widgets.py b/source/frontend/carla_widgets.py index 451ef0dd0..0a90cdd12 100755 --- a/source/frontend/carla_widgets.py +++ b/source/frontend/carla_widgets.py @@ -42,7 +42,6 @@ elif qt_config == 6: # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) -import ui_carla_about import ui_carla_edit 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_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 = " - %s" % self.tr("OSC Bridge Version") - elif host.isPlugin: - extraInfo = " - %s" % self.tr("Plugin Version") - else: - extraInfo = "" - - self.ui.l_about.setText(self.tr("" - "
Version %s" - "
Carla is a fully-featured audio plugin host%s.
" - "
Copyright (C) 2011-2025 falkTX
" - "" % (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("" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "
" "/set_active" " <i-value>
" "/set_drywet" " <f-value>
" "/set_volume" " <f-value>
" "/set_balance_left" " <f-value>
" "/set_balance_right" " <f-value>
" "/set_panning" " <f-value>
" "/set_parameter_value" " <i-index> <f-value>
" "/set_parameter_midi_cc" " <i-index> <i-cc>
" "/set_parameter_midi_channel" " <i-index> <i-channel>
" "/set_program" " <i-index>
" "/set_midi_program" " <i-index>
" "/note_on" " <i-channel> <i-note> <i-velo>
" "/note_off" " <i-channel> <i-note
" - ) - - self.ui.l_example.setText("/Carla/2/set_parameter_value 5 1.0") - self.ui.l_example_help.setText("(as in this example, \"2\" is the plugin number and \"5\" the parameter)") - # 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)
" - "Implemented Feature/Extensions:" - "
    " - "
  • http://lv2plug.in/ns/ext/atom
  • " - "
  • http://lv2plug.in/ns/ext/buf-size
  • " - "
  • http://lv2plug.in/ns/ext/data-access
  • " - #"
  • http://lv2plug.in/ns/ext/dynmanifest
  • " - "
  • http://lv2plug.in/ns/ext/event
  • " - "
  • http://lv2plug.in/ns/ext/instance-access
  • " - "
  • http://lv2plug.in/ns/ext/log
  • " - "
  • http://lv2plug.in/ns/ext/midi
  • " - #"
  • http://lv2plug.in/ns/ext/morph
  • " - "
  • http://lv2plug.in/ns/ext/options
  • " - "
  • http://lv2plug.in/ns/ext/parameters
  • " - #"
  • http://lv2plug.in/ns/ext/patch
  • " - "
  • http://lv2plug.in/ns/ext/port-props
  • " - "
  • http://lv2plug.in/ns/ext/presets
  • " - "
  • http://lv2plug.in/ns/ext/resize-port
  • " - "
  • http://lv2plug.in/ns/ext/state
  • " - "
  • http://lv2plug.in/ns/ext/time
  • " - "
  • http://lv2plug.in/ns/ext/uri-map
  • " - "
  • http://lv2plug.in/ns/ext/urid
  • " - "
  • http://lv2plug.in/ns/ext/worker
  • " - "
  • http://lv2plug.in/ns/extensions/ui
  • " - "
  • http://lv2plug.in/ns/extensions/units
  • " - "
  • http://home.gna.org/lv2dynparam/rtmempool/v1
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/external-ui
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/programs
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/props
  • " - "
  • http://kxstudio.sf.net/ns/lv2ext/rtmempool
  • " - "
  • http://ll-plugins.nongnu.org/lv2/ext/midimap
  • " - "
  • http://ll-plugins.nongnu.org/lv2/ext/miditype
  • " - "
")) - - 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 @@ -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.set_active(0, True) - gui1 = CarlaAboutW(None, _host) - gui1.show() - gui2 = PluginEdit(None, _host, 0) gui2.testTimer() gui2.show() diff --git a/source/frontend/dialogs/__init__.py b/source/frontend/dialogs/__init__.py deleted file mode 100644 index e933411be..000000000 --- a/source/frontend/dialogs/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla plugin host -# Copyright (C) 2011-2022 Filipe Coelho -# -# 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 diff --git a/source/frontend/dialogs/aboutdialog.cpp b/source/frontend/dialogs/aboutdialog.cpp new file mode 100644 index 000000000..4f6d6abf7 --- /dev/null +++ b/source/frontend/dialogs/aboutdialog.cpp @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// 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 +// #include +// #include + +#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(" - %1").arg(tr("OSC Bridge Version")); + else if (isPlugin) + extraInfo = QString(" - %1").arg(tr("Plugin Version")); + + ui.l_about->setText(tr("" + "
Version %1" + "
Carla is a fully-featured audio plugin host%2.
" + "
Copyright (C) 2011-2025 falkTX
" + "").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("" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
" "/set_active" " <i-value>
" "/set_drywet" " <f-value>
" "/set_volume" " <f-value>
" "/set_balance_left" " <f-value>
" "/set_balance_right" " <f-value>
" "/set_panning" " <f-value>
" "/set_parameter_value" " <i-index> <f-value>
" "/set_parameter_midi_cc" " <i-index> <i-cc>
" "/set_parameter_midi_channel" " <i-index> <i-channel>
" "/set_program" " <i-index>
" "/set_midi_program" " <i-index>
" "/note_on" " <i-channel> <i-note> <i-velo>
" "/note_off" " <i-channel> <i-note
"); + + ui.l_example->setText("/Carla/2/set_parameter_value 5 1.0"); + ui.l_example_help->setText("(as in this example, \"2\" is the plugin number and \"5\" the parameter)"); + + 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)
" + "Implemented Feature/Extensions:" + "
    " + "
  • http://lv2plug.in/ns/ext/atom
  • " + "
  • http://lv2plug.in/ns/ext/buf-size
  • " + "
  • http://lv2plug.in/ns/ext/data-access
  • " + // "
  • http://lv2plug.in/ns/ext/dynmanifest
  • " + "
  • http://lv2plug.in/ns/ext/event
  • " + "
  • http://lv2plug.in/ns/ext/instance-access
  • " + "
  • http://lv2plug.in/ns/ext/log
  • " + "
  • http://lv2plug.in/ns/ext/midi
  • " + // "
  • http://lv2plug.in/ns/ext/morph
  • " + "
  • http://lv2plug.in/ns/ext/options
  • " + "
  • http://lv2plug.in/ns/ext/parameters
  • " + // "
  • http://lv2plug.in/ns/ext/patch
  • " + // "
  • http://lv2plug.in/ns/ext/port-groups
  • " + "
  • http://lv2plug.in/ns/ext/port-props
  • " + "
  • http://lv2plug.in/ns/ext/presets
  • " + "
  • http://lv2plug.in/ns/ext/resize-port
  • " + "
  • http://lv2plug.in/ns/ext/state
  • " + "
  • http://lv2plug.in/ns/ext/time
  • " + "
  • http://lv2plug.in/ns/ext/uri-map
  • " + "
  • http://lv2plug.in/ns/ext/urid
  • " + "
  • http://lv2plug.in/ns/ext/worker
  • " + "
  • http://lv2plug.in/ns/extensions/ui
  • " + "
  • http://lv2plug.in/ns/extensions/units
  • " + "
  • http://home.gna.org/lv2dynparam/rtmempool/v1
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/external-ui
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/programs
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/props
  • " + "
  • http://kxstudio.sf.net/ns/lv2ext/rtmempool
  • " + "
  • http://ll-plugins.nongnu.org/lv2/ext/midimap
  • " + "
  • http://ll-plugins.nongnu.org/lv2/ext/miditype
  • " + "
")); + + 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 +} + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/dialogs/aboutdialog.hpp b/source/frontend/dialogs/aboutdialog.hpp new file mode 100644 index 000000000..6d557b0d9 --- /dev/null +++ b/source/frontend/dialogs/aboutdialog.hpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho +// 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); +}; + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/resources/ui/carla_about.ui b/source/frontend/dialogs/aboutdialog.ui similarity index 99% rename from resources/ui/carla_about.ui rename to source/frontend/dialogs/aboutdialog.ui index 2eb2f0a7e..3e6cdca0a 100644 --- a/resources/ui/carla_about.ui +++ b/source/frontend/dialogs/aboutdialog.ui @@ -1,7 +1,7 @@ - CarlaAboutW - + AboutDialog + 0 @@ -1425,7 +1425,7 @@ POSSIBILITY OF SUCH DAMAGES. buttonBox accepted() - CarlaAboutW + AboutDialog accept() @@ -1441,7 +1441,7 @@ POSSIBILITY OF SUCH DAMAGES. buttonBox rejected() - CarlaAboutW + AboutDialog reject() diff --git a/source/frontend/dialogs/jackappdialog.cpp b/source/frontend/dialogs/jackappdialog.cpp index 371042868..b117f6abc 100644 --- a/source/frontend/dialogs/jackappdialog.cpp +++ b/source/frontend/dialogs/jackappdialog.cpp @@ -1,19 +1,5 @@ -/* - * Carla plugin host - * Copyright (C) 2011-2023 Filipe Coelho - * - * 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 +// SPDX-License-Identifier: GPL-2.0-or-later #include "jackappdialog.hpp" @@ -27,9 +13,7 @@ # pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif -#include "ui_jackappdialog.h" #include -#include #include #ifdef __clang__ @@ -40,43 +24,29 @@ #include "qsafesettings.hpp" -#include "CarlaFrontend.h" #include "CarlaLibJackHints.h" #include "CarlaString.hpp" // -------------------------------------------------------------------------------------------------------------------- // 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; - Self(const char* const projectFilename) + PrivateData(const char* const 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) : QDialog(parent), - self(Self::create(projectFilename)) + p(new PrivateData(projectFilename)) { - self.ui.setupUi(this); + ui.setupUi(this); - // ------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- // UI setup - self.ui.group_error->setVisible(false); + ui.group_error->setVisible(false); adjustSize(); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -86,34 +56,34 @@ JackAppDialog::JackAppDialog(QWidget* const parent, const char* const projectFil setWindowModality(Qt::WindowModal); #endif - // ------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- // Load settings loadSettings(); - // ------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------- // Set-up connections connect(this, &QDialog::finished, this, &JackAppDialog::slot_saveSettings); - connect(self.ui.cb_session_mgr, static_cast(&QComboBox::currentIndexChanged), + connect(ui.cb_session_mgr, static_cast(&QComboBox::currentIndexChanged), this, &JackAppDialog::slot_sessionManagerChanged); - connect(self.ui.le_command, &QLineEdit::textChanged, + connect(ui.le_command, &QLineEdit::textChanged, this, &JackAppDialog::slot_commandChanged); } JackAppDialog::~JackAppDialog() { - delete &self; + delete p; } -// ----------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // public methods 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()) { @@ -122,7 +92,7 @@ JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const } SessionManager smgr; - switch (self.ui.cb_session_mgr->currentIndex()) + switch (ui.cb_session_mgr->currentIndex()) { case UI_SESSION_LADISH: smgr = LIBJACK_SESSION_MANAGER_LADISH; @@ -136,28 +106,28 @@ JackAppDialog::CommandAndFlags JackAppDialog::getCommandAndFlags() const } uint flags = 0x0; - if (self.ui.cb_manage_window->isChecked()) + if (ui.cb_manage_window->isChecked()) 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; - if (self.ui.cb_buffers_addition_mode->isChecked()) + if (ui.cb_buffers_addition_mode->isChecked()) 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; - if (self.ui.cb_external_start->isChecked()) + if (ui.cb_external_start->isChecked()) 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' + flags))); return {command, name, labelSetup}; } -// ----------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // private methods void JackAppDialog::checkIfButtonBoxShouldBeEnabled(const int index, const QCarlaString& command) @@ -166,28 +136,28 @@ void JackAppDialog::checkIfButtonBoxShouldBeEnabled(const int index, const QCarl QCarlaString showErr; // 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{'.', '/'}.contains(command[0])) + if (command[0] == '.' || command[0] == '/') showErr = tr("NSM applications cannot use abstract or absolute paths"); else if (command.contains(' ') or command.contains(';') or command.contains('&')) 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"); } if (showErr.isNotEmpty()) { 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 { - 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); } @@ -198,104 +168,53 @@ void JackAppDialog::loadSettings() const QString smName = settings.valueString("SessionManager", ""); 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") - self.ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NSM); + ui.cb_session_mgr->setCurrentIndex(UI_SESSION_NSM); 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 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) { - checkIfButtonBoxShouldBeEnabled(index, self.ui.le_command->text()); + checkIfButtonBoxShouldBeEnabled(index, ui.le_command->text()); } void JackAppDialog::slot_saveSettings() { 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(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 - -// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/dialogs/jackappdialog.hpp b/source/frontend/dialogs/jackappdialog.hpp index 0a52a5d2b..922ab11a0 100644 --- a/source/frontend/dialogs/jackappdialog.hpp +++ b/source/frontend/dialogs/jackappdialog.hpp @@ -1,22 +1,10 @@ -/* - * Carla plugin host - * Copyright (C) 2011-2022 Filipe Coelho - * - * 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 +// 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" @@ -27,7 +15,7 @@ # pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif -#include +#include "ui_jackappdialog.h" #ifdef __clang__ # pragma clang diagnostic pop @@ -42,8 +30,16 @@ 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; // ---------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/dialogs/jackappdialog.py b/source/frontend/dialogs/jackappdialog.py deleted file mode 100755 index 878ebd830..000000000 --- a/source/frontend/dialogs/jackappdialog.py +++ /dev/null @@ -1,221 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Carla plugin host -# Copyright (C) 2011-2022 Filipe Coelho -# -# 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}") - -# --------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/pluginlist/pluginlistdialog.cpp b/source/frontend/pluginlist/pluginlistdialog.cpp index 95fe247d2..5196d6052 100644 --- a/source/frontend/pluginlist/pluginlistdialog.cpp +++ b/source/frontend/pluginlist/pluginlistdialog.cpp @@ -382,31 +382,6 @@ int fontMetricsHorizontalAdvance(const QFontMetrics& fontMetrics, const QString& // -------------------------------------------------------------------------------------------------------------------- // 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 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(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(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(parent), hostSettings); -// -// return carla_frontend_execPluginListDialog(&gui); -// } - -// -------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/pluginlist/pluginlistdialog.hpp b/source/frontend/pluginlist/pluginlistdialog.hpp index 447cbeee7..332b37f40 100644 --- a/source/frontend/pluginlist/pluginlistdialog.hpp +++ b/source/frontend/pluginlist/pluginlistdialog.hpp @@ -1,9 +1,9 @@ -// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho +// SPDX-FileCopyrightText: 2011-2025 Filipe Coelho // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include "CarlaFrontend.h" +#include "carla_frontend.h" #ifdef __clang__ # pragma clang diagnostic push @@ -15,7 +15,6 @@ # pragma GCC diagnostic ignored "-Wdeprecated-copy" #endif -#include #include "ui_pluginlistdialog.h" #ifdef __clang__ @@ -24,10 +23,35 @@ # pragma GCC diagnostic pop #endif -class QSafeSettings; typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo; 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