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.

pluginlistdialog.py 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla plugin host
  4. # Copyright (C) 2011-2022 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 (Global)
  19. import os
  20. from PyQt5.QtCore import pyqtSlot, Qt, QByteArray, QEventLoop
  21. from PyQt5.QtWidgets import QApplication, QDialog, QHeaderView, QTableWidgetItem, QWidget
  22. # ---------------------------------------------------------------------------------------------------------------------
  23. # Imports (Carla)
  24. from carla_backend import (
  25. BINARY_NATIVE,
  26. BINARY_OTHER,
  27. BINARY_POSIX32,
  28. BINARY_POSIX64,
  29. BINARY_WIN32,
  30. BINARY_WIN64,
  31. PLUGIN_AU,
  32. PLUGIN_DSSI,
  33. PLUGIN_HAS_CUSTOM_UI,
  34. PLUGIN_HAS_INLINE_DISPLAY,
  35. PLUGIN_INTERNAL,
  36. PLUGIN_IS_BRIDGE,
  37. PLUGIN_IS_RTSAFE,
  38. PLUGIN_IS_SYNTH,
  39. PLUGIN_JSFX,
  40. PLUGIN_LADSPA,
  41. PLUGIN_LV2,
  42. PLUGIN_SF2,
  43. PLUGIN_SFZ,
  44. PLUGIN_VST2,
  45. PLUGIN_VST3,
  46. PLUGIN_CLAP,
  47. )
  48. from carla_shared import (
  49. CARLA_DEFAULT_LV2_PATH,
  50. CARLA_KEY_PATHS_LV2,
  51. HAIKU,
  52. LINUX,
  53. MACOS,
  54. WINDOWS,
  55. fontMetricsHorizontalAdvance,
  56. gCarla,
  57. getIcon,
  58. kIs64bit,
  59. splitter,
  60. )
  61. from carla_utils import getPluginTypeAsString
  62. from utils import QSafeSettings
  63. # ---------------------------------------------------------------------------------------------------------------------
  64. # Imports (Local)
  65. from .discovery import PLUGIN_QUERY_API_VERSION, checkPluginCached
  66. from .pluginlistdialog_ui import Ui_PluginListDialog
  67. from .pluginlistrefreshdialog import PluginRefreshW
  68. # ---------------------------------------------------------------------------------------------------------------------
  69. # Plugin Database Dialog
  70. class PluginListDialog(QDialog):
  71. TABLEWIDGET_ITEM_FAVORITE = 0
  72. TABLEWIDGET_ITEM_NAME = 1
  73. TABLEWIDGET_ITEM_LABEL = 2
  74. TABLEWIDGET_ITEM_MAKER = 3
  75. TABLEWIDGET_ITEM_BINARY = 4
  76. def __init__(self, parent: QWidget, host, useSystemIcons: bool):
  77. QDialog.__init__(self, parent)
  78. self.host = host
  79. self.ui = Ui_PluginListDialog()
  80. self.ui.setupUi(self)
  81. # To be changed by parent
  82. self.hasLoadedLv2Plugins = False
  83. # ----------------------------------------------------------------------------------------------------
  84. # Internal stuff
  85. self.fLastTableIndex = 0
  86. self.fRetPlugin = None
  87. self.fRealParent = parent
  88. self.fFavoritePlugins = []
  89. self.fFavoritePluginsChanged = False
  90. self.fUseSystemIcons = useSystemIcons
  91. self.fTrYes = self.tr("Yes")
  92. self.fTrNo = self.tr("No")
  93. self.fTrNative = self.tr("Native")
  94. # ----------------------------------------------------------------------------------------------------
  95. # Set-up GUI
  96. self.ui.b_add.setEnabled(False)
  97. self.addAction(self.ui.act_focus_search)
  98. self.ui.act_focus_search.triggered.connect(self.slot_focusSearchFieldAndSelectAll)
  99. if BINARY_NATIVE in (BINARY_POSIX32, BINARY_WIN32):
  100. self.ui.ch_bridged.setText(self.tr("Bridged (64bit)"))
  101. else:
  102. self.ui.ch_bridged.setText(self.tr("Bridged (32bit)"))
  103. if not (LINUX or MACOS):
  104. self.ui.ch_bridged_wine.setChecked(False)
  105. self.ui.ch_bridged_wine.setEnabled(False)
  106. if MACOS:
  107. self.setWindowModality(Qt.WindowModal)
  108. else:
  109. self.ui.ch_au.setChecked(False)
  110. self.ui.ch_au.setEnabled(False)
  111. self.ui.ch_au.setVisible(False)
  112. self.ui.tab_info.tabBar().hide()
  113. self.ui.tab_reqs.tabBar().hide()
  114. # FIXME, why /2 needed?
  115. self.ui.tab_info.setMinimumWidth(int(self.ui.la_id.width()/2) +
  116. fontMetricsHorizontalAdvance(self.ui.l_id.fontMetrics(), "9999999999") + 6*3)
  117. self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
  118. # ----------------------------------------------------------------------------------------------------
  119. # Load settings
  120. self.loadSettings()
  121. # ----------------------------------------------------------------------------------------------------
  122. # Disable bridges if not enabled in settings
  123. # NOTE: We Assume win32 carla build will not run win64 plugins
  124. if (WINDOWS and not kIs64bit) or not host.showPluginBridges:
  125. self.ui.ch_native.setChecked(True)
  126. self.ui.ch_native.setEnabled(False)
  127. self.ui.ch_native.setVisible(True)
  128. self.ui.ch_bridged.setChecked(False)
  129. self.ui.ch_bridged.setEnabled(False)
  130. self.ui.ch_bridged.setVisible(False)
  131. self.ui.ch_bridged_wine.setChecked(False)
  132. self.ui.ch_bridged_wine.setEnabled(False)
  133. self.ui.ch_bridged_wine.setVisible(False)
  134. elif not host.showWineBridges:
  135. self.ui.ch_bridged_wine.setChecked(False)
  136. self.ui.ch_bridged_wine.setEnabled(False)
  137. self.ui.ch_bridged_wine.setVisible(False)
  138. # ----------------------------------------------------------------------------------------------------
  139. # Set-up Icons
  140. if useSystemIcons:
  141. self.ui.b_add.setIcon(getIcon('list-add', 16, 'svgz'))
  142. self.ui.b_cancel.setIcon(getIcon('dialog-cancel', 16, 'svgz'))
  143. self.ui.b_clear_filters.setIcon(getIcon('edit-clear', 16, 'svgz'))
  144. self.ui.b_refresh.setIcon(getIcon('view-refresh', 16, 'svgz'))
  145. hhi = self.ui.tableWidget.horizontalHeaderItem(self.TABLEWIDGET_ITEM_FAVORITE)
  146. hhi.setIcon(getIcon('bookmarks', 16, 'svgz'))
  147. # ----------------------------------------------------------------------------------------------------
  148. # Set-up connections
  149. self.finished.connect(self.slot_saveSettings)
  150. self.ui.b_add.clicked.connect(self.slot_addPlugin)
  151. self.ui.b_cancel.clicked.connect(self.reject)
  152. self.ui.b_refresh.clicked.connect(self.slot_refreshPlugins)
  153. self.ui.b_clear_filters.clicked.connect(self.slot_clearFilters)
  154. self.ui.lineEdit.textChanged.connect(self.slot_checkFilters)
  155. self.ui.tableWidget.currentCellChanged.connect(self.slot_checkPlugin)
  156. self.ui.tableWidget.cellClicked.connect(self.slot_cellClicked)
  157. self.ui.tableWidget.cellDoubleClicked.connect(self.slot_cellDoubleClicked)
  158. self.ui.ch_internal.clicked.connect(self.slot_checkFilters)
  159. self.ui.ch_ladspa.clicked.connect(self.slot_checkFilters)
  160. self.ui.ch_dssi.clicked.connect(self.slot_checkFilters)
  161. self.ui.ch_lv2.clicked.connect(self.slot_checkFilters)
  162. self.ui.ch_vst.clicked.connect(self.slot_checkFilters)
  163. self.ui.ch_vst3.clicked.connect(self.slot_checkFilters)
  164. self.ui.ch_clap.clicked.connect(self.slot_checkFilters)
  165. self.ui.ch_au.clicked.connect(self.slot_checkFilters)
  166. self.ui.ch_jsfx.clicked.connect(self.slot_checkFilters)
  167. self.ui.ch_kits.clicked.connect(self.slot_checkFilters)
  168. self.ui.ch_effects.clicked.connect(self.slot_checkFilters)
  169. self.ui.ch_instruments.clicked.connect(self.slot_checkFilters)
  170. self.ui.ch_midi.clicked.connect(self.slot_checkFilters)
  171. self.ui.ch_other.clicked.connect(self.slot_checkFilters)
  172. self.ui.ch_native.clicked.connect(self.slot_checkFilters)
  173. self.ui.ch_bridged.clicked.connect(self.slot_checkFilters)
  174. self.ui.ch_bridged_wine.clicked.connect(self.slot_checkFilters)
  175. self.ui.ch_favorites.clicked.connect(self.slot_checkFilters)
  176. self.ui.ch_rtsafe.clicked.connect(self.slot_checkFilters)
  177. self.ui.ch_cv.clicked.connect(self.slot_checkFilters)
  178. self.ui.ch_gui.clicked.connect(self.slot_checkFilters)
  179. self.ui.ch_inline_display.clicked.connect(self.slot_checkFilters)
  180. self.ui.ch_stereo.clicked.connect(self.slot_checkFilters)
  181. self.ui.ch_cat_all.clicked.connect(self.slot_checkFiltersCategoryAll)
  182. self.ui.ch_cat_delay.clicked.connect(self.slot_checkFiltersCategorySpecific)
  183. self.ui.ch_cat_distortion.clicked.connect(self.slot_checkFiltersCategorySpecific)
  184. self.ui.ch_cat_dynamics.clicked.connect(self.slot_checkFiltersCategorySpecific)
  185. self.ui.ch_cat_eq.clicked.connect(self.slot_checkFiltersCategorySpecific)
  186. self.ui.ch_cat_filter.clicked.connect(self.slot_checkFiltersCategorySpecific)
  187. self.ui.ch_cat_modulator.clicked.connect(self.slot_checkFiltersCategorySpecific)
  188. self.ui.ch_cat_synth.clicked.connect(self.slot_checkFiltersCategorySpecific)
  189. self.ui.ch_cat_utility.clicked.connect(self.slot_checkFiltersCategorySpecific)
  190. self.ui.ch_cat_other.clicked.connect(self.slot_checkFiltersCategorySpecific)
  191. # ----------------------------------------------------------------------------------------------------
  192. # Post-connect setup
  193. self._reAddPlugins()
  194. self.slot_focusSearchFieldAndSelectAll()
  195. # --------------------------------------------------------------------------------------------------------
  196. @pyqtSlot(int, int)
  197. def slot_cellClicked(self, row, column):
  198. if column == self.TABLEWIDGET_ITEM_FAVORITE:
  199. widget = self.ui.tableWidget.item(row, self.TABLEWIDGET_ITEM_FAVORITE)
  200. plugin = self.ui.tableWidget.item(row, self.TABLEWIDGET_ITEM_NAME).data(Qt.UserRole+1)
  201. plugin = self._createFavoritePluginDict(plugin)
  202. if widget.checkState() == Qt.Checked:
  203. if not plugin in self.fFavoritePlugins:
  204. self.fFavoritePlugins.append(plugin)
  205. self.fFavoritePluginsChanged = True
  206. else:
  207. try:
  208. self.fFavoritePlugins.remove(plugin)
  209. self.fFavoritePluginsChanged = True
  210. except ValueError:
  211. pass
  212. @pyqtSlot(int, int)
  213. def slot_cellDoubleClicked(self, _, column):
  214. if column != self.TABLEWIDGET_ITEM_FAVORITE:
  215. self.slot_addPlugin()
  216. @pyqtSlot()
  217. def slot_focusSearchFieldAndSelectAll(self):
  218. self.ui.lineEdit.setFocus()
  219. self.ui.lineEdit.selectAll()
  220. @pyqtSlot()
  221. def slot_addPlugin(self):
  222. if self.ui.tableWidget.currentRow() >= 0:
  223. self.fRetPlugin = self.ui.tableWidget.item(self.ui.tableWidget.currentRow(),
  224. self.TABLEWIDGET_ITEM_NAME).data(Qt.UserRole+1)
  225. self.accept()
  226. else:
  227. self.reject()
  228. @pyqtSlot(int)
  229. def slot_checkPlugin(self, row):
  230. if row >= 0:
  231. self.ui.b_add.setEnabled(True)
  232. plugin = self.ui.tableWidget.item(self.ui.tableWidget.currentRow(),
  233. self.TABLEWIDGET_ITEM_NAME).data(Qt.UserRole+1)
  234. isSynth = bool(plugin['hints'] & PLUGIN_IS_SYNTH)
  235. isEffect = bool(plugin['audio.ins'] > 0 < plugin['audio.outs'] and not isSynth)
  236. isMidi = bool(plugin['audio.ins'] == 0 and
  237. plugin['audio.outs'] == 0 and
  238. plugin['midi.ins'] > 0 < plugin['midi.outs'])
  239. # isKit = bool(plugin['type'] in (PLUGIN_SF2, PLUGIN_SFZ))
  240. # isOther = bool(not (isEffect or isSynth or isMidi or isKit))
  241. if isSynth:
  242. ptype = "Instrument"
  243. elif isEffect:
  244. ptype = "Effect"
  245. elif isMidi:
  246. ptype = "MIDI Plugin"
  247. else:
  248. ptype = "Other"
  249. if plugin['build'] == BINARY_NATIVE:
  250. parch = self.fTrNative
  251. elif plugin['build'] == BINARY_POSIX32:
  252. parch = "posix32"
  253. elif plugin['build'] == BINARY_POSIX64:
  254. parch = "posix64"
  255. elif plugin['build'] == BINARY_WIN32:
  256. parch = "win32"
  257. elif plugin['build'] == BINARY_WIN64:
  258. parch = "win64"
  259. elif plugin['build'] == BINARY_OTHER:
  260. parch = self.tr("Other")
  261. elif plugin['build'] == BINARY_WIN32:
  262. parch = self.tr("Unknown")
  263. self.ui.l_format.setText(getPluginTypeAsString(plugin['type']))
  264. self.ui.l_type.setText(ptype)
  265. self.ui.l_arch.setText(parch)
  266. self.ui.l_id.setText(str(plugin['uniqueId']))
  267. self.ui.l_ains.setText(str(plugin['audio.ins']))
  268. self.ui.l_aouts.setText(str(plugin['audio.outs']))
  269. self.ui.l_cvins.setText(str(plugin['cv.ins']))
  270. self.ui.l_cvouts.setText(str(plugin['cv.outs']))
  271. self.ui.l_mins.setText(str(plugin['midi.ins']))
  272. self.ui.l_mouts.setText(str(plugin['midi.outs']))
  273. self.ui.l_pins.setText(str(plugin['parameters.ins']))
  274. self.ui.l_pouts.setText(str(plugin['parameters.outs']))
  275. self.ui.l_gui.setText(self.fTrYes if plugin['hints'] & PLUGIN_HAS_CUSTOM_UI else self.fTrNo)
  276. self.ui.l_idisp.setText(self.fTrYes if plugin['hints'] & PLUGIN_HAS_INLINE_DISPLAY else self.fTrNo)
  277. self.ui.l_bridged.setText(self.fTrYes if plugin['hints'] & PLUGIN_IS_BRIDGE else self.fTrNo)
  278. self.ui.l_synth.setText(self.fTrYes if isSynth else self.fTrNo)
  279. else:
  280. self.ui.b_add.setEnabled(False)
  281. self.ui.l_format.setText("---")
  282. self.ui.l_type.setText("---")
  283. self.ui.l_arch.setText("---")
  284. self.ui.l_id.setText("---")
  285. self.ui.l_ains.setText("---")
  286. self.ui.l_aouts.setText("---")
  287. self.ui.l_cvins.setText("---")
  288. self.ui.l_cvouts.setText("---")
  289. self.ui.l_mins.setText("---")
  290. self.ui.l_mouts.setText("---")
  291. self.ui.l_pins.setText("---")
  292. self.ui.l_pouts.setText("---")
  293. self.ui.l_gui.setText("---")
  294. self.ui.l_idisp.setText("---")
  295. self.ui.l_bridged.setText("---")
  296. self.ui.l_synth.setText("---")
  297. @pyqtSlot()
  298. def slot_checkFilters(self):
  299. self._checkFilters()
  300. @pyqtSlot(bool)
  301. def slot_checkFiltersCategoryAll(self, clicked):
  302. self.ui.ch_cat_delay.setChecked(not clicked)
  303. self.ui.ch_cat_distortion.setChecked(not clicked)
  304. self.ui.ch_cat_dynamics.setChecked(not clicked)
  305. self.ui.ch_cat_eq.setChecked(not clicked)
  306. self.ui.ch_cat_filter.setChecked(not clicked)
  307. self.ui.ch_cat_modulator.setChecked(not clicked)
  308. self.ui.ch_cat_synth.setChecked(not clicked)
  309. self.ui.ch_cat_utility.setChecked(not clicked)
  310. self.ui.ch_cat_other.setChecked(not clicked)
  311. self._checkFilters()
  312. @pyqtSlot(bool)
  313. def slot_checkFiltersCategorySpecific(self, clicked):
  314. if clicked:
  315. self.ui.ch_cat_all.setChecked(False)
  316. elif not (self.ui.ch_cat_delay.isChecked() or
  317. self.ui.ch_cat_distortion.isChecked() or
  318. self.ui.ch_cat_dynamics.isChecked() or
  319. self.ui.ch_cat_eq.isChecked() or
  320. self.ui.ch_cat_filter.isChecked() or
  321. self.ui.ch_cat_modulator.isChecked() or
  322. self.ui.ch_cat_synth.isChecked() or
  323. self.ui.ch_cat_utility.isChecked() or
  324. self.ui.ch_cat_other.isChecked()):
  325. self.ui.ch_cat_all.setChecked(True)
  326. self._checkFilters()
  327. @pyqtSlot()
  328. def slot_refreshPlugins(self):
  329. if PluginRefreshW(self, self.host, self.fUseSystemIcons, self.hasLoadedLv2Plugins).exec_():
  330. self._reAddPlugins()
  331. if self.fRealParent:
  332. self.fRealParent.setLoadRDFsNeeded()
  333. @pyqtSlot()
  334. def slot_clearFilters(self):
  335. self.blockSignals(True)
  336. self.ui.ch_internal.setChecked(True)
  337. self.ui.ch_ladspa.setChecked(True)
  338. self.ui.ch_dssi.setChecked(True)
  339. self.ui.ch_lv2.setChecked(True)
  340. self.ui.ch_vst.setChecked(True)
  341. self.ui.ch_vst3.setChecked(True)
  342. self.ui.ch_clap.setChecked(True)
  343. self.ui.ch_jsfx.setChecked(True)
  344. self.ui.ch_kits.setChecked(True)
  345. self.ui.ch_instruments.setChecked(True)
  346. self.ui.ch_effects.setChecked(True)
  347. self.ui.ch_midi.setChecked(True)
  348. self.ui.ch_other.setChecked(True)
  349. self.ui.ch_native.setChecked(True)
  350. self.ui.ch_bridged.setChecked(False)
  351. self.ui.ch_bridged_wine.setChecked(False)
  352. self.ui.ch_favorites.setChecked(False)
  353. self.ui.ch_rtsafe.setChecked(False)
  354. self.ui.ch_stereo.setChecked(False)
  355. self.ui.ch_cv.setChecked(False)
  356. self.ui.ch_gui.setChecked(False)
  357. self.ui.ch_inline_display.setChecked(False)
  358. if self.ui.ch_au.isEnabled():
  359. self.ui.ch_au.setChecked(True)
  360. self.ui.ch_cat_all.setChecked(True)
  361. self.ui.ch_cat_delay.setChecked(False)
  362. self.ui.ch_cat_distortion.setChecked(False)
  363. self.ui.ch_cat_dynamics.setChecked(False)
  364. self.ui.ch_cat_eq.setChecked(False)
  365. self.ui.ch_cat_filter.setChecked(False)
  366. self.ui.ch_cat_modulator.setChecked(False)
  367. self.ui.ch_cat_synth.setChecked(False)
  368. self.ui.ch_cat_utility.setChecked(False)
  369. self.ui.ch_cat_other.setChecked(False)
  370. self.ui.lineEdit.clear()
  371. self.blockSignals(False)
  372. self._checkFilters()
  373. # --------------------------------------------------------------------------------------------------------
  374. @pyqtSlot()
  375. def slot_saveSettings(self):
  376. settings = QSafeSettings("falkTX", "CarlaDatabase2")
  377. settings.setValue("PluginDatabase/Geometry", self.saveGeometry())
  378. settings.setValue("PluginDatabase/TableGeometry_6", self.ui.tableWidget.horizontalHeader().saveState())
  379. settings.setValue("PluginDatabase/ShowEffects", self.ui.ch_effects.isChecked())
  380. settings.setValue("PluginDatabase/ShowInstruments", self.ui.ch_instruments.isChecked())
  381. settings.setValue("PluginDatabase/ShowMIDI", self.ui.ch_midi.isChecked())
  382. settings.setValue("PluginDatabase/ShowOther", self.ui.ch_other.isChecked())
  383. settings.setValue("PluginDatabase/ShowInternal", self.ui.ch_internal.isChecked())
  384. settings.setValue("PluginDatabase/ShowLADSPA", self.ui.ch_ladspa.isChecked())
  385. settings.setValue("PluginDatabase/ShowDSSI", self.ui.ch_dssi.isChecked())
  386. settings.setValue("PluginDatabase/ShowLV2", self.ui.ch_lv2.isChecked())
  387. settings.setValue("PluginDatabase/ShowVST2", self.ui.ch_vst.isChecked())
  388. settings.setValue("PluginDatabase/ShowVST3", self.ui.ch_vst3.isChecked())
  389. settings.setValue("PluginDatabase/ShowCLAP", self.ui.ch_clap.isChecked())
  390. settings.setValue("PluginDatabase/ShowAU", self.ui.ch_au.isChecked())
  391. settings.setValue("PluginDatabase/ShowJSFX", self.ui.ch_jsfx.isChecked())
  392. settings.setValue("PluginDatabase/ShowKits", self.ui.ch_kits.isChecked())
  393. settings.setValue("PluginDatabase/ShowNative", self.ui.ch_native.isChecked())
  394. settings.setValue("PluginDatabase/ShowBridged", self.ui.ch_bridged.isChecked())
  395. settings.setValue("PluginDatabase/ShowBridgedWine", self.ui.ch_bridged_wine.isChecked())
  396. settings.setValue("PluginDatabase/ShowFavorites", self.ui.ch_favorites.isChecked())
  397. settings.setValue("PluginDatabase/ShowRtSafe", self.ui.ch_rtsafe.isChecked())
  398. settings.setValue("PluginDatabase/ShowHasCV", self.ui.ch_cv.isChecked())
  399. settings.setValue("PluginDatabase/ShowHasGUI", self.ui.ch_gui.isChecked())
  400. settings.setValue("PluginDatabase/ShowHasInlineDisplay", self.ui.ch_inline_display.isChecked())
  401. settings.setValue("PluginDatabase/ShowStereoOnly", self.ui.ch_stereo.isChecked())
  402. settings.setValue("PluginDatabase/SearchText", self.ui.lineEdit.text())
  403. if self.ui.ch_cat_all.isChecked():
  404. settings.setValue("PluginDatabase/ShowCategory", "all")
  405. else:
  406. categoryhash = ""
  407. if self.ui.ch_cat_delay.isChecked():
  408. categoryhash += ":delay"
  409. if self.ui.ch_cat_distortion.isChecked():
  410. categoryhash += ":distortion"
  411. if self.ui.ch_cat_dynamics.isChecked():
  412. categoryhash += ":dynamics"
  413. if self.ui.ch_cat_eq.isChecked():
  414. categoryhash += ":eq"
  415. if self.ui.ch_cat_filter.isChecked():
  416. categoryhash += ":filter"
  417. if self.ui.ch_cat_modulator.isChecked():
  418. categoryhash += ":modulator"
  419. if self.ui.ch_cat_synth.isChecked():
  420. categoryhash += ":synth"
  421. if self.ui.ch_cat_utility.isChecked():
  422. categoryhash += ":utility"
  423. if self.ui.ch_cat_other.isChecked():
  424. categoryhash += ":other"
  425. if categoryhash:
  426. categoryhash += ":"
  427. settings.setValue("PluginDatabase/ShowCategory", categoryhash)
  428. if self.fFavoritePluginsChanged:
  429. settings.setValue("PluginDatabase/Favorites", self.fFavoritePlugins)
  430. # --------------------------------------------------------------------------------------------------------
  431. def loadSettings(self):
  432. settings = QSafeSettings("falkTX", "CarlaDatabase2")
  433. self.fFavoritePlugins = settings.value("PluginDatabase/Favorites", [], list)
  434. self.fFavoritePluginsChanged = False
  435. self.restoreGeometry(settings.value("PluginDatabase/Geometry", QByteArray(), QByteArray))
  436. self.ui.ch_effects.setChecked(settings.value("PluginDatabase/ShowEffects", True, bool))
  437. self.ui.ch_instruments.setChecked(settings.value("PluginDatabase/ShowInstruments", True, bool))
  438. self.ui.ch_midi.setChecked(settings.value("PluginDatabase/ShowMIDI", True, bool))
  439. self.ui.ch_other.setChecked(settings.value("PluginDatabase/ShowOther", True, bool))
  440. self.ui.ch_internal.setChecked(settings.value("PluginDatabase/ShowInternal", True, bool))
  441. self.ui.ch_ladspa.setChecked(settings.value("PluginDatabase/ShowLADSPA", True, bool))
  442. self.ui.ch_dssi.setChecked(settings.value("PluginDatabase/ShowDSSI", True, bool))
  443. self.ui.ch_lv2.setChecked(settings.value("PluginDatabase/ShowLV2", True, bool))
  444. self.ui.ch_vst.setChecked(settings.value("PluginDatabase/ShowVST2", True, bool))
  445. self.ui.ch_vst3.setChecked(settings.value("PluginDatabase/ShowVST3", True, bool))
  446. self.ui.ch_clap.setChecked(settings.value("PluginDatabase/ShowCLAP", True, bool))
  447. self.ui.ch_au.setChecked(settings.value("PluginDatabase/ShowAU", MACOS, bool))
  448. self.ui.ch_jsfx.setChecked(settings.value("PluginDatabase/ShowJSFX", True, bool))
  449. self.ui.ch_kits.setChecked(settings.value("PluginDatabase/ShowKits", True, bool))
  450. self.ui.ch_native.setChecked(settings.value("PluginDatabase/ShowNative", True, bool))
  451. self.ui.ch_bridged.setChecked(settings.value("PluginDatabase/ShowBridged", True, bool))
  452. self.ui.ch_bridged_wine.setChecked(settings.value("PluginDatabase/ShowBridgedWine", True, bool))
  453. self.ui.ch_favorites.setChecked(settings.value("PluginDatabase/ShowFavorites", False, bool))
  454. self.ui.ch_rtsafe.setChecked(settings.value("PluginDatabase/ShowRtSafe", False, bool))
  455. self.ui.ch_cv.setChecked(settings.value("PluginDatabase/ShowHasCV", False, bool))
  456. self.ui.ch_gui.setChecked(settings.value("PluginDatabase/ShowHasGUI", False, bool))
  457. self.ui.ch_inline_display.setChecked(settings.value("PluginDatabase/ShowHasInlineDisplay", False, bool))
  458. self.ui.ch_stereo.setChecked(settings.value("PluginDatabase/ShowStereoOnly", False, bool))
  459. self.ui.lineEdit.setText(settings.value("PluginDatabase/SearchText", "", str))
  460. categoryhash = settings.value("PluginDatabase/ShowCategory", "all", str)
  461. if categoryhash == "all" or len(categoryhash) < 2:
  462. self.ui.ch_cat_all.setChecked(True)
  463. self.ui.ch_cat_delay.setChecked(False)
  464. self.ui.ch_cat_distortion.setChecked(False)
  465. self.ui.ch_cat_dynamics.setChecked(False)
  466. self.ui.ch_cat_eq.setChecked(False)
  467. self.ui.ch_cat_filter.setChecked(False)
  468. self.ui.ch_cat_modulator.setChecked(False)
  469. self.ui.ch_cat_synth.setChecked(False)
  470. self.ui.ch_cat_utility.setChecked(False)
  471. self.ui.ch_cat_other.setChecked(False)
  472. else:
  473. self.ui.ch_cat_all.setChecked(False)
  474. self.ui.ch_cat_delay.setChecked(":delay:" in categoryhash)
  475. self.ui.ch_cat_distortion.setChecked(":distortion:" in categoryhash)
  476. self.ui.ch_cat_dynamics.setChecked(":dynamics:" in categoryhash)
  477. self.ui.ch_cat_eq.setChecked(":eq:" in categoryhash)
  478. self.ui.ch_cat_filter.setChecked(":filter:" in categoryhash)
  479. self.ui.ch_cat_modulator.setChecked(":modulator:" in categoryhash)
  480. self.ui.ch_cat_synth.setChecked(":synth:" in categoryhash)
  481. self.ui.ch_cat_utility.setChecked(":utility:" in categoryhash)
  482. self.ui.ch_cat_other.setChecked(":other:" in categoryhash)
  483. tableGeometry = settings.value("PluginDatabase/TableGeometry_6", QByteArray(), QByteArray)
  484. horizontalHeader = self.ui.tableWidget.horizontalHeader()
  485. if not tableGeometry.isNull():
  486. horizontalHeader.restoreState(tableGeometry)
  487. else:
  488. horizontalHeader.setSectionResizeMode(self.TABLEWIDGET_ITEM_FAVORITE, QHeaderView.Fixed)
  489. self.ui.tableWidget.setColumnWidth(self.TABLEWIDGET_ITEM_FAVORITE, 24)
  490. self.ui.tableWidget.setColumnWidth(self.TABLEWIDGET_ITEM_NAME, 250)
  491. self.ui.tableWidget.setColumnWidth(self.TABLEWIDGET_ITEM_LABEL, 200)
  492. self.ui.tableWidget.setColumnWidth(self.TABLEWIDGET_ITEM_MAKER, 150)
  493. self.ui.tableWidget.sortByColumn(self.TABLEWIDGET_ITEM_NAME, Qt.AscendingOrder)
  494. # --------------------------------------------------------------------------------------------------------
  495. def _createFavoritePluginDict(self, plugin):
  496. return {
  497. 'name' : plugin['name'],
  498. 'build' : plugin['build'],
  499. 'type' : plugin['type'],
  500. 'filename': plugin['filename'],
  501. 'label' : plugin['label'],
  502. 'uniqueId': plugin['uniqueId'],
  503. }
  504. def _checkFilters(self):
  505. text = self.ui.lineEdit.text().lower()
  506. hideEffects = not self.ui.ch_effects.isChecked()
  507. hideInstruments = not self.ui.ch_instruments.isChecked()
  508. hideMidi = not self.ui.ch_midi.isChecked()
  509. hideOther = not self.ui.ch_other.isChecked()
  510. hideInternal = not self.ui.ch_internal.isChecked()
  511. hideLadspa = not self.ui.ch_ladspa.isChecked()
  512. hideDssi = not self.ui.ch_dssi.isChecked()
  513. hideLV2 = not self.ui.ch_lv2.isChecked()
  514. hideVST2 = not self.ui.ch_vst.isChecked()
  515. hideVST3 = not self.ui.ch_vst3.isChecked()
  516. hideCLAP = not self.ui.ch_clap.isChecked()
  517. hideAU = not self.ui.ch_au.isChecked()
  518. hideJSFX = not self.ui.ch_jsfx.isChecked()
  519. hideKits = not self.ui.ch_kits.isChecked()
  520. hideNative = not self.ui.ch_native.isChecked()
  521. hideBridged = not self.ui.ch_bridged.isChecked()
  522. hideBridgedWine = not self.ui.ch_bridged_wine.isChecked()
  523. hideNonFavs = self.ui.ch_favorites.isChecked()
  524. hideNonRtSafe = self.ui.ch_rtsafe.isChecked()
  525. hideNonCV = self.ui.ch_cv.isChecked()
  526. hideNonGui = self.ui.ch_gui.isChecked()
  527. hideNonIDisp = self.ui.ch_inline_display.isChecked()
  528. hideNonStereo = self.ui.ch_stereo.isChecked()
  529. if HAIKU or LINUX or MACOS:
  530. nativeBins = [BINARY_POSIX32, BINARY_POSIX64]
  531. wineBins = [BINARY_WIN32, BINARY_WIN64]
  532. elif WINDOWS:
  533. nativeBins = [BINARY_WIN32, BINARY_WIN64]
  534. wineBins = []
  535. else:
  536. nativeBins = []
  537. wineBins = []
  538. self.ui.tableWidget.setRowCount(self.fLastTableIndex)
  539. for i in range(self.fLastTableIndex):
  540. plugin = self.ui.tableWidget.item(i, self.TABLEWIDGET_ITEM_NAME).data(Qt.UserRole+1)
  541. ptext = self.ui.tableWidget.item(i, self.TABLEWIDGET_ITEM_NAME).data(Qt.UserRole+2)
  542. aIns = plugin['audio.ins']
  543. aOuts = plugin['audio.outs']
  544. cvIns = plugin['cv.ins']
  545. cvOuts = plugin['cv.outs']
  546. mIns = plugin['midi.ins']
  547. mOuts = plugin['midi.outs']
  548. phints = plugin['hints']
  549. ptype = plugin['type']
  550. categ = plugin['category']
  551. isSynth = bool(phints & PLUGIN_IS_SYNTH)
  552. isEffect = bool(aIns > 0 < aOuts and not isSynth)
  553. isMidi = bool(aIns == 0 and aOuts == 0 and mIns > 0 < mOuts)
  554. isKit = bool(ptype in (PLUGIN_SF2, PLUGIN_SFZ))
  555. isOther = bool(not (isEffect or isSynth or isMidi or isKit))
  556. isNative = bool(plugin['build'] == BINARY_NATIVE)
  557. isRtSafe = bool(phints & PLUGIN_IS_RTSAFE)
  558. isStereo = bool(aIns == 2 and aOuts == 2) or (isSynth and aOuts == 2)
  559. hasCV = bool(cvIns + cvOuts > 0)
  560. hasGui = bool(phints & PLUGIN_HAS_CUSTOM_UI)
  561. hasIDisp = bool(phints & PLUGIN_HAS_INLINE_DISPLAY)
  562. isBridged = bool(not isNative and plugin['build'] in nativeBins)
  563. isBridgedWine = bool(not isNative and plugin['build'] in wineBins)
  564. if hideEffects and isEffect:
  565. self.ui.tableWidget.hideRow(i)
  566. elif hideInstruments and isSynth:
  567. self.ui.tableWidget.hideRow(i)
  568. elif hideMidi and isMidi:
  569. self.ui.tableWidget.hideRow(i)
  570. elif hideOther and isOther:
  571. self.ui.tableWidget.hideRow(i)
  572. elif hideKits and isKit:
  573. self.ui.tableWidget.hideRow(i)
  574. elif hideInternal and ptype == PLUGIN_INTERNAL:
  575. self.ui.tableWidget.hideRow(i)
  576. elif hideLadspa and ptype == PLUGIN_LADSPA:
  577. self.ui.tableWidget.hideRow(i)
  578. elif hideDssi and ptype == PLUGIN_DSSI:
  579. self.ui.tableWidget.hideRow(i)
  580. elif hideLV2 and ptype == PLUGIN_LV2:
  581. self.ui.tableWidget.hideRow(i)
  582. elif hideVST2 and ptype == PLUGIN_VST2:
  583. self.ui.tableWidget.hideRow(i)
  584. elif hideVST3 and ptype == PLUGIN_VST3:
  585. self.ui.tableWidget.hideRow(i)
  586. elif hideCLAP and ptype == PLUGIN_CLAP:
  587. self.ui.tableWidget.hideRow(i)
  588. elif hideAU and ptype == PLUGIN_AU:
  589. self.ui.tableWidget.hideRow(i)
  590. elif hideJSFX and ptype == PLUGIN_JSFX:
  591. self.ui.tableWidget.hideRow(i)
  592. elif hideNative and isNative:
  593. self.ui.tableWidget.hideRow(i)
  594. elif hideBridged and isBridged:
  595. self.ui.tableWidget.hideRow(i)
  596. elif hideBridgedWine and isBridgedWine:
  597. self.ui.tableWidget.hideRow(i)
  598. elif hideNonRtSafe and not isRtSafe:
  599. self.ui.tableWidget.hideRow(i)
  600. elif hideNonCV and not hasCV:
  601. self.ui.tableWidget.hideRow(i)
  602. elif hideNonGui and not hasGui:
  603. self.ui.tableWidget.hideRow(i)
  604. elif hideNonIDisp and not hasIDisp:
  605. self.ui.tableWidget.hideRow(i)
  606. elif hideNonStereo and not isStereo:
  607. self.ui.tableWidget.hideRow(i)
  608. elif text and not all(t in ptext for t in text.strip().split(' ')):
  609. self.ui.tableWidget.hideRow(i)
  610. elif hideNonFavs and self._createFavoritePluginDict(plugin) not in self.fFavoritePlugins:
  611. self.ui.tableWidget.hideRow(i)
  612. elif (self.ui.ch_cat_all.isChecked() or
  613. (self.ui.ch_cat_delay.isChecked() and categ == "delay") or
  614. (self.ui.ch_cat_distortion.isChecked() and categ == "distortion") or
  615. (self.ui.ch_cat_dynamics.isChecked() and categ == "dynamics") or
  616. (self.ui.ch_cat_eq.isChecked() and categ == "eq") or
  617. (self.ui.ch_cat_filter.isChecked() and categ == "filter") or
  618. (self.ui.ch_cat_modulator.isChecked() and categ == "modulator") or
  619. (self.ui.ch_cat_synth.isChecked() and categ == "synth") or
  620. (self.ui.ch_cat_utility.isChecked() and categ == "utility") or
  621. (self.ui.ch_cat_other.isChecked() and categ == "other")):
  622. self.ui.tableWidget.showRow(i)
  623. else:
  624. self.ui.tableWidget.hideRow(i)
  625. # --------------------------------------------------------------------------------------------------------
  626. def _addPluginToTable(self, plugin, ptype):
  627. if plugin['API'] != PLUGIN_QUERY_API_VERSION:
  628. return
  629. if ptype in (self.tr("Internal"), "LV2", "SF2", "SFZ", "JSFX"):
  630. plugin['build'] = BINARY_NATIVE
  631. index = self.fLastTableIndex
  632. isFav = bool(self._createFavoritePluginDict(plugin) in self.fFavoritePlugins)
  633. favItem = QTableWidgetItem()
  634. favItem.setCheckState(Qt.Checked if isFav else Qt.Unchecked)
  635. favItem.setText(" " if isFav else " ")
  636. pluginText = (plugin['name']+plugin['label']+plugin['maker']+plugin['filename']).lower()
  637. self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_FAVORITE, favItem)
  638. self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_NAME, QTableWidgetItem(plugin['name']))
  639. self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_LABEL, QTableWidgetItem(plugin['label']))
  640. self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_MAKER, QTableWidgetItem(plugin['maker']))
  641. self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_BINARY, QTableWidgetItem(os.path.basename(plugin['filename'])))
  642. self.ui.tableWidget.item(index, self.TABLEWIDGET_ITEM_NAME).setData(Qt.UserRole+1, plugin)
  643. self.ui.tableWidget.item(index, self.TABLEWIDGET_ITEM_NAME).setData(Qt.UserRole+2, pluginText)
  644. self.fLastTableIndex += 1
  645. # --------------------------------------------------------------------------------------------------------
  646. def _reAddInternalHelper(self, settingsDB, ptype, path):
  647. if ptype == PLUGIN_INTERNAL:
  648. ptypeStr = "Internal"
  649. ptypeStrTr = self.tr("Internal")
  650. elif ptype == PLUGIN_LV2:
  651. ptypeStr = "LV2"
  652. ptypeStrTr = ptypeStr
  653. elif ptype == PLUGIN_AU:
  654. ptypeStr = "AU"
  655. ptypeStrTr = ptypeStr
  656. #elif ptype == PLUGIN_SFZ:
  657. #ptypeStr = "SFZ"
  658. #ptypeStrTr = ptypeStr
  659. # TODO(jsfx) what to do here?
  660. else:
  661. return 0
  662. plugins = settingsDB.value("Plugins/" + ptypeStr, [], list)
  663. pluginCount = settingsDB.value("PluginCount/" + ptypeStr, 0, int)
  664. if ptype == PLUGIN_AU:
  665. gCarla.utils.juce_init()
  666. pluginCountNew = gCarla.utils.get_cached_plugin_count(ptype, path)
  667. if pluginCountNew != pluginCount or len(plugins) != pluginCount or (len(plugins) > 0 and plugins[0]['API'] != PLUGIN_QUERY_API_VERSION):
  668. plugins = []
  669. pluginCount = pluginCountNew
  670. QApplication.processEvents(QEventLoop.ExcludeUserInputEvents, 50)
  671. if ptype == PLUGIN_AU:
  672. gCarla.utils.juce_idle()
  673. for i in range(pluginCountNew):
  674. descInfo = gCarla.utils.get_cached_plugin_info(ptype, i)
  675. if not descInfo['valid']:
  676. continue
  677. info = checkPluginCached(descInfo, ptype)
  678. plugins.append(info)
  679. if i % 50 == 0:
  680. QApplication.processEvents(QEventLoop.ExcludeUserInputEvents, 50)
  681. if ptype == PLUGIN_AU:
  682. gCarla.utils.juce_idle()
  683. settingsDB.setValue("Plugins/" + ptypeStr, plugins)
  684. settingsDB.setValue("PluginCount/" + ptypeStr, pluginCount)
  685. if ptype == PLUGIN_AU:
  686. gCarla.utils.juce_cleanup()
  687. # prepare rows in advance
  688. self.ui.tableWidget.setRowCount(self.fLastTableIndex + len(plugins))
  689. for plugin in plugins:
  690. self._addPluginToTable(plugin, ptypeStrTr)
  691. return pluginCount
  692. def _reAddPlugins(self):
  693. settingsDB = QSafeSettings("falkTX", "CarlaPlugins5")
  694. self.fLastTableIndex = 0
  695. self.ui.tableWidget.setSortingEnabled(False)
  696. self.ui.tableWidget.clearContents()
  697. settings = QSafeSettings("falkTX", "Carla2")
  698. LV2_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH, list))
  699. del settings
  700. # ----------------------------------------------------------------------------------------------------
  701. # plugins handled through backend
  702. internalCount = self._reAddInternalHelper(settingsDB, PLUGIN_INTERNAL, "")
  703. lv2Count = self._reAddInternalHelper(settingsDB, PLUGIN_LV2, LV2_PATH)
  704. auCount = self._reAddInternalHelper(settingsDB, PLUGIN_AU, "") if MACOS else 0
  705. # ----------------------------------------------------------------------------------------------------
  706. # LADSPA
  707. ladspaPlugins = []
  708. ladspaPlugins += settingsDB.value("Plugins/LADSPA_native", [], list)
  709. ladspaPlugins += settingsDB.value("Plugins/LADSPA_posix32", [], list)
  710. ladspaPlugins += settingsDB.value("Plugins/LADSPA_posix64", [], list)
  711. ladspaPlugins += settingsDB.value("Plugins/LADSPA_win32", [], list)
  712. ladspaPlugins += settingsDB.value("Plugins/LADSPA_win64", [], list)
  713. # ----------------------------------------------------------------------------------------------------
  714. # DSSI
  715. dssiPlugins = []
  716. dssiPlugins += settingsDB.value("Plugins/DSSI_native", [], list)
  717. dssiPlugins += settingsDB.value("Plugins/DSSI_posix32", [], list)
  718. dssiPlugins += settingsDB.value("Plugins/DSSI_posix64", [], list)
  719. dssiPlugins += settingsDB.value("Plugins/DSSI_win32", [], list)
  720. dssiPlugins += settingsDB.value("Plugins/DSSI_win64", [], list)
  721. # ----------------------------------------------------------------------------------------------------
  722. # VST2
  723. vst2Plugins = []
  724. vst2Plugins += settingsDB.value("Plugins/VST2_native", [], list)
  725. vst2Plugins += settingsDB.value("Plugins/VST2_posix32", [], list)
  726. vst2Plugins += settingsDB.value("Plugins/VST2_posix64", [], list)
  727. vst2Plugins += settingsDB.value("Plugins/VST2_win32", [], list)
  728. vst2Plugins += settingsDB.value("Plugins/VST2_win64", [], list)
  729. # ----------------------------------------------------------------------------------------------------
  730. # VST3
  731. vst3Plugins = []
  732. vst3Plugins += settingsDB.value("Plugins/VST3_native", [], list)
  733. vst3Plugins += settingsDB.value("Plugins/VST3_posix32", [], list)
  734. vst3Plugins += settingsDB.value("Plugins/VST3_posix64", [], list)
  735. vst3Plugins += settingsDB.value("Plugins/VST3_win32", [], list)
  736. vst3Plugins += settingsDB.value("Plugins/VST3_win64", [], list)
  737. # ----------------------------------------------------------------------------------------------------
  738. # CLAP
  739. clapPlugins = []
  740. clapPlugins += settingsDB.value("Plugins/CLAP_native", [], list)
  741. clapPlugins += settingsDB.value("Plugins/CLAP_posix32", [], list)
  742. clapPlugins += settingsDB.value("Plugins/CLAP_posix64", [], list)
  743. clapPlugins += settingsDB.value("Plugins/CLAP_win32", [], list)
  744. clapPlugins += settingsDB.value("Plugins/CLAP_win64", [], list)
  745. # ----------------------------------------------------------------------------------------------------
  746. # AU (extra non-cached)
  747. auPlugins32 = settingsDB.value("Plugins/AU_posix32", [], list) if MACOS else []
  748. # ----------------------------------------------------------------------------------------------------
  749. # JSFX
  750. jsfxPlugins = settingsDB.value("Plugins/JSFX", [], list)
  751. # ----------------------------------------------------------------------------------------------------
  752. # Kits
  753. sf2s = settingsDB.value("Plugins/SF2", [], list)
  754. sfzs = settingsDB.value("Plugins/SFZ", [], list)
  755. # ----------------------------------------------------------------------------------------------------
  756. # count plugins first, so we can create rows in advance
  757. ladspaCount = 0
  758. dssiCount = 0
  759. vstCount = 0
  760. vst3Count = 0
  761. clapCount = 0
  762. au32Count = 0
  763. jsfxCount = len(jsfxPlugins)
  764. sf2Count = 0
  765. sfzCount = len(sfzs)
  766. for plugins in ladspaPlugins:
  767. ladspaCount += len(plugins)
  768. for plugins in dssiPlugins:
  769. dssiCount += len(plugins)
  770. for plugins in vst2Plugins:
  771. vstCount += len(plugins)
  772. for plugins in vst3Plugins:
  773. vst3Count += len(plugins)
  774. for plugins in clapPlugins:
  775. clapCount += len(plugins)
  776. for plugins in auPlugins32:
  777. au32Count += len(plugins)
  778. for plugins in sf2s:
  779. sf2Count += len(plugins)
  780. self.ui.tableWidget.setRowCount(self.fLastTableIndex +
  781. ladspaCount + dssiCount + vstCount + vst3Count + clapCount +
  782. auCount + au32Count + jsfxCount + sf2Count + sfzCount)
  783. if MACOS:
  784. self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2, %i VST3, %i CLAP, %i AudioUnit and %i JSFX plugins, plus %i Sound Kits" % (
  785. internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, clapCount, auCount+au32Count, jsfxCount, sf2Count+sfzCount)))
  786. else:
  787. self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2, %i VST3, %i CLAP and %i JSFX plugins, plus %i Sound Kits" % (
  788. internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, clapCount, jsfxCount, sf2Count+sfzCount)))
  789. # ----------------------------------------------------------------------------------------------------
  790. # now add all plugins to the table
  791. for plugins in ladspaPlugins:
  792. for plugin in plugins:
  793. self._addPluginToTable(plugin, "LADSPA")
  794. for plugins in dssiPlugins:
  795. for plugin in plugins:
  796. self._addPluginToTable(plugin, "DSSI")
  797. for plugins in vst2Plugins:
  798. for plugin in plugins:
  799. self._addPluginToTable(plugin, "VST2")
  800. for plugins in vst3Plugins:
  801. for plugin in plugins:
  802. self._addPluginToTable(plugin, "VST3")
  803. for plugins in clapPlugins:
  804. for plugin in plugins:
  805. self._addPluginToTable(plugin, "CLAP")
  806. for plugins in auPlugins32:
  807. for plugin in plugins:
  808. self._addPluginToTable(plugin, "AU")
  809. for plugin in jsfxPlugins:
  810. self._addPluginToTable(plugin, "JSFX")
  811. for sf2 in sf2s:
  812. for sf2_i in sf2:
  813. self._addPluginToTable(sf2_i, "SF2")
  814. for sfz in sfzs:
  815. self._addPluginToTable(sfz, "SFZ")
  816. # ----------------------------------------------------------------------------------------------------
  817. self.ui.tableWidget.setSortingEnabled(True)
  818. self._checkFilters()
  819. self.slot_checkPlugin(self.ui.tableWidget.currentRow())
  820. # --------------------------------------------------------------------------------------------------------
  821. def showEvent(self, event):
  822. self.slot_focusSearchFieldAndSelectAll()
  823. QDialog.showEvent(self, event)
  824. # ---------------------------------------------------------------------------------------------------------------------
  825. # Testing
  826. if __name__ == '__main__':
  827. import sys
  828. class _host:
  829. pathBinaries = ""
  830. showPluginBridges = False
  831. showWineBridges = False
  832. _host = _host()
  833. _app = QApplication(sys.argv)
  834. _gui = PluginListDialog(None, _host, True)
  835. if _gui.exec_():
  836. print(f"Result: {_gui.fRetPlugin}")
  837. # ---------------------------------------------------------------------------------------------------------------------