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.

1272 lines
46KB

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