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.

1293 lines
47KB

  1. /*
  2. * Carla settings code
  3. * Copyright (C) 2011-2019 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 "carla_settings.hpp"
  18. //---------------------------------------------------------------------------------------------------------------------
  19. // Imports (Global)
  20. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  21. # pragma GCC diagnostic push
  22. # pragma GCC diagnostic ignored "-Wconversion"
  23. # pragma GCC diagnostic ignored "-Weffc++"
  24. # pragma GCC diagnostic ignored "-Wsign-conversion"
  25. #endif
  26. // --------------------------------------------------------------------------------------------------------------------
  27. #include <QtCore/QStringList>
  28. #include <QtWidgets/QFileDialog>
  29. // --------------------------------------------------------------------------------------------------------------------
  30. #include "ui_carla_settings.hpp"
  31. #include "ui_carla_settings_driver.hpp"
  32. // --------------------------------------------------------------------------------------------------------------------
  33. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  34. # pragma GCC diagnostic pop
  35. #endif
  36. //---------------------------------------------------------------------------------------------------------------------
  37. // Imports (Custom)
  38. #include "carla_host.hpp"
  39. #include "patchcanvas/theme.hpp"
  40. #include "CarlaHost.h"
  41. #include "CarlaMathUtils.hpp"
  42. // --------------------------------------------------------------------------------------------------------------------
  43. static const char* const AUTOMATIC_OPTION = "(Auto)";
  44. static const QList<uint> BUFFER_SIZE_LIST = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
  45. static const QList<double> SAMPLE_RATE_LIST = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
  46. CARLA_BACKEND_USE_NAMESPACE;
  47. // --------------------------------------------------------------------------------------------------------------------
  48. // Driver Settings
  49. struct DriverSettingsW::PrivateData {
  50. Ui::DriverSettingsW ui;
  51. uint fDriverIndex;
  52. QString fDriverName;
  53. QStringList fDeviceNames;
  54. QList<uint> fBufferSizes;
  55. QList<double> fSampleRates;
  56. PrivateData(DriverSettingsW* const self, const uint driverIndex, const QString driverName)
  57. : ui(),
  58. fDriverIndex(driverIndex),
  59. fDriverName(driverName),
  60. fDeviceNames(),
  61. fBufferSizes(BUFFER_SIZE_LIST),
  62. fSampleRates(SAMPLE_RATE_LIST)
  63. {
  64. ui.setupUi(self);
  65. const char* const* const deviceNames = carla_get_engine_driver_device_names(driverIndex);
  66. CARLA_SAFE_ASSERT_RETURN(deviceNames != nullptr,);
  67. fillQStringListFromStringArray(fDeviceNames, deviceNames);
  68. }
  69. void loadSettings(DriverSettingsW* const self)
  70. {
  71. const QSafeSettings settings("falkTX", "Carla2");
  72. const QString prefix(QString("%1%2").arg(CARLA_KEY_ENGINE_DRIVER_PREFIX).arg(fDriverName));
  73. const QCarlaString audioDevice = settings.valueString(QString("%1/Device").arg(prefix), "");
  74. const uint audioBufferSize = settings.valueUInt(QString("%1/BufferSize").arg(prefix), CARLA_DEFAULT_AUDIO_BUFFER_SIZE);
  75. const uint audioSampleRate = settings.valueUInt(QString("%1/SampleRate").arg(prefix), CARLA_DEFAULT_AUDIO_SAMPLE_RATE);
  76. const bool audioTripleBuffer = settings.valueBool(QString("%1/TripleBuffer").arg(prefix), CARLA_DEFAULT_AUDIO_TRIPLE_BUFFER);
  77. if (audioDevice.isNotEmpty() && fDeviceNames.contains(audioDevice))
  78. ui.cb_device->setCurrentIndex(fDeviceNames.indexOf(audioDevice));
  79. else
  80. ui.cb_device->setCurrentIndex(-1);
  81. // fill combo-boxes first
  82. self->slot_updateDeviceInfo();
  83. if (audioBufferSize != 0 && fBufferSizes.contains(audioBufferSize))
  84. ui.cb_buffersize->setCurrentIndex(fBufferSizes.indexOf(audioBufferSize));
  85. else if (fBufferSizes == BUFFER_SIZE_LIST)
  86. ui.cb_buffersize->setCurrentIndex(BUFFER_SIZE_LIST.indexOf(CARLA_DEFAULT_AUDIO_BUFFER_SIZE));
  87. else
  88. ui.cb_buffersize->setCurrentIndex(fBufferSizes.size()/2);
  89. if (audioSampleRate != 0 && fSampleRates.contains(audioSampleRate))
  90. ui.cb_samplerate->setCurrentIndex(getIndexOfQDoubleListValue(fSampleRates, audioSampleRate));
  91. else if (isQDoubleListEqual(fSampleRates, SAMPLE_RATE_LIST))
  92. ui.cb_samplerate->setCurrentIndex(getIndexOfQDoubleListValue(SAMPLE_RATE_LIST, CARLA_DEFAULT_AUDIO_SAMPLE_RATE));
  93. else
  94. ui.cb_samplerate->setCurrentIndex(fSampleRates.size()/2);
  95. ui.cb_triple_buffer->setChecked(audioTripleBuffer && ui.cb_triple_buffer->isEnabled());
  96. }
  97. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
  98. };
  99. DriverSettingsW::DriverSettingsW(QWidget* const parent, const uint driverIndex, const QString driverName)
  100. : QDialog(parent),
  101. self(new PrivateData(this, driverIndex, driverName))
  102. {
  103. // ----------------------------------------------------------------------------------------------------------------
  104. // Set-up GUI
  105. for (const auto& name : self->fDeviceNames)
  106. self->ui.cb_device->addItem(name);
  107. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  108. // ----------------------------------------------------------------------------------------------------------------
  109. // Load settings
  110. self->loadSettings(this);
  111. // ----------------------------------------------------------------------------------------------------------------
  112. // Set-up connections
  113. connect(this, SIGNAL(accepted()), SLOT(slot_saveSettings()));
  114. connect(self->ui.b_panel, SIGNAL(clicked()), SLOT(slot_showDevicePanel()));
  115. connect(self->ui.cb_device, SIGNAL(currentIndexChanged(int)), SLOT(slot_updateDeviceInfo()));
  116. }
  117. DriverSettingsW::~DriverSettingsW()
  118. {
  119. delete self;
  120. }
  121. // --------------------------------------------------------------------------------------------------------------------
  122. void DriverSettingsW::slot_saveSettings()
  123. {
  124. QSafeSettings settings("falkTX", "Carla2");
  125. QString bufferSize = self->ui.cb_buffersize->currentText();
  126. QString sampleRate = self->ui.cb_samplerate->currentText();
  127. if (bufferSize == AUTOMATIC_OPTION)
  128. bufferSize = "0";
  129. if (sampleRate == AUTOMATIC_OPTION)
  130. sampleRate = "0";
  131. const QString prefix(QString("%1%2").arg(CARLA_KEY_ENGINE_DRIVER_PREFIX).arg(self->fDriverName));
  132. settings.setValue(QString("%1/Device").arg(prefix), self->ui.cb_device->currentText());
  133. settings.setValue(QString("%1/BufferSize").arg(prefix), bufferSize);
  134. settings.setValue(QString("%1/SampleRate").arg(prefix), sampleRate);
  135. settings.setValue(QString("%1/TripleBuffer").arg(prefix), self->ui.cb_triple_buffer->isChecked());
  136. }
  137. void DriverSettingsW::slot_showDevicePanel()
  138. {
  139. carla_show_engine_driver_device_control_panel(self->fDriverIndex, self->ui.cb_device->currentText().toUtf8());
  140. }
  141. void DriverSettingsW::slot_updateDeviceInfo()
  142. {
  143. const QString deviceName = self->ui.cb_device->currentText();
  144. const QString oldBufferSize = self->ui.cb_buffersize->currentText();
  145. const QString oldSampleRate = self->ui.cb_samplerate->currentText();
  146. self->ui.cb_buffersize->clear();
  147. self->ui.cb_samplerate->clear();
  148. self->fBufferSizes.clear();
  149. self->fSampleRates.clear();
  150. const EngineDriverDeviceInfo* const driverDeviceInfo = carla_get_engine_driver_device_info(self->fDriverIndex, deviceName.toUtf8());
  151. CARLA_SAFE_ASSERT_RETURN(driverDeviceInfo != nullptr,);
  152. const uint driverDeviceHints = driverDeviceInfo->hints;
  153. fillQUIntListFromUIntArray(self->fBufferSizes, driverDeviceInfo->bufferSizes);
  154. fillQDoubleListFromDoubleArray(self->fSampleRates, driverDeviceInfo->sampleRates);
  155. if (driverDeviceHints & ENGINE_DRIVER_DEVICE_CAN_TRIPLE_BUFFER)
  156. self->ui.cb_triple_buffer->setEnabled(true);
  157. else
  158. self->ui.cb_triple_buffer->setEnabled(false);
  159. if (driverDeviceHints & ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL)
  160. self->ui.b_panel->setEnabled(true);
  161. else
  162. self->ui.b_panel->setEnabled(false);
  163. if (self->fBufferSizes.size() > 0)
  164. {
  165. for (const uint bsize : self->fBufferSizes)
  166. {
  167. const QString sbsize(QString("%1").arg(bsize));
  168. self->ui.cb_buffersize->addItem(sbsize);
  169. if (oldBufferSize == sbsize)
  170. self->ui.cb_buffersize->setCurrentIndex(self->ui.cb_buffersize->count()-1);
  171. }
  172. }
  173. else
  174. {
  175. self->ui.cb_buffersize->addItem(AUTOMATIC_OPTION);
  176. self->ui.cb_buffersize->setCurrentIndex(0);
  177. }
  178. if (self->fSampleRates.size() > 0)
  179. {
  180. for (const double srate : self->fSampleRates)
  181. {
  182. const QString ssrate(QString("%1").arg(srate));
  183. self->ui.cb_samplerate->addItem(ssrate);
  184. if (oldSampleRate == ssrate)
  185. self->ui.cb_samplerate->setCurrentIndex(self->ui.cb_samplerate->count()-1);
  186. }
  187. }
  188. else
  189. {
  190. self->ui.cb_samplerate->addItem(AUTOMATIC_OPTION);
  191. self->ui.cb_samplerate->setCurrentIndex(0);
  192. }
  193. }
  194. // --------------------------------------------------------------------------------------------------------------------
  195. // Runtime Driver Settings
  196. struct RuntimeDriverSettingsW::PrivateData {
  197. Ui::DriverSettingsW ui;
  198. PrivateData(RuntimeDriverSettingsW* const self)
  199. : ui()
  200. {
  201. ui.setupUi(self);
  202. }
  203. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
  204. };
  205. RuntimeDriverSettingsW::RuntimeDriverSettingsW(QWidget* const parent)
  206. : QDialog(parent),
  207. self(new PrivateData(this))
  208. {
  209. const CarlaRuntimeEngineDriverDeviceInfo* const driverDeviceInfo = carla_get_runtime_engine_driver_device_info();
  210. QList<uint> bufferSizes;
  211. fillQUIntListFromUIntArray(bufferSizes, driverDeviceInfo->bufferSizes);
  212. QList<double> sampleRates;
  213. fillQDoubleListFromDoubleArray(sampleRates, driverDeviceInfo->sampleRates);
  214. // ----------------------------------------------------------------------------------------------------------------
  215. // Set-up GUI
  216. self->ui.cb_device->clear();
  217. self->ui.cb_buffersize->clear();
  218. self->ui.cb_samplerate->clear();
  219. self->ui.cb_triple_buffer->hide();
  220. self->ui.ico_restart->hide();
  221. self->ui.label_restart->hide();
  222. self->ui.layout_triple_buffer->takeAt(2);
  223. self->ui.layout_triple_buffer->takeAt(1);
  224. self->ui.layout_triple_buffer->takeAt(0);
  225. self->ui.verticalLayout->removeItem(self->ui.layout_triple_buffer);
  226. self->ui.layout_restart->takeAt(3);
  227. self->ui.layout_restart->takeAt(2);
  228. self->ui.layout_restart->takeAt(1);
  229. self->ui.layout_restart->takeAt(0);
  230. self->ui.verticalLayout->removeItem(self->ui.layout_restart);
  231. adjustSize();
  232. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  233. // ----------------------------------------------------------------------------------------------------------------
  234. // Load runtime settings
  235. if (carla_is_engine_running())
  236. {
  237. self->ui.cb_device->addItem(driverDeviceInfo->name);
  238. self->ui.cb_device->setCurrentIndex(0);
  239. self->ui.cb_device->setEnabled(false);
  240. }
  241. else
  242. {
  243. self->ui.cb_device->addItem(driverDeviceInfo->name);
  244. self->ui.cb_device->setCurrentIndex(0);
  245. }
  246. if (bufferSizes.size() > 0)
  247. {
  248. for (const uint bsize : bufferSizes)
  249. {
  250. const QString sbsize(QString("%1").arg(bsize));
  251. self->ui.cb_buffersize->addItem(sbsize);
  252. if (driverDeviceInfo->bufferSize == bsize)
  253. self->ui.cb_buffersize->setCurrentIndex(self->ui.cb_buffersize->count()-1);
  254. }
  255. }
  256. else
  257. {
  258. self->ui.cb_buffersize->addItem(AUTOMATIC_OPTION);
  259. self->ui.cb_buffersize->setCurrentIndex(0);
  260. }
  261. if ((driverDeviceInfo->hints & ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE) == 0x0)
  262. self->ui.cb_buffersize->setEnabled(false);
  263. if (sampleRates.size() > 0)
  264. {
  265. for (const double srate : sampleRates)
  266. {
  267. const QString ssrate(QString("%1").arg(srate));
  268. self->ui.cb_samplerate->addItem(ssrate);
  269. if (carla_isEqual(driverDeviceInfo->sampleRate, srate))
  270. self->ui.cb_samplerate->setCurrentIndex(self->ui.cb_samplerate->count()-1);
  271. }
  272. }
  273. else
  274. {
  275. self->ui.cb_samplerate->addItem(AUTOMATIC_OPTION);
  276. self->ui.cb_samplerate->setCurrentIndex(0);
  277. }
  278. if ((driverDeviceInfo->hints & ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE) == 0x0)
  279. self->ui.cb_samplerate->setEnabled(false);
  280. if ((driverDeviceInfo->hints & ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL) == 0x0)
  281. self->ui.b_panel->setEnabled(false);
  282. // ----------------------------------------------------------------------------------------------------------------
  283. // Set-up connections
  284. connect(self->ui.b_panel, SIGNAL(clicked()), SLOT(slot_showDevicePanel()));
  285. }
  286. RuntimeDriverSettingsW::~RuntimeDriverSettingsW()
  287. {
  288. delete self;
  289. }
  290. void RuntimeDriverSettingsW::getValues(QString& retAudioDevice, uint& retBufferSize, double& retSampleRate)
  291. {
  292. const QString bufferSize = self->ui.cb_buffersize->currentText();
  293. const QString sampleRate = self->ui.cb_samplerate->currentText();
  294. if (bufferSize == AUTOMATIC_OPTION)
  295. retBufferSize = 0;
  296. else
  297. retBufferSize = bufferSize.toUInt();
  298. if (sampleRate == AUTOMATIC_OPTION)
  299. retSampleRate = 0.0;
  300. else
  301. retSampleRate = sampleRate.toDouble();
  302. retAudioDevice = self->ui.cb_buffersize->currentText();
  303. }
  304. void RuntimeDriverSettingsW::slot_showDevicePanel()
  305. {
  306. carla_show_engine_device_control_panel();
  307. }
  308. // --------------------------------------------------------------------------------------------------------------------
  309. // Settings Dialog
  310. enum TabIndexes {
  311. TAB_INDEX_MAIN,
  312. TAB_INDEX_CANVAS,
  313. TAB_INDEX_ENGINE,
  314. TAB_INDEX_OSC,
  315. TAB_INDEX_FILEPATHS,
  316. TAB_INDEX_PLUGINPATHS,
  317. TAB_INDEX_WINE,
  318. TAB_INDEX_EXPERIMENTAL,
  319. TAB_INDEX_NONE,
  320. };
  321. enum FilePathIndexes {
  322. FILEPATH_INDEX_AUDIO,
  323. FILEPATH_INDEX_MIDI
  324. };
  325. enum PluginPathIndexes {
  326. PLUGINPATH_INDEX_LADSPA,
  327. PLUGINPATH_INDEX_DSSI,
  328. PLUGINPATH_INDEX_LV2,
  329. PLUGINPATH_INDEX_VST2,
  330. PLUGINPATH_INDEX_VST3,
  331. PLUGINPATH_INDEX_SF2,
  332. PLUGINPATH_INDEX_SFZ
  333. };
  334. /*
  335. Single and Multiple client mode is only for JACK,
  336. but we still want to match QComboBox index to backend defines,
  337. so add +2 pos padding if driverName != "JACK".
  338. */
  339. #define PROCESS_MODE_NON_JACK_PADDING 2
  340. struct CarlaSettingsW::PrivateData {
  341. Ui::CarlaSettingsW ui;
  342. const CarlaHost& host;
  343. PrivateData(CarlaSettingsW* const self, const CarlaHost& h)
  344. : ui(),
  345. host(h)
  346. {
  347. ui.setupUi(self);
  348. }
  349. void loadSettings()
  350. {
  351. {
  352. const QSafeSettings settings;
  353. // --------------------------------------------------------------------------------------------------------
  354. // Main
  355. ui.ch_main_show_logs->setChecked(host.showLogs);
  356. ui.ch_engine_uis_always_on_top->setChecked(host.uisAlwaysOnTop);
  357. ui.le_main_proj_folder->setText(settings.valueString(CARLA_KEY_MAIN_PROJECT_FOLDER,
  358. CARLA_DEFAULT_MAIN_PROJECT_FOLDER));
  359. ui.ch_main_theme_pro->setChecked(settings.valueBool(CARLA_KEY_MAIN_USE_PRO_THEME,
  360. CARLA_DEFAULT_MAIN_USE_PRO_THEME) && ui.group_main_theme->isEnabled());
  361. ui.cb_main_theme_color->setCurrentIndex(ui.cb_main_theme_color->findText(settings.valueString(CARLA_KEY_MAIN_PRO_THEME_COLOR,
  362. CARLA_DEFAULT_MAIN_PRO_THEME_COLOR)));
  363. ui.sb_main_refresh_interval->setValue(settings.valueIntPositive(CARLA_KEY_MAIN_REFRESH_INTERVAL,
  364. CARLA_DEFAULT_MAIN_REFRESH_INTERVAL));
  365. ui.ch_main_confirm_exit->setChecked(settings.valueBool(CARLA_KEY_MAIN_CONFIRM_EXIT,
  366. CARLA_DEFAULT_MAIN_CONFIRM_EXIT));
  367. // --------------------------------------------------------------------------------------------------------
  368. // Canvas
  369. ui.cb_canvas_theme->setCurrentIndex(ui.cb_canvas_theme->findText(settings.valueString(CARLA_KEY_CANVAS_THEME,
  370. CARLA_DEFAULT_CANVAS_THEME)));
  371. ui.cb_canvas_size->setCurrentIndex(ui.cb_canvas_size->findText(settings.valueString(CARLA_KEY_CANVAS_SIZE,
  372. CARLA_DEFAULT_CANVAS_SIZE)));
  373. ui.cb_canvas_bezier_lines->setChecked(settings.valueBool(CARLA_KEY_CANVAS_USE_BEZIER_LINES,
  374. CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES));
  375. ui.cb_canvas_hide_groups->setChecked(settings.valueBool(CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS,
  376. CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS));
  377. ui.cb_canvas_auto_select->setChecked(settings.valueBool(CARLA_KEY_CANVAS_AUTO_SELECT_ITEMS,
  378. CARLA_DEFAULT_CANVAS_AUTO_SELECT_ITEMS));
  379. ui.cb_canvas_eyecandy->setChecked(settings.valueBool(CARLA_KEY_CANVAS_EYE_CANDY,
  380. CARLA_DEFAULT_CANVAS_EYE_CANDY));
  381. ui.cb_canvas_fancy_eyecandy->setChecked(settings.valueBool(CARLA_KEY_CANVAS_FANCY_EYE_CANDY,
  382. CARLA_DEFAULT_CANVAS_FANCY_EYE_CANDY));
  383. ui.cb_canvas_use_opengl->setChecked(settings.valueBool(CARLA_KEY_CANVAS_USE_OPENGL,
  384. CARLA_DEFAULT_CANVAS_USE_OPENGL) && ui.cb_canvas_use_opengl->isEnabled());
  385. ui.cb_canvas_render_aa->setCheckState(settings.valueCheckState(CARLA_KEY_CANVAS_ANTIALIASING,
  386. CARLA_DEFAULT_CANVAS_ANTIALIASING));
  387. ui.cb_canvas_render_hq_aa->setChecked(settings.valueBool(CARLA_KEY_CANVAS_HQ_ANTIALIASING,
  388. CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING) && ui.cb_canvas_render_hq_aa->isEnabled());
  389. ui.cb_canvas_full_repaints->setChecked(settings.valueBool(CARLA_KEY_CANVAS_FULL_REPAINTS,
  390. CARLA_DEFAULT_CANVAS_FULL_REPAINTS));
  391. ui.cb_canvas_inline_displays->setChecked(settings.valueBool(CARLA_KEY_CANVAS_INLINE_DISPLAYS,
  392. CARLA_DEFAULT_CANVAS_INLINE_DISPLAYS));
  393. }
  394. // ------------------------------------------------------------------------------------------------------------
  395. const QSafeSettings settings("falkTX", "Carla2");
  396. // ------------------------------------------------------------------------------------------------------------
  397. // Main
  398. ui.ch_main_experimental->setChecked(host.experimental);
  399. if (! host.experimental)
  400. {
  401. ui.lw_page->hideRow(TAB_INDEX_EXPERIMENTAL);
  402. ui.lw_page->hideRow(TAB_INDEX_WINE);
  403. }
  404. else if (! host.showWineBridges)
  405. {
  406. ui.lw_page->hideRow(TAB_INDEX_WINE);
  407. }
  408. // ------------------------------------------------------------------------------------------------------------
  409. // Engine
  410. QString audioDriver;
  411. if (host.isPlugin)
  412. {
  413. audioDriver = "Plugin";
  414. ui.cb_engine_audio_driver->setCurrentIndex(0);
  415. }
  416. else if (host.audioDriverForced.isNotEmpty())
  417. {
  418. audioDriver = host.audioDriverForced;
  419. ui.cb_engine_audio_driver->setCurrentIndex(0);
  420. }
  421. else
  422. {
  423. audioDriver = settings.valueString(CARLA_KEY_ENGINE_AUDIO_DRIVER, CARLA_DEFAULT_AUDIO_DRIVER);
  424. bool found = false;
  425. for (int i=0; i < ui.cb_engine_audio_driver->count(); ++i)
  426. {
  427. if (ui.cb_engine_audio_driver->itemText(i) == audioDriver)
  428. {
  429. found = true;
  430. ui.cb_engine_audio_driver->setCurrentIndex(i);
  431. break;
  432. }
  433. }
  434. if (! found)
  435. ui.cb_engine_audio_driver->setCurrentIndex(-1);
  436. }
  437. if (audioDriver == "JACK")
  438. ui.sw_engine_process_mode->setCurrentIndex(0);
  439. else
  440. ui.sw_engine_process_mode->setCurrentIndex(1);
  441. ui.tb_engine_driver_config->setEnabled(host.audioDriverForced.isNotEmpty() && ! host.isPlugin);
  442. ui.cb_engine_process_mode_jack->setCurrentIndex(host.nextProcessMode);
  443. if (host.nextProcessMode >= PROCESS_MODE_NON_JACK_PADDING)
  444. ui.cb_engine_process_mode_other->setCurrentIndex(host.nextProcessMode-PROCESS_MODE_NON_JACK_PADDING);
  445. else
  446. ui.cb_engine_process_mode_other->setCurrentIndex(0);
  447. ui.sb_engine_max_params->setValue(static_cast<int>(host.maxParameters));
  448. ui.ch_engine_manage_uis->setChecked(host.manageUIs);
  449. ui.ch_engine_prefer_ui_bridges->setChecked(host.preferUIBridges);
  450. ui.sb_engine_ui_bridges_timeout->setValue(host.uiBridgesTimeout);
  451. ui.ch_engine_force_stereo->setChecked(host.forceStereo || ! ui.ch_engine_force_stereo->isEnabled());
  452. ui.ch_engine_prefer_plugin_bridges->setChecked(host.preferPluginBridges);
  453. ui.ch_exp_export_lv2->setChecked(host.exportLV2);
  454. ui.cb_exp_plugin_bridges->setChecked(host.showPluginBridges);
  455. ui.ch_exp_wine_bridges->setChecked(host.showWineBridges);
  456. // ------------------------------------------------------------------------------------------------------------
  457. // OSC
  458. ui.ch_osc_enable->setChecked(settings.valueBool(CARLA_KEY_OSC_ENABLED,
  459. CARLA_DEFAULT_OSC_ENABLED));
  460. ui.group_osc_tcp_port->setChecked(settings.valueBool(CARLA_KEY_OSC_TCP_PORT_ENABLED,
  461. CARLA_DEFAULT_OSC_TCP_PORT_ENABLED));
  462. ui.group_osc_udp_port->setChecked(settings.valueBool(CARLA_KEY_OSC_UDP_PORT_ENABLED,
  463. CARLA_DEFAULT_OSC_UDP_PORT_ENABLED));
  464. ui.sb_osc_tcp_port_number->setValue(settings.valueIntPositive(CARLA_KEY_OSC_TCP_PORT_NUMBER,
  465. CARLA_DEFAULT_OSC_TCP_PORT_NUMBER));
  466. ui.sb_osc_udp_port_number->setValue(settings.valueIntPositive(CARLA_KEY_OSC_UDP_PORT_NUMBER,
  467. CARLA_DEFAULT_OSC_UDP_PORT_NUMBER));
  468. if (settings.valueBool(CARLA_KEY_OSC_TCP_PORT_RANDOM, CARLA_DEFAULT_OSC_TCP_PORT_RANDOM))
  469. {
  470. ui.rb_osc_tcp_port_specific->setChecked(false);
  471. ui.rb_osc_tcp_port_random->setChecked(true);
  472. }
  473. else
  474. {
  475. ui.rb_osc_tcp_port_random->setChecked(false);
  476. ui.rb_osc_tcp_port_specific->setChecked(true);
  477. }
  478. if (settings.valueBool(CARLA_KEY_OSC_UDP_PORT_RANDOM, CARLA_DEFAULT_OSC_UDP_PORT_RANDOM))
  479. {
  480. ui.rb_osc_udp_port_specific->setChecked(false);
  481. ui.rb_osc_udp_port_random->setChecked(true);
  482. }
  483. else
  484. {
  485. ui.rb_osc_udp_port_random->setChecked(false);
  486. ui.rb_osc_udp_port_specific->setChecked(true);
  487. }
  488. // ------------------------------------------------------------------------------------------------------------
  489. // File Paths
  490. QStringList audioPaths = settings.valueStringList(CARLA_KEY_PATHS_AUDIO, CARLA_DEFAULT_FILE_PATH_AUDIO);
  491. QStringList midiPaths = settings.valueStringList(CARLA_KEY_PATHS_MIDI, CARLA_DEFAULT_FILE_PATH_MIDI);
  492. audioPaths.sort();
  493. midiPaths.sort();
  494. for (const QString& audioPath : audioPaths)
  495. {
  496. if (audioPath.isEmpty()) continue;
  497. ui.lw_files_audio->addItem(audioPath);
  498. }
  499. for (const QString& midiPath : midiPaths)
  500. {
  501. if (midiPath.isEmpty()) continue;
  502. ui.lw_files_midi->addItem(midiPath);
  503. }
  504. // ------------------------------------------------------------------------------------------------------------
  505. // Plugin Paths
  506. QStringList ladspas = settings.valueStringList(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH);
  507. QStringList dssis = settings.valueStringList(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH);
  508. QStringList lv2s = settings.valueStringList(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH);
  509. QStringList vst2s = settings.valueStringList(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH);
  510. QStringList vst3s = settings.valueStringList(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH);
  511. QStringList sf2s = settings.valueStringList(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH);
  512. QStringList sfzs = settings.valueStringList(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH);
  513. ladspas.sort();
  514. dssis.sort();
  515. lv2s.sort();
  516. vst2s.sort();
  517. vst3s.sort();
  518. sf2s.sort();
  519. sfzs.sort();
  520. for (const QString& ladspa : ladspas)
  521. {
  522. if (ladspa.isEmpty()) continue;
  523. ui.lw_ladspa->addItem(ladspa);
  524. }
  525. for (const QString& dssi : dssis)
  526. {
  527. if (dssi.isEmpty()) continue;
  528. ui.lw_dssi->addItem(dssi);
  529. }
  530. for (const QString& lv2 : lv2s)
  531. {
  532. if (lv2.isEmpty()) continue;
  533. ui.lw_lv2->addItem(lv2);
  534. }
  535. for (const QString& vst2 : vst2s)
  536. {
  537. if (vst2.isEmpty()) continue;
  538. ui.lw_vst->addItem(vst2);
  539. }
  540. for (const QString& vst3 : vst3s)
  541. {
  542. if (vst3.isEmpty()) continue;
  543. ui.lw_vst3->addItem(vst3);
  544. }
  545. for (const QString& sf2 : sf2s)
  546. {
  547. if (sf2.isEmpty()) continue;
  548. ui.lw_sf2->addItem(sf2);
  549. }
  550. for (const QString& sfz : sfzs)
  551. {
  552. if (sfz.isEmpty()) continue;
  553. ui.lw_sfz->addItem(sfz);
  554. }
  555. // ------------------------------------------------------------------------------------------------------------
  556. // Wine
  557. ui.le_wine_exec->setText(settings.valueString(CARLA_KEY_WINE_EXECUTABLE,
  558. CARLA_DEFAULT_WINE_EXECUTABLE));
  559. ui.cb_wine_prefix_detect->setChecked(settings.valueBool(CARLA_KEY_WINE_AUTO_PREFIX,
  560. CARLA_DEFAULT_WINE_AUTO_PREFIX));
  561. ui.le_wine_prefix_fallback->setText(settings.valueString(CARLA_KEY_WINE_FALLBACK_PREFIX,
  562. CARLA_DEFAULT_WINE_FALLBACK_PREFIX));
  563. ui.group_wine_realtime->setChecked(settings.valueBool(CARLA_KEY_WINE_RT_PRIO_ENABLED,
  564. CARLA_DEFAULT_WINE_RT_PRIO_ENABLED));
  565. ui.sb_wine_base_prio->setValue(settings.valueIntPositive(CARLA_KEY_WINE_BASE_RT_PRIO,
  566. CARLA_DEFAULT_WINE_BASE_RT_PRIO));
  567. ui.sb_wine_server_prio->setValue(settings.valueIntPositive(CARLA_KEY_WINE_SERVER_RT_PRIO,
  568. CARLA_DEFAULT_WINE_SERVER_RT_PRIO));
  569. // ------------------------------------------------------------------------------------------------------------
  570. // Experimental
  571. ui.ch_exp_jack_apps->setChecked(settings.valueBool(CARLA_KEY_EXPERIMENTAL_JACK_APPS,
  572. CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS));
  573. ui.ch_exp_export_lv2->setChecked(settings.valueBool(CARLA_KEY_EXPERIMENTAL_EXPORT_LV2,
  574. CARLA_DEFAULT_EXPERIMENTAL_LV2_EXPORT));
  575. ui.ch_exp_load_lib_global->setChecked(settings.valueBool(CARLA_KEY_EXPERIMENTAL_LOAD_LIB_GLOBAL,
  576. CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL));
  577. ui.ch_exp_prevent_bad_behaviour->setChecked(settings.valueBool(CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR,
  578. CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR));
  579. }
  580. void resetExperimentalSettings()
  581. {
  582. // Forever experimental
  583. ui.cb_exp_plugin_bridges->setChecked(CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES);
  584. ui.ch_exp_wine_bridges->setChecked(CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES);
  585. ui.ch_exp_jack_apps->setChecked(CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS);
  586. ui.ch_exp_export_lv2->setChecked(CARLA_DEFAULT_EXPERIMENTAL_LV2_EXPORT);
  587. ui.ch_exp_load_lib_global->setChecked(CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL);
  588. ui.ch_exp_prevent_bad_behaviour->setChecked(CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR);
  589. // Temporary, until stable
  590. ui.cb_canvas_fancy_eyecandy->setChecked(CARLA_DEFAULT_CANVAS_FANCY_EYE_CANDY);
  591. ui.cb_canvas_use_opengl->setChecked(CARLA_DEFAULT_CANVAS_USE_OPENGL and ui.cb_canvas_use_opengl->isEnabled());
  592. ui.cb_canvas_render_hq_aa->setChecked(CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING and ui.cb_canvas_render_hq_aa->isEnabled());
  593. ui.cb_canvas_inline_displays->setChecked(CARLA_DEFAULT_CANVAS_INLINE_DISPLAYS);
  594. ui.ch_engine_force_stereo->setChecked(CARLA_DEFAULT_FORCE_STEREO);
  595. ui.ch_engine_prefer_plugin_bridges->setChecked(CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES);
  596. }
  597. };
  598. CarlaSettingsW::CarlaSettingsW(QWidget* const parent, const CarlaHost& host, const bool hasCanvas, const bool hasCanvasGL)
  599. : QDialog(parent),
  600. self(new PrivateData(this, host))
  601. {
  602. // ----------------------------------------------------------------------------------------------------------------
  603. // Set-up GUI
  604. self->ui.lw_page->setFixedWidth(48 + 6*3 + fontMetricsHorizontalAdvance(self->ui.lw_page->fontMetrics(), " Experimental "));
  605. for (uint i=0; i < carla_get_engine_driver_count(); ++i)
  606. self->ui.cb_engine_audio_driver->addItem(carla_get_engine_driver_name(i));
  607. for (uint i=0; i < Theme::THEME_MAX; ++i)
  608. self->ui.cb_canvas_theme->addItem(getThemeName((Theme::List)i));
  609. #ifdef CARLA_OS_MAC
  610. self->ui.group_main_theme->setEnabled(false);
  611. self->ui.group_main_theme->setVisible(false);
  612. #endif
  613. #ifdef CARLA_OS_Win
  614. if (true)
  615. #else
  616. if (host.isControl)
  617. #endif
  618. {
  619. self->ui.ch_main_show_logs->setEnabled(false);
  620. self->ui.ch_main_show_logs->setVisible(false);
  621. }
  622. if (host.isControl)
  623. {
  624. self->ui.lw_page->hideRow(TAB_INDEX_ENGINE);
  625. self->ui.lw_page->hideRow(TAB_INDEX_FILEPATHS);
  626. self->ui.lw_page->hideRow(TAB_INDEX_PLUGINPATHS);
  627. self->ui.ch_exp_export_lv2->hide();
  628. self->ui.group_experimental_engine->hide();
  629. }
  630. else if (! hasCanvas)
  631. {
  632. self->ui.lw_page->hideRow(TAB_INDEX_CANVAS);
  633. }
  634. else if (! hasCanvasGL)
  635. {
  636. self->ui.cb_canvas_use_opengl->setEnabled(false);
  637. self->ui.cb_canvas_render_hq_aa->setEnabled(false);
  638. }
  639. if (host.isPlugin)
  640. self->ui.cb_engine_audio_driver->setEnabled(false);
  641. if (host.audioDriverForced.isNotEmpty())
  642. {
  643. self->ui.cb_engine_audio_driver->setEnabled(false);
  644. self->ui.tb_engine_driver_config->setEnabled(false);
  645. }
  646. if (host.processModeForced)
  647. {
  648. self->ui.cb_engine_process_mode_jack->setEnabled(false);
  649. self->ui.cb_engine_process_mode_other->setEnabled(false);
  650. if (host.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  651. self->ui.ch_engine_force_stereo->setEnabled(false);
  652. }
  653. if (host.isControl || host.isPlugin)
  654. {
  655. self->ui.ch_main_confirm_exit->hide();
  656. self->ui.ch_exp_load_lib_global->hide();
  657. self->ui.lw_page->hideRow(TAB_INDEX_OSC);
  658. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  659. }
  660. #ifndef CARLA_OS_LINUX
  661. self->ui.ch_exp_wine_bridges->setVisible(false);
  662. self->ui.ch_exp_jack_apps->setVisible(false);
  663. self->ui.ch_exp_prevent_bad_behaviour->setVisible(false);
  664. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  665. #endif
  666. #ifndef CARLA_OS_MAC
  667. self->ui.label_engine_ui_bridges_mac_note->setVisible(false);
  668. #endif
  669. // FIXME, not implemented yet
  670. self->ui.ch_engine_uis_always_on_top->hide();
  671. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  672. // ----------------------------------------------------------------------------------------------------------------
  673. // Load settings
  674. self->loadSettings();
  675. // ----------------------------------------------------------------------------------------------------------------
  676. // Set-up connections
  677. connect(this, SIGNAL(accepted()), SLOT(slot_saveSettings()));
  678. connect(self->ui.buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(slot_resetSettings()));
  679. connect(self->ui.b_main_proj_folder_open, SIGNAL(clicked()), SLOT(slot_getAndSetProjectPath()));
  680. connect(self->ui.cb_engine_audio_driver, SIGNAL(currentIndexChanged(int)), SLOT(slot_engineAudioDriverChanged()));
  681. connect(self->ui.tb_engine_driver_config, SIGNAL(clicked()), SLOT(slot_showAudioDriverSettings()));
  682. connect(self->ui.b_paths_add, SIGNAL(clicked()), SLOT(slot_addPluginPath()));
  683. connect(self->ui.b_paths_remove, SIGNAL(clicked()), SLOT(slot_removePluginPath()));
  684. connect(self->ui.b_paths_change, SIGNAL(clicked()), SLOT(slot_changePluginPath()));
  685. connect(self->ui.cb_paths, SIGNAL(currentIndexChanged(int)), SLOT(slot_pluginPathTabChanged(int)));
  686. connect(self->ui.lw_ladspa, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  687. connect(self->ui.lw_dssi, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  688. connect(self->ui.lw_lv2, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  689. connect(self->ui.lw_vst, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  690. connect(self->ui.lw_vst3, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  691. connect(self->ui.lw_sf2, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  692. connect(self->ui.lw_sfz, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  693. connect(self->ui.b_filepaths_add, SIGNAL(clicked()), SLOT(slot_addFilePath()));
  694. connect(self->ui.b_filepaths_remove, SIGNAL(clicked()), SLOT(slot_removeFilePath()));
  695. connect(self->ui.b_filepaths_change, SIGNAL(clicked()), SLOT(slot_changeFilePath()));
  696. connect(self->ui.cb_filepaths, SIGNAL(currentIndexChanged(int)), SLOT(slot_filePathTabChanged(int)));
  697. connect(self->ui.lw_files_audio, SIGNAL(currentRowChanged(int)), SLOT(slot_filePathRowChanged(int)));
  698. connect(self->ui.lw_files_midi, SIGNAL(currentRowChanged(int)), SLOT(slot_filePathRowChanged(int)));
  699. connect(self->ui.ch_main_experimental, SIGNAL(toggled(bool)), SLOT(slot_enableExperimental(bool)));
  700. connect(self->ui.ch_exp_wine_bridges, SIGNAL(toggled(bool)), SLOT(slot_enableWineBridges(bool)));
  701. connect(self->ui.cb_exp_plugin_bridges, SIGNAL(toggled(bool)), SLOT(slot_pluginBridgesToggled(bool)));
  702. connect(self->ui.cb_canvas_eyecandy, SIGNAL(toggled(bool)), SLOT(slot_canvasEyeCandyToggled(bool)));
  703. connect(self->ui.cb_canvas_fancy_eyecandy, SIGNAL(toggled(bool)), SLOT(slot_canvasFancyEyeCandyToggled(bool)));
  704. connect(self->ui.cb_canvas_use_opengl, SIGNAL(toggled(bool)), SLOT(slot_canvasOpenGLToggled(bool)));
  705. // ----------------------------------------------------------------------------------------------------------------
  706. // Post-connect setup
  707. self->ui.lw_ladspa->setCurrentRow(0);
  708. self->ui.lw_dssi->setCurrentRow(0);
  709. self->ui.lw_lv2->setCurrentRow(0);
  710. self->ui.lw_vst->setCurrentRow(0);
  711. self->ui.lw_vst3->setCurrentRow(0);
  712. self->ui.lw_sf2->setCurrentRow(0);
  713. self->ui.lw_sfz->setCurrentRow(0);
  714. self->ui.lw_files_audio->setCurrentRow(0);
  715. self->ui.lw_files_midi->setCurrentRow(0);
  716. self->ui.lw_page->setCurrentCell(0, 0);
  717. slot_filePathTabChanged(0);
  718. slot_pluginPathTabChanged(0);
  719. adjustSize();
  720. }
  721. CarlaSettingsW::~CarlaSettingsW()
  722. {
  723. delete self;
  724. }
  725. // --------------------------------------------------------------------------------------------------------------------
  726. void CarlaSettingsW::slot_saveSettings()
  727. {
  728. // TODO
  729. }
  730. void CarlaSettingsW::slot_resetSettings()
  731. {
  732. // TODO
  733. }
  734. // --------------------------------------------------------------------------------------------------------------------
  735. void CarlaSettingsW::slot_enableExperimental(const bool toggled)
  736. {
  737. if (toggled)
  738. {
  739. self->ui.lw_page->showRow(TAB_INDEX_EXPERIMENTAL);
  740. if (self->ui.ch_exp_wine_bridges->isChecked() and not self->host.isControl)
  741. self->ui.lw_page->showRow(TAB_INDEX_WINE);
  742. }
  743. else
  744. {
  745. self->ui.lw_page->hideRow(TAB_INDEX_EXPERIMENTAL);
  746. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  747. }
  748. }
  749. void CarlaSettingsW::slot_enableWineBridges(const bool toggled)
  750. {
  751. if (toggled && ! self->host.isControl)
  752. self->ui.lw_page->showRow(TAB_INDEX_WINE);
  753. else
  754. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  755. }
  756. void CarlaSettingsW::slot_pluginBridgesToggled(const bool toggled)
  757. {
  758. if (! toggled)
  759. {
  760. self->ui.ch_exp_wine_bridges->setChecked(false);
  761. self->ui.ch_engine_prefer_plugin_bridges->setChecked(false);
  762. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  763. }
  764. }
  765. void CarlaSettingsW::slot_canvasEyeCandyToggled(const bool toggled)
  766. {
  767. if (! toggled)
  768. {
  769. // disable fancy eyecandy too
  770. self->ui.cb_canvas_fancy_eyecandy->setChecked(false);
  771. }
  772. }
  773. void CarlaSettingsW::slot_canvasFancyEyeCandyToggled(const bool toggled)
  774. {
  775. if (! toggled)
  776. {
  777. // make sure normal eyecandy is enabled too
  778. self->ui.cb_canvas_eyecandy->setChecked(true);
  779. }
  780. }
  781. void CarlaSettingsW::slot_canvasOpenGLToggled(const bool toggled)
  782. {
  783. if (! toggled)
  784. {
  785. // uncheck GL specific option
  786. self->ui.cb_canvas_render_hq_aa->setChecked(false);
  787. }
  788. }
  789. // --------------------------------------------------------------------------------------------------------------------
  790. void CarlaSettingsW::slot_getAndSetProjectPath()
  791. {
  792. // FIXME?
  793. getAndSetPath(this, self->ui.le_main_proj_folder);
  794. }
  795. // --------------------------------------------------------------------------------------------------------------------
  796. void CarlaSettingsW::slot_engineAudioDriverChanged()
  797. {
  798. if (self->ui.cb_engine_audio_driver->currentText() == "JACK")
  799. self->ui.sw_engine_process_mode->setCurrentIndex(0);
  800. else
  801. self->ui.sw_engine_process_mode->setCurrentIndex(1);
  802. }
  803. void CarlaSettingsW::slot_showAudioDriverSettings()
  804. {
  805. const int driverIndex = self->ui.cb_engine_audio_driver->currentIndex();
  806. const QString driverName = self->ui.cb_engine_audio_driver->currentText();
  807. CARLA_SAFE_ASSERT_RETURN(driverIndex >= 0,);
  808. DriverSettingsW(this, static_cast<uint>(driverIndex), driverName).exec();
  809. }
  810. // --------------------------------------------------------------------------------------------------------------------
  811. void CarlaSettingsW::slot_addPluginPath()
  812. {
  813. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), "", QFileDialog::ShowDirsOnly);
  814. if (newPath.isEmpty())
  815. return;
  816. switch (self->ui.tw_paths->currentIndex())
  817. {
  818. case PLUGINPATH_INDEX_LADSPA:
  819. self->ui.lw_ladspa->addItem(newPath);
  820. break;
  821. case PLUGINPATH_INDEX_DSSI:
  822. self->ui.lw_dssi->addItem(newPath);
  823. break;
  824. case PLUGINPATH_INDEX_LV2:
  825. self->ui.lw_lv2->addItem(newPath);
  826. break;
  827. case PLUGINPATH_INDEX_VST2:
  828. self->ui.lw_vst->addItem(newPath);
  829. break;
  830. case PLUGINPATH_INDEX_VST3:
  831. self->ui.lw_vst3->addItem(newPath);
  832. break;
  833. case PLUGINPATH_INDEX_SF2:
  834. self->ui.lw_sf2->addItem(newPath);
  835. break;
  836. case PLUGINPATH_INDEX_SFZ:
  837. self->ui.lw_sfz->addItem(newPath);
  838. break;
  839. }
  840. }
  841. void CarlaSettingsW::slot_removePluginPath()
  842. {
  843. switch (self->ui.tw_paths->currentIndex())
  844. {
  845. case PLUGINPATH_INDEX_LADSPA:
  846. self->ui.lw_ladspa->takeItem(self->ui.lw_ladspa->currentRow());
  847. break;
  848. case PLUGINPATH_INDEX_DSSI:
  849. self->ui.lw_dssi->takeItem(self->ui.lw_dssi->currentRow());
  850. break;
  851. case PLUGINPATH_INDEX_LV2:
  852. self->ui.lw_lv2->takeItem(self->ui.lw_lv2->currentRow());
  853. break;
  854. case PLUGINPATH_INDEX_VST2:
  855. self->ui.lw_vst->takeItem(self->ui.lw_vst->currentRow());
  856. break;
  857. case PLUGINPATH_INDEX_VST3:
  858. self->ui.lw_vst3->takeItem(self->ui.lw_vst3->currentRow());
  859. break;
  860. case PLUGINPATH_INDEX_SF2:
  861. self->ui.lw_sf2->takeItem(self->ui.lw_sf2->currentRow());
  862. break;
  863. case PLUGINPATH_INDEX_SFZ:
  864. self->ui.lw_sfz->takeItem(self->ui.lw_sfz->currentRow());
  865. break;
  866. }
  867. }
  868. void CarlaSettingsW::slot_changePluginPath()
  869. {
  870. const int curIndex = self->ui.tw_paths->currentIndex();
  871. QString currentPath;
  872. switch (curIndex)
  873. {
  874. case PLUGINPATH_INDEX_LADSPA:
  875. currentPath = self->ui.lw_ladspa->currentItem()->text();
  876. break;
  877. case PLUGINPATH_INDEX_DSSI:
  878. currentPath = self->ui.lw_dssi->currentItem()->text();
  879. break;
  880. case PLUGINPATH_INDEX_LV2:
  881. currentPath = self->ui.lw_lv2->currentItem()->text();
  882. break;
  883. case PLUGINPATH_INDEX_VST2:
  884. currentPath = self->ui.lw_vst->currentItem()->text();
  885. break;
  886. case PLUGINPATH_INDEX_VST3:
  887. currentPath = self->ui.lw_vst3->currentItem()->text();
  888. break;
  889. case PLUGINPATH_INDEX_SF2:
  890. currentPath = self->ui.lw_sf2->currentItem()->text();
  891. break;
  892. case PLUGINPATH_INDEX_SFZ:
  893. currentPath = self->ui.lw_sfz->currentItem()->text();
  894. break;
  895. }
  896. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), currentPath, QFileDialog::ShowDirsOnly);
  897. if (newPath.isEmpty())
  898. return;
  899. switch (curIndex)
  900. {
  901. case PLUGINPATH_INDEX_LADSPA:
  902. self->ui.lw_ladspa->currentItem()->setText(newPath);
  903. break;
  904. case PLUGINPATH_INDEX_DSSI:
  905. self->ui.lw_dssi->currentItem()->setText(newPath);
  906. break;
  907. case PLUGINPATH_INDEX_LV2:
  908. self->ui.lw_lv2->currentItem()->setText(newPath);
  909. break;
  910. case PLUGINPATH_INDEX_VST2:
  911. self->ui.lw_vst->currentItem()->setText(newPath);
  912. break;
  913. case PLUGINPATH_INDEX_VST3:
  914. self->ui.lw_vst3->currentItem()->setText(newPath);
  915. break;
  916. case PLUGINPATH_INDEX_SF2:
  917. self->ui.lw_sf2->currentItem()->setText(newPath);
  918. break;
  919. case PLUGINPATH_INDEX_SFZ:
  920. self->ui.lw_sfz->currentItem()->setText(newPath);
  921. break;
  922. }
  923. }
  924. // --------------------------------------------------------------------------------------------------------------------
  925. void CarlaSettingsW::slot_pluginPathTabChanged(const int index)
  926. {
  927. int row;
  928. switch (index)
  929. {
  930. case PLUGINPATH_INDEX_LADSPA:
  931. row = self->ui.lw_ladspa->currentRow();
  932. break;
  933. case PLUGINPATH_INDEX_DSSI:
  934. row = self->ui.lw_dssi->currentRow();
  935. break;
  936. case PLUGINPATH_INDEX_LV2:
  937. row = self->ui.lw_lv2->currentRow();
  938. break;
  939. case PLUGINPATH_INDEX_VST2:
  940. row = self->ui.lw_vst->currentRow();
  941. break;
  942. case PLUGINPATH_INDEX_VST3:
  943. row = self->ui.lw_vst3->currentRow();
  944. break;
  945. case PLUGINPATH_INDEX_SF2:
  946. row = self->ui.lw_sf2->currentRow();
  947. break;
  948. case PLUGINPATH_INDEX_SFZ:
  949. row = self->ui.lw_sfz->currentRow();
  950. break;
  951. default:
  952. row = -1;
  953. break;
  954. }
  955. slot_pluginPathRowChanged(row);
  956. }
  957. void CarlaSettingsW::slot_pluginPathRowChanged(const int row)
  958. {
  959. const bool check = bool(row >= 0);
  960. self->ui.b_paths_remove->setEnabled(check);
  961. self->ui.b_paths_change->setEnabled(check);
  962. }
  963. // --------------------------------------------------------------------------------------------------------------------
  964. void CarlaSettingsW::slot_addFilePath()
  965. {
  966. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), "", QFileDialog::ShowDirsOnly);
  967. if (newPath.isEmpty())
  968. return;
  969. switch (self->ui.tw_filepaths->currentIndex())
  970. {
  971. case FILEPATH_INDEX_AUDIO:
  972. self->ui.lw_files_audio->addItem(newPath);
  973. break;
  974. case FILEPATH_INDEX_MIDI:
  975. self->ui.lw_files_midi->addItem(newPath);
  976. break;
  977. }
  978. }
  979. void CarlaSettingsW::slot_removeFilePath()
  980. {
  981. switch (self->ui.tw_filepaths->currentIndex())
  982. {
  983. case FILEPATH_INDEX_AUDIO:
  984. self->ui.lw_files_audio->takeItem(self->ui.lw_files_audio->currentRow());
  985. break;
  986. case FILEPATH_INDEX_MIDI:
  987. self->ui.lw_files_midi->takeItem(self->ui.lw_files_midi->currentRow());
  988. break;
  989. }
  990. }
  991. void CarlaSettingsW::slot_changeFilePath()
  992. {
  993. const int curIndex = self->ui.tw_filepaths->currentIndex();
  994. QString currentPath;
  995. switch (curIndex)
  996. {
  997. case FILEPATH_INDEX_AUDIO:
  998. currentPath = self->ui.lw_files_audio->currentItem()->text();
  999. break;
  1000. case FILEPATH_INDEX_MIDI:
  1001. currentPath = self->ui.lw_files_midi->currentItem()->text();
  1002. break;
  1003. }
  1004. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), currentPath, QFileDialog::ShowDirsOnly);
  1005. if (newPath.isEmpty())
  1006. return;
  1007. switch (curIndex)
  1008. {
  1009. case FILEPATH_INDEX_AUDIO:
  1010. self->ui.lw_files_audio->currentItem()->setText(newPath);
  1011. break;
  1012. case FILEPATH_INDEX_MIDI:
  1013. self->ui.lw_files_midi->currentItem()->setText(newPath);
  1014. break;
  1015. }
  1016. }
  1017. // --------------------------------------------------------------------------------------------------------------------
  1018. void CarlaSettingsW::slot_filePathTabChanged(const int index)
  1019. {
  1020. int row;
  1021. switch (index)
  1022. {
  1023. case FILEPATH_INDEX_AUDIO:
  1024. row = self->ui.lw_files_audio->currentRow();
  1025. break;
  1026. case FILEPATH_INDEX_MIDI:
  1027. row = self->ui.lw_files_midi->currentRow();
  1028. break;
  1029. default:
  1030. row = -1;
  1031. break;
  1032. }
  1033. slot_filePathRowChanged(row);
  1034. }
  1035. void CarlaSettingsW::slot_filePathRowChanged(const int row)
  1036. {
  1037. const bool check = bool(row >= 0);
  1038. self->ui.b_filepaths_remove->setEnabled(check);
  1039. self->ui.b_filepaths_change->setEnabled(check);
  1040. }
  1041. // --------------------------------------------------------------------------------------------------------------------