Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

carla_settings.py 37KB

11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla settings code
  4. # Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License as
  8. # published by the Free Software Foundation; either version 2 of
  9. # the License, or any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Config)
  19. from carla_config import *
  20. # ------------------------------------------------------------------------------------------------------------
  21. # Imports (Global)
  22. if config_UseQt5:
  23. from PyQt5.QtCore import pyqtSlot, QByteArray, QDir, QSettings
  24. from PyQt5.QtGui import QColor, QCursor, QFontMetrics, QPainter, QPainterPath
  25. from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFrame, QInputDialog, QLineEdit, QMenu, QVBoxLayout, QWidget
  26. else:
  27. from PyQt4.QtCore import pyqtSlot, QByteArray, QDir, QSettings
  28. from PyQt4.QtGui import QColor, QCursor, QFontMetrics, QPainter, QPainterPath
  29. from PyQt4.QtGui import QDialog, QDialogButtonBox, QFrame, QInputDialog, QLineEdit, QMenu, QVBoxLayout, QWidget
  30. # ------------------------------------------------------------------------------------------------------------
  31. # Imports (Custom)
  32. import ui_carla_settings
  33. import ui_carla_settings_driver
  34. from carla_style import *
  35. from patchcanvas_theme import *
  36. # ------------------------------------------------------------------------------------------------------------
  37. # PatchCanvas defines
  38. CANVAS_ANTIALIASING_SMALL = 1
  39. CANVAS_EYECANDY_SMALL = 1
  40. # ------------------------------------------------------------------------------------------------------------
  41. # Carla defaults
  42. # Main
  43. CARLA_DEFAULT_MAIN_PROJECT_FOLDER = QDir.homePath()
  44. CARLA_DEFAULT_MAIN_USE_PRO_THEME = True
  45. CARLA_DEFAULT_MAIN_PRO_THEME_COLOR = "Black"
  46. CARLA_DEFAULT_MAIN_REFRESH_INTERVAL = 20
  47. # Canvas
  48. CARLA_DEFAULT_CANVAS_THEME = "Modern Dark"
  49. CARLA_DEFAULT_CANVAS_SIZE = "3100x2400"
  50. CARLA_DEFAULT_CANVAS_SIZE_WIDTH = 3100
  51. CARLA_DEFAULT_CANVAS_SIZE_HEIGHT = 2400
  52. CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES = True
  53. CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS = True
  54. CARLA_DEFAULT_CANVAS_EYE_CANDY = CANVAS_EYECANDY_SMALL
  55. CARLA_DEFAULT_CANVAS_USE_OPENGL = False
  56. CARLA_DEFAULT_CANVAS_ANTIALIASING = CANVAS_ANTIALIASING_SMALL
  57. CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING = False
  58. # Engine
  59. CARLA_DEFAULT_FORCE_STEREO = False
  60. CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES = False
  61. CARLA_DEFAULT_PREFER_UI_BRIDGES = True
  62. CARLA_DEFAULT_UIS_ALWAYS_ON_TOP = True
  63. CARLA_DEFAULT_MAX_PARAMETERS = MAX_DEFAULT_PARAMETERS
  64. CARLA_DEFAULT_UI_BRIDGES_TIMEOUT = 4000
  65. CARLA_DEFAULT_AUDIO_NUM_PERIODS = 2
  66. CARLA_DEFAULT_AUDIO_BUFFER_SIZE = 512
  67. CARLA_DEFAULT_AUDIO_SAMPLE_RATE = 44100
  68. if WINDOWS:
  69. CARLA_DEFAULT_AUDIO_DRIVER = "DirectSound"
  70. elif MACOS:
  71. CARLA_DEFAULT_AUDIO_DRIVER = "CoreAudio"
  72. else:
  73. CARLA_DEFAULT_AUDIO_DRIVER = "JACK"
  74. if LINUX:
  75. CARLA_DEFAULT_PROCESS_MODE = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS
  76. CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_JACK
  77. else:
  78. CARLA_DEFAULT_PROCESS_MODE = ENGINE_PROCESS_MODE_CONTINUOUS_RACK
  79. CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_INTERNAL
  80. # ------------------------------------------------------------------------------------------------------------
  81. # ...
  82. BUFFER_SIZE_LIST = (16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192)
  83. SAMPLE_RATE_LIST = (22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
  84. # ------------------------------------------------------------------------------------------------------------
  85. # Driver Settings
  86. class DriverSettingsW(QDialog):
  87. def __init__(self, parent, driverIndex, driverName):
  88. QDialog.__init__(self, parent)
  89. self.ui = ui_carla_settings_driver.Ui_DriverSettingsW()
  90. self.ui.setupUi(self)
  91. # -------------------------------------------------------------
  92. # Internal stuff
  93. self.fDriverIndex = driverIndex
  94. self.fDriverName = driverName
  95. self.fDeviceNames = gCarla.host.get_engine_driver_device_names(driverIndex) if gCarla.host is not None else []
  96. self.fBufferSizes = BUFFER_SIZE_LIST
  97. self.fSampleRates = SAMPLE_RATE_LIST
  98. # -------------------------------------------------------------
  99. # Set-up GUI
  100. for name in self.fDeviceNames:
  101. self.ui.cb_device.addItem(name)
  102. # -------------------------------------------------------------
  103. # Load settings
  104. self.loadSettings()
  105. # -------------------------------------------------------------
  106. # Set-up connections
  107. self.accepted.connect(self.slot_saveSettings)
  108. self.ui.cb_device.currentIndexChanged.connect(self.slot_updateDeviceInfo)
  109. # -------------------------------------------------------------
  110. def loadSettings(self):
  111. settings = QSettings()
  112. audioDevice = settings.value("%s%s/Device" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), "", type=str)
  113. audioNumPeriods = settings.value("%s%s/NumPeriods" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_NUM_PERIODS, type=int)
  114. audioBufferSize = settings.value("%s%s/BufferSize" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_BUFFER_SIZE, type=int)
  115. audioSampleRate = settings.value("%s%s/SampleRate" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_SAMPLE_RATE, type=int)
  116. if audioDevice and audioDevice in self.fDeviceNames:
  117. self.ui.cb_device.setCurrentIndex(self.fDeviceNames.index(audioDevice))
  118. else:
  119. self.ui.cb_device.setCurrentIndex(-1)
  120. # fill combo-boxes first
  121. self.slot_updateDeviceInfo()
  122. if audioNumPeriods in (2, 3):
  123. self.ui.sb_numperiods.setValue(audioNumPeriods)
  124. else:
  125. self.ui.sb_numperiods.setValue(CARLA_DEFAULT_AUDIO_NUM_PERIODS)
  126. if audioBufferSize and audioBufferSize in self.fBufferSizes:
  127. self.ui.cb_buffersize.setCurrentIndex(self.fBufferSizes.index(audioBufferSize))
  128. elif self.fBufferSizes == BUFFER_SIZE_LIST:
  129. self.ui.cb_buffersize.setCurrentIndex(BUFFER_SIZE_LIST.index(CARLA_DEFAULT_AUDIO_BUFFER_SIZE))
  130. else:
  131. self.ui.cb_buffersize.setCurrentIndex(len(self.fBufferSizes)/2)
  132. if audioSampleRate and audioSampleRate in self.fSampleRates:
  133. self.ui.cb_samplerate.setCurrentIndex(self.fSampleRates.index(audioSampleRate))
  134. elif self.fSampleRates == SAMPLE_RATE_LIST:
  135. self.ui.cb_samplerate.setCurrentIndex(SAMPLE_RATE_LIST.index(CARLA_DEFAULT_AUDIO_SAMPLE_RATE))
  136. else:
  137. self.ui.cb_samplerate.setCurrentIndex(len(self.fSampleRates)/2)
  138. @pyqtSlot()
  139. def slot_saveSettings(self):
  140. settings = QSettings()
  141. settings.setValue("%s%s/Device" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.cb_device.currentText())
  142. settings.setValue("%s%s/NumPeriods" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.sb_numperiods.value())
  143. settings.setValue("%s%s/BufferSize" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.cb_buffersize.currentText())
  144. settings.setValue("%s%s/SampleRate" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), self.ui.cb_samplerate.currentText())
  145. @pyqtSlot()
  146. def slot_updateDeviceInfo(self):
  147. deviceName = self.ui.cb_device.currentText()
  148. oldBufferSize = self.ui.cb_buffersize.currentText()
  149. oldSampleRate = self.ui.cb_samplerate.currentText()
  150. self.ui.cb_buffersize.clear()
  151. self.ui.cb_samplerate.clear()
  152. if deviceName and gCarla.host is not None:
  153. driverDeviceInfo = gCarla.host.get_engine_driver_device_info(self.fDriverIndex, deviceName)
  154. self.fBufferSizes = driverDeviceInfo['bufferSizes']
  155. self.fSampleRates = driverDeviceInfo['sampleRates']
  156. else:
  157. self.fBufferSizes = BUFFER_SIZE_LIST
  158. self.fSampleRates = SAMPLE_RATE_LIST
  159. for bsize in self.fBufferSizes:
  160. sbsize = str(bsize)
  161. self.ui.cb_buffersize.addItem(sbsize)
  162. if oldBufferSize == sbsize:
  163. self.ui.cb_buffersize.setCurrentIndex(self.ui.cb_buffersize.count()-1)
  164. for srate in self.fSampleRates:
  165. ssrate = str(int(srate))
  166. self.ui.cb_samplerate.addItem(ssrate)
  167. if oldSampleRate == ssrate:
  168. self.ui.cb_samplerate.setCurrentIndex(self.ui.cb_samplerate.count()-1)
  169. def done(self, r):
  170. QDialog.done(self, r)
  171. self.close()
  172. # ------------------------------------------------------------------------------------------------------------
  173. # Settings Dialog
  174. class CarlaSettingsW(QDialog):
  175. # Tab indexes
  176. TAB_INDEX_MAIN = 0
  177. TAB_INDEX_CANVAS = 1
  178. TAB_INDEX_ENGINE = 2
  179. TAB_INDEX_PATHS = 3
  180. TAB_INDEX_NONE = 4
  181. # Path indexes
  182. PATH_INDEX_LADSPA = 0
  183. PATH_INDEX_DSSI = 1
  184. PATH_INDEX_LV2 = 2
  185. PATH_INDEX_VST = 3
  186. PATH_INDEX_VST3 = 4
  187. PATH_INDEX_AU = 5
  188. PATH_INDEX_CSOUND = 6
  189. PATH_INDEX_GIG = 7
  190. PATH_INDEX_SF2 = 8
  191. PATH_INDEX_SFZ = 9
  192. # Single and Multiple client mode is only for JACK,
  193. # but we still want to match QComboBox index to defines,
  194. # so add +2 pos padding if driverName != "JACK".
  195. PROCESS_MODE_NON_JACK_PADDING = 2
  196. def __init__(self, parent, hasCanvas, hasCanvasGL, hasEngine):
  197. QDialog.__init__(self, parent)
  198. self.ui = ui_carla_settings.Ui_CarlaSettingsW()
  199. self.ui.setupUi(self)
  200. self.ui.lw_page.setFixedWidth(48 + 6 + 6 + QFontMetrics(self.ui.lw_page.font()).width("88888888"))
  201. # -------------------------------------------------------------
  202. # Set-up GUI
  203. if gCarla.host is not None:
  204. for i in range(gCarla.host.get_engine_driver_count()):
  205. self.ui.cb_engine_audio_driver.addItem(gCarla.host.get_engine_driver_name(i))
  206. else:
  207. self.ui.tb_engine_driver_config.setEnabled(False)
  208. for i in range(Theme.THEME_MAX):
  209. self.ui.cb_canvas_theme.addItem(getThemeName(i))
  210. # -------------------------------------------------------------
  211. # Load settings
  212. self.loadSettings()
  213. if not hasCanvas:
  214. self.ui.lw_page.hideRow(self.TAB_INDEX_CANVAS)
  215. if not hasCanvasGL:
  216. self.ui.cb_canvas_use_opengl.setChecked(False)
  217. self.ui.cb_canvas_use_opengl.setEnabled(False)
  218. if gCarla.isPlugin or not hasEngine:
  219. self.ui.lw_page.hideRow(self.TAB_INDEX_ENGINE)
  220. if gCarla.isPlugin:
  221. self.ui.lw_page.hideRow(self.TAB_INDEX_PATHS)
  222. if WINDOWS:
  223. self.ui.group_main_theme.setEnabled(False)
  224. self.ui.ch_main_theme_pro.setChecked(False)
  225. if not MACOS:
  226. self.ui.cb_paths.removeItem(self.ui.cb_paths.findText("AU"))
  227. # -------------------------------------------------------------
  228. # Set-up connections
  229. self.accepted.connect(self.slot_saveSettings)
  230. self.ui.buttonBox.button(QDialogButtonBox.Reset).clicked.connect(self.slot_resetSettings)
  231. self.ui.b_main_proj_folder_open.clicked.connect(self.slot_getAndSetProjectPath)
  232. self.ui.cb_engine_audio_driver.currentIndexChanged.connect(self.slot_engineAudioDriverChanged)
  233. self.ui.tb_engine_driver_config.clicked.connect(self.slot_showAudioDriverSettings)
  234. self.ui.b_paths_add.clicked.connect(self.slot_addPluginPath)
  235. self.ui.b_paths_remove.clicked.connect(self.slot_removePluginPath)
  236. self.ui.b_paths_change.clicked.connect(self.slot_changePluginPath)
  237. self.ui.cb_paths.currentIndexChanged.connect(self.slot_pluginPathTabChanged)
  238. self.ui.lw_ladspa.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  239. self.ui.lw_dssi.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  240. self.ui.lw_lv2.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  241. self.ui.lw_vst.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  242. self.ui.lw_vst3.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  243. self.ui.lw_au.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  244. self.ui.lw_csound.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  245. self.ui.lw_gig.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  246. self.ui.lw_sf2.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  247. self.ui.lw_sfz.currentRowChanged.connect(self.slot_pluginPathRowChanged)
  248. # -------------------------------------------------------------
  249. # Post-connect setup
  250. self.ui.lw_ladspa.setCurrentRow(0)
  251. self.ui.lw_dssi.setCurrentRow(0)
  252. self.ui.lw_lv2.setCurrentRow(0)
  253. self.ui.lw_vst.setCurrentRow(0)
  254. self.ui.lw_vst3.setCurrentRow(0)
  255. self.ui.lw_au.setCurrentRow(0)
  256. self.ui.lw_csound.setCurrentRow(0)
  257. self.ui.lw_gig.setCurrentRow(0)
  258. self.ui.lw_sf2.setCurrentRow(0)
  259. self.ui.lw_sfz.setCurrentRow(0)
  260. self.ui.lw_page.setCurrentCell(0, 0)
  261. def loadSettings(self):
  262. settings = QSettings()
  263. # ---------------------------------------
  264. # Main
  265. self.ui.le_main_proj_folder.setText(settings.value(CARLA_KEY_MAIN_PROJECT_FOLDER, CARLA_DEFAULT_MAIN_PROJECT_FOLDER, type=str))
  266. self.ui.ch_main_theme_pro.setChecked(settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, CARLA_DEFAULT_MAIN_USE_PRO_THEME, type=bool))
  267. self.ui.cb_main_theme_color.setCurrentIndex(self.ui.cb_main_theme_color.findText(settings.value(CARLA_KEY_MAIN_PRO_THEME_COLOR, CARLA_DEFAULT_MAIN_PRO_THEME_COLOR, type=str)))
  268. self.ui.sb_main_refresh_interval.setValue(settings.value(CARLA_KEY_MAIN_REFRESH_INTERVAL, CARLA_DEFAULT_MAIN_REFRESH_INTERVAL, type=int))
  269. # ---------------------------------------
  270. # Canvas
  271. self.ui.cb_canvas_theme.setCurrentIndex(self.ui.cb_canvas_theme.findText(settings.value(CARLA_KEY_CANVAS_THEME, CARLA_DEFAULT_CANVAS_THEME, type=str)))
  272. self.ui.cb_canvas_size.setCurrentIndex(self.ui.cb_canvas_size.findText(settings.value(CARLA_KEY_CANVAS_SIZE, CARLA_DEFAULT_CANVAS_SIZE, type=str)))
  273. self.ui.cb_canvas_bezier_lines.setChecked(settings.value(CARLA_KEY_CANVAS_USE_BEZIER_LINES, CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES, type=bool))
  274. self.ui.cb_canvas_hide_groups.setChecked(settings.value(CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS, CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS, type=bool))
  275. self.ui.cb_canvas_eyecandy.setCheckState(settings.value(CARLA_KEY_CANVAS_EYE_CANDY, CARLA_DEFAULT_CANVAS_EYE_CANDY, type=int))
  276. self.ui.cb_canvas_use_opengl.setChecked(settings.value(CARLA_KEY_CANVAS_USE_OPENGL, CARLA_DEFAULT_CANVAS_USE_OPENGL, type=bool))
  277. self.ui.cb_canvas_render_aa.setCheckState(settings.value(CARLA_KEY_CANVAS_ANTIALIASING, CARLA_DEFAULT_CANVAS_ANTIALIASING, type=int))
  278. self.ui.cb_canvas_render_hq_aa.setChecked(settings.value(CARLA_KEY_CANVAS_HQ_ANTIALIASING, CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING, type=bool))
  279. # --------------------------------------------
  280. # Engine
  281. audioDriver = settings.value(CARLA_KEY_ENGINE_AUDIO_DRIVER, CARLA_DEFAULT_AUDIO_DRIVER, type=str)
  282. for i in range(self.ui.cb_engine_audio_driver.count()):
  283. if self.ui.cb_engine_audio_driver.itemText(i) == audioDriver:
  284. self.ui.cb_engine_audio_driver.setCurrentIndex(i)
  285. break
  286. else:
  287. self.ui.cb_engine_audio_driver.setCurrentIndex(-1)
  288. if audioDriver == "JACK":
  289. processModeIndex = settings.value(CARLA_KEY_ENGINE_PROCESS_MODE, ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, type=int)
  290. self.ui.cb_engine_process_mode_jack.setCurrentIndex(processModeIndex)
  291. self.ui.sw_engine_process_mode.setCurrentIndex(0)
  292. else:
  293. processModeIndex = settings.value(CARLA_KEY_ENGINE_PROCESS_MODE, ENGINE_PROCESS_MODE_CONTINUOUS_RACK, type=int)
  294. processModeIndex -= self.PROCESS_MODE_NON_JACK_PADDING
  295. self.ui.cb_engine_process_mode_other.setCurrentIndex(processModeIndex)
  296. self.ui.sw_engine_process_mode.setCurrentIndex(1)
  297. self.ui.sb_engine_max_params.setValue(settings.value(CARLA_KEY_ENGINE_MAX_PARAMETERS, CARLA_DEFAULT_MAX_PARAMETERS, type=int))
  298. self.ui.ch_engine_uis_always_on_top.setChecked(settings.value(CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP, CARLA_DEFAULT_UIS_ALWAYS_ON_TOP, type=bool))
  299. self.ui.ch_engine_prefer_ui_bridges.setChecked(settings.value(CARLA_KEY_ENGINE_PREFER_UI_BRIDGES, CARLA_DEFAULT_PREFER_UI_BRIDGES, type=bool))
  300. self.ui.sb_engine_ui_bridges_timeout.setValue(settings.value(CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT, CARLA_DEFAULT_UI_BRIDGES_TIMEOUT, type=int))
  301. self.ui.ch_engine_force_stereo.setChecked(settings.value(CARLA_KEY_ENGINE_FORCE_STEREO, CARLA_DEFAULT_FORCE_STEREO, type=bool))
  302. self.ui.ch_engine_prefer_plugin_bridges.setChecked(settings.value(CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES, CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES, type=bool))
  303. # --------------------------------------------
  304. # Paths
  305. ladspas = toList(settings.value(CARLA_KEY_PATHS_LADSPA, gCarla.DEFAULT_LADSPA_PATH))
  306. dssis = toList(settings.value(CARLA_KEY_PATHS_DSSI, gCarla.DEFAULT_DSSI_PATH))
  307. lv2s = toList(settings.value(CARLA_KEY_PATHS_LV2, gCarla.DEFAULT_LV2_PATH))
  308. vsts = toList(settings.value(CARLA_KEY_PATHS_VST, gCarla.DEFAULT_VST_PATH))
  309. vst3s = toList(settings.value(CARLA_KEY_PATHS_VST3, gCarla.DEFAULT_VST3_PATH))
  310. aus = toList(settings.value(CARLA_KEY_PATHS_AU, gCarla.DEFAULT_AU_PATH))
  311. csds = toList(settings.value(CARLA_KEY_PATHS_CSD, gCarla.DEFAULT_CSOUND_PATH))
  312. gigs = toList(settings.value(CARLA_KEY_PATHS_GIG, gCarla.DEFAULT_GIG_PATH))
  313. sf2s = toList(settings.value(CARLA_KEY_PATHS_SF2, gCarla.DEFAULT_SF2_PATH))
  314. sfzs = toList(settings.value(CARLA_KEY_PATHS_SFZ, gCarla.DEFAULT_SFZ_PATH))
  315. ladspas.sort()
  316. dssis.sort()
  317. lv2s.sort()
  318. vsts.sort()
  319. vst3s.sort()
  320. aus.sort()
  321. csds.sort()
  322. gigs.sort()
  323. sf2s.sort()
  324. sfzs.sort()
  325. for ladspa in ladspas:
  326. if not ladspa: continue
  327. self.ui.lw_ladspa.addItem(ladspa)
  328. for dssi in dssis:
  329. if not dssi: continue
  330. self.ui.lw_dssi.addItem(dssi)
  331. for lv2 in lv2s:
  332. if not lv2: continue
  333. self.ui.lw_lv2.addItem(lv2)
  334. for vst in vsts:
  335. if not vst: continue
  336. self.ui.lw_vst.addItem(vst)
  337. for vst3 in vst3s:
  338. if not vst3: continue
  339. self.ui.lw_vst3.addItem(vst3)
  340. for au in aus:
  341. if not au: continue
  342. self.ui.lw_au.addItem(au)
  343. for csd in csds:
  344. if not csd: continue
  345. self.ui.lw_csound.addItem(csd)
  346. for gig in gigs:
  347. if not gig: continue
  348. self.ui.lw_gig.addItem(gig)
  349. for sf2 in sf2s:
  350. if not sf2: continue
  351. self.ui.lw_sf2.addItem(sf2)
  352. for sfz in sfzs:
  353. if not sfz: continue
  354. self.ui.lw_sfz.addItem(sfz)
  355. @pyqtSlot()
  356. def slot_saveSettings(self):
  357. settings = QSettings()
  358. # ---------------------------------------
  359. settings.setValue(CARLA_KEY_MAIN_PROJECT_FOLDER, self.ui.le_main_proj_folder.text())
  360. settings.setValue(CARLA_KEY_MAIN_USE_PRO_THEME, self.ui.ch_main_theme_pro.isChecked())
  361. settings.setValue(CARLA_KEY_MAIN_PRO_THEME_COLOR, self.ui.cb_main_theme_color.currentText())
  362. settings.setValue(CARLA_KEY_MAIN_REFRESH_INTERVAL, self.ui.sb_main_refresh_interval.value())
  363. # ---------------------------------------
  364. settings.setValue(CARLA_KEY_CANVAS_THEME, self.ui.cb_canvas_theme.currentText())
  365. settings.setValue(CARLA_KEY_CANVAS_SIZE, self.ui.cb_canvas_size.currentText())
  366. settings.setValue(CARLA_KEY_CANVAS_USE_BEZIER_LINES, self.ui.cb_canvas_bezier_lines.isChecked())
  367. settings.setValue(CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS, self.ui.cb_canvas_hide_groups.isChecked())
  368. settings.setValue(CARLA_KEY_CANVAS_EYE_CANDY, self.ui.cb_canvas_eyecandy.checkState()) # 0, 1, 2 match their enum variants
  369. settings.setValue(CARLA_KEY_CANVAS_USE_OPENGL, self.ui.cb_canvas_use_opengl.isChecked())
  370. settings.setValue(CARLA_KEY_CANVAS_HQ_ANTIALIASING, self.ui.cb_canvas_render_hq_aa.isChecked())
  371. settings.setValue(CARLA_KEY_CANVAS_ANTIALIASING, self.ui.cb_canvas_render_aa.checkState()) # 0, 1, 2 match their enum variants
  372. # --------------------------------------------
  373. audioDriver = self.ui.cb_engine_audio_driver.currentText()
  374. if audioDriver:
  375. settings.setValue(CARLA_KEY_ENGINE_AUDIO_DRIVER, audioDriver)
  376. if audioDriver == "JACK":
  377. settings.setValue(CARLA_KEY_ENGINE_PROCESS_MODE, self.ui.cb_engine_process_mode_jack.currentIndex())
  378. else:
  379. settings.setValue(CARLA_KEY_ENGINE_PROCESS_MODE, self.ui.cb_engine_process_mode_other.currentIndex()+self.PROCESS_MODE_NON_JACK_PADDING)
  380. settings.setValue(CARLA_KEY_ENGINE_MAX_PARAMETERS, self.ui.sb_engine_max_params.value())
  381. settings.setValue(CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP, self.ui.ch_engine_uis_always_on_top.isChecked())
  382. settings.setValue(CARLA_KEY_ENGINE_PREFER_UI_BRIDGES, self.ui.ch_engine_prefer_ui_bridges.isChecked())
  383. settings.setValue(CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT, self.ui.sb_engine_ui_bridges_timeout.value())
  384. settings.setValue(CARLA_KEY_ENGINE_FORCE_STEREO, self.ui.ch_engine_force_stereo.isChecked())
  385. settings.setValue(CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES, self.ui.ch_engine_prefer_plugin_bridges.isChecked())
  386. # --------------------------------------------
  387. ladspas = []
  388. dssis = []
  389. lv2s = []
  390. vsts = []
  391. vst3s = []
  392. aus = []
  393. csds = []
  394. gigs = []
  395. sf2s = []
  396. sfzs = []
  397. for i in range(self.ui.lw_ladspa.count()):
  398. ladspas.append(self.ui.lw_ladspa.item(i).text())
  399. for i in range(self.ui.lw_dssi.count()):
  400. dssis.append(self.ui.lw_dssi.item(i).text())
  401. for i in range(self.ui.lw_lv2.count()):
  402. lv2s.append(self.ui.lw_lv2.item(i).text())
  403. for i in range(self.ui.lw_vst.count()):
  404. vsts.append(self.ui.lw_vst.item(i).text())
  405. for i in range(self.ui.lw_vst3.count()):
  406. vst3s.append(self.ui.lw_vst3.item(i).text())
  407. for i in range(self.ui.lw_au.count()):
  408. aus.append(self.ui.lw_au.item(i).text())
  409. for i in range(self.ui.lw_csound.count()):
  410. csds.append(self.ui.lw_csound.item(i).text())
  411. for i in range(self.ui.lw_gig.count()):
  412. gigs.append(self.ui.lw_gig.item(i).text())
  413. for i in range(self.ui.lw_sf2.count()):
  414. sf2s.append(self.ui.lw_sf2.item(i).text())
  415. for i in range(self.ui.lw_sfz.count()):
  416. sfzs.append(self.ui.lw_sfz.item(i).text())
  417. settings.setValue(CARLA_KEY_PATHS_LADSPA, ladspas)
  418. settings.setValue(CARLA_KEY_PATHS_DSSI, dssis)
  419. settings.setValue(CARLA_KEY_PATHS_LV2, lv2s)
  420. settings.setValue(CARLA_KEY_PATHS_VST, vsts)
  421. settings.setValue(CARLA_KEY_PATHS_VST3, vst3s)
  422. settings.setValue(CARLA_KEY_PATHS_AU, aus)
  423. settings.setValue(CARLA_KEY_PATHS_CSD, csds)
  424. settings.setValue(CARLA_KEY_PATHS_GIG, gigs)
  425. settings.setValue(CARLA_KEY_PATHS_SF2, sf2s)
  426. settings.setValue(CARLA_KEY_PATHS_SFZ, sfzs)
  427. @pyqtSlot()
  428. def slot_resetSettings(self):
  429. if self.ui.lw_page.currentRow() == self.TAB_INDEX_MAIN:
  430. self.ui.le_main_proj_folder.setText(CARLA_DEFAULT_MAIN_PROJECT_FOLDER)
  431. self.ui.ch_theme_pro.setChecked(CARLA_DEFAULT_MAIN_USE_PRO_THEME)
  432. self.ui.cb_theme_color.setCurrentIndex(self.ui.cb_theme_color.findText(CARLA_DEFAULT_MAIN_PRO_THEME_COLOR))
  433. self.ui.sb_gui_refresh.setValue(CARLA_DEFAULT_MAIN_REFRESH_INTERVAL)
  434. elif self.ui.lw_page.currentRow() == self.TAB_INDEX_CANVAS:
  435. self.ui.cb_canvas_theme.setCurrentIndex(self.ui.cb_canvas_theme.findText(CARLA_DEFAULT_CANVAS_THEME))
  436. self.ui.cb_canvas_size.setCurrentIndex(self.ui.cb_canvas_size.findText(CARLA_DEFAULT_CANVAS_SIZE))
  437. self.ui.cb_canvas_bezier_lines.setChecked(CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES)
  438. self.ui.cb_canvas_hide_groups.setChecked(CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS)
  439. self.ui.cb_canvas_eyecandy.setCheckState(Qt.PartiallyChecked) # CARLA_DEFAULT_CANVAS_EYE_CANDY
  440. self.ui.cb_canvas_use_opengl.setChecked(CARLA_DEFAULT_CANVAS_USE_OPENGL)
  441. self.ui.cb_canvas_render_aa.setCheckState(Qt.PartiallyChecked) # CARLA_DEFAULT_CANVAS_ANTIALIASING
  442. self.ui.cb_canvas_render_hq_aa.setChecked(CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING)
  443. elif self.ui.lw_page.currentRow() == self.TAB_INDEX_ENGINE:
  444. self.ui.cb_engine_audio_driver.setCurrentIndex(0)
  445. self.ui.sb_engine_max_params.setValue(CARLA_DEFAULT_MAX_PARAMETERS)
  446. self.ui.ch_engine_uis_always_on_top.setChecked(CARLA_DEFAULT_UIS_ALWAYS_ON_TOP)
  447. self.ui.ch_engine_prefer_ui_bridges.setChecked(CARLA_DEFAULT_PREFER_UI_BRIDGES)
  448. self.ui.sb_engine_ui_bridges_timeout.setValue(CARLA_DEFAULT_UI_BRIDGES_TIMEOUT)
  449. self.ui.ch_engine_force_stereo.setChecked(CARLA_DEFAULT_FORCE_STEREO)
  450. self.ui.ch_engine_prefer_plugin_bridges.setChecked(CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES)
  451. if self.ui.cb_engine_audio_driver.currentText() == "JACK":
  452. self.ui.cb_engine_process_mode_jack.setCurrentIndex(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  453. self.ui.sw_engine_process_mode.setCurrentIndex(0) # show all modes
  454. else:
  455. self.ui.cb_engine_process_mode_other.setCurrentIndex(ENGINE_PROCESS_MODE_CONTINUOUS_RACK-self.PROCESS_MODE_NON_JACK_PADDING)
  456. self.ui.sw_engine_process_mode.setCurrentIndex(1) # hide single+multi client modes
  457. elif self.ui.lw_page.currentRow() == self.TAB_INDEX_PATHS:
  458. curIndex = self.ui.tw_paths.currentIndex()
  459. if curIndex == self.PATH_INDEX_LADSPA:
  460. paths = DEFAULT_LADSPA_PATH.split(splitter)
  461. paths.sort()
  462. self.ui.lw_ladspa.clear()
  463. for path in paths:
  464. if not path: continue
  465. self.ui.lw_ladspa.addItem(path)
  466. elif curIndex == self.PATH_INDEX_DSSI:
  467. paths = DEFAULT_DSSI_PATH.split(splitter)
  468. paths.sort()
  469. self.ui.lw_dssi.clear()
  470. for path in paths:
  471. if not path: continue
  472. self.ui.lw_dssi.addItem(path)
  473. elif curIndex == self.PATH_INDEX_LV2:
  474. paths = DEFAULT_LV2_PATH.split(splitter)
  475. paths.sort()
  476. self.ui.lw_lv2.clear()
  477. for path in paths:
  478. if not path: continue
  479. self.ui.lw_lv2.addItem(path)
  480. elif curIndex == self.PATH_INDEX_VST:
  481. paths = DEFAULT_VST_PATH.split(splitter)
  482. paths.sort()
  483. self.ui.lw_vst.clear()
  484. for path in paths:
  485. if not path: continue
  486. self.ui.lw_vst.addItem(path)
  487. elif curIndex == self.PATH_INDEX_VST3:
  488. paths = DEFAULT_VST3_PATH.split(splitter)
  489. paths.sort()
  490. self.ui.lw_vst3.clear()
  491. for path in paths:
  492. if not path: continue
  493. self.ui.lw_vst3.addItem(path)
  494. elif curIndex == self.PATH_INDEX_AU:
  495. paths = DEFAULT_AU_PATH.split(splitter)
  496. paths.sort()
  497. self.ui.lw_au.clear()
  498. for path in paths:
  499. if not path: continue
  500. self.ui.lw_au.addItem(path)
  501. elif curIndex == self.PATH_INDEX_CSOUND:
  502. paths = DEFAULT_CSOUND_PATH.split(splitter)
  503. paths.sort()
  504. self.ui.lw_csound.clear()
  505. for path in paths:
  506. if not path: continue
  507. self.ui.lw_csound.addItem(path)
  508. elif curIndex == self.PATH_INDEX_GIG:
  509. paths = DEFAULT_GIG_PATH.split(splitter)
  510. paths.sort()
  511. self.ui.lw_gig.clear()
  512. for path in paths:
  513. if not path: continue
  514. self.ui.lw_gig.addItem(path)
  515. elif curIndex == self.PATH_INDEX_SF2:
  516. paths = DEFAULT_SF2_PATH.split(splitter)
  517. paths.sort()
  518. self.ui.lw_sf2.clear()
  519. for path in paths:
  520. if not path: continue
  521. self.ui.lw_sf2.addItem(path)
  522. elif curIndex == self.PATH_INDEX_SFZ:
  523. paths = DEFAULT_SFZ_PATH.split(splitter)
  524. paths.sort()
  525. self.ui.lw_sfz.clear()
  526. for path in paths:
  527. if not path: continue
  528. self.ui.lw_sfz.addItem(path)
  529. @pyqtSlot()
  530. def slot_getAndSetProjectPath(self):
  531. getAndSetPath(self, self.ui.le_main_proj_folder.text(), self.ui.le_main_proj_folder)
  532. @pyqtSlot()
  533. def slot_engineAudioDriverChanged(self):
  534. if self.ui.cb_engine_audio_driver.currentText() == "JACK":
  535. self.ui.sw_engine_process_mode.setCurrentIndex(0)
  536. self.ui.tb_engine_driver_config.setEnabled(False)
  537. else:
  538. self.ui.sw_engine_process_mode.setCurrentIndex(1)
  539. self.ui.tb_engine_driver_config.setEnabled(True)
  540. @pyqtSlot()
  541. def slot_showAudioDriverSettings(self):
  542. driverIndex = self.ui.cb_engine_audio_driver.currentIndex()
  543. driverName = self.ui.cb_engine_audio_driver.currentText()
  544. DriverSettingsW(self, driverIndex, driverName).exec_()
  545. @pyqtSlot()
  546. def slot_addPluginPath(self):
  547. newPath = QFileDialog.getExistingDirectory(self, self.tr("Add Path"), "", QFileDialog.ShowDirsOnly)
  548. if not newPath:
  549. return
  550. curIndex = self.ui.tw_paths.currentIndex()
  551. if curIndex == self.PATH_INDEX_LADSPA:
  552. self.ui.lw_ladspa.addItem(newPath)
  553. elif curIndex == self.PATH_INDEX_DSSI:
  554. self.ui.lw_dssi.addItem(newPath)
  555. elif curIndex == self.PATH_INDEX_LV2:
  556. self.ui.lw_lv2.addItem(newPath)
  557. elif curIndex == self.PATH_INDEX_VST:
  558. self.ui.lw_vst.addItem(newPath)
  559. elif curIndex == self.PATH_INDEX_VST3:
  560. self.ui.lw_vst3.addItem(newPath)
  561. elif curIndex == self.PATH_INDEX_AU:
  562. self.ui.lw_au.addItem(newPath)
  563. elif curIndex == self.PATH_INDEX_CSOUND:
  564. self.ui.lw_csound.addItem(newPath)
  565. elif curIndex == self.PATH_INDEX_GIG:
  566. self.ui.lw_gig.addItem(newPath)
  567. elif curIndex == self.PATH_INDEX_SF2:
  568. self.ui.lw_sf2.addItem(newPath)
  569. elif curIndex == self.PATH_INDEX_SFZ:
  570. self.ui.lw_sfz.addItem(newPath)
  571. @pyqtSlot()
  572. def slot_removePluginPath(self):
  573. curIndex = self.ui.tw_paths.currentIndex()
  574. if curIndex == self.PATH_INDEX_LADSPA:
  575. self.ui.lw_ladspa.takeItem(self.ui.lw_ladspa.currentRow())
  576. elif curIndex == self.PATH_INDEX_DSSI:
  577. self.ui.lw_dssi.takeItem(self.ui.lw_dssi.currentRow())
  578. elif curIndex == self.PATH_INDEX_LV2:
  579. self.ui.lw_lv2.takeItem(self.ui.lw_lv2.currentRow())
  580. elif curIndex == self.PATH_INDEX_VST:
  581. self.ui.lw_vst.takeItem(self.ui.lw_vst.currentRow())
  582. elif curIndex == self.PATH_INDEX_VST3:
  583. self.ui.lw_vst3.takeItem(self.ui.lw_vst3.currentRow())
  584. elif curIndex == self.PATH_INDEX_AU:
  585. self.ui.lw_au.takeItem(self.ui.lw_au.currentRow())
  586. elif curIndex == self.PATH_INDEX_CSOUND:
  587. self.ui.lw_csound.takeItem(self.ui.lw_csound.currentRow())
  588. elif curIndex == self.PATH_INDEX_GIG:
  589. self.ui.lw_gig.takeItem(self.ui.lw_gig.currentRow())
  590. elif curIndex == self.PATH_INDEX_SF2:
  591. self.ui.lw_sf2.takeItem(self.ui.lw_sf2.currentRow())
  592. elif curIndex == self.PATH_INDEX_SFZ:
  593. self.ui.lw_sfz.takeItem(self.ui.lw_sfz.currentRow())
  594. @pyqtSlot()
  595. def slot_changePluginPath(self):
  596. curIndex = self.ui.tw_paths.currentIndex()
  597. if curIndex == self.PATH_INDEX_LADSPA:
  598. currentPath = self.ui.lw_ladspa.currentItem().text()
  599. elif curIndex == self.PATH_INDEX_DSSI:
  600. currentPath = self.ui.lw_dssi.currentItem().text()
  601. elif curIndex == self.PATH_INDEX_LV2:
  602. currentPath = self.ui.lw_lv2.currentItem().text()
  603. elif curIndex == self.PATH_INDEX_VST:
  604. currentPath = self.ui.lw_vst.currentItem().text()
  605. elif curIndex == self.PATH_INDEX_VST3:
  606. currentPath = self.ui.lw_vst3.currentItem().text()
  607. elif curIndex == self.PATH_INDEX_AU:
  608. currentPath = self.ui.lw_au.currentItem().text()
  609. elif curIndex == self.PATH_INDEX_CSOUND:
  610. currentPath = self.ui.lw_csound.currentItem().text()
  611. elif curIndex == self.PATH_INDEX_GIG:
  612. currentPath = self.ui.lw_gig.currentItem().text()
  613. elif curIndex == self.PATH_INDEX_SF2:
  614. currentPath = self.ui.lw_sf2.currentItem().text()
  615. elif curIndex == self.PATH_INDEX_SFZ:
  616. currentPath = self.ui.lw_sfz.currentItem().text()
  617. else:
  618. currentPath = ""
  619. newPath = QFileDialog.getExistingDirectory(self, self.tr("Add Path"), currentPath, QFileDialog.ShowDirsOnly)
  620. if not newPath:
  621. return
  622. if curIndex == self.PATH_INDEX_LADSPA:
  623. self.ui.lw_ladspa.currentItem().setText(newPath)
  624. elif curIndex == self.PATH_INDEX_DSSI:
  625. self.ui.lw_dssi.currentItem().setText(newPath)
  626. elif curIndex == self.PATH_INDEX_LV2:
  627. self.ui.lw_lv2.currentItem().setText(newPath)
  628. elif curIndex == self.PATH_INDEX_VST:
  629. self.ui.lw_vst.currentItem().setText(newPath)
  630. elif curIndex == self.PATH_INDEX_VST3:
  631. self.ui.lw_vst3.currentItem().setText(newPath)
  632. elif curIndex == self.PATH_INDEX_AU:
  633. self.ui.lw_au.currentItem().setText(newPath)
  634. elif curIndex == self.PATH_INDEX_CSOUND:
  635. self.ui.lw_csound.currentItem().setText(newPath)
  636. elif curIndex == self.PATH_INDEX_GIG:
  637. self.ui.lw_gig.currentItem().setText(newPath)
  638. elif curIndex == self.PATH_INDEX_SF2:
  639. self.ui.lw_sf2.currentItem().setText(newPath)
  640. elif curIndex == self.PATH_INDEX_SFZ:
  641. self.ui.lw_sfz.currentItem().setText(newPath)
  642. @pyqtSlot(int)
  643. def slot_pluginPathTabChanged(self, index):
  644. if index >= self.PATH_INDEX_AU and not MACOS:
  645. self.ui.tw_paths.setCurrentIndex(index+1)
  646. if index == self.PATH_INDEX_LADSPA:
  647. row = self.ui.lw_ladspa.currentRow()
  648. elif index == self.PATH_INDEX_DSSI:
  649. row = self.ui.lw_dssi.currentRow()
  650. elif index == self.PATH_INDEX_LV2:
  651. row = self.ui.lw_lv2.currentRow()
  652. elif index == self.PATH_INDEX_VST:
  653. row = self.ui.lw_vst.currentRow()
  654. elif index == self.PATH_INDEX_VST3:
  655. row = self.ui.lw_vst3.currentRow()
  656. elif index == self.PATH_INDEX_AU:
  657. row = self.ui.lw_au.currentRow()
  658. elif index == self.PATH_INDEX_CSOUND:
  659. row = self.ui.lw_csound.currentRow()
  660. elif index == self.PATH_INDEX_GIG:
  661. row = self.ui.lw_gig.currentRow()
  662. elif index == self.PATH_INDEX_SF2:
  663. row = self.ui.lw_sf2.currentRow()
  664. elif index == self.PATH_INDEX_SFZ:
  665. row = self.ui.lw_sfz.currentRow()
  666. else:
  667. row = -1
  668. check = bool(row >= 0)
  669. self.ui.b_paths_remove.setEnabled(check)
  670. self.ui.b_paths_change.setEnabled(check)
  671. @pyqtSlot(int)
  672. def slot_pluginPathRowChanged(self, row):
  673. check = bool(row >= 0)
  674. self.ui.b_paths_remove.setEnabled(check)
  675. self.ui.b_paths_change.setEnabled(check)
  676. def done(self, r):
  677. QDialog.done(self, r)
  678. self.close()
  679. # ------------------------------------------------------------------------------------------------------------
  680. # Main
  681. if __name__ == '__main__':
  682. app = CarlaApplication()
  683. initHost("Settings", None, False)
  684. gui = CarlaSettingsW(None, True, True, True)
  685. gui.show()
  686. sys.exit(app.exec_())