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.

884 lines
34KB

  1. /*
  2. * Carla plugin host
  3. * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "pluginlistdialog.hpp"
  18. #ifdef __clang__
  19. # pragma clang diagnostic push
  20. # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy"
  21. # pragma clang diagnostic ignored "-Wdeprecated-register"
  22. #elif defined(__GNUC__) && __GNUC__ >= 8
  23. # pragma GCC diagnostic push
  24. # pragma GCC diagnostic ignored "-Wclass-memaccess"
  25. # pragma GCC diagnostic ignored "-Wdeprecated-copy"
  26. #endif
  27. #include "pluginlistdialog_ui.hpp"
  28. #include <QtCore/QList>
  29. #ifdef __clang__
  30. # pragma clang diagnostic pop
  31. #elif defined(__GNUC__) && __GNUC__ >= 8
  32. # pragma GCC diagnostic pop
  33. #endif
  34. #include "qcarlastring.hpp"
  35. #include "qsafesettings.hpp"
  36. #include "CarlaBackendUtils.hpp"
  37. #include "CarlaUtils.h"
  38. #include "CarlaString.hpp"
  39. using namespace CarlaBackend;
  40. // --------------------------------------------------------------------------------------------------------------------
  41. typedef QList<PluginInfo> QPluginInfoList;
  42. class QSafePluginListSettings : public QSafeSettings
  43. {
  44. public:
  45. inline QSafePluginListSettings()
  46. : QSafeSettings() {}
  47. inline QSafePluginListSettings(const QString& organization, const QString& application)
  48. : QSafeSettings(organization, application) {}
  49. QPluginInfoList valuePluginInfoList(const QString& key, QPluginInfoList defaultValue = {}) const
  50. {
  51. /*
  52. QVariant var(value(key, defaultValue));
  53. if (!var.isNull() && var.convert(QVariant::List) && var.isValid())
  54. {
  55. QList<QVariant> varVariant(var.toList());
  56. QPluginInfoList varReal;
  57. varReal.reserve(varVariant.size());
  58. for (QVariant v : varVariant)
  59. {
  60. CARLA_SAFE_ASSERT_BREAK(!v.isNull());
  61. CARLA_SAFE_ASSERT_BREAK(v.convert(QVariant::UserType));
  62. CARLA_SAFE_ASSERT_BREAK(v.isValid());
  63. // varReal.append(v.toU);
  64. }
  65. }
  66. */
  67. return defaultValue;
  68. }
  69. void setValue(const QString& key, const uint value)
  70. {
  71. QSafeSettings::setValue(key, value);
  72. }
  73. void setValue(const QString& key, const QPluginInfoList& value)
  74. {
  75. }
  76. };
  77. // --------------------------------------------------------------------------------------------------------------------
  78. // Jack Application Dialog
  79. struct PluginListDialog::Self {
  80. enum TableIndex {
  81. TABLEWIDGET_ITEM_FAVORITE,
  82. TABLEWIDGET_ITEM_NAME,
  83. TABLEWIDGET_ITEM_LABEL,
  84. TABLEWIDGET_ITEM_MAKER,
  85. TABLEWIDGET_ITEM_BINARY,
  86. };
  87. // To be changed by parent
  88. bool hasLoadedLv2Plugins = false;
  89. Ui_PluginListDialog ui;
  90. HostSettings hostSettings;
  91. int fLastTableIndex;
  92. PluginListDialogResults fRetPlugin;
  93. QWidget* fRealParent;
  94. QStringList fFavoritePlugins;
  95. bool fFavoritePluginsChanged;
  96. QString fTrYes;
  97. QString fTrNo;
  98. QString fTrNative;
  99. Self() {}
  100. static Self& create()
  101. {
  102. Self* const self = new Self();
  103. return *self;
  104. }
  105. void createFavoritePluginDict()
  106. {
  107. // return {
  108. // 'name' : plugin['name'],
  109. // 'build' : plugin['build'],
  110. // 'type' : plugin['type'],
  111. // 'filename': plugin['filename'],
  112. // 'label' : plugin['label'],
  113. // 'uniqueId': plugin['uniqueId'],
  114. // }
  115. }
  116. void checkFilters()
  117. {
  118. }
  119. void addPluginToTable(uint plugin, const PluginType ptype)
  120. {
  121. }
  122. PluginInfo checkPluginCached(const CarlaCachedPluginInfo* const desc, const PluginType ptype)
  123. {
  124. PluginInfo pinfo = {};
  125. pinfo.build = BINARY_NATIVE;
  126. pinfo.type = ptype;
  127. pinfo.hints = desc->hints;
  128. pinfo.name = desc->name;
  129. pinfo.label = desc->label;
  130. pinfo.maker = desc->maker;
  131. pinfo.category = getPluginCategoryAsString(desc->category);
  132. pinfo.audioIns = desc->audioIns;
  133. pinfo.audioOuts = desc->audioOuts;
  134. pinfo.cvIns = desc->cvIns;
  135. pinfo.cvOuts = desc->cvOuts;
  136. pinfo.midiIns = desc->midiIns;
  137. pinfo.midiOuts = desc->midiOuts;
  138. pinfo.parametersIns = desc->parameterIns;
  139. pinfo.parametersOuts = desc->parameterOuts;
  140. switch (ptype)
  141. {
  142. case PLUGIN_LV2:
  143. {
  144. QString label(desc->label);
  145. pinfo.filename = label.split(CARLA_OS_SEP).first();
  146. pinfo.label = label.section(CARLA_OS_SEP, 1);
  147. }
  148. break;
  149. case PLUGIN_SFZ:
  150. pinfo.filename = pinfo.label;
  151. pinfo.label = pinfo.name;
  152. break;
  153. default:
  154. break;
  155. }
  156. return pinfo;
  157. }
  158. uint reAddInternalHelper(QSafePluginListSettings& settingsDB, const PluginType ptype, const char* const path)
  159. {
  160. QString ptypeStr, ptypeStrTr;
  161. switch (ptype)
  162. {
  163. case PLUGIN_INTERNAL:
  164. ptypeStr = "Internal";
  165. ptypeStrTr = "Internal"; // self.tr("Internal")
  166. break;
  167. case PLUGIN_LV2:
  168. ptypeStr = "LV2";
  169. ptypeStrTr = ptypeStr;
  170. break;
  171. case PLUGIN_AU:
  172. ptypeStr = "AU";
  173. ptypeStrTr = ptypeStr;
  174. break;
  175. case PLUGIN_SFZ:
  176. ptypeStr = "SFZ";
  177. ptypeStrTr = ptypeStr;
  178. break;
  179. // TODO(jsfx) what to do here?
  180. default:
  181. return 0;
  182. }
  183. QPluginInfoList plugins = settingsDB.valuePluginInfoList("Plugins/" + ptypeStr);
  184. uint pluginCount = settingsDB.valueUInt("PluginCount/" + ptypeStr, 0);
  185. if (ptype == PLUGIN_AU)
  186. carla_juce_init();
  187. const uint pluginCountNew = carla_get_cached_plugin_count(ptype, path);
  188. if (pluginCountNew != pluginCount || plugins.size() != pluginCount ||
  189. (plugins.size() > 0 && plugins[0].API != PLUGIN_QUERY_API_VERSION))
  190. {
  191. plugins.clear();
  192. pluginCount = pluginCountNew;
  193. QApplication::instance()->processEvents(QEventLoop::ExcludeUserInputEvents, 50);
  194. if (ptype == PLUGIN_AU)
  195. carla_juce_idle();
  196. for (uint i=0; i<pluginCountNew; ++i)
  197. {
  198. const CarlaCachedPluginInfo* const descInfo = carla_get_cached_plugin_info(ptype, i);
  199. if (descInfo == nullptr)
  200. continue;
  201. const PluginInfo info = checkPluginCached(descInfo, ptype);
  202. plugins.append(info);
  203. if ((i % 50) == 0)
  204. {
  205. QApplication::instance()->processEvents(QEventLoop::ExcludeUserInputEvents, 50);
  206. if (ptype == PLUGIN_AU)
  207. carla_juce_idle();
  208. }
  209. }
  210. settingsDB.setValue("Plugins/" + ptypeStr, plugins);
  211. settingsDB.setValue("PluginCount/" + ptypeStr, pluginCount);
  212. }
  213. if (ptype == PLUGIN_AU)
  214. carla_juce_cleanup();
  215. // prepare rows in advance
  216. ui.tableWidget->setRowCount(fLastTableIndex + plugins.size());
  217. // for plugin in plugins:
  218. // self._addPluginToTable(plugin, ptypeStrTr)
  219. return pluginCount;
  220. }
  221. void reAddPlugins()
  222. {
  223. QSafePluginListSettings settingsDB("falkTX", "CarlaPlugins5");
  224. fLastTableIndex = 0;
  225. ui.tableWidget->setSortingEnabled(false);
  226. ui.tableWidget->clearContents();
  227. QString LV2_PATH;
  228. {
  229. const QSafeSettings settings("falkTX", "Carla2");
  230. // LV2_PATH = splitter.join()
  231. // settings.valueStringList(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH);
  232. }
  233. // ------------------------------------------------------------------------------------------------------------
  234. // plugins handled through backend
  235. const uint internalCount = reAddInternalHelper(settingsDB, PLUGIN_INTERNAL, "");
  236. const uint lv2Count = reAddInternalHelper(settingsDB, PLUGIN_LV2, LV2_PATH.toUtf8());
  237. #ifdef CARLA_OS_MAC
  238. const uint auCount = reAddInternalHelper(settingsDB, PLUGIN_AU, "");
  239. #else
  240. const uint auCount = 0;
  241. #endif
  242. // ------------------------------------------------------------------------------------------------------------
  243. // LADSPA
  244. QStringList ladspaPlugins;
  245. ladspaPlugins << settingsDB.valueStringList("Plugins/LADSPA_native");
  246. ladspaPlugins << settingsDB.valueStringList("Plugins/LADSPA_posix32");
  247. ladspaPlugins << settingsDB.valueStringList("Plugins/LADSPA_posix64");
  248. ladspaPlugins << settingsDB.valueStringList("Plugins/LADSPA_win32");
  249. ladspaPlugins << settingsDB.valueStringList("Plugins/LADSPA_win64");
  250. }
  251. };
  252. PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& hostSettings)
  253. : QDialog(parent),
  254. self(Self::create())
  255. {
  256. self.ui.setupUi(this);
  257. self.hostSettings = hostSettings;
  258. // ----------------------------------------------------------------------------------------------------------------
  259. // Internal stuff
  260. self.fLastTableIndex = 0;
  261. self.fRetPlugin = {};
  262. self.fRealParent = parent;
  263. self.fFavoritePlugins.clear();
  264. self.fFavoritePluginsChanged = false;
  265. self.fTrYes = tr("Yes");
  266. self.fTrNo = tr("No");
  267. self.fTrNative = tr("Native");
  268. // ----------------------------------------------------------------------------------------------------------------
  269. // Set-up GUI
  270. self.ui.b_add->setEnabled(false);
  271. addAction(self.ui.act_focus_search);
  272. // TODO
  273. // self.ui.act_focus_search.triggered.connect(self.slot_focusSearchFieldAndSelectAll);
  274. #if BINARY_NATIVE == BINARY_POSIX32 || BINARY_NATIVE == BINARY_WIN32
  275. self.ui.ch_bridged->setText(tr("Bridged (64bit)"));
  276. #else
  277. self.ui.ch_bridged->setText(tr("Bridged (32bit)"));
  278. #endif
  279. #if !(defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC))
  280. self.ui.ch_bridged_wine->setChecked(false);
  281. self.ui.ch_bridged_wine->setEnabled(false);
  282. #endif
  283. #ifdef CARLA_OS_MAC
  284. setWindowModality(Qt::WindowModal);
  285. #else
  286. self.ui.ch_au->setChecked(false);
  287. self.ui.ch_au->setEnabled(false);
  288. self.ui.ch_au->setVisible(false);
  289. #endif
  290. self.ui.tab_info->tabBar()->hide();
  291. self.ui.tab_reqs->tabBar()->hide();
  292. // FIXME, why /2 needed?
  293. self.ui.tab_info->setMinimumWidth(self.ui.la_id->width()/2 +
  294. self.ui.l_id->fontMetrics().horizontalAdvance("9999999999") + 6*3);
  295. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  296. // ----------------------------------------------------------------------------------------------------------------
  297. // Load settings
  298. loadSettings();
  299. // ----------------------------------------------------------------------------------------------------------------
  300. // Disable bridges if not enabled in settings
  301. // NOTE: We Assume win32 carla build will not run win64 plugins
  302. // if (WINDOWS and not kIs64bit) or not host.showPluginBridges:
  303. // self.ui.ch_native.setChecked(True)
  304. // self.ui.ch_native.setEnabled(False)
  305. // self.ui.ch_native.setVisible(True)
  306. // self.ui.ch_bridged.setChecked(False)
  307. // self.ui.ch_bridged.setEnabled(False)
  308. // self.ui.ch_bridged.setVisible(False)
  309. // self.ui.ch_bridged_wine.setChecked(False)
  310. // self.ui.ch_bridged_wine.setEnabled(False)
  311. // self.ui.ch_bridged_wine.setVisible(False)
  312. //
  313. // elif not host.showWineBridges:
  314. // self.ui.ch_bridged_wine.setChecked(False)
  315. // self.ui.ch_bridged_wine.setEnabled(False)
  316. // self.ui.ch_bridged_wine.setVisible(False)
  317. // ----------------------------------------------------------------------------------------------------------------
  318. // Set-up Icons
  319. if (hostSettings.useSystemIcons)
  320. {
  321. // self.ui.b_add.setIcon(getIcon('list-add', 16, 'svgz'))
  322. // self.ui.b_cancel.setIcon(getIcon('dialog-cancel', 16, 'svgz'))
  323. // self.ui.b_clear_filters.setIcon(getIcon('edit-clear', 16, 'svgz'))
  324. // self.ui.b_refresh.setIcon(getIcon('view-refresh', 16, 'svgz'))
  325. QTableWidgetItem* const hhi = self.ui.tableWidget->horizontalHeaderItem(self.TABLEWIDGET_ITEM_FAVORITE);
  326. // hhi.setIcon(getIcon('bookmarks', 16, 'svgz'))
  327. }
  328. // ----------------------------------------------------------------------------------------------------------------
  329. // Set-up connections
  330. // self.finished.connect(self.slot_saveSettings)
  331. // self.ui.b_add.clicked.connect(self.slot_addPlugin)
  332. // self.ui.b_cancel.clicked.connect(self.reject)
  333. // self.ui.b_refresh.clicked.connect(self.slot_refreshPlugins)
  334. // self.ui.b_clear_filters.clicked.connect(self.slot_clearFilters)
  335. // self.ui.lineEdit.textChanged.connect(self.slot_checkFilters)
  336. // self.ui.tableWidget.currentCellChanged.connect(self.slot_checkPlugin)
  337. // self.ui.tableWidget.cellClicked.connect(self.slot_cellClicked)
  338. // self.ui.tableWidget.cellDoubleClicked.connect(self.slot_cellDoubleClicked)
  339. //
  340. // self.ui.ch_internal.clicked.connect(self.slot_checkFilters)
  341. // self.ui.ch_ladspa.clicked.connect(self.slot_checkFilters)
  342. // self.ui.ch_dssi.clicked.connect(self.slot_checkFilters)
  343. // self.ui.ch_lv2.clicked.connect(self.slot_checkFilters)
  344. // self.ui.ch_vst.clicked.connect(self.slot_checkFilters)
  345. // self.ui.ch_vst3.clicked.connect(self.slot_checkFilters)
  346. // self.ui.ch_clap.clicked.connect(self.slot_checkFilters)
  347. // self.ui.ch_au.clicked.connect(self.slot_checkFilters)
  348. // self.ui.ch_jsfx.clicked.connect(self.slot_checkFilters)
  349. // self.ui.ch_kits.clicked.connect(self.slot_checkFilters)
  350. // self.ui.ch_effects.clicked.connect(self.slot_checkFilters)
  351. // self.ui.ch_instruments.clicked.connect(self.slot_checkFilters)
  352. // self.ui.ch_midi.clicked.connect(self.slot_checkFilters)
  353. // self.ui.ch_other.clicked.connect(self.slot_checkFilters)
  354. // self.ui.ch_native.clicked.connect(self.slot_checkFilters)
  355. // self.ui.ch_bridged.clicked.connect(self.slot_checkFilters)
  356. // self.ui.ch_bridged_wine.clicked.connect(self.slot_checkFilters)
  357. // self.ui.ch_favorites.clicked.connect(self.slot_checkFilters)
  358. // self.ui.ch_rtsafe.clicked.connect(self.slot_checkFilters)
  359. // self.ui.ch_cv.clicked.connect(self.slot_checkFilters)
  360. // self.ui.ch_gui.clicked.connect(self.slot_checkFilters)
  361. // self.ui.ch_inline_display.clicked.connect(self.slot_checkFilters)
  362. // self.ui.ch_stereo.clicked.connect(self.slot_checkFilters)
  363. // self.ui.ch_cat_all.clicked.connect(self.slot_checkFiltersCategoryAll)
  364. // self.ui.ch_cat_delay.clicked.connect(self.slot_checkFiltersCategorySpecific)
  365. // self.ui.ch_cat_distortion.clicked.connect(self.slot_checkFiltersCategorySpecific)
  366. // self.ui.ch_cat_dynamics.clicked.connect(self.slot_checkFiltersCategorySpecific)
  367. // self.ui.ch_cat_eq.clicked.connect(self.slot_checkFiltersCategorySpecific)
  368. // self.ui.ch_cat_filter.clicked.connect(self.slot_checkFiltersCategorySpecific)
  369. // self.ui.ch_cat_modulator.clicked.connect(self.slot_checkFiltersCategorySpecific)
  370. // self.ui.ch_cat_synth.clicked.connect(self.slot_checkFiltersCategorySpecific)
  371. // self.ui.ch_cat_utility.clicked.connect(self.slot_checkFiltersCategorySpecific)
  372. // self.ui.ch_cat_other.clicked.connect(self.slot_checkFiltersCategorySpecific)
  373. // ----------------------------------------------------------------------------------------------------------------
  374. // Post-connect setup
  375. self.reAddPlugins();
  376. slot_focusSearchFieldAndSelectAll();
  377. }
  378. PluginListDialog::~PluginListDialog()
  379. {
  380. delete &self;
  381. }
  382. // --------------------------------------------------------------------------------------------------------------------
  383. // public methods
  384. // --------------------------------------------------------------------------------------------------------------------
  385. // protected methods
  386. void PluginListDialog::showEvent(QShowEvent* const event)
  387. {
  388. slot_focusSearchFieldAndSelectAll();
  389. QDialog::showEvent(event);
  390. }
  391. // --------------------------------------------------------------------------------------------------------------------
  392. // private methods
  393. void PluginListDialog::loadSettings()
  394. {
  395. const QSafeSettings settings("falkTX", "CarlaDatabase2");
  396. self.fFavoritePlugins = settings.valueStringList("PluginDatabase/Favorites");
  397. self.fFavoritePluginsChanged = false;
  398. restoreGeometry(settings.valueByteArray("PluginDatabase/Geometry"));
  399. self.ui.ch_effects->setChecked(settings.valueBool("PluginDatabase/ShowEffects", true));
  400. self.ui.ch_instruments->setChecked(settings.valueBool("PluginDatabase/ShowInstruments", true));
  401. self.ui.ch_midi->setChecked(settings.valueBool("PluginDatabase/ShowMIDI", true));
  402. self.ui.ch_other->setChecked(settings.valueBool("PluginDatabase/ShowOther", true));
  403. self.ui.ch_internal->setChecked(settings.valueBool("PluginDatabase/ShowInternal", true));
  404. self.ui.ch_ladspa->setChecked(settings.valueBool("PluginDatabase/ShowLADSPA", true));
  405. self.ui.ch_dssi->setChecked(settings.valueBool("PluginDatabase/ShowDSSI", true));
  406. self.ui.ch_lv2->setChecked(settings.valueBool("PluginDatabase/ShowLV2", true));
  407. self.ui.ch_vst->setChecked(settings.valueBool("PluginDatabase/ShowVST2", true));
  408. self.ui.ch_vst3->setChecked(settings.valueBool("PluginDatabase/ShowVST3", true));
  409. self.ui.ch_clap->setChecked(settings.valueBool("PluginDatabase/ShowCLAP", true));
  410. #ifdef CARLA_OS_MAC
  411. self.ui.ch_au->setChecked(settings.valueBool("PluginDatabase/ShowAU", true));
  412. #endif
  413. self.ui.ch_jsfx->setChecked(settings.valueBool("PluginDatabase/ShowJSFX", true));
  414. self.ui.ch_kits->setChecked(settings.valueBool("PluginDatabase/ShowKits", true));
  415. self.ui.ch_native->setChecked(settings.valueBool("PluginDatabase/ShowNative", true));
  416. self.ui.ch_bridged->setChecked(settings.valueBool("PluginDatabase/ShowBridged", true));
  417. self.ui.ch_bridged_wine->setChecked(settings.valueBool("PluginDatabase/ShowBridgedWine", true));
  418. self.ui.ch_favorites->setChecked(settings.valueBool("PluginDatabase/ShowFavorites", false));
  419. self.ui.ch_rtsafe->setChecked(settings.valueBool("PluginDatabase/ShowRtSafe", false));
  420. self.ui.ch_cv->setChecked(settings.valueBool("PluginDatabase/ShowHasCV", false));
  421. self.ui.ch_gui->setChecked(settings.valueBool("PluginDatabase/ShowHasGUI", false));
  422. self.ui.ch_inline_display->setChecked(settings.valueBool("PluginDatabase/ShowHasInlineDisplay", false));
  423. self.ui.ch_stereo->setChecked(settings.valueBool("PluginDatabase/ShowStereoOnly", false));
  424. self.ui.lineEdit->setText(settings.valueString("PluginDatabase/SearchText", ""));
  425. QString categoryhash = settings.valueString("PluginDatabase/ShowCategory", "all");
  426. if (categoryhash == "all" or categoryhash.length() < 2)
  427. {
  428. self.ui.ch_cat_all->setChecked(true);
  429. self.ui.ch_cat_delay->setChecked(false);
  430. self.ui.ch_cat_distortion->setChecked(false);
  431. self.ui.ch_cat_dynamics->setChecked(false);
  432. self.ui.ch_cat_eq->setChecked(false);
  433. self.ui.ch_cat_filter->setChecked(false);
  434. self.ui.ch_cat_modulator->setChecked(false);
  435. self.ui.ch_cat_synth->setChecked(false);
  436. self.ui.ch_cat_utility->setChecked(false);
  437. self.ui.ch_cat_other->setChecked(false);
  438. }
  439. else
  440. {
  441. self.ui.ch_cat_all->setChecked(false);
  442. self.ui.ch_cat_delay->setChecked(categoryhash.contains(":delay:"));
  443. self.ui.ch_cat_distortion->setChecked(categoryhash.contains(":distortion:"));
  444. self.ui.ch_cat_dynamics->setChecked(categoryhash.contains(":dynamics:"));
  445. self.ui.ch_cat_eq->setChecked(categoryhash.contains(":eq:"));
  446. self.ui.ch_cat_filter->setChecked(categoryhash.contains(":filter:"));
  447. self.ui.ch_cat_modulator->setChecked(categoryhash.contains(":modulator:"));
  448. self.ui.ch_cat_synth->setChecked(categoryhash.contains(":synth:"));
  449. self.ui.ch_cat_utility->setChecked(categoryhash.contains(":utility:"));
  450. self.ui.ch_cat_other->setChecked(categoryhash.contains(":other:"));
  451. }
  452. QByteArray tableGeometry = settings.valueByteArray("PluginDatabase/TableGeometry_6");
  453. QHeaderView* const horizontalHeader = self.ui.tableWidget->horizontalHeader();
  454. if (! tableGeometry.isNull())
  455. {
  456. horizontalHeader->restoreState(tableGeometry);
  457. }
  458. else
  459. {
  460. horizontalHeader->setSectionResizeMode(self.TABLEWIDGET_ITEM_FAVORITE, QHeaderView::Fixed);
  461. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_FAVORITE, 24);
  462. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_NAME, 250);
  463. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_LABEL, 200);
  464. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_MAKER, 150);
  465. self.ui.tableWidget->sortByColumn(self.TABLEWIDGET_ITEM_NAME, Qt::AscendingOrder);
  466. }
  467. }
  468. // -----------------------------------------------------------------------------------------------------------------
  469. // private slots
  470. void PluginListDialog::slot_cellClicked(int row, int column)
  471. {
  472. if (column == self.TABLEWIDGET_ITEM_FAVORITE)
  473. {
  474. QTableWidgetItem* const widget = self.ui.tableWidget->item(row, self.TABLEWIDGET_ITEM_FAVORITE);
  475. // plugin = self.ui.tableWidget.item(row, self.TABLEWIDGET_ITEM_NAME).data(Qt.UserRole+1);
  476. // plugin = self._createFavoritePluginDict(plugin);
  477. if (widget->checkState() == Qt::Checked)
  478. {
  479. // if (not plugin in self.fFavoritePlugins)
  480. // {
  481. // self.fFavoritePlugins.append(plugin);
  482. // self.fFavoritePluginsChanged = true;
  483. // }
  484. }
  485. else
  486. {
  487. // try:
  488. // self.fFavoritePlugins.remove(plugin);
  489. // self.fFavoritePluginsChanged = True;
  490. // except ValueError:
  491. // pass
  492. }
  493. }
  494. }
  495. void PluginListDialog::slot_cellDoubleClicked(int, int column)
  496. {
  497. if (column != self.TABLEWIDGET_ITEM_FAVORITE)
  498. slot_addPlugin();
  499. }
  500. void PluginListDialog::slot_focusSearchFieldAndSelectAll()
  501. {
  502. self.ui.lineEdit->setFocus();
  503. self.ui.lineEdit->selectAll();
  504. }
  505. void PluginListDialog::slot_addPlugin()
  506. {
  507. if (self.ui.tableWidget->currentRow() >= 0)
  508. {
  509. // self.fRetPlugin = self.ui.tableWidget->item(self.ui.tableWidget->currentRow(),
  510. // self.TABLEWIDGET_ITEM_NAME).data(Qt.UserRole+1);
  511. accept();
  512. }
  513. else
  514. {
  515. reject();
  516. }
  517. }
  518. void PluginListDialog::slot_checkPlugin(int row)
  519. {
  520. if (row >= 0)
  521. {
  522. self.ui.b_add->setEnabled(true);
  523. // auto plugin = self.ui.tableWidget.item(self.ui.tableWidget.currentRow(),
  524. // self.TABLEWIDGET_ITEM_NAME).data(Qt::UserRole+1);
  525. //
  526. // const bool isSynth = plugin['hints'] & PLUGIN_IS_SYNTH;
  527. // const bool isEffect = plugin['audio.ins'] > 0 && plugin['audio.outs'] > 0 && !isSynth;
  528. // const bool isMidi = plugin['audio.ins'] == 0 &&
  529. // plugin['audio.outs'] == 0 &&
  530. // plugin['midi.ins'] > 0 < plugin['midi.outs'];
  531. // // const bool isKit = plugin['type'] in (PLUGIN_SF2, PLUGIN_SFZ);
  532. // // const bool isOther = ! (isEffect || isSynth || isMidi || isKit);
  533. QString ptype;
  534. // /**/ if (isSynth)
  535. // ptype = "Instrument";
  536. // else if (isEffect)
  537. // ptype = "Effect";
  538. // else if (isMidi)
  539. // ptype = "MIDI Plugin";
  540. // else
  541. // ptype = "Other";
  542. QString parch;
  543. // /**/ if (plugin['build'] == BINARY_NATIVE)
  544. // parch = self.fTrNative;
  545. // else if (plugin['build'] == BINARY_POSIX32)
  546. // parch = "posix32";
  547. // else if (plugin['build'] == BINARY_POSIX64)
  548. // parch = "posix64";
  549. // else if (plugin['build'] == BINARY_WIN32)
  550. // parch = "win32";
  551. // else if (plugin['build'] == BINARY_WIN64)
  552. // parch = "win64";
  553. // else if (plugin['build'] == BINARY_OTHER)
  554. // parch = tr("Other");
  555. // else if (plugin['build'] == BINARY_WIN32)
  556. // parch = tr("Unknown");
  557. // self.ui.l_format->setText(getPluginTypeAsString(plugin['type']));
  558. self.ui.l_type->setText(ptype);
  559. self.ui.l_arch->setText(parch);
  560. // self.ui.l_id->setText(str(plugin['uniqueId']));
  561. // self.ui.l_ains->setText(str(plugin['audio.ins']));
  562. // self.ui.l_aouts->setText(str(plugin['audio.outs']));
  563. // self.ui.l_cvins->setText(str(plugin['cv.ins']));
  564. // self.ui.l_cvouts->setText(str(plugin['cv.outs']));
  565. // self.ui.l_mins->setText(str(plugin['midi.ins']));
  566. // self.ui.l_mouts->setText(str(plugin['midi.outs']));
  567. // self.ui.l_pins->setText(str(plugin['parameters.ins']));
  568. // self.ui.l_pouts->setText(str(plugin['parameters.outs']));
  569. // self.ui.l_gui->setText(plugin['hints'] & PLUGIN_HAS_CUSTOM_UI ? self.fTrYes : self.fTrNo);
  570. // self.ui.l_idisp->setText(plugin['hints'] & PLUGIN_HAS_INLINE_DISPLAY ? self.fTrYes : self.fTrNo);
  571. // self.ui.l_bridged->setText(plugin['hints'] & PLUGIN_IS_BRIDGE ? self.fTrYes : self.fTrNo);
  572. // self.ui.l_synth->setText(isSynth ? self.fTrYes : self.fTrNo);
  573. }
  574. else
  575. {
  576. self.ui.b_add->setEnabled(false);
  577. self.ui.l_format->setText("---");
  578. self.ui.l_type->setText("---");
  579. self.ui.l_arch->setText("---");
  580. self.ui.l_id->setText("---");
  581. self.ui.l_ains->setText("---");
  582. self.ui.l_aouts->setText("---");
  583. self.ui.l_cvins->setText("---");
  584. self.ui.l_cvouts->setText("---");
  585. self.ui.l_mins->setText("---");
  586. self.ui.l_mouts->setText("---");
  587. self.ui.l_pins->setText("---");
  588. self.ui.l_pouts->setText("---");
  589. self.ui.l_gui->setText("---");
  590. self.ui.l_idisp->setText("---");
  591. self.ui.l_bridged->setText("---");
  592. self.ui.l_synth->setText("---");
  593. }
  594. }
  595. void PluginListDialog::slot_checkFilters()
  596. {
  597. // TODO
  598. }
  599. void PluginListDialog::slot_checkFiltersCategoryAll(const bool clicked)
  600. {
  601. const bool notClicked = !clicked;
  602. self.ui.ch_cat_delay->setChecked(notClicked);
  603. self.ui.ch_cat_distortion->setChecked(notClicked);
  604. self.ui.ch_cat_dynamics->setChecked(notClicked);
  605. self.ui.ch_cat_eq->setChecked(notClicked);
  606. self.ui.ch_cat_filter->setChecked(notClicked);
  607. self.ui.ch_cat_modulator->setChecked(notClicked);
  608. self.ui.ch_cat_synth->setChecked(notClicked);
  609. self.ui.ch_cat_utility->setChecked(notClicked);
  610. self.ui.ch_cat_other->setChecked(notClicked);
  611. slot_checkFilters();
  612. }
  613. void PluginListDialog::slot_checkFiltersCategorySpecific(bool clicked)
  614. {
  615. if (clicked)
  616. {
  617. self.ui.ch_cat_all->setChecked(false);
  618. }
  619. else if (! (self.ui.ch_cat_delay->isChecked() ||
  620. self.ui.ch_cat_distortion->isChecked() ||
  621. self.ui.ch_cat_dynamics->isChecked() ||
  622. self.ui.ch_cat_eq->isChecked() ||
  623. self.ui.ch_cat_filter->isChecked() ||
  624. self.ui.ch_cat_modulator->isChecked() ||
  625. self.ui.ch_cat_synth->isChecked() ||
  626. self.ui.ch_cat_utility->isChecked() ||
  627. self.ui.ch_cat_other->isChecked()))
  628. {
  629. self.ui.ch_cat_all->setChecked(true);
  630. }
  631. slot_checkFilters();
  632. }
  633. void PluginListDialog::slot_refreshPlugins()
  634. {
  635. // if (PluginRefreshW(this, self.hostSettings, self.hasLoadedLv2Plugins).exec())
  636. // reAddPlugins();
  637. }
  638. void PluginListDialog::slot_clearFilters()
  639. {
  640. blockSignals(true);
  641. self.ui.ch_internal->setChecked(true);
  642. self.ui.ch_ladspa->setChecked(true);
  643. self.ui.ch_dssi->setChecked(true);
  644. self.ui.ch_lv2->setChecked(true);
  645. self.ui.ch_vst->setChecked(true);
  646. self.ui.ch_vst3->setChecked(true);
  647. self.ui.ch_clap->setChecked(true);
  648. self.ui.ch_jsfx->setChecked(true);
  649. self.ui.ch_kits->setChecked(true);
  650. self.ui.ch_instruments->setChecked(true);
  651. self.ui.ch_effects->setChecked(true);
  652. self.ui.ch_midi->setChecked(true);
  653. self.ui.ch_other->setChecked(true);
  654. self.ui.ch_native->setChecked(true);
  655. self.ui.ch_bridged->setChecked(false);
  656. self.ui.ch_bridged_wine->setChecked(false);
  657. self.ui.ch_favorites->setChecked(false);
  658. self.ui.ch_rtsafe->setChecked(false);
  659. self.ui.ch_stereo->setChecked(false);
  660. self.ui.ch_cv->setChecked(false);
  661. self.ui.ch_gui->setChecked(false);
  662. self.ui.ch_inline_display->setChecked(false);
  663. if (self.ui.ch_au->isEnabled())
  664. self.ui.ch_au->setChecked(true);
  665. self.ui.ch_cat_all->setChecked(true);
  666. self.ui.ch_cat_delay->setChecked(false);
  667. self.ui.ch_cat_distortion->setChecked(false);
  668. self.ui.ch_cat_dynamics->setChecked(false);
  669. self.ui.ch_cat_eq->setChecked(false);
  670. self.ui.ch_cat_filter->setChecked(false);
  671. self.ui.ch_cat_modulator->setChecked(false);
  672. self.ui.ch_cat_synth->setChecked(false);
  673. self.ui.ch_cat_utility->setChecked(false);
  674. self.ui.ch_cat_other->setChecked(false);
  675. self.ui.lineEdit->clear();
  676. blockSignals(false);
  677. slot_checkFilters();
  678. }
  679. // --------------------------------------------------------------------------------------------------------------------
  680. void PluginListDialog::slot_saveSettings()
  681. {
  682. QSafeSettings settings("falkTX", "CarlaDatabase2");
  683. settings.setValue("PluginDatabase/Geometry", saveGeometry());
  684. settings.setValue("PluginDatabase/TableGeometry_6", self.ui.tableWidget->horizontalHeader()->saveState());
  685. settings.setValue("PluginDatabase/ShowEffects", self.ui.ch_effects->isChecked());
  686. settings.setValue("PluginDatabase/ShowInstruments", self.ui.ch_instruments->isChecked());
  687. settings.setValue("PluginDatabase/ShowMIDI", self.ui.ch_midi->isChecked());
  688. settings.setValue("PluginDatabase/ShowOther", self.ui.ch_other->isChecked());
  689. settings.setValue("PluginDatabase/ShowInternal", self.ui.ch_internal->isChecked());
  690. settings.setValue("PluginDatabase/ShowLADSPA", self.ui.ch_ladspa->isChecked());
  691. settings.setValue("PluginDatabase/ShowDSSI", self.ui.ch_dssi->isChecked());
  692. settings.setValue("PluginDatabase/ShowLV2", self.ui.ch_lv2->isChecked());
  693. settings.setValue("PluginDatabase/ShowVST2", self.ui.ch_vst->isChecked());
  694. settings.setValue("PluginDatabase/ShowVST3", self.ui.ch_vst3->isChecked());
  695. settings.setValue("PluginDatabase/ShowCLAP", self.ui.ch_clap->isChecked());
  696. settings.setValue("PluginDatabase/ShowAU", self.ui.ch_au->isChecked());
  697. settings.setValue("PluginDatabase/ShowJSFX", self.ui.ch_jsfx->isChecked());
  698. settings.setValue("PluginDatabase/ShowKits", self.ui.ch_kits->isChecked());
  699. settings.setValue("PluginDatabase/ShowNative", self.ui.ch_native->isChecked());
  700. settings.setValue("PluginDatabase/ShowBridged", self.ui.ch_bridged->isChecked());
  701. settings.setValue("PluginDatabase/ShowBridgedWine", self.ui.ch_bridged_wine->isChecked());
  702. settings.setValue("PluginDatabase/ShowFavorites", self.ui.ch_favorites->isChecked());
  703. settings.setValue("PluginDatabase/ShowRtSafe", self.ui.ch_rtsafe->isChecked());
  704. settings.setValue("PluginDatabase/ShowHasCV", self.ui.ch_cv->isChecked());
  705. settings.setValue("PluginDatabase/ShowHasGUI", self.ui.ch_gui->isChecked());
  706. settings.setValue("PluginDatabase/ShowHasInlineDisplay", self.ui.ch_inline_display->isChecked());
  707. settings.setValue("PluginDatabase/ShowStereoOnly", self.ui.ch_stereo->isChecked());
  708. settings.setValue("PluginDatabase/SearchText", self.ui.lineEdit->text());
  709. if (self.ui.ch_cat_all->isChecked())
  710. {
  711. settings.setValue("PluginDatabase/ShowCategory", "all");
  712. }
  713. else
  714. {
  715. QCarlaString categoryhash;
  716. if (self.ui.ch_cat_delay->isChecked())
  717. categoryhash += ":delay";
  718. if (self.ui.ch_cat_distortion->isChecked())
  719. categoryhash += ":distortion";
  720. if (self.ui.ch_cat_dynamics->isChecked())
  721. categoryhash += ":dynamics";
  722. if (self.ui.ch_cat_eq->isChecked())
  723. categoryhash += ":eq";
  724. if (self.ui.ch_cat_filter->isChecked())
  725. categoryhash += ":filter";
  726. if (self.ui.ch_cat_modulator->isChecked())
  727. categoryhash += ":modulator";
  728. if (self.ui.ch_cat_synth->isChecked())
  729. categoryhash += ":synth";
  730. if (self.ui.ch_cat_utility->isChecked())
  731. categoryhash += ":utility";
  732. if (self.ui.ch_cat_other->isChecked())
  733. categoryhash += ":other";
  734. if (categoryhash.isNotEmpty())
  735. categoryhash += ":";
  736. settings.setValue("PluginDatabase/ShowCategory", categoryhash);
  737. }
  738. if (self.fFavoritePluginsChanged)
  739. settings.setValue("PluginDatabase/Favorites", self.fFavoritePlugins);
  740. }
  741. // --------------------------------------------------------------------------------------------------------------------
  742. PluginListDialogResults*
  743. carla_frontend_createAndExecPluginListDialog(void* const parent/*, const HostSettings& hostSettings*/)
  744. {
  745. const HostSettings hostSettings = {};
  746. PluginListDialog gui(reinterpret_cast<QWidget*>(parent), hostSettings);
  747. if (gui.exec())
  748. {
  749. static PluginListDialogResults ret = {};
  750. static CarlaString retBinary;
  751. // TODO
  752. return &ret;
  753. }
  754. return nullptr;
  755. }
  756. // --------------------------------------------------------------------------------------------------------------------