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.

1766 lines
66KB

  1. /*
  2. * Carla plugin host
  3. * Copyright (C) 2011-2023 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 "ui_pluginlistdialog.h"
  28. #include <QtCore/QDir>
  29. #include <QtCore/QFileInfo>
  30. #include <QtCore/QList>
  31. #ifdef __clang__
  32. # pragma clang diagnostic pop
  33. #elif defined(__GNUC__) && __GNUC__ >= 8
  34. # pragma GCC diagnostic pop
  35. #endif
  36. #include "qcarlastring.hpp"
  37. #include "qsafesettings.hpp"
  38. #include "CarlaBackendUtils.hpp"
  39. #include "CarlaFrontend.h"
  40. #include "CarlaUtils.h"
  41. #include "CarlaString.hpp"
  42. #include <cstdlib>
  43. CARLA_BACKEND_USE_NAMESPACE
  44. // --------------------------------------------------------------------------------------------------------------------
  45. // Carla Settings keys
  46. #define CARLA_KEY_PATHS_LADSPA "Paths/LADSPA"
  47. #define CARLA_KEY_PATHS_DSSI "Paths/DSSI"
  48. #define CARLA_KEY_PATHS_LV2 "Paths/LV2"
  49. #define CARLA_KEY_PATHS_VST2 "Paths/VST2"
  50. #define CARLA_KEY_PATHS_VST3 "Paths/VST3"
  51. #define CARLA_KEY_PATHS_CLAP "Paths/CLAP"
  52. #define CARLA_KEY_PATHS_SF2 "Paths/SF2"
  53. #define CARLA_KEY_PATHS_SFZ "Paths/SFZ"
  54. #define CARLA_KEY_PATHS_JSFX "Paths/JSFX"
  55. // --------------------------------------------------------------------------------------------------------------------
  56. // Carla Settings defaults
  57. // --------------------------------------------------------------------------------------------------------------------
  58. // utils
  59. const char* getEnv(const char* const env, const char* const fallback)
  60. {
  61. if (const char* const value = std::getenv(env))
  62. return value;
  63. return fallback;
  64. }
  65. QCarlaString getTMP()
  66. {
  67. QCarlaString tmp;
  68. if (const char* const envTMP = std::getenv("TMP"))
  69. {
  70. tmp = envTMP;
  71. }
  72. else
  73. {
  74. #ifdef CARLA_OS_WIN
  75. qWarning("TMP variable not set");
  76. #endif
  77. tmp = QDir::tempPath();
  78. }
  79. if (!QDir(tmp).exists())
  80. {
  81. qWarning("TMP does not exist");
  82. tmp = "/";
  83. }
  84. return tmp;
  85. }
  86. QCarlaString getHome()
  87. {
  88. QCarlaString home;
  89. if (const char* const envHOME = std::getenv("HOME"))
  90. {
  91. home = envHOME;
  92. }
  93. else
  94. {
  95. #ifndef CARLA_OS_WIN
  96. qWarning("HOME variable not set");
  97. #endif
  98. home = QDir::toNativeSeparators(QDir::homePath());
  99. }
  100. if (!QDir(home).exists())
  101. {
  102. qWarning("HOME does not exist");
  103. home = getTMP();
  104. }
  105. return home;
  106. }
  107. // --------------------------------------------------------------------------------------------------------------------
  108. // Default Plugin Folders (get)
  109. struct DefaultPaths {
  110. QCarlaString ladspa;
  111. QCarlaString dssi;
  112. QCarlaString lv2;
  113. QCarlaString vst2;
  114. QCarlaString vst3;
  115. QCarlaString clap;
  116. QCarlaString sf2;
  117. QCarlaString sfz;
  118. QCarlaString jsfx;
  119. void init()
  120. {
  121. const QCarlaString HOME = getHome();
  122. #if defined(CARLA_OS_WIN)
  123. const char* const envAPPDATA = std::getenv("APPDATA");
  124. const char* const envLOCALAPPDATA = getEnv("LOCALAPPDATA", envAPPDATA);
  125. const char* const envPROGRAMFILES = std::getenv("PROGRAMFILES");
  126. const char* const envPROGRAMFILESx86 = std::getenv("PROGRAMFILES(x86)");
  127. const char* const envCOMMONPROGRAMFILES = std::getenv("COMMONPROGRAMFILES");
  128. const char* const envCOMMONPROGRAMFILESx86 = std::getenv("COMMONPROGRAMFILES(x86)");
  129. // Small integrity tests
  130. if (envAPPDATA == nullptr)
  131. {
  132. qFatal("APPDATA variable not set, cannot continue");
  133. abort();
  134. }
  135. if (envPROGRAMFILES == nullptr)
  136. {
  137. qFatal("PROGRAMFILES variable not set, cannot continue");
  138. abort();
  139. }
  140. if (envCOMMONPROGRAMFILES == nullptr)
  141. {
  142. qFatal("COMMONPROGRAMFILES variable not set, cannot continue");
  143. abort();
  144. }
  145. const QCarlaString APPDATA(envAPPDATA);
  146. const QCarlaString LOCALAPPDATA(envLOCALAPPDATA);
  147. const QCarlaString PROGRAMFILES(envPROGRAMFILES);
  148. const QCarlaString COMMONPROGRAMFILES(envCOMMONPROGRAMFILES);
  149. ladspa = APPDATA + "\\LADSPA";
  150. ladspa += ";" + PROGRAMFILES + "\\LADSPA";
  151. dssi = APPDATA + "\\DSSI";
  152. dssi += ";" + PROGRAMFILES + "\\DSSI";
  153. lv2 = APPDATA + "\\LV2";
  154. lv2 += ";" + COMMONPROGRAMFILES + "\\LV2";
  155. vst2 = PROGRAMFILES + "\\VstPlugins";
  156. vst2 += ";" + PROGRAMFILES + "\\Steinberg\\VstPlugins";
  157. jsfx = APPDATA + "\\REAPER\\Effects";
  158. //jsfx += ";" + PROGRAMFILES + "\\REAPER\\InstallData\\Effects";
  159. #ifdef CARLA_OS_WIN64
  160. vst2 += ";" + COMMONPROGRAMFILES + "\\VST2";
  161. #endif
  162. vst3 = COMMONPROGRAMFILES + "\\VST3";
  163. vst3 += ";" + LOCALAPPDATA + "\\Programs\\Common\\VST3";
  164. clap = COMMONPROGRAMFILES + "\\CLAP";
  165. clap += ";" + LOCALAPPDATA + "\\Programs\\Common\\CLAP";
  166. sf2 = APPDATA + "\\SF2";
  167. sfz = APPDATA + "\\SFZ";
  168. if (envPROGRAMFILESx86 != nullptr)
  169. {
  170. const QCarlaString PROGRAMFILESx86(envPROGRAMFILESx86);
  171. ladspa += ";" + PROGRAMFILESx86 + "\\LADSPA";
  172. dssi += ";" + PROGRAMFILESx86 + "\\DSSI";
  173. vst2 += ";" + PROGRAMFILESx86 + "\\VstPlugins";
  174. vst2 += ";" + PROGRAMFILESx86 + "\\Steinberg\\VstPlugins";
  175. //jsfx += ";" + PROGRAMFILESx86 + "\\REAPER\\InstallData\\Effects";
  176. }
  177. if (envCOMMONPROGRAMFILESx86 != nullptr)
  178. {
  179. const QCarlaString COMMONPROGRAMFILESx86(envCOMMONPROGRAMFILESx86);
  180. vst3 += COMMONPROGRAMFILESx86 + "\\VST3";
  181. clap += COMMONPROGRAMFILESx86 + "\\CLAP";
  182. }
  183. #elif defined(CARLA_OS_HAIKU)
  184. ladspa = HOME + "/.ladspa";
  185. ladspa += ":/system/add-ons/media/ladspaplugins";
  186. ladspa += ":/system/lib/ladspa";
  187. dssi = HOME + "/.dssi";
  188. dssi += ":/system/add-ons/media/dssiplugins";
  189. dssi += ":/system/lib/dssi";
  190. lv2 = HOME + "/.lv2";
  191. lv2 += ":/system/add-ons/media/lv2plugins";
  192. vst2 = HOME + "/.vst";
  193. vst2 += ":/system/add-ons/media/vstplugins";
  194. vst3 = HOME + "/.vst3";
  195. vst3 += ":/system/add-ons/media/vst3plugins";
  196. clap = HOME + "/.clap";
  197. clap += ":/system/add-ons/media/clapplugins";
  198. #elif defined(CARLA_OS_MAC)
  199. ladspa = HOME + "/Library/Audio/Plug-Ins/LADSPA";
  200. ladspa += ":/Library/Audio/Plug-Ins/LADSPA";
  201. dssi = HOME + "/Library/Audio/Plug-Ins/DSSI";
  202. dssi += ":/Library/Audio/Plug-Ins/DSSI";
  203. lv2 = HOME + "/Library/Audio/Plug-Ins/LV2";
  204. lv2 += ":/Library/Audio/Plug-Ins/LV2";
  205. vst2 = HOME + "/Library/Audio/Plug-Ins/VST";
  206. vst2 += ":/Library/Audio/Plug-Ins/VST";
  207. vst3 = HOME + "/Library/Audio/Plug-Ins/VST3";
  208. vst3 += ":/Library/Audio/Plug-Ins/VST3";
  209. clap = HOME + "/Library/Audio/Plug-Ins/CLAP";
  210. clap += ":/Library/Audio/Plug-Ins/CLAP";
  211. jsfx = HOME + "/Library/Application Support/REAPER/Effects";
  212. //jsfx += ":/Applications/REAPER.app/Contents/InstallFiles/Effects";
  213. #else
  214. const QCarlaString CONFIG_HOME(getEnv("XDG_CONFIG_HOME", (HOME + "/.config").toUtf8()));
  215. ladspa = HOME + "/.ladspa";
  216. ladspa += ":/usr/lib/ladspa";
  217. ladspa += ":/usr/local/lib/ladspa";
  218. dssi = HOME + "/.dssi";
  219. dssi += ":/usr/lib/dssi";
  220. dssi += ":/usr/local/lib/dssi";
  221. lv2 = HOME + "/.lv2";
  222. lv2 += ":/usr/lib/lv2";
  223. lv2 += ":/usr/local/lib/lv2";
  224. vst2 = HOME + "/.vst";
  225. vst2 += ":/usr/lib/vst";
  226. vst2 += ":/usr/local/lib/vst";
  227. vst2 += HOME + "/.lxvst";
  228. vst2 += ":/usr/lib/lxvst";
  229. vst2 += ":/usr/local/lib/lxvst";
  230. vst3 = HOME + "/.vst3";
  231. vst3 += ":/usr/lib/vst3";
  232. vst3 += ":/usr/local/lib/vst3";
  233. clap = HOME + "/.clap";
  234. clap += ":/usr/lib/clap";
  235. clap += ":/usr/local/lib/clap";
  236. sf2 = HOME + "/.sounds/sf2";
  237. sf2 += ":" + HOME + "/.sounds/sf3";
  238. sf2 += ":/usr/share/sounds/sf2";
  239. sf2 += ":/usr/share/sounds/sf3";
  240. sf2 += ":/usr/share/soundfonts";
  241. sfz = HOME + "/.sounds/sfz";
  242. sfz += ":/usr/share/sounds/sfz";
  243. jsfx = CONFIG_HOME + "/REAPER/Effects";
  244. //jsfx += ":" + "/opt/REAPER/InstallData/Effects";
  245. #endif
  246. #ifndef CARLA_OS_WIN
  247. QCarlaString winePrefix;
  248. if (const char* const envWINEPREFIX = std::getenv("WINEPREFIX"))
  249. winePrefix = envWINEPREFIX;
  250. if (winePrefix.isEmpty())
  251. winePrefix = HOME + "/.wine";
  252. if (QDir(winePrefix).exists())
  253. {
  254. vst2 += ":" + winePrefix + "/drive_c/Program Files/VstPlugins";
  255. vst3 += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3";
  256. clap += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP";
  257. #ifdef CARLA_OS_64BIT
  258. if (QDir(winePrefix + "/drive_c/Program Files (x86)").exists())
  259. {
  260. vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins";
  261. vst3 += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3";
  262. clap += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/CLAP";
  263. }
  264. #endif
  265. }
  266. #endif
  267. }
  268. void loadFromEnv()
  269. {
  270. if (const char* const envLADSPA = std::getenv("LADSPA_PATH"))
  271. ladspa = envLADSPA;
  272. if (const char* const envDSSI = std::getenv("DSSI_PATH"))
  273. dssi = envDSSI;
  274. if (const char* const envLV2 = std::getenv("LV2_PATH"))
  275. lv2 = envLV2;
  276. if (const char* const envVST = std::getenv("VST_PATH"))
  277. vst2 = envVST;
  278. if (const char* const envVST3 = std::getenv("VST3_PATH"))
  279. vst3 = envVST3;
  280. if (const char* const envCLAP = std::getenv("CLAP_PATH"))
  281. clap = envCLAP;
  282. if (const char* const envSF2 = std::getenv("SF2_PATH"))
  283. sf2 = envSF2;
  284. if (const char* const envSFZ = std::getenv("SFZ_PATH"))
  285. sfz = envSFZ;
  286. if (const char* const envJSFX = std::getenv("JSFX_PATH"))
  287. jsfx = envJSFX;
  288. }
  289. };
  290. // --------------------------------------------------------------------------------------------------------------------
  291. PluginInfo checkPluginCached(const CarlaCachedPluginInfo* const desc, const PluginType ptype)
  292. {
  293. PluginInfo pinfo = {};
  294. pinfo.API = PLUGIN_QUERY_API_VERSION;
  295. pinfo.build = BINARY_NATIVE;
  296. pinfo.type = ptype;
  297. pinfo.hints = desc->hints;
  298. pinfo.name = desc->name;
  299. pinfo.label = desc->label;
  300. pinfo.maker = desc->maker;
  301. pinfo.category = getPluginCategoryAsString(desc->category);
  302. pinfo.audioIns = desc->audioIns;
  303. pinfo.audioOuts = desc->audioOuts;
  304. pinfo.cvIns = desc->cvIns;
  305. pinfo.cvOuts = desc->cvOuts;
  306. pinfo.midiIns = desc->midiIns;
  307. pinfo.midiOuts = desc->midiOuts;
  308. pinfo.parametersIns = desc->parameterIns;
  309. pinfo.parametersOuts = desc->parameterOuts;
  310. switch (ptype)
  311. {
  312. case PLUGIN_LV2:
  313. {
  314. const QString label(desc->label);
  315. pinfo.filename = label.split(CARLA_OS_SEP).first();
  316. pinfo.label = label.section(CARLA_OS_SEP, 1);
  317. }
  318. break;
  319. case PLUGIN_SFZ:
  320. pinfo.filename = pinfo.label;
  321. pinfo.label = pinfo.name;
  322. break;
  323. default:
  324. break;
  325. }
  326. return pinfo;
  327. }
  328. // --------------------------------------------------------------------------------------------------------------------
  329. // Backwards-compatible horizontalAdvance/width call, depending on Qt version
  330. static inline
  331. int fontMetricsHorizontalAdvance(const QFontMetrics& fontMetrics, const QString& string)
  332. {
  333. #if QT_VERSION >= 0x50b00
  334. return fontMetrics.horizontalAdvance(string);
  335. #else
  336. return fontMetrics.width(string);
  337. #endif
  338. }
  339. // --------------------------------------------------------------------------------------------------------------------
  340. typedef QList<PluginInfo> QPluginInfoList;
  341. class QSafePluginListSettings : public QSafeSettings
  342. {
  343. public:
  344. inline QSafePluginListSettings()
  345. : QSafeSettings() {}
  346. inline QSafePluginListSettings(const QString& organization, const QString& application)
  347. : QSafeSettings(organization, application) {}
  348. QPluginInfoList valuePluginInfoList(const QString& key) const
  349. {
  350. /*
  351. QVariant var(value(key, {}));
  352. if (!var.isNull() && var.convert(QVariant::List) && var.isValid())
  353. {
  354. QList<QVariant> varVariant(var.toList());
  355. QPluginInfoList varReal;
  356. varReal.reserve(varVariant.size());
  357. for (QVariant v : varVariant)
  358. {
  359. CARLA_SAFE_ASSERT_BREAK(!v.isNull());
  360. CARLA_SAFE_ASSERT_BREAK(v.convert(QVariant::UserType));
  361. CARLA_SAFE_ASSERT_BREAK(v.isValid());
  362. // varReal.append(v.toU);
  363. }
  364. }
  365. */
  366. return {};
  367. // TODO
  368. (void)key;
  369. }
  370. void setValue(const QString& key, const uint value)
  371. {
  372. QSafeSettings::setValue(key, value);
  373. }
  374. void setValue(const QString& key, const QPluginInfoList& value)
  375. {
  376. return;
  377. // TODO
  378. (void)key;
  379. (void)value;
  380. }
  381. };
  382. // --------------------------------------------------------------------------------------------------------------------
  383. template <class T> inline T static_cast_void(const void* ptr)
  384. {
  385. return static_cast<T>(ptr);
  386. }
  387. struct PluginInfoBytes {
  388. uint API;
  389. uint build;
  390. CARLA_BACKEND_NAMESPACE::PluginType type;
  391. uint hints;
  392. uint64_t uniqueId;
  393. uint audioIns;
  394. uint audioOuts;
  395. uint cvIns;
  396. uint cvOuts;
  397. uint midiIns;
  398. uint midiOuts;
  399. uint parametersIns;
  400. uint parametersOuts;
  401. };
  402. QVariant asVariant(const PluginInfo& plugin)
  403. {
  404. const PluginInfoBytes data = {
  405. plugin.API,
  406. plugin.build,
  407. plugin.type,
  408. plugin.hints,
  409. plugin.uniqueId,
  410. plugin.audioIns,
  411. plugin.audioOuts,
  412. plugin.cvIns,
  413. plugin.cvOuts,
  414. plugin.midiIns,
  415. plugin.midiOuts,
  416. plugin.parametersIns,
  417. plugin.parametersOuts
  418. };
  419. QByteArray qdata(static_cast_void<const char*>(&data), sizeof(data));
  420. {
  421. const QByteArray qcategory(plugin.category.toUtf8());
  422. qdata += qcategory.constData();
  423. qdata += '\0';
  424. }
  425. {
  426. const QByteArray qfilename(plugin.filename.toUtf8());
  427. qdata += qfilename.constData();
  428. qdata += '\0';
  429. }
  430. {
  431. const QByteArray qname(plugin.name.toUtf8());
  432. qdata += qname.constData();
  433. qdata += '\0';
  434. }
  435. {
  436. const QByteArray qlabel(plugin.label.toUtf8());
  437. qdata += qlabel.constData();
  438. qdata += '\0';
  439. }
  440. {
  441. const QByteArray qmaker(plugin.maker.toUtf8());
  442. qdata += qmaker.constData();
  443. qdata += '\0';
  444. }
  445. QVariant var;
  446. var.setValue(qdata);
  447. return var;
  448. }
  449. PluginInfo asPluginInfo(const QVariant& var)
  450. {
  451. const QByteArray qdata(var.toByteArray());
  452. CARLA_SAFE_ASSERT_RETURN((size_t)qdata.size() >= sizeof(PluginInfoBytes) + sizeof(char)*5, {});
  453. const PluginInfoBytes* const data = static_cast_void<const PluginInfoBytes*>(qdata.constData());
  454. PluginInfo plugin = {
  455. data->API,
  456. data->build,
  457. static_cast<PluginType>(data->type),
  458. data->hints,
  459. {}, {}, {}, {}, {},
  460. data->uniqueId,
  461. data->audioIns,
  462. data->audioOuts,
  463. data->cvIns,
  464. data->cvOuts,
  465. data->midiIns,
  466. data->midiOuts,
  467. data->parametersIns,
  468. data->parametersOuts
  469. };
  470. const char* sdata = static_cast_void<const char*>(data) + sizeof(PluginInfoBytes);
  471. plugin.category = QString::fromUtf8(sdata);
  472. sdata += plugin.category.size() + 1;
  473. plugin.filename = QString::fromUtf8(sdata);
  474. sdata += plugin.filename.size() + 1;
  475. plugin.name = QString::fromUtf8(sdata);
  476. sdata += plugin.name.size() + 1;
  477. plugin.label = QString::fromUtf8(sdata);
  478. sdata += plugin.label.size() + 1;
  479. plugin.maker = QString::fromUtf8(sdata);
  480. sdata += plugin.maker.size() + 1;
  481. return plugin;
  482. }
  483. // --------------------------------------------------------------------------------------------------------------------
  484. // Plugin List Dialog
  485. struct PluginListDialog::Self {
  486. enum TableIndex {
  487. TABLEWIDGET_ITEM_FAVORITE,
  488. TABLEWIDGET_ITEM_NAME,
  489. TABLEWIDGET_ITEM_LABEL,
  490. TABLEWIDGET_ITEM_MAKER,
  491. TABLEWIDGET_ITEM_BINARY,
  492. };
  493. // To be changed by parent
  494. bool hasLoadedLv2Plugins = false;
  495. Ui_PluginListDialog ui;
  496. HostSettings hostSettings = {};
  497. int fLastTableIndex = 0;
  498. PluginInfo fRetPlugin;
  499. QWidget* const fRealParent;
  500. QStringList fFavoritePlugins;
  501. bool fFavoritePluginsChanged = false;
  502. const QString fTrYes;
  503. const QString fTrNo;
  504. const QString fTrNative;
  505. Self(QWidget* const parent)
  506. : fRealParent(parent),
  507. fTrYes(tr("Yes")),
  508. fTrNo(tr("No")),
  509. fTrNative(tr("Native")) {}
  510. static Self& create(QWidget* const parent)
  511. {
  512. Self* const self = new Self(parent);
  513. return *self;
  514. }
  515. inline QString tr(const char* const txt)
  516. {
  517. return fRealParent != nullptr ? fRealParent->tr(txt) : QString::fromUtf8(txt);
  518. }
  519. void createFavoritePluginDict()
  520. {
  521. #if 0
  522. return {
  523. 'name' : plugin['name'],
  524. 'build' : plugin['build'],
  525. 'type' : plugin['type'],
  526. 'filename': plugin['filename'],
  527. 'label' : plugin['label'],
  528. 'uniqueId': plugin['uniqueId'],
  529. }
  530. #endif
  531. }
  532. void checkFilters()
  533. {
  534. const QCarlaString text = ui.lineEdit->text().toLower();
  535. const bool hideEffects = !ui.ch_effects->isChecked();
  536. const bool hideInstruments = !ui.ch_instruments->isChecked();
  537. const bool hideMidi = !ui.ch_midi->isChecked();
  538. const bool hideOther = !ui.ch_other->isChecked();
  539. const bool hideInternal = !ui.ch_internal->isChecked();
  540. const bool hideLadspa = !ui.ch_ladspa->isChecked();
  541. const bool hideDssi = !ui.ch_dssi->isChecked();
  542. const bool hideLV2 = !ui.ch_lv2->isChecked();
  543. const bool hideVST2 = !ui.ch_vst->isChecked();
  544. const bool hideVST3 = !ui.ch_vst3->isChecked();
  545. const bool hideCLAP = !ui.ch_clap->isChecked();
  546. const bool hideAU = !ui.ch_au->isChecked();
  547. const bool hideJSFX = !ui.ch_jsfx->isChecked();
  548. const bool hideKits = !ui.ch_kits->isChecked();
  549. const bool hideNative = !ui.ch_native->isChecked();
  550. const bool hideBridged = !ui.ch_bridged->isChecked();
  551. const bool hideBridgedWine = !ui.ch_bridged_wine->isChecked();
  552. const bool hideNonFavs = ui.ch_favorites->isChecked();
  553. const bool hideNonRtSafe = ui.ch_rtsafe->isChecked();
  554. const bool hideNonCV = ui.ch_cv->isChecked();
  555. const bool hideNonGui = ui.ch_gui->isChecked();
  556. const bool hideNonIDisp = ui.ch_inline_display->isChecked();
  557. const bool hideNonStereo = ui.ch_stereo->isChecked();
  558. #if 0
  559. if HAIKU or LINUX or MACOS:
  560. nativeBins = [BINARY_POSIX32, BINARY_POSIX64]
  561. wineBins = [BINARY_WIN32, BINARY_WIN64]
  562. elif WINDOWS:
  563. nativeBins = [BINARY_WIN32, BINARY_WIN64]
  564. wineBins = []
  565. else:
  566. nativeBins = []
  567. wineBins = []
  568. #endif
  569. ui.tableWidget->setRowCount(fLastTableIndex);
  570. for (int i=0; i<fLastTableIndex; ++i)
  571. {
  572. const PluginInfo plugin = asPluginInfo(ui.tableWidget->item(i, TABLEWIDGET_ITEM_NAME)->data(Qt::UserRole+1));
  573. const QString ptext = ui.tableWidget->item(i, TABLEWIDGET_ITEM_NAME)->data(Qt::UserRole+2).toString();
  574. const uint aIns = plugin.audioIns;
  575. const uint aOuts = plugin.audioOuts;
  576. const uint cvIns = plugin.cvIns;
  577. const uint cvOuts = plugin.cvOuts;
  578. const uint mIns = plugin.midiIns;
  579. const uint mOuts = plugin.midiOuts;
  580. const uint phints = plugin.hints;
  581. const PluginType ptype = plugin.type;
  582. const QString categ = plugin.category;
  583. const bool isSynth = phints & PLUGIN_IS_SYNTH;
  584. const bool isEffect = aIns > 0 && aOuts > 0 && !isSynth;
  585. const bool isMidi = aIns == 0 && aOuts == 0 && mIns > 0 && mOuts > 0;
  586. const bool isKit = ptype == PLUGIN_SF2 || ptype == PLUGIN_SFZ;
  587. const bool isOther = !(isEffect || isSynth || isMidi || isKit);
  588. const bool isNative = plugin.build == BINARY_NATIVE;
  589. const bool isRtSafe = phints & PLUGIN_IS_RTSAFE;
  590. const bool isStereo = (aIns == 2 && aOuts == 2) || (isSynth && aOuts == 2);
  591. const bool hasCV = cvIns + cvOuts > 0;
  592. const bool hasGui = phints & PLUGIN_HAS_CUSTOM_UI;
  593. const bool hasIDisp = phints & PLUGIN_HAS_INLINE_DISPLAY;
  594. #if 0
  595. const bool isBridged = bool(not isNative and plugin.build in nativeBins);
  596. const bool isBridgedWine = bool(not isNative and plugin.build in wineBins);
  597. #else
  598. const bool isBridged = false;
  599. const bool isBridgedWine = false;
  600. #endif
  601. const auto hasText = [text, ptext]() {
  602. const QStringList textSplit = text.strip().split(' ');
  603. for (const QString& t : textSplit)
  604. if (ptext.contains(t))
  605. return true;
  606. return false;
  607. };
  608. /**/ if (hideEffects && isEffect)
  609. ui.tableWidget->hideRow(i);
  610. else if (hideInstruments && isSynth)
  611. ui.tableWidget->hideRow(i);
  612. else if (hideMidi && isMidi)
  613. ui.tableWidget->hideRow(i);
  614. else if (hideOther && isOther)
  615. ui.tableWidget->hideRow(i);
  616. else if (hideKits && isKit)
  617. ui.tableWidget->hideRow(i);
  618. else if (hideInternal && ptype == PLUGIN_INTERNAL)
  619. ui.tableWidget->hideRow(i);
  620. else if (hideLadspa && ptype == PLUGIN_LADSPA)
  621. ui.tableWidget->hideRow(i);
  622. else if (hideDssi && ptype == PLUGIN_DSSI)
  623. ui.tableWidget->hideRow(i);
  624. else if (hideLV2 && ptype == PLUGIN_LV2)
  625. ui.tableWidget->hideRow(i);
  626. else if (hideVST2 && ptype == PLUGIN_VST2)
  627. ui.tableWidget->hideRow(i);
  628. else if (hideVST3 && ptype == PLUGIN_VST3)
  629. ui.tableWidget->hideRow(i);
  630. else if (hideCLAP && ptype == PLUGIN_CLAP)
  631. ui.tableWidget->hideRow(i);
  632. else if (hideAU && ptype == PLUGIN_AU)
  633. ui.tableWidget->hideRow(i);
  634. else if (hideJSFX && ptype == PLUGIN_JSFX)
  635. ui.tableWidget->hideRow(i);
  636. else if (hideNative && isNative)
  637. ui.tableWidget->hideRow(i);
  638. else if (hideBridged && isBridged)
  639. ui.tableWidget->hideRow(i);
  640. else if (hideBridgedWine && isBridgedWine)
  641. ui.tableWidget->hideRow(i);
  642. else if (hideNonRtSafe && not isRtSafe)
  643. ui.tableWidget->hideRow(i);
  644. else if (hideNonCV && not hasCV)
  645. ui.tableWidget->hideRow(i);
  646. else if (hideNonGui && not hasGui)
  647. ui.tableWidget->hideRow(i);
  648. else if (hideNonIDisp && not hasIDisp)
  649. ui.tableWidget->hideRow(i);
  650. else if (hideNonStereo && not isStereo)
  651. ui.tableWidget->hideRow(i);
  652. else if (text.isNotEmpty() && ! hasText())
  653. ui.tableWidget->hideRow(i);
  654. #if 0
  655. else if (hideNonFavs && _createFavoritePluginDict(plugin) not in fFavoritePlugins)
  656. ui.tableWidget->hideRow(i);
  657. #endif
  658. else if (ui.ch_cat_all->isChecked() or
  659. (ui.ch_cat_delay->isChecked() && categ == "delay") or
  660. (ui.ch_cat_distortion->isChecked() && categ == "distortion") or
  661. (ui.ch_cat_dynamics->isChecked() && categ == "dynamics") or
  662. (ui.ch_cat_eq->isChecked() && categ == "eq") or
  663. (ui.ch_cat_filter->isChecked() && categ == "filter") or
  664. (ui.ch_cat_modulator->isChecked() && categ == "modulator") or
  665. (ui.ch_cat_synth->isChecked() && categ == "synth") or
  666. (ui.ch_cat_utility->isChecked() && categ == "utility") or
  667. (ui.ch_cat_other->isChecked() && categ == "other"))
  668. ui.tableWidget->showRow(i);
  669. else
  670. ui.tableWidget->hideRow(i);
  671. }
  672. }
  673. void addPluginToTable(const PluginInfo& plugin, const PluginType ptype)
  674. {
  675. if (plugin.API != PLUGIN_QUERY_API_VERSION)
  676. return;
  677. PluginInfo plugincopy = plugin;
  678. switch (ptype)
  679. {
  680. case PLUGIN_INTERNAL:
  681. case PLUGIN_LV2:
  682. case PLUGIN_SF2:
  683. case PLUGIN_SFZ:
  684. case PLUGIN_JSFX:
  685. plugincopy.build = BINARY_NATIVE;
  686. break;
  687. default:
  688. break;
  689. }
  690. const int index = fLastTableIndex;
  691. #if 0
  692. const bool isFav = bool(self._createFavoritePluginDict(plugin) in self.fFavoritePlugins)
  693. #else
  694. const bool isFav = false;
  695. #endif
  696. QTableWidgetItem* const itemFav = new QTableWidgetItem;
  697. itemFav->setCheckState(isFav ? Qt::Checked : Qt::Unchecked);
  698. itemFav->setText(isFav ? " " : " ");
  699. const QString pluginText = (plugin.name + plugin.label + plugin.maker + plugin.filename).toLower();
  700. ui.tableWidget->setItem(index, TABLEWIDGET_ITEM_FAVORITE, itemFav);
  701. ui.tableWidget->setItem(index, TABLEWIDGET_ITEM_NAME, new QTableWidgetItem(plugin.name));
  702. ui.tableWidget->setItem(index, TABLEWIDGET_ITEM_LABEL, new QTableWidgetItem(plugin.label));
  703. ui.tableWidget->setItem(index, TABLEWIDGET_ITEM_MAKER, new QTableWidgetItem(plugin.maker));
  704. ui.tableWidget->setItem(index, TABLEWIDGET_ITEM_BINARY, new QTableWidgetItem(QFileInfo(plugin.filename).fileName()));
  705. QTableWidgetItem* const itemName = ui.tableWidget->item(index, TABLEWIDGET_ITEM_NAME);
  706. itemName->setData(Qt::UserRole+1, asVariant(plugincopy));
  707. itemName->setData(Qt::UserRole+2, pluginText);
  708. fLastTableIndex += 1;
  709. }
  710. uint reAddInternalHelper(QSafePluginListSettings& settingsDB, const PluginType ptype, const char* const path)
  711. {
  712. QString ptypeStr, ptypeStrTr;
  713. switch (ptype)
  714. {
  715. case PLUGIN_INTERNAL:
  716. ptypeStr = "Internal";
  717. ptypeStrTr = tr("Internal");
  718. break;
  719. case PLUGIN_LV2:
  720. ptypeStr = "LV2";
  721. ptypeStrTr = ptypeStr;
  722. break;
  723. case PLUGIN_AU:
  724. ptypeStr = "AU";
  725. ptypeStrTr = ptypeStr;
  726. break;
  727. case PLUGIN_SFZ:
  728. ptypeStr = "SFZ";
  729. ptypeStrTr = ptypeStr;
  730. break;
  731. // TODO(jsfx) what to do here?
  732. default:
  733. return 0;
  734. }
  735. QPluginInfoList plugins = settingsDB.valuePluginInfoList("Plugins/" + ptypeStr);
  736. uint pluginCount = settingsDB.valueUInt("PluginCount/" + ptypeStr, 0);
  737. if (ptype == PLUGIN_AU)
  738. carla_juce_init();
  739. const uint pluginCountNew = carla_get_cached_plugin_count(ptype, path);
  740. #if 0
  741. if (pluginCountNew != pluginCount || plugins.size() != pluginCount ||
  742. (plugins.size() > 0 && plugins[0].API != PLUGIN_QUERY_API_VERSION))
  743. #endif
  744. {
  745. plugins.clear();
  746. pluginCount = pluginCountNew;
  747. QApplication::instance()->processEvents(QEventLoop::ExcludeUserInputEvents, 50);
  748. if (ptype == PLUGIN_AU)
  749. carla_juce_idle();
  750. for (uint i=0; i<pluginCountNew; ++i)
  751. {
  752. const CarlaCachedPluginInfo* const descInfo = carla_get_cached_plugin_info(ptype, i);
  753. if (descInfo == nullptr)
  754. continue;
  755. const PluginInfo info = checkPluginCached(descInfo, ptype);
  756. plugins.append(info);
  757. if ((i % 50) == 0)
  758. {
  759. QApplication::instance()->processEvents(QEventLoop::ExcludeUserInputEvents, 50);
  760. if (ptype == PLUGIN_AU)
  761. carla_juce_idle();
  762. }
  763. }
  764. settingsDB.setValue("Plugins/" + ptypeStr, plugins);
  765. settingsDB.setValue("PluginCount/" + ptypeStr, pluginCount);
  766. }
  767. if (ptype == PLUGIN_AU)
  768. carla_juce_cleanup();
  769. // prepare rows in advance
  770. ui.tableWidget->setRowCount(fLastTableIndex + plugins.size());
  771. for (const PluginInfo& plugin : plugins)
  772. addPluginToTable(plugin, ptype);
  773. return pluginCount;
  774. }
  775. void reAddPlugins()
  776. {
  777. QSafePluginListSettings settingsDB("falkTX", "CarlaPlugins5");
  778. fLastTableIndex = 0;
  779. ui.tableWidget->setSortingEnabled(false);
  780. ui.tableWidget->clearContents();
  781. DefaultPaths paths;
  782. paths.init();
  783. paths.loadFromEnv();
  784. QCarlaString LV2_PATH;
  785. {
  786. const QSafeSettings settings("falkTX", "Carla2");
  787. LV2_PATH = settings.valueString(CARLA_KEY_PATHS_LV2, paths.lv2);
  788. }
  789. // ------------------------------------------------------------------------------------------------------------
  790. // plugins handled through backend
  791. const uint internalCount = reAddInternalHelper(settingsDB, PLUGIN_INTERNAL, "");
  792. const uint lv2Count = reAddInternalHelper(settingsDB, PLUGIN_LV2, LV2_PATH.toUtf8());
  793. #ifdef CARLA_OS_MAC
  794. const uint auCount = reAddInternalHelper(settingsDB, PLUGIN_AU, "");
  795. #else
  796. const uint auCount = 0;
  797. #endif
  798. // ------------------------------------------------------------------------------------------------------------
  799. // LADSPA
  800. QList<QPluginInfoList> ladspaPlugins;
  801. ladspaPlugins += settingsDB.valuePluginInfoList("Plugins/LADSPA_native");
  802. ladspaPlugins += settingsDB.valuePluginInfoList("Plugins/LADSPA_posix32");
  803. ladspaPlugins += settingsDB.valuePluginInfoList("Plugins/LADSPA_posix64");
  804. ladspaPlugins += settingsDB.valuePluginInfoList("Plugins/LADSPA_win32");
  805. ladspaPlugins += settingsDB.valuePluginInfoList("Plugins/LADSPA_win64");
  806. // ------------------------------------------------------------------------------------------------------------
  807. // DSSI
  808. QList<QPluginInfoList> dssiPlugins;
  809. dssiPlugins += settingsDB.valuePluginInfoList("Plugins/DSSI_native");
  810. dssiPlugins += settingsDB.valuePluginInfoList("Plugins/DSSI_posix32");
  811. dssiPlugins += settingsDB.valuePluginInfoList("Plugins/DSSI_posix64");
  812. dssiPlugins += settingsDB.valuePluginInfoList("Plugins/DSSI_win32");
  813. dssiPlugins += settingsDB.valuePluginInfoList("Plugins/DSSI_win64");
  814. // ------------------------------------------------------------------------------------------------------------
  815. // VST2
  816. QList<QPluginInfoList> vst2Plugins;
  817. vst2Plugins += settingsDB.valuePluginInfoList("Plugins/VST2_native");
  818. vst2Plugins += settingsDB.valuePluginInfoList("Plugins/VST2_posix32");
  819. vst2Plugins += settingsDB.valuePluginInfoList("Plugins/VST2_posix64");
  820. vst2Plugins += settingsDB.valuePluginInfoList("Plugins/VST2_win32");
  821. vst2Plugins += settingsDB.valuePluginInfoList("Plugins/VST2_win64");
  822. // ------------------------------------------------------------------------------------------------------------
  823. // VST3
  824. QList<QPluginInfoList> vst3Plugins;
  825. vst3Plugins += settingsDB.valuePluginInfoList("Plugins/VST3_native");
  826. vst3Plugins += settingsDB.valuePluginInfoList("Plugins/VST3_posix32");
  827. vst3Plugins += settingsDB.valuePluginInfoList("Plugins/VST3_posix64");
  828. vst3Plugins += settingsDB.valuePluginInfoList("Plugins/VST3_win32");
  829. vst3Plugins += settingsDB.valuePluginInfoList("Plugins/VST3_win64");
  830. // ------------------------------------------------------------------------------------------------------------
  831. // CLAP
  832. QList<QPluginInfoList> clapPlugins;
  833. clapPlugins += settingsDB.valuePluginInfoList("Plugins/CLAP_native");
  834. clapPlugins += settingsDB.valuePluginInfoList("Plugins/CLAP_posix32");
  835. clapPlugins += settingsDB.valuePluginInfoList("Plugins/CLAP_posix64");
  836. clapPlugins += settingsDB.valuePluginInfoList("Plugins/CLAP_win32");
  837. clapPlugins += settingsDB.valuePluginInfoList("Plugins/CLAP_win64");
  838. #ifdef CARLA_OS_MAC
  839. // ------------------------------------------------------------------------------------------------------------
  840. // AU (extra non-cached)
  841. QList<QPluginInfoList> auPlugins32;
  842. auPlugins32 += settingsDB.valuePluginInfoList("Plugins/AU_posix32");
  843. #endif
  844. // ------------------------------------------------------------------------------------------------------------
  845. // JSFX
  846. QPluginInfoList jsfxPlugins = settingsDB.valuePluginInfoList("Plugins/JSFX");
  847. // ------------------------------------------------------------------------------------------------------------
  848. // Kits
  849. QList<QPluginInfoList> sf2s;
  850. sf2s += settingsDB.valuePluginInfoList("Plugins/SF2");
  851. QPluginInfoList sfzs = settingsDB.valuePluginInfoList("Plugins/SFZ");
  852. // ------------------------------------------------------------------------------------------------------------
  853. // count plugins first, so we can create rows in advance
  854. int ladspaCount = 0;
  855. int dssiCount = 0;
  856. int vstCount = 0;
  857. int vst3Count = 0;
  858. int clapCount = 0;
  859. int au32Count = 0;
  860. int jsfxCount = jsfxPlugins.size();
  861. int sf2Count = 0;
  862. int sfzCount = sfzs.size();
  863. for (const QPluginInfoList& plugins : ladspaPlugins)
  864. ladspaCount += plugins.size();
  865. for (const QPluginInfoList& plugins : dssiPlugins)
  866. dssiCount += plugins.size();
  867. for (const QPluginInfoList& plugins : vst2Plugins)
  868. vstCount += plugins.size();
  869. for (const QPluginInfoList& plugins : vst3Plugins)
  870. vst3Count += plugins.size();
  871. for (const QPluginInfoList& plugins : clapPlugins)
  872. clapCount += plugins.size();
  873. #ifdef CARLA_OS_MAC
  874. for (const QPluginInfoList& plugins : auPlugins32)
  875. au32Count += plugins.size();
  876. #endif
  877. for (const QPluginInfoList& plugins : sf2s)
  878. sf2Count += plugins.size();
  879. ui.tableWidget->setRowCount(fLastTableIndex +
  880. ladspaCount + dssiCount + vstCount + vst3Count + clapCount +
  881. auCount + au32Count + jsfxCount + sf2Count + sfzCount);
  882. constexpr const char* const txt = "Have %1 Internal, %2 LADSPA, %3 DSSI, %4 LV2, %5 VST2, %6 VST3, %7 CLAP"
  883. #ifdef CARLA_OS_MAC
  884. ", %8 AudioUnit and %9 JSFX plugins, plus %10 Sound Kits"
  885. #endif
  886. " and %8 JSFX plugins, plus %9 Sound Kits";
  887. ui.label->setText(fRealParent->tr(txt)
  888. .arg(QString::number(internalCount))
  889. .arg(QString::number(ladspaCount))
  890. .arg(QString::number(dssiCount))
  891. .arg(QString::number(lv2Count))
  892. .arg(QString::number(vstCount))
  893. .arg(QString::number(vst3Count))
  894. .arg(QString::number(clapCount))
  895. #ifdef CARLA_OS_MAC
  896. .arg(QString::number(auCount+au32Count))
  897. #endif
  898. .arg(QString::number(jsfxCount))
  899. .arg(QString::number(sf2Count+sfzCount))
  900. );
  901. // ------------------------------------------------------------------------------------------------------------
  902. // now add all plugins to the table
  903. for (const QPluginInfoList& plugins : ladspaPlugins)
  904. for (const PluginInfo& plugin : plugins)
  905. addPluginToTable(plugin, PLUGIN_LADSPA);
  906. for (const QPluginInfoList& plugins : dssiPlugins)
  907. for (const PluginInfo& plugin : plugins)
  908. addPluginToTable(plugin, PLUGIN_DSSI);
  909. for (const QPluginInfoList& plugins : vst2Plugins)
  910. for (const PluginInfo& plugin : plugins)
  911. addPluginToTable(plugin, PLUGIN_VST2);
  912. for (const QPluginInfoList& plugins : vst3Plugins)
  913. for (const PluginInfo& plugin : plugins)
  914. addPluginToTable(plugin, PLUGIN_VST3);
  915. for (const QPluginInfoList& plugins : clapPlugins)
  916. for (const PluginInfo& plugin : plugins)
  917. addPluginToTable(plugin, PLUGIN_CLAP);
  918. #ifdef CARLA_OS_MAC
  919. for (const QPluginInfoList& plugins : auPlugins32)
  920. for (const PluginInfo& plugin : plugins)
  921. addPluginToTable(plugin, PLUGIN_AU);
  922. #endif
  923. for (const PluginInfo& plugin : jsfxPlugins)
  924. addPluginToTable(plugin, PLUGIN_JSFX);
  925. for (const QPluginInfoList& sf2 : sf2s)
  926. for (const PluginInfo& sf2_i : sf2)
  927. addPluginToTable(sf2_i, PLUGIN_SF2);
  928. for (const PluginInfo& sfz : sfzs)
  929. addPluginToTable(sfz, PLUGIN_SFZ);
  930. // ------------------------------------------------------------------------------------------------------------
  931. ui.tableWidget->setSortingEnabled(true);
  932. checkFilters();
  933. checkPlugin(ui.tableWidget->currentRow());
  934. }
  935. void checkPlugin(const int row)
  936. {
  937. if (row >= 0)
  938. {
  939. ui.b_add->setEnabled(true);
  940. PluginInfo plugin = asPluginInfo(ui.tableWidget->item(row, TABLEWIDGET_ITEM_NAME)->data(Qt::UserRole+1));
  941. const bool isSynth = plugin.hints & PLUGIN_IS_SYNTH;
  942. const bool isEffect = plugin.audioIns > 0 && plugin.audioOuts > 0 && !isSynth;
  943. const bool isMidi = plugin.audioIns == 0 &&
  944. plugin.audioOuts == 0 &&
  945. plugin.midiIns > 0 && plugin.midiOuts > 0;
  946. // const bool isKit = plugin['type'] in (PLUGIN_SF2, PLUGIN_SFZ);
  947. // const bool isOther = ! (isEffect || isSynth || isMidi || isKit);
  948. QString ptype;
  949. /**/ if (isSynth)
  950. ptype = "Instrument";
  951. else if (isEffect)
  952. ptype = "Effect";
  953. else if (isMidi)
  954. ptype = "MIDI Plugin";
  955. else
  956. ptype = "Other";
  957. QString parch;
  958. /**/ if (plugin.build == BINARY_NATIVE)
  959. parch = fTrNative;
  960. else if (plugin.build == BINARY_POSIX32)
  961. parch = "posix32";
  962. else if (plugin.build == BINARY_POSIX64)
  963. parch = "posix64";
  964. else if (plugin.build == BINARY_WIN32)
  965. parch = "win32";
  966. else if (plugin.build == BINARY_WIN64)
  967. parch = "win64";
  968. else if (plugin.build == BINARY_OTHER)
  969. parch = tr("Other");
  970. else if (plugin.build == BINARY_WIN32)
  971. parch = tr("Unknown");
  972. ui.l_format->setText(getPluginTypeAsString(plugin.type));
  973. ui.l_type->setText(ptype);
  974. ui.l_arch->setText(parch);
  975. ui.l_id->setText(QString::number(plugin.uniqueId));
  976. ui.l_ains->setText(QString::number(plugin.audioIns));
  977. ui.l_aouts->setText(QString::number(plugin.audioOuts));
  978. ui.l_cvins->setText(QString::number(plugin.cvIns));
  979. ui.l_cvouts->setText(QString::number(plugin.cvOuts));
  980. ui.l_mins->setText(QString::number(plugin.midiIns));
  981. ui.l_mouts->setText(QString::number(plugin.midiOuts));
  982. ui.l_pins->setText(QString::number(plugin.parametersIns));
  983. ui.l_pouts->setText(QString::number(plugin.parametersOuts));
  984. ui.l_gui->setText(plugin.hints & PLUGIN_HAS_CUSTOM_UI ? fTrYes : fTrNo);
  985. ui.l_idisp->setText(plugin.hints & PLUGIN_HAS_INLINE_DISPLAY ? fTrYes : fTrNo);
  986. ui.l_bridged->setText(plugin.hints & PLUGIN_IS_BRIDGE ? fTrYes : fTrNo);
  987. ui.l_synth->setText(isSynth ? fTrYes : fTrNo);
  988. }
  989. else
  990. {
  991. ui.b_add->setEnabled(false);
  992. ui.l_format->setText("---");
  993. ui.l_type->setText("---");
  994. ui.l_arch->setText("---");
  995. ui.l_id->setText("---");
  996. ui.l_ains->setText("---");
  997. ui.l_aouts->setText("---");
  998. ui.l_cvins->setText("---");
  999. ui.l_cvouts->setText("---");
  1000. ui.l_mins->setText("---");
  1001. ui.l_mouts->setText("---");
  1002. ui.l_pins->setText("---");
  1003. ui.l_pouts->setText("---");
  1004. ui.l_gui->setText("---");
  1005. ui.l_idisp->setText("---");
  1006. ui.l_bridged->setText("---");
  1007. ui.l_synth->setText("---");
  1008. }
  1009. }
  1010. };
  1011. PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& hostSettings)
  1012. : QDialog(parent),
  1013. self(Self::create(parent))
  1014. {
  1015. self.ui.setupUi(this);
  1016. self.hostSettings = hostSettings;
  1017. // ----------------------------------------------------------------------------------------------------------------
  1018. // Set-up GUI
  1019. self.ui.b_add->setEnabled(false);
  1020. addAction(self.ui.act_focus_search);
  1021. QObject::connect(self.ui.act_focus_search, &QAction::triggered,
  1022. this, &PluginListDialog::slot_focusSearchFieldAndSelectAll);
  1023. #if BINARY_NATIVE == BINARY_POSIX32 || BINARY_NATIVE == BINARY_WIN32
  1024. self.ui.ch_bridged->setText(tr("Bridged (64bit)"));
  1025. #else
  1026. self.ui.ch_bridged->setText(tr("Bridged (32bit)"));
  1027. #endif
  1028. #if !(defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC))
  1029. self.ui.ch_bridged_wine->setChecked(false);
  1030. self.ui.ch_bridged_wine->setEnabled(false);
  1031. #endif
  1032. #ifdef CARLA_OS_MAC
  1033. setWindowModality(Qt::WindowModal);
  1034. #else
  1035. self.ui.ch_au->setChecked(false);
  1036. self.ui.ch_au->setEnabled(false);
  1037. self.ui.ch_au->setVisible(false);
  1038. #endif
  1039. self.ui.tab_info->tabBar()->hide();
  1040. self.ui.tab_reqs->tabBar()->hide();
  1041. // FIXME, why /2 needed?
  1042. self.ui.tab_info->setMinimumWidth(self.ui.la_id->width()/2 +
  1043. fontMetricsHorizontalAdvance(self.ui.l_id->fontMetrics(), "9999999999") + 6*3);
  1044. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  1045. // ----------------------------------------------------------------------------------------------------------------
  1046. // Load settings
  1047. loadSettings();
  1048. // ----------------------------------------------------------------------------------------------------------------
  1049. // Disable bridges if not enabled in settings
  1050. #if 0
  1051. // NOTE: We Assume win32 carla build will not run win64 plugins
  1052. if (WINDOWS and not kIs64bit) or not host.showPluginBridges:
  1053. self.ui.ch_native.setChecked(True)
  1054. self.ui.ch_native.setEnabled(False)
  1055. self.ui.ch_native.setVisible(True)
  1056. self.ui.ch_bridged.setChecked(False)
  1057. self.ui.ch_bridged.setEnabled(False)
  1058. self.ui.ch_bridged.setVisible(False)
  1059. self.ui.ch_bridged_wine.setChecked(False)
  1060. self.ui.ch_bridged_wine.setEnabled(False)
  1061. self.ui.ch_bridged_wine.setVisible(False)
  1062. elif not host.showWineBridges:
  1063. self.ui.ch_bridged_wine.setChecked(False)
  1064. self.ui.ch_bridged_wine.setEnabled(False)
  1065. self.ui.ch_bridged_wine.setVisible(False)
  1066. #endif
  1067. // ----------------------------------------------------------------------------------------------------------------
  1068. // Set-up Icons
  1069. if (hostSettings.useSystemIcons)
  1070. {
  1071. #if 0
  1072. self.ui.b_add.setIcon(getIcon('list-add', 16, 'svgz'))
  1073. self.ui.b_cancel.setIcon(getIcon('dialog-cancel', 16, 'svgz'))
  1074. self.ui.b_clear_filters.setIcon(getIcon('edit-clear', 16, 'svgz'))
  1075. self.ui.b_refresh.setIcon(getIcon('view-refresh', 16, 'svgz'))
  1076. QTableWidgetItem* const hhi = self.ui.tableWidget->horizontalHeaderItem(self.TABLEWIDGET_ITEM_FAVORITE);
  1077. hhi.setIcon(getIcon('bookmarks', 16, 'svgz'))
  1078. #endif
  1079. }
  1080. // ----------------------------------------------------------------------------------------------------------------
  1081. // Set-up connections
  1082. QObject::connect(this, &QDialog::finished, this, &PluginListDialog::slot_saveSettings);
  1083. QObject::connect(self.ui.b_add, &QPushButton::clicked, this, &PluginListDialog::slot_addPlugin);
  1084. QObject::connect(self.ui.b_cancel, &QPushButton::clicked, this, &QDialog::reject);
  1085. QObject::connect(self.ui.b_refresh, &QPushButton::clicked, this, &PluginListDialog::slot_refreshPlugins);
  1086. QObject::connect(self.ui.b_clear_filters, &QPushButton::clicked, this, &PluginListDialog::slot_clearFilters);
  1087. QObject::connect(self.ui.lineEdit, &QLineEdit::textChanged, this, &PluginListDialog::slot_checkFilters);
  1088. QObject::connect(self.ui.tableWidget, &QTableWidget::currentCellChanged,
  1089. this, &PluginListDialog::slot_checkPlugin);
  1090. QObject::connect(self.ui.tableWidget, &QTableWidget::cellClicked,
  1091. this, &PluginListDialog::slot_cellClicked);
  1092. QObject::connect(self.ui.tableWidget, &QTableWidget::cellDoubleClicked,
  1093. this, &PluginListDialog::slot_cellDoubleClicked);
  1094. QObject::connect(self.ui.ch_internal, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1095. QObject::connect(self.ui.ch_ladspa, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1096. QObject::connect(self.ui.ch_dssi, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1097. QObject::connect(self.ui.ch_lv2, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1098. QObject::connect(self.ui.ch_vst, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1099. QObject::connect(self.ui.ch_vst3, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1100. QObject::connect(self.ui.ch_clap, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1101. QObject::connect(self.ui.ch_au, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1102. QObject::connect(self.ui.ch_jsfx, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1103. QObject::connect(self.ui.ch_kits, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1104. QObject::connect(self.ui.ch_effects, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1105. QObject::connect(self.ui.ch_instruments, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1106. QObject::connect(self.ui.ch_midi, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1107. QObject::connect(self.ui.ch_other, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1108. QObject::connect(self.ui.ch_native, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1109. QObject::connect(self.ui.ch_bridged, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1110. QObject::connect(self.ui.ch_bridged_wine, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1111. QObject::connect(self.ui.ch_favorites, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1112. QObject::connect(self.ui.ch_rtsafe, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1113. QObject::connect(self.ui.ch_cv, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1114. QObject::connect(self.ui.ch_gui, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1115. QObject::connect(self.ui.ch_inline_display, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1116. QObject::connect(self.ui.ch_stereo, &QCheckBox::clicked, this, &PluginListDialog::slot_checkFilters);
  1117. QObject::connect(self.ui.ch_cat_all, &QCheckBox::clicked,
  1118. this, &PluginListDialog::slot_checkFiltersCategoryAll);
  1119. QObject::connect(self.ui.ch_cat_delay, &QCheckBox::clicked,
  1120. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1121. QObject::connect(self.ui.ch_cat_distortion, &QCheckBox::clicked,
  1122. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1123. QObject::connect(self.ui.ch_cat_dynamics, &QCheckBox::clicked,
  1124. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1125. QObject::connect(self.ui.ch_cat_eq, &QCheckBox::clicked,
  1126. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1127. QObject::connect(self.ui.ch_cat_filter, &QCheckBox::clicked,
  1128. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1129. QObject::connect(self.ui.ch_cat_modulator, &QCheckBox::clicked,
  1130. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1131. QObject::connect(self.ui.ch_cat_synth, &QCheckBox::clicked,
  1132. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1133. QObject::connect(self.ui.ch_cat_utility, &QCheckBox::clicked,
  1134. this, &PluginListDialog::slot_checkFiltersCategorySpecific);
  1135. QObject::connect(self.ui.ch_cat_other, &QCheckBox::clicked, this,
  1136. &PluginListDialog::slot_checkFiltersCategorySpecific);
  1137. // ----------------------------------------------------------------------------------------------------------------
  1138. // Post-connect setup
  1139. self.reAddPlugins();
  1140. slot_focusSearchFieldAndSelectAll();
  1141. }
  1142. PluginListDialog::~PluginListDialog()
  1143. {
  1144. delete &self;
  1145. }
  1146. // --------------------------------------------------------------------------------------------------------------------
  1147. // public methods
  1148. const PluginInfo& PluginListDialog::getSelectedPluginInfo() const
  1149. {
  1150. return self.fRetPlugin;
  1151. }
  1152. // --------------------------------------------------------------------------------------------------------------------
  1153. // protected methods
  1154. void PluginListDialog::showEvent(QShowEvent* const event)
  1155. {
  1156. slot_focusSearchFieldAndSelectAll();
  1157. QDialog::showEvent(event);
  1158. }
  1159. // --------------------------------------------------------------------------------------------------------------------
  1160. // private methods
  1161. void PluginListDialog::loadSettings()
  1162. {
  1163. const QSafeSettings settings("falkTX", "CarlaDatabase2");
  1164. self.fFavoritePlugins = settings.valueStringList("PluginDatabase/Favorites");
  1165. self.fFavoritePluginsChanged = false;
  1166. restoreGeometry(settings.valueByteArray("PluginDatabase/Geometry"));
  1167. self.ui.ch_effects->setChecked(settings.valueBool("PluginDatabase/ShowEffects", true));
  1168. self.ui.ch_instruments->setChecked(settings.valueBool("PluginDatabase/ShowInstruments", true));
  1169. self.ui.ch_midi->setChecked(settings.valueBool("PluginDatabase/ShowMIDI", true));
  1170. self.ui.ch_other->setChecked(settings.valueBool("PluginDatabase/ShowOther", true));
  1171. self.ui.ch_internal->setChecked(settings.valueBool("PluginDatabase/ShowInternal", true));
  1172. self.ui.ch_ladspa->setChecked(settings.valueBool("PluginDatabase/ShowLADSPA", true));
  1173. self.ui.ch_dssi->setChecked(settings.valueBool("PluginDatabase/ShowDSSI", true));
  1174. self.ui.ch_lv2->setChecked(settings.valueBool("PluginDatabase/ShowLV2", true));
  1175. self.ui.ch_vst->setChecked(settings.valueBool("PluginDatabase/ShowVST2", true));
  1176. self.ui.ch_vst3->setChecked(settings.valueBool("PluginDatabase/ShowVST3", true));
  1177. self.ui.ch_clap->setChecked(settings.valueBool("PluginDatabase/ShowCLAP", true));
  1178. #ifdef CARLA_OS_MAC
  1179. self.ui.ch_au->setChecked(settings.valueBool("PluginDatabase/ShowAU", true));
  1180. #endif
  1181. self.ui.ch_jsfx->setChecked(settings.valueBool("PluginDatabase/ShowJSFX", true));
  1182. self.ui.ch_kits->setChecked(settings.valueBool("PluginDatabase/ShowKits", true));
  1183. self.ui.ch_native->setChecked(settings.valueBool("PluginDatabase/ShowNative", true));
  1184. self.ui.ch_bridged->setChecked(settings.valueBool("PluginDatabase/ShowBridged", true));
  1185. self.ui.ch_bridged_wine->setChecked(settings.valueBool("PluginDatabase/ShowBridgedWine", true));
  1186. self.ui.ch_favorites->setChecked(settings.valueBool("PluginDatabase/ShowFavorites", false));
  1187. self.ui.ch_rtsafe->setChecked(settings.valueBool("PluginDatabase/ShowRtSafe", false));
  1188. self.ui.ch_cv->setChecked(settings.valueBool("PluginDatabase/ShowHasCV", false));
  1189. self.ui.ch_gui->setChecked(settings.valueBool("PluginDatabase/ShowHasGUI", false));
  1190. self.ui.ch_inline_display->setChecked(settings.valueBool("PluginDatabase/ShowHasInlineDisplay", false));
  1191. self.ui.ch_stereo->setChecked(settings.valueBool("PluginDatabase/ShowStereoOnly", false));
  1192. self.ui.lineEdit->setText(settings.valueString("PluginDatabase/SearchText", ""));
  1193. const QString categories = settings.valueString("PluginDatabase/ShowCategory", "all");
  1194. if (categories == "all" or categories.length() < 2)
  1195. {
  1196. self.ui.ch_cat_all->setChecked(true);
  1197. self.ui.ch_cat_delay->setChecked(false);
  1198. self.ui.ch_cat_distortion->setChecked(false);
  1199. self.ui.ch_cat_dynamics->setChecked(false);
  1200. self.ui.ch_cat_eq->setChecked(false);
  1201. self.ui.ch_cat_filter->setChecked(false);
  1202. self.ui.ch_cat_modulator->setChecked(false);
  1203. self.ui.ch_cat_synth->setChecked(false);
  1204. self.ui.ch_cat_utility->setChecked(false);
  1205. self.ui.ch_cat_other->setChecked(false);
  1206. }
  1207. else
  1208. {
  1209. self.ui.ch_cat_all->setChecked(false);
  1210. self.ui.ch_cat_delay->setChecked(categories.contains(":delay:"));
  1211. self.ui.ch_cat_distortion->setChecked(categories.contains(":distortion:"));
  1212. self.ui.ch_cat_dynamics->setChecked(categories.contains(":dynamics:"));
  1213. self.ui.ch_cat_eq->setChecked(categories.contains(":eq:"));
  1214. self.ui.ch_cat_filter->setChecked(categories.contains(":filter:"));
  1215. self.ui.ch_cat_modulator->setChecked(categories.contains(":modulator:"));
  1216. self.ui.ch_cat_synth->setChecked(categories.contains(":synth:"));
  1217. self.ui.ch_cat_utility->setChecked(categories.contains(":utility:"));
  1218. self.ui.ch_cat_other->setChecked(categories.contains(":other:"));
  1219. }
  1220. const QByteArray tableGeometry = settings.valueByteArray("PluginDatabase/TableGeometry_6");
  1221. QHeaderView* const horizontalHeader = self.ui.tableWidget->horizontalHeader();
  1222. if (! tableGeometry.isNull())
  1223. {
  1224. horizontalHeader->restoreState(tableGeometry);
  1225. }
  1226. else
  1227. {
  1228. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_NAME, 250);
  1229. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_LABEL, 200);
  1230. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_MAKER, 150);
  1231. self.ui.tableWidget->sortByColumn(self.TABLEWIDGET_ITEM_NAME, Qt::AscendingOrder);
  1232. }
  1233. horizontalHeader->setSectionResizeMode(self.TABLEWIDGET_ITEM_FAVORITE, QHeaderView::Fixed);
  1234. self.ui.tableWidget->setColumnWidth(self.TABLEWIDGET_ITEM_FAVORITE, 24);
  1235. self.ui.tableWidget->setSortingEnabled(true);
  1236. }
  1237. // -----------------------------------------------------------------------------------------------------------------
  1238. // private slots
  1239. void PluginListDialog::slot_cellClicked(int row, int column)
  1240. {
  1241. if (column != self.TABLEWIDGET_ITEM_FAVORITE)
  1242. return;
  1243. const QTableWidgetItem* const widget = self.ui.tableWidget->item(row, self.TABLEWIDGET_ITEM_FAVORITE);
  1244. const PluginInfo plugin = asPluginInfo(self.ui.tableWidget->item(row, self.TABLEWIDGET_ITEM_NAME)->data(Qt::UserRole+1));
  1245. #if 0
  1246. plugin = self._createFavoritePluginDict(plugin);
  1247. #endif
  1248. if (widget->checkState() == Qt::Checked)
  1249. {
  1250. #if 0
  1251. if (not plugin in self.fFavoritePlugins)
  1252. {
  1253. self.fFavoritePlugins.append(plugin);
  1254. self.fFavoritePluginsChanged = true;
  1255. }
  1256. #endif
  1257. }
  1258. else
  1259. {
  1260. #if 0
  1261. try:
  1262. self.fFavoritePlugins.remove(plugin);
  1263. self.fFavoritePluginsChanged = True;
  1264. except ValueError:
  1265. pass
  1266. #endif
  1267. }
  1268. }
  1269. void PluginListDialog::slot_cellDoubleClicked(int, int column)
  1270. {
  1271. if (column != self.TABLEWIDGET_ITEM_FAVORITE)
  1272. slot_addPlugin();
  1273. }
  1274. void PluginListDialog::slot_focusSearchFieldAndSelectAll()
  1275. {
  1276. self.ui.lineEdit->setFocus();
  1277. self.ui.lineEdit->selectAll();
  1278. }
  1279. void PluginListDialog::slot_addPlugin()
  1280. {
  1281. if (self.ui.tableWidget->currentRow() >= 0)
  1282. {
  1283. self.fRetPlugin = asPluginInfo(self.ui.tableWidget->item(self.ui.tableWidget->currentRow(),
  1284. self.TABLEWIDGET_ITEM_NAME)->data(Qt::UserRole+1));
  1285. accept();
  1286. }
  1287. else
  1288. {
  1289. reject();
  1290. }
  1291. }
  1292. void PluginListDialog::slot_checkPlugin(const int row)
  1293. {
  1294. self.checkPlugin(row);
  1295. }
  1296. void PluginListDialog::slot_checkFilters()
  1297. {
  1298. self.checkFilters();
  1299. }
  1300. void PluginListDialog::slot_checkFiltersCategoryAll(const bool clicked)
  1301. {
  1302. const bool notClicked = !clicked;
  1303. self.ui.ch_cat_delay->setChecked(notClicked);
  1304. self.ui.ch_cat_distortion->setChecked(notClicked);
  1305. self.ui.ch_cat_dynamics->setChecked(notClicked);
  1306. self.ui.ch_cat_eq->setChecked(notClicked);
  1307. self.ui.ch_cat_filter->setChecked(notClicked);
  1308. self.ui.ch_cat_modulator->setChecked(notClicked);
  1309. self.ui.ch_cat_synth->setChecked(notClicked);
  1310. self.ui.ch_cat_utility->setChecked(notClicked);
  1311. self.ui.ch_cat_other->setChecked(notClicked);
  1312. self.checkFilters();
  1313. }
  1314. void PluginListDialog::slot_checkFiltersCategorySpecific(bool clicked)
  1315. {
  1316. if (clicked)
  1317. {
  1318. self.ui.ch_cat_all->setChecked(false);
  1319. }
  1320. else if (! (self.ui.ch_cat_delay->isChecked() ||
  1321. self.ui.ch_cat_distortion->isChecked() ||
  1322. self.ui.ch_cat_dynamics->isChecked() ||
  1323. self.ui.ch_cat_eq->isChecked() ||
  1324. self.ui.ch_cat_filter->isChecked() ||
  1325. self.ui.ch_cat_modulator->isChecked() ||
  1326. self.ui.ch_cat_synth->isChecked() ||
  1327. self.ui.ch_cat_utility->isChecked() ||
  1328. self.ui.ch_cat_other->isChecked()))
  1329. {
  1330. self.ui.ch_cat_all->setChecked(true);
  1331. }
  1332. self.checkFilters();
  1333. }
  1334. void PluginListDialog::slot_refreshPlugins()
  1335. {
  1336. #if 0
  1337. if (PluginRefreshW(this, self.hostSettings, self.hasLoadedLv2Plugins).exec())
  1338. reAddPlugins();
  1339. #endif
  1340. }
  1341. void PluginListDialog::slot_clearFilters()
  1342. {
  1343. blockSignals(true);
  1344. self.ui.ch_internal->setChecked(true);
  1345. self.ui.ch_ladspa->setChecked(true);
  1346. self.ui.ch_dssi->setChecked(true);
  1347. self.ui.ch_lv2->setChecked(true);
  1348. self.ui.ch_vst->setChecked(true);
  1349. self.ui.ch_vst3->setChecked(true);
  1350. self.ui.ch_clap->setChecked(true);
  1351. self.ui.ch_jsfx->setChecked(true);
  1352. self.ui.ch_kits->setChecked(true);
  1353. self.ui.ch_instruments->setChecked(true);
  1354. self.ui.ch_effects->setChecked(true);
  1355. self.ui.ch_midi->setChecked(true);
  1356. self.ui.ch_other->setChecked(true);
  1357. self.ui.ch_native->setChecked(true);
  1358. self.ui.ch_bridged->setChecked(false);
  1359. self.ui.ch_bridged_wine->setChecked(false);
  1360. self.ui.ch_favorites->setChecked(false);
  1361. self.ui.ch_rtsafe->setChecked(false);
  1362. self.ui.ch_stereo->setChecked(false);
  1363. self.ui.ch_cv->setChecked(false);
  1364. self.ui.ch_gui->setChecked(false);
  1365. self.ui.ch_inline_display->setChecked(false);
  1366. if (self.ui.ch_au->isEnabled())
  1367. self.ui.ch_au->setChecked(true);
  1368. self.ui.ch_cat_all->setChecked(true);
  1369. self.ui.ch_cat_delay->setChecked(false);
  1370. self.ui.ch_cat_distortion->setChecked(false);
  1371. self.ui.ch_cat_dynamics->setChecked(false);
  1372. self.ui.ch_cat_eq->setChecked(false);
  1373. self.ui.ch_cat_filter->setChecked(false);
  1374. self.ui.ch_cat_modulator->setChecked(false);
  1375. self.ui.ch_cat_synth->setChecked(false);
  1376. self.ui.ch_cat_utility->setChecked(false);
  1377. self.ui.ch_cat_other->setChecked(false);
  1378. self.ui.lineEdit->clear();
  1379. blockSignals(false);
  1380. self.checkFilters();
  1381. }
  1382. // --------------------------------------------------------------------------------------------------------------------
  1383. void PluginListDialog::slot_saveSettings()
  1384. {
  1385. QSafeSettings settings("falkTX", "CarlaDatabase2");
  1386. settings.setValue("PluginDatabase/Geometry", saveGeometry());
  1387. settings.setValue("PluginDatabase/TableGeometry_6", self.ui.tableWidget->horizontalHeader()->saveState());
  1388. settings.setValue("PluginDatabase/ShowEffects", self.ui.ch_effects->isChecked());
  1389. settings.setValue("PluginDatabase/ShowInstruments", self.ui.ch_instruments->isChecked());
  1390. settings.setValue("PluginDatabase/ShowMIDI", self.ui.ch_midi->isChecked());
  1391. settings.setValue("PluginDatabase/ShowOther", self.ui.ch_other->isChecked());
  1392. settings.setValue("PluginDatabase/ShowInternal", self.ui.ch_internal->isChecked());
  1393. settings.setValue("PluginDatabase/ShowLADSPA", self.ui.ch_ladspa->isChecked());
  1394. settings.setValue("PluginDatabase/ShowDSSI", self.ui.ch_dssi->isChecked());
  1395. settings.setValue("PluginDatabase/ShowLV2", self.ui.ch_lv2->isChecked());
  1396. settings.setValue("PluginDatabase/ShowVST2", self.ui.ch_vst->isChecked());
  1397. settings.setValue("PluginDatabase/ShowVST3", self.ui.ch_vst3->isChecked());
  1398. settings.setValue("PluginDatabase/ShowCLAP", self.ui.ch_clap->isChecked());
  1399. settings.setValue("PluginDatabase/ShowAU", self.ui.ch_au->isChecked());
  1400. settings.setValue("PluginDatabase/ShowJSFX", self.ui.ch_jsfx->isChecked());
  1401. settings.setValue("PluginDatabase/ShowKits", self.ui.ch_kits->isChecked());
  1402. settings.setValue("PluginDatabase/ShowNative", self.ui.ch_native->isChecked());
  1403. settings.setValue("PluginDatabase/ShowBridged", self.ui.ch_bridged->isChecked());
  1404. settings.setValue("PluginDatabase/ShowBridgedWine", self.ui.ch_bridged_wine->isChecked());
  1405. settings.setValue("PluginDatabase/ShowFavorites", self.ui.ch_favorites->isChecked());
  1406. settings.setValue("PluginDatabase/ShowRtSafe", self.ui.ch_rtsafe->isChecked());
  1407. settings.setValue("PluginDatabase/ShowHasCV", self.ui.ch_cv->isChecked());
  1408. settings.setValue("PluginDatabase/ShowHasGUI", self.ui.ch_gui->isChecked());
  1409. settings.setValue("PluginDatabase/ShowHasInlineDisplay", self.ui.ch_inline_display->isChecked());
  1410. settings.setValue("PluginDatabase/ShowStereoOnly", self.ui.ch_stereo->isChecked());
  1411. settings.setValue("PluginDatabase/SearchText", self.ui.lineEdit->text());
  1412. if (self.ui.ch_cat_all->isChecked())
  1413. {
  1414. settings.setValue("PluginDatabase/ShowCategory", "all");
  1415. }
  1416. else
  1417. {
  1418. QCarlaString categories;
  1419. if (self.ui.ch_cat_delay->isChecked())
  1420. categories += ":delay";
  1421. if (self.ui.ch_cat_distortion->isChecked())
  1422. categories += ":distortion";
  1423. if (self.ui.ch_cat_dynamics->isChecked())
  1424. categories += ":dynamics";
  1425. if (self.ui.ch_cat_eq->isChecked())
  1426. categories += ":eq";
  1427. if (self.ui.ch_cat_filter->isChecked())
  1428. categories += ":filter";
  1429. if (self.ui.ch_cat_modulator->isChecked())
  1430. categories += ":modulator";
  1431. if (self.ui.ch_cat_synth->isChecked())
  1432. categories += ":synth";
  1433. if (self.ui.ch_cat_utility->isChecked())
  1434. categories += ":utility";
  1435. if (self.ui.ch_cat_other->isChecked())
  1436. categories += ":other";
  1437. if (categories.isNotEmpty())
  1438. categories += ":";
  1439. settings.setValue("PluginDatabase/ShowCategory", categories);
  1440. }
  1441. if (self.fFavoritePluginsChanged)
  1442. settings.setValue("PluginDatabase/Favorites", self.fFavoritePlugins);
  1443. }
  1444. // --------------------------------------------------------------------------------------------------------------------
  1445. const PluginListDialogResults*
  1446. carla_frontend_createAndExecPluginListDialog(void* const parent/*, const HostSettings& hostSettings*/)
  1447. {
  1448. const HostSettings hostSettings = {};
  1449. PluginListDialog gui(reinterpret_cast<QWidget*>(parent), hostSettings);
  1450. if (gui.exec())
  1451. {
  1452. static PluginListDialogResults ret;
  1453. static CarlaString category;
  1454. static CarlaString filename;
  1455. static CarlaString name;
  1456. static CarlaString label;
  1457. static CarlaString maker;
  1458. const PluginInfo& plugin(gui.getSelectedPluginInfo());
  1459. category = plugin.category.toUtf8();
  1460. filename = plugin.filename.toUtf8();
  1461. name = plugin.name.toUtf8();
  1462. label = plugin.label.toUtf8();
  1463. maker = plugin.maker.toUtf8();
  1464. ret.API = plugin.API;
  1465. ret.build = plugin.build;
  1466. ret.type = plugin.type;
  1467. ret.hints = plugin.hints;
  1468. ret.category = category;
  1469. ret.filename = filename;
  1470. ret.name = name;
  1471. ret.label = label;
  1472. ret.maker = maker;
  1473. ret.audioIns = plugin.audioIns;
  1474. ret.audioOuts = plugin.audioOuts;
  1475. ret.cvIns = plugin.cvIns;
  1476. ret.cvOuts = plugin.cvOuts;
  1477. ret.midiIns = plugin.midiIns;
  1478. ret.midiOuts = plugin.midiOuts;
  1479. ret.parametersIns = plugin.parametersIns;
  1480. ret.parametersOuts = plugin.parametersOuts;
  1481. return &ret;
  1482. }
  1483. return nullptr;
  1484. }
  1485. // --------------------------------------------------------------------------------------------------------------------