Cleanup
[carla.git] / source / frontend / dialogs / jackappdialog.py
blob878ebd8304084fbf92c22387f6c959aa7ec6a6a7
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
4 # Carla plugin host
5 # Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License as
9 # published by the Free Software Foundation; either version 2 of
10 # the License, or any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # For a full copy of the GNU General Public License see the doc/GPL.txt file.
19 # ---------------------------------------------------------------------------------------------------------------------
20 # Imports (Global)
22 import os
24 from PyQt5.QtCore import pyqtSlot, Qt
25 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QWidget
27 # ---------------------------------------------------------------------------------------------------------------------
28 # Imports (Carla)
30 from utils import QSafeSettings
32 # ---------------------------------------------------------------------------------------------------------------------
33 # Imports (Local)
35 from jackappdialog_ui import Ui_JackAppDialog
37 # ---------------------------------------------------------------------------------------------------------------------
38 # Imports (API)
40 SESSION_MGR_NONE = 0
41 SESSION_MGR_AUTO = 1
42 SESSION_MGR_JACK = 2
43 SESSION_MGR_LADISH = 3
44 SESSION_MGR_NSM = 4
46 FLAG_CONTROL_WINDOW = 0x01
47 FLAG_CAPTURE_FIRST_WINDOW = 0x02
48 FLAG_BUFFERS_ADDITION_MODE = 0x10
49 FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN = 0x20
50 FLAG_EXTERNAL_START = 0x40
52 # ---------------------------------------------------------------------------------------------------------------------
53 # Jack Application Dialog
55 UI_SESSION_NONE = 0
56 UI_SESSION_LADISH = 1
57 UI_SESSION_NSM = 2
59 class JackAppDialog(QDialog):
60 def __init__(self, parent: QWidget, projectFilename: str):
61 QDialog.__init__(self, parent)
62 self.ui = Ui_JackAppDialog()
63 self.ui.setupUi(self)
65 self.fProjectFilename = projectFilename
67 # --------------------------------------------------------------------------------------------------------------
68 # UI setup
70 self.ui.group_error.setVisible(False)
71 self.adjustSize()
72 self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
74 # --------------------------------------------------------------------------------------------------------------
75 # Load settings
77 self._loadSettings()
79 # --------------------------------------------------------------------------------------------------------------
80 # Set-up connections
82 self.finished.connect(self._slot_saveSettings)
83 self.ui.cb_session_mgr.currentIndexChanged.connect(self._slot_sessionManagerChanged)
84 self.ui.le_command.textChanged.connect(self._slot_commandChanged)
86 # -----------------------------------------------------------------------------------------------------------------
87 # public methods
89 def getCommandAndFlags(self):
90 name = self.ui.le_name.text()
91 command = self.ui.le_command.text()
92 smgr = SESSION_MGR_NONE
93 flags = 0x0
95 if not name:
96 name = os.path.basename(command.split(" ",1)[0]).title()
98 uiSessionMgrIndex = self.ui.cb_session_mgr.currentIndex()
99 if uiSessionMgrIndex == UI_SESSION_LADISH:
100 smgr = SESSION_MGR_LADISH
101 elif uiSessionMgrIndex == UI_SESSION_NSM:
102 smgr = SESSION_MGR_NSM
104 if self.ui.cb_manage_window.isChecked():
105 flags |= FLAG_CONTROL_WINDOW
106 if self.ui.cb_capture_first_window.isChecked():
107 flags |= FLAG_CAPTURE_FIRST_WINDOW
108 if self.ui.cb_buffers_addition_mode.isChecked():
109 flags |= FLAG_BUFFERS_ADDITION_MODE
110 if self.ui.cb_out_midi_mixdown.isChecked():
111 flags |= FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN
112 if self.ui.cb_external_start.isChecked():
113 flags |= FLAG_EXTERNAL_START
115 bv = ord('0')
116 v1 = chr(bv + self.ui.sb_audio_ins.value())
117 v2 = chr(bv + self.ui.sb_audio_outs.value())
118 v3 = chr(bv + self.ui.sb_midi_ins.value())
119 v4 = chr(bv + self.ui.sb_midi_outs.value())
120 v5 = chr(bv + smgr)
121 v6 = chr(bv + flags)
122 labelSetup = f"{v1}{v2}{v3}{v4}{v5}{v6}"
124 return (command, name, labelSetup)
126 # -----------------------------------------------------------------------------------------------------------------
127 # private methods
129 def _checkIfButtonBoxShouldBeEnabled(self, index: int, command: str):
130 enabled = len(command) > 0
131 showErr = ""
133 # NSM applications must not be abstract or absolute paths, and must not contain arguments
134 if enabled and index == UI_SESSION_NSM:
135 if command[0] in (".", "/"):
136 showErr = self.tr("NSM applications cannot use abstract or absolute paths")
137 elif " " in command or ";" in command or "&" in command:
138 showErr = self.tr("NSM applications cannot use CLI arguments")
139 elif not self.fProjectFilename:
140 showErr = self.tr("You need to save the current Carla project before NSM can be used")
142 if showErr:
143 enabled = False
144 self.ui.l_error.setText(showErr)
145 self.ui.group_error.setVisible(True)
146 else:
147 self.ui.group_error.setVisible(False)
149 self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enabled)
151 def _loadSettings(self):
152 settings = QSafeSettings("falkTX", "CarlaAddJackApp")
154 smName = settings.value("SessionManager", "", str)
156 if smName == "LADISH (SIGUSR1)":
157 self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_LADISH)
158 elif smName == "NSM":
159 self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_NSM)
160 else:
161 self.ui.cb_session_mgr.setCurrentIndex(UI_SESSION_NONE)
163 self.ui.le_command.setText(settings.value("Command", "", str))
164 self.ui.le_name.setText(settings.value("Name", "", str))
165 self.ui.sb_audio_ins.setValue(settings.value("NumAudioIns", 2, int))
166 self.ui.sb_audio_ins.setValue(settings.value("NumAudioIns", 2, int))
167 self.ui.sb_audio_outs.setValue(settings.value("NumAudioOuts", 2, int))
168 self.ui.sb_midi_ins.setValue(settings.value("NumMidiIns", 0, int))
169 self.ui.sb_midi_outs.setValue(settings.value("NumMidiOuts", 0, int))
170 self.ui.cb_manage_window.setChecked(settings.value("ManageWindow", True, bool))
171 self.ui.cb_capture_first_window.setChecked(settings.value("CaptureFirstWindow", False, bool))
172 self.ui.cb_out_midi_mixdown.setChecked(settings.value("MidiOutMixdown", False, bool))
174 self._checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr.currentIndex(),
175 self.ui.le_command.text())
177 # -----------------------------------------------------------------------------------------------------------------
178 # private slots
180 @pyqtSlot(str)
181 def _slot_commandChanged(self, command: str):
182 self._checkIfButtonBoxShouldBeEnabled(self.ui.cb_session_mgr.currentIndex(), command)
184 @pyqtSlot(int)
185 def _slot_sessionManagerChanged(self, index: int):
186 self._checkIfButtonBoxShouldBeEnabled(index, self.ui.le_command.text())
188 @pyqtSlot()
189 def _slot_saveSettings(self):
190 settings = QSafeSettings("falkTX", "CarlaAddJackApp")
191 settings.setValue("Command", self.ui.le_command.text())
192 settings.setValue("Name", self.ui.le_name.text())
193 settings.setValue("SessionManager", self.ui.cb_session_mgr.currentText())
194 settings.setValue("NumAudioIns", self.ui.sb_audio_ins.value())
195 settings.setValue("NumAudioOuts", self.ui.sb_audio_outs.value())
196 settings.setValue("NumMidiIns", self.ui.sb_midi_ins.value())
197 settings.setValue("NumMidiOuts", self.ui.sb_midi_outs.value())
198 settings.setValue("ManageWindow", self.ui.cb_manage_window.isChecked())
199 settings.setValue("CaptureFirstWindow", self.ui.cb_capture_first_window.isChecked())
200 settings.setValue("MidiOutMixdown", self.ui.cb_out_midi_mixdown.isChecked())
202 # ---------------------------------------------------------------------------------------------------------------------
203 # Testing
205 if __name__ == '__main__':
206 import sys
207 # pylint: disable=ungrouped-imports
208 from PyQt5.QtWidgets import QApplication
209 # pylint: enable=ungrouped-imports
211 _app = QApplication(sys.argv)
212 _gui = JackAppDialog(None, "")
214 if _gui.exec_():
215 _command, _name, _labelSetup = _gui.getCommandAndFlags()
216 print("Results:")
217 print(f"\tCommand: {_command}")
218 print(f"\tName: {_name}")
219 print(f"\tLabelSetup: {_labelSetup}")
221 # ---------------------------------------------------------------------------------------------------------------------