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.

1302 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. #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. #if 0
  475. // ------------------------------------------------------------------------------------------------------------
  476. // File Paths
  477. audioPaths = settings.value(CARLA_KEY_PATHS_AUDIO, CARLA_DEFAULT_FILE_PATH_AUDIO, list)
  478. midiPaths = settings.value(CARLA_KEY_PATHS_MIDI, CARLA_DEFAULT_FILE_PATH_MIDI, list)
  479. audioPaths.sort()
  480. midiPaths.sort()
  481. for audioPath in audioPaths:
  482. if not audioPath: continue
  483. ui.lw_files_audio.addItem(audioPath)
  484. for midiPath in midiPaths:
  485. if not midiPath: continue
  486. ui.lw_files_midi.addItem(midiPath)
  487. // ------------------------------------------------------------------------------------------------------------
  488. // Plugin Paths
  489. ladspas = settings.value(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH, list)
  490. dssis = settings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH, list)
  491. lv2s = settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH, list)
  492. vst2s = settings.value(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH, list)
  493. vst3s = settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list)
  494. sf2s = settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list)
  495. sfzs = settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list)
  496. ladspas.sort()
  497. dssis.sort()
  498. lv2s.sort()
  499. vst2s.sort()
  500. vst3s.sort()
  501. sf2s.sort()
  502. sfzs.sort()
  503. for ladspa in ladspas:
  504. if not ladspa: continue
  505. ui.lw_ladspa.addItem(ladspa)
  506. for dssi in dssis:
  507. if not dssi: continue
  508. ui.lw_dssi.addItem(dssi)
  509. for lv2 in lv2s:
  510. if not lv2: continue
  511. ui.lw_lv2.addItem(lv2)
  512. for vst2 in vst2s:
  513. if not vst2: continue
  514. ui.lw_vst.addItem(vst2)
  515. for vst3 in vst3s:
  516. if not vst3: continue
  517. ui.lw_vst3.addItem(vst3)
  518. for sf2 in sf2s:
  519. if not sf2: continue
  520. ui.lw_sf2.addItem(sf2)
  521. for sfz in sfzs:
  522. if not sfz: continue
  523. ui.lw_sfz.addItem(sfz)
  524. // ------------------------------------------------------------------------------------------------------------
  525. // Wine
  526. ui.le_wine_exec.setText(settings.value(CARLA_KEY_WINE_EXECUTABLE,
  527. CARLA_DEFAULT_WINE_EXECUTABLE,
  528. str))
  529. ui.cb_wine_prefix_detect.setChecked(settings.value(CARLA_KEY_WINE_AUTO_PREFIX,
  530. CARLA_DEFAULT_WINE_AUTO_PREFIX,
  531. bool))
  532. ui.le_wine_prefix_fallback.setText(settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX,
  533. CARLA_DEFAULT_WINE_FALLBACK_PREFIX,
  534. str))
  535. ui.group_wine_realtime.setChecked(settings.value(CARLA_KEY_WINE_RT_PRIO_ENABLED,
  536. CARLA_DEFAULT_WINE_RT_PRIO_ENABLED,
  537. bool))
  538. ui.sb_wine_base_prio.setValue(settings.value(CARLA_KEY_WINE_BASE_RT_PRIO,
  539. CARLA_DEFAULT_WINE_BASE_RT_PRIO,
  540. int))
  541. ui.sb_wine_server_prio.setValue(settings.value(CARLA_KEY_WINE_SERVER_RT_PRIO,
  542. CARLA_DEFAULT_WINE_SERVER_RT_PRIO,
  543. int))
  544. // ------------------------------------------------------------------------------------------------------------
  545. // Experimental
  546. ui.ch_exp_jack_apps.setChecked(settings.value(CARLA_KEY_EXPERIMENTAL_JACK_APPS,
  547. CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS,
  548. bool))
  549. ui.ch_exp_export_lv2.setChecked(settings.value(CARLA_KEY_EXPERIMENTAL_EXPORT_LV2,
  550. CARLA_DEFAULT_EXPERIMENTAL_LV2_EXPORT,
  551. bool))
  552. ui.ch_exp_load_lib_global.setChecked(settings.value(CARLA_KEY_EXPERIMENTAL_LOAD_LIB_GLOBAL,
  553. CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL,
  554. bool))
  555. ui.ch_exp_prevent_bad_behaviour.setChecked(settings.value(CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR,
  556. CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR,
  557. bool))
  558. #endif
  559. }
  560. void resetExperimentalSettings()
  561. {
  562. // Forever experimental
  563. ui.cb_exp_plugin_bridges->setChecked(CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES);
  564. ui.ch_exp_wine_bridges->setChecked(CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES);
  565. ui.ch_exp_jack_apps->setChecked(CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS);
  566. ui.ch_exp_export_lv2->setChecked(CARLA_DEFAULT_EXPERIMENTAL_LV2_EXPORT);
  567. ui.ch_exp_load_lib_global->setChecked(CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL);
  568. ui.ch_exp_prevent_bad_behaviour->setChecked(CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR);
  569. // Temporary, until stable
  570. ui.cb_canvas_fancy_eyecandy->setChecked(CARLA_DEFAULT_CANVAS_FANCY_EYE_CANDY);
  571. ui.cb_canvas_use_opengl->setChecked(CARLA_DEFAULT_CANVAS_USE_OPENGL and ui.cb_canvas_use_opengl->isEnabled());
  572. ui.cb_canvas_render_hq_aa->setChecked(CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING and ui.cb_canvas_render_hq_aa->isEnabled());
  573. ui.cb_canvas_inline_displays->setChecked(CARLA_DEFAULT_CANVAS_INLINE_DISPLAYS);
  574. ui.ch_engine_force_stereo->setChecked(CARLA_DEFAULT_FORCE_STEREO);
  575. ui.ch_engine_prefer_plugin_bridges->setChecked(CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES);
  576. }
  577. };
  578. CarlaSettingsW::CarlaSettingsW(QWidget* const parent, const CarlaHost& host, const bool hasCanvas, const bool hasCanvasGL)
  579. : QDialog(parent),
  580. self(new PrivateData(this, host))
  581. {
  582. // ----------------------------------------------------------------------------------------------------------------
  583. // Set-up GUI
  584. self->ui.lw_page->setFixedWidth(48 + 6*3 + fontMetricsHorizontalAdvance(self->ui.lw_page->fontMetrics(), " Experimental "));
  585. for (uint i=0; i < carla_get_engine_driver_count(); ++i)
  586. self->ui.cb_engine_audio_driver->addItem(carla_get_engine_driver_name(i));
  587. for (uint i=0; i < Theme::THEME_MAX; ++i)
  588. self->ui.cb_canvas_theme->addItem(getThemeName((Theme::List)i));
  589. #ifdef CARLA_OS_MAC
  590. self->ui.group_main_theme->setEnabled(false);
  591. self->ui.group_main_theme->setVisible(false);
  592. #endif
  593. #ifdef CARLA_OS_Win
  594. if (true)
  595. #else
  596. if (host.isControl)
  597. #endif
  598. {
  599. self->ui.ch_main_show_logs->setEnabled(false);
  600. self->ui.ch_main_show_logs->setVisible(false);
  601. }
  602. if (host.isControl)
  603. {
  604. self->ui.lw_page->hideRow(TAB_INDEX_ENGINE);
  605. self->ui.lw_page->hideRow(TAB_INDEX_FILEPATHS);
  606. self->ui.lw_page->hideRow(TAB_INDEX_PLUGINPATHS);
  607. self->ui.ch_exp_export_lv2->hide();
  608. self->ui.group_experimental_engine->hide();
  609. }
  610. else if (! hasCanvas)
  611. {
  612. self->ui.lw_page->hideRow(TAB_INDEX_CANVAS);
  613. }
  614. else if (! hasCanvasGL)
  615. {
  616. self->ui.cb_canvas_use_opengl->setEnabled(false);
  617. self->ui.cb_canvas_render_hq_aa->setEnabled(false);
  618. }
  619. if (host.isPlugin)
  620. self->ui.cb_engine_audio_driver->setEnabled(false);
  621. if (host.audioDriverForced.isNotEmpty())
  622. {
  623. self->ui.cb_engine_audio_driver->setEnabled(false);
  624. self->ui.tb_engine_driver_config->setEnabled(false);
  625. }
  626. if (host.processModeForced)
  627. {
  628. self->ui.cb_engine_process_mode_jack->setEnabled(false);
  629. self->ui.cb_engine_process_mode_other->setEnabled(false);
  630. if (host.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  631. self->ui.ch_engine_force_stereo->setEnabled(false);
  632. }
  633. if (host.isControl || host.isPlugin)
  634. {
  635. self->ui.ch_main_confirm_exit->hide();
  636. self->ui.ch_exp_load_lib_global->hide();
  637. self->ui.lw_page->hideRow(TAB_INDEX_OSC);
  638. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  639. }
  640. #ifndef CARLA_OS_LINUX
  641. self->ui.ch_exp_wine_bridges->setVisible(false);
  642. self->ui.ch_exp_jack_apps->setVisible(false);
  643. self->ui.ch_exp_prevent_bad_behaviour->setVisible(false);
  644. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  645. #endif
  646. #ifndef CARLA_OS_MAC
  647. self->ui.label_engine_ui_bridges_mac_note->setVisible(false);
  648. #endif
  649. // FIXME, not implemented yet
  650. self->ui.ch_engine_uis_always_on_top->hide();
  651. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  652. // ----------------------------------------------------------------------------------------------------------------
  653. // Load settings
  654. self->loadSettings();
  655. // ----------------------------------------------------------------------------------------------------------------
  656. // Set-up connections
  657. connect(this, SIGNAL(accepted()), SLOT(slot_saveSettings()));
  658. connect(self->ui.buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(slot_resetSettings()));
  659. connect(self->ui.b_main_proj_folder_open, SIGNAL(clicked()), SLOT(slot_getAndSetProjectPath()));
  660. connect(self->ui.cb_engine_audio_driver, SIGNAL(currentIndexChanged(int)), SLOT(slot_engineAudioDriverChanged()));
  661. connect(self->ui.tb_engine_driver_config, SIGNAL(clicked()), SLOT(slot_showAudioDriverSettings()));
  662. connect(self->ui.b_paths_add, SIGNAL(clicked()), SLOT(slot_addPluginPath()));
  663. connect(self->ui.b_paths_remove, SIGNAL(clicked()), SLOT(slot_removePluginPath()));
  664. connect(self->ui.b_paths_change, SIGNAL(clicked()), SLOT(slot_changePluginPath()));
  665. connect(self->ui.cb_paths, SIGNAL(currentIndexChanged(int)), SLOT(slot_pluginPathTabChanged(int)));
  666. connect(self->ui.lw_ladspa, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  667. connect(self->ui.lw_dssi, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  668. connect(self->ui.lw_lv2, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  669. connect(self->ui.lw_vst, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  670. connect(self->ui.lw_vst3, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  671. connect(self->ui.lw_sf2, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  672. connect(self->ui.lw_sfz, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
  673. connect(self->ui.b_filepaths_add, SIGNAL(clicked()), SLOT(slot_addFilePath()));
  674. connect(self->ui.b_filepaths_remove, SIGNAL(clicked()), SLOT(slot_removeFilePath()));
  675. connect(self->ui.b_filepaths_change, SIGNAL(clicked()), SLOT(slot_changeFilePath()));
  676. connect(self->ui.cb_filepaths, SIGNAL(currentIndexChanged(int)), SLOT(slot_filePathTabChanged(int)));
  677. connect(self->ui.lw_files_audio, SIGNAL(currentRowChanged(int)), SLOT(slot_filePathRowChanged(int)));
  678. connect(self->ui.lw_files_midi, SIGNAL(currentRowChanged(int)), SLOT(slot_filePathRowChanged(int)));
  679. connect(self->ui.ch_main_experimental, SIGNAL(toggled(bool)), SLOT(slot_enableExperimental(bool)));
  680. connect(self->ui.ch_exp_wine_bridges, SIGNAL(toggled(bool)), SLOT(slot_enableWineBridges(bool)));
  681. connect(self->ui.cb_exp_plugin_bridges, SIGNAL(toggled(bool)), SLOT(slot_pluginBridgesToggled(bool)));
  682. connect(self->ui.cb_canvas_eyecandy, SIGNAL(toggled(bool)), SLOT(slot_canvasEyeCandyToggled(bool)));
  683. connect(self->ui.cb_canvas_fancy_eyecandy, SIGNAL(toggled(bool)), SLOT(slot_canvasFancyEyeCandyToggled(bool)));
  684. connect(self->ui.cb_canvas_use_opengl, SIGNAL(toggled(bool)), SLOT(slot_canvasOpenGLToggled(bool)));
  685. // ----------------------------------------------------------------------------------------------------------------
  686. // Post-connect setup
  687. self->ui.lw_ladspa->setCurrentRow(0);
  688. self->ui.lw_dssi->setCurrentRow(0);
  689. self->ui.lw_lv2->setCurrentRow(0);
  690. self->ui.lw_vst->setCurrentRow(0);
  691. self->ui.lw_vst3->setCurrentRow(0);
  692. self->ui.lw_sf2->setCurrentRow(0);
  693. self->ui.lw_sfz->setCurrentRow(0);
  694. self->ui.lw_files_audio->setCurrentRow(0);
  695. self->ui.lw_files_midi->setCurrentRow(0);
  696. self->ui.lw_page->setCurrentCell(0, 0);
  697. slot_filePathTabChanged(0);
  698. slot_pluginPathTabChanged(0);
  699. adjustSize();
  700. }
  701. CarlaSettingsW::~CarlaSettingsW()
  702. {
  703. delete self;
  704. }
  705. // --------------------------------------------------------------------------------------------------------------------
  706. void CarlaSettingsW::slot_saveSettings()
  707. {
  708. }
  709. void CarlaSettingsW::slot_resetSettings()
  710. {
  711. }
  712. // --------------------------------------------------------------------------------------------------------------------
  713. void CarlaSettingsW::slot_enableExperimental(const bool toggled)
  714. {
  715. if (toggled)
  716. {
  717. self->ui.lw_page->showRow(TAB_INDEX_EXPERIMENTAL);
  718. if (self->ui.ch_exp_wine_bridges->isChecked() and not self->host.isControl)
  719. self->ui.lw_page->showRow(TAB_INDEX_WINE);
  720. }
  721. else
  722. {
  723. self->ui.lw_page->hideRow(TAB_INDEX_EXPERIMENTAL);
  724. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  725. }
  726. }
  727. void CarlaSettingsW::slot_enableWineBridges(const bool toggled)
  728. {
  729. if (toggled && ! self->host.isControl)
  730. self->ui.lw_page->showRow(TAB_INDEX_WINE);
  731. else
  732. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  733. }
  734. void CarlaSettingsW::slot_pluginBridgesToggled(const bool toggled)
  735. {
  736. if (! toggled)
  737. {
  738. self->ui.ch_exp_wine_bridges->setChecked(false);
  739. self->ui.ch_engine_prefer_plugin_bridges->setChecked(false);
  740. self->ui.lw_page->hideRow(TAB_INDEX_WINE);
  741. }
  742. }
  743. void CarlaSettingsW::slot_canvasEyeCandyToggled(const bool toggled)
  744. {
  745. if (! toggled)
  746. {
  747. // disable fancy eyecandy too
  748. self->ui.cb_canvas_fancy_eyecandy->setChecked(false);
  749. }
  750. }
  751. void CarlaSettingsW::slot_canvasFancyEyeCandyToggled(const bool toggled)
  752. {
  753. if (! toggled)
  754. {
  755. // make sure normal eyecandy is enabled too
  756. self->ui.cb_canvas_eyecandy->setChecked(true);
  757. }
  758. }
  759. void CarlaSettingsW::slot_canvasOpenGLToggled(const bool toggled)
  760. {
  761. if (! toggled)
  762. {
  763. // uncheck GL specific option
  764. self->ui.cb_canvas_render_hq_aa->setChecked(false);
  765. }
  766. }
  767. // --------------------------------------------------------------------------------------------------------------------
  768. void CarlaSettingsW::slot_getAndSetProjectPath()
  769. {
  770. // FIXME?
  771. getAndSetPath(this, self->ui.le_main_proj_folder);
  772. }
  773. // --------------------------------------------------------------------------------------------------------------------
  774. void CarlaSettingsW::slot_engineAudioDriverChanged()
  775. {
  776. if (self->ui.cb_engine_audio_driver->currentText() == "JACK")
  777. self->ui.sw_engine_process_mode->setCurrentIndex(0);
  778. else
  779. self->ui.sw_engine_process_mode->setCurrentIndex(1);
  780. }
  781. void CarlaSettingsW::slot_showAudioDriverSettings()
  782. {
  783. const int driverIndex = self->ui.cb_engine_audio_driver->currentIndex();
  784. const QString driverName = self->ui.cb_engine_audio_driver->currentText();
  785. CARLA_SAFE_ASSERT_RETURN(driverIndex >= 0,);
  786. DriverSettingsW(this, static_cast<uint>(driverIndex), driverName).exec();
  787. }
  788. // --------------------------------------------------------------------------------------------------------------------
  789. void CarlaSettingsW::slot_addPluginPath()
  790. {
  791. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), "", QFileDialog::ShowDirsOnly);
  792. if (newPath.isEmpty())
  793. return;
  794. switch (self->ui.tw_paths->currentIndex())
  795. {
  796. case PLUGINPATH_INDEX_LADSPA:
  797. self->ui.lw_ladspa->addItem(newPath);
  798. break;
  799. case PLUGINPATH_INDEX_DSSI:
  800. self->ui.lw_dssi->addItem(newPath);
  801. break;
  802. case PLUGINPATH_INDEX_LV2:
  803. self->ui.lw_lv2->addItem(newPath);
  804. break;
  805. case PLUGINPATH_INDEX_VST2:
  806. self->ui.lw_vst->addItem(newPath);
  807. break;
  808. case PLUGINPATH_INDEX_VST3:
  809. self->ui.lw_vst3->addItem(newPath);
  810. break;
  811. case PLUGINPATH_INDEX_SF2:
  812. self->ui.lw_sf2->addItem(newPath);
  813. break;
  814. case PLUGINPATH_INDEX_SFZ:
  815. self->ui.lw_sfz->addItem(newPath);
  816. break;
  817. }
  818. }
  819. void CarlaSettingsW::slot_removePluginPath()
  820. {
  821. switch (self->ui.tw_paths->currentIndex())
  822. {
  823. case PLUGINPATH_INDEX_LADSPA:
  824. self->ui.lw_ladspa->takeItem(self->ui.lw_ladspa->currentRow());
  825. break;
  826. case PLUGINPATH_INDEX_DSSI:
  827. self->ui.lw_dssi->takeItem(self->ui.lw_dssi->currentRow());
  828. break;
  829. case PLUGINPATH_INDEX_LV2:
  830. self->ui.lw_lv2->takeItem(self->ui.lw_lv2->currentRow());
  831. break;
  832. case PLUGINPATH_INDEX_VST2:
  833. self->ui.lw_vst->takeItem(self->ui.lw_vst->currentRow());
  834. break;
  835. case PLUGINPATH_INDEX_VST3:
  836. self->ui.lw_vst3->takeItem(self->ui.lw_vst3->currentRow());
  837. break;
  838. case PLUGINPATH_INDEX_SF2:
  839. self->ui.lw_sf2->takeItem(self->ui.lw_sf2->currentRow());
  840. break;
  841. case PLUGINPATH_INDEX_SFZ:
  842. self->ui.lw_sfz->takeItem(self->ui.lw_sfz->currentRow());
  843. break;
  844. }
  845. }
  846. void CarlaSettingsW::slot_changePluginPath()
  847. {
  848. const int curIndex = self->ui.tw_paths->currentIndex();
  849. QString currentPath;
  850. switch (curIndex)
  851. {
  852. case PLUGINPATH_INDEX_LADSPA:
  853. currentPath = self->ui.lw_ladspa->currentItem()->text();
  854. break;
  855. case PLUGINPATH_INDEX_DSSI:
  856. currentPath = self->ui.lw_dssi->currentItem()->text();
  857. break;
  858. case PLUGINPATH_INDEX_LV2:
  859. currentPath = self->ui.lw_lv2->currentItem()->text();
  860. break;
  861. case PLUGINPATH_INDEX_VST2:
  862. currentPath = self->ui.lw_vst->currentItem()->text();
  863. break;
  864. case PLUGINPATH_INDEX_VST3:
  865. currentPath = self->ui.lw_vst3->currentItem()->text();
  866. break;
  867. case PLUGINPATH_INDEX_SF2:
  868. currentPath = self->ui.lw_sf2->currentItem()->text();
  869. break;
  870. case PLUGINPATH_INDEX_SFZ:
  871. currentPath = self->ui.lw_sfz->currentItem()->text();
  872. break;
  873. }
  874. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), currentPath, QFileDialog::ShowDirsOnly);
  875. if (newPath.isEmpty())
  876. return;
  877. switch (curIndex)
  878. {
  879. case PLUGINPATH_INDEX_LADSPA:
  880. self->ui.lw_ladspa->currentItem()->setText(newPath);
  881. break;
  882. case PLUGINPATH_INDEX_DSSI:
  883. self->ui.lw_dssi->currentItem()->setText(newPath);
  884. break;
  885. case PLUGINPATH_INDEX_LV2:
  886. self->ui.lw_lv2->currentItem()->setText(newPath);
  887. break;
  888. case PLUGINPATH_INDEX_VST2:
  889. self->ui.lw_vst->currentItem()->setText(newPath);
  890. break;
  891. case PLUGINPATH_INDEX_VST3:
  892. self->ui.lw_vst3->currentItem()->setText(newPath);
  893. break;
  894. case PLUGINPATH_INDEX_SF2:
  895. self->ui.lw_sf2->currentItem()->setText(newPath);
  896. break;
  897. case PLUGINPATH_INDEX_SFZ:
  898. self->ui.lw_sfz->currentItem()->setText(newPath);
  899. break;
  900. }
  901. }
  902. // --------------------------------------------------------------------------------------------------------------------
  903. void CarlaSettingsW::slot_pluginPathTabChanged(const int index)
  904. {
  905. int row;
  906. switch (index)
  907. {
  908. case PLUGINPATH_INDEX_LADSPA:
  909. row = self->ui.lw_ladspa->currentRow();
  910. break;
  911. case PLUGINPATH_INDEX_DSSI:
  912. row = self->ui.lw_dssi->currentRow();
  913. break;
  914. case PLUGINPATH_INDEX_LV2:
  915. row = self->ui.lw_lv2->currentRow();
  916. break;
  917. case PLUGINPATH_INDEX_VST2:
  918. row = self->ui.lw_vst->currentRow();
  919. break;
  920. case PLUGINPATH_INDEX_VST3:
  921. row = self->ui.lw_vst3->currentRow();
  922. break;
  923. case PLUGINPATH_INDEX_SF2:
  924. row = self->ui.lw_sf2->currentRow();
  925. break;
  926. case PLUGINPATH_INDEX_SFZ:
  927. row = self->ui.lw_sfz->currentRow();
  928. break;
  929. default:
  930. row = -1;
  931. break;
  932. }
  933. slot_pluginPathRowChanged(row);
  934. }
  935. void CarlaSettingsW::slot_pluginPathRowChanged(const int row)
  936. {
  937. const bool check = bool(row >= 0);
  938. self->ui.b_paths_remove->setEnabled(check);
  939. self->ui.b_paths_change->setEnabled(check);
  940. }
  941. // --------------------------------------------------------------------------------------------------------------------
  942. void CarlaSettingsW::slot_addFilePath()
  943. {
  944. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), "", QFileDialog::ShowDirsOnly);
  945. if (newPath.isEmpty())
  946. return;
  947. switch (self->ui.tw_filepaths->currentIndex())
  948. {
  949. case FILEPATH_INDEX_AUDIO:
  950. self->ui.lw_files_audio->addItem(newPath);
  951. break;
  952. case FILEPATH_INDEX_MIDI:
  953. self->ui.lw_files_midi->addItem(newPath);
  954. break;
  955. }
  956. }
  957. void CarlaSettingsW::slot_removeFilePath()
  958. {
  959. switch (self->ui.tw_filepaths->currentIndex())
  960. {
  961. case FILEPATH_INDEX_AUDIO:
  962. self->ui.lw_files_audio->takeItem(self->ui.lw_files_audio->currentRow());
  963. break;
  964. case FILEPATH_INDEX_MIDI:
  965. self->ui.lw_files_midi->takeItem(self->ui.lw_files_midi->currentRow());
  966. break;
  967. }
  968. }
  969. void CarlaSettingsW::slot_changeFilePath()
  970. {
  971. const int curIndex = self->ui.tw_filepaths->currentIndex();
  972. QString currentPath;
  973. switch (curIndex)
  974. {
  975. case FILEPATH_INDEX_AUDIO:
  976. currentPath = self->ui.lw_files_audio->currentItem()->text();
  977. break;
  978. case FILEPATH_INDEX_MIDI:
  979. currentPath = self->ui.lw_files_midi->currentItem()->text();
  980. break;
  981. }
  982. const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), currentPath, QFileDialog::ShowDirsOnly);
  983. if (newPath.isEmpty())
  984. return;
  985. switch (curIndex)
  986. {
  987. case FILEPATH_INDEX_AUDIO:
  988. self->ui.lw_files_audio->currentItem()->setText(newPath);
  989. break;
  990. case FILEPATH_INDEX_MIDI:
  991. self->ui.lw_files_midi->currentItem()->setText(newPath);
  992. break;
  993. }
  994. }
  995. // --------------------------------------------------------------------------------------------------------------------
  996. void CarlaSettingsW::slot_filePathTabChanged(const int index)
  997. {
  998. int row;
  999. switch (index)
  1000. {
  1001. case FILEPATH_INDEX_AUDIO:
  1002. row = self->ui.lw_files_audio->currentRow();
  1003. break;
  1004. case FILEPATH_INDEX_MIDI:
  1005. row = self->ui.lw_files_midi->currentRow();
  1006. break;
  1007. default:
  1008. row = -1;
  1009. break;
  1010. }
  1011. slot_filePathRowChanged(row);
  1012. }
  1013. void CarlaSettingsW::slot_filePathRowChanged(const int row)
  1014. {
  1015. const bool check = bool(row >= 0);
  1016. self->ui.b_filepaths_remove->setEnabled(check);
  1017. self->ui.b_filepaths_change->setEnabled(check);
  1018. }
  1019. // --------------------------------------------------------------------------------------------------------------------
  1020. // Main
  1021. #include "carla_app.hpp"
  1022. #include "carla_shared.hpp"
  1023. int main(int argc, char* argv[])
  1024. {
  1025. // ----------------------------------------------------------------------------------------------------------------
  1026. // Read CLI args
  1027. const QString initName(handleInitialCommandLineArguments(argc, argv));
  1028. // ----------------------------------------------------------------------------------------------------------------
  1029. // App initialization
  1030. const CarlaApplication app("Carla2-Settings", argc, argv);
  1031. // ----------------------------------------------------------------------------------------------------------------
  1032. // Init host backend
  1033. CarlaHost& host = initHost(initName, false, false, true);
  1034. loadHostSettings(host);
  1035. // ----------------------------------------------------------------------------------------------------------------
  1036. // Create GUI
  1037. CarlaSettingsW gui(nullptr, host, true, true);
  1038. // ----------------------------------------------------------------------------------------------------------------
  1039. // Show GUI
  1040. gui.show();
  1041. // ----------------------------------------------------------------------------------------------------------------
  1042. // App-Loop
  1043. return app.exec();
  1044. }