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.

550 lines
20KB

  1. /*
  2. * Common Carla 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. #ifndef CARLA_SHARED_HPP_INCLUDED
  18. #define CARLA_SHARED_HPP_INCLUDED
  19. #include "../../utils/CarlaUtils.hpp"
  20. //---------------------------------------------------------------------------------------------------------------------
  21. #include <QtCore/QSettings>
  22. #include <QtCore/QStringList>
  23. #include <QtGui/QFontMetrics>
  24. class QMainWindow;
  25. //---------------------------------------------------------------------------------------------------------------------
  26. // Static MIDI CC list
  27. static const char* const* const MIDI_CC_LIST = {
  28. "0x01 Modulation",
  29. "0x02 Breath",
  30. "0x03 (Undefined)",
  31. "0x04 Foot",
  32. "0x05 Portamento",
  33. "0x07 Volume",
  34. "0x08 Balance",
  35. "0x09 (Undefined)",
  36. "0x0A Pan",
  37. "0x0B Expression",
  38. "0x0C FX Control 1",
  39. "0x0D FX Control 2",
  40. "0x0E (Undefined)",
  41. "0x0F (Undefined)",
  42. "0x10 General Purpose 1",
  43. "0x11 General Purpose 2",
  44. "0x12 General Purpose 3",
  45. "0x13 General Purpose 4",
  46. "0x14 (Undefined)",
  47. "0x15 (Undefined)",
  48. "0x16 (Undefined)",
  49. "0x17 (Undefined)",
  50. "0x18 (Undefined)",
  51. "0x19 (Undefined)",
  52. "0x1A (Undefined)",
  53. "0x1B (Undefined)",
  54. "0x1C (Undefined)",
  55. "0x1D (Undefined)",
  56. "0x1E (Undefined)",
  57. "0x1F (Undefined)",
  58. "0x46 Control 1 [Variation]",
  59. "0x47 Control 2 [Timbre]",
  60. "0x48 Control 3 [Release]",
  61. "0x49 Control 4 [Attack]",
  62. "0x4A Control 5 [Brightness]",
  63. "0x4B Control 6 [Decay]",
  64. "0x4C Control 7 [Vib Rate]",
  65. "0x4D Control 8 [Vib Depth]",
  66. "0x4E Control 9 [Vib Delay]",
  67. "0x4F Control 10 [Undefined]",
  68. "0x50 General Purpose 5",
  69. "0x51 General Purpose 6",
  70. "0x52 General Purpose 7",
  71. "0x53 General Purpose 8",
  72. "0x54 Portamento Control",
  73. "0x5B FX 1 Depth [Reverb]",
  74. "0x5C FX 2 Depth [Tremolo]",
  75. "0x5D FX 3 Depth [Chorus]",
  76. "0x5E FX 4 Depth [Detune]",
  77. "0x5F FX 5 Depth [Phaser]",
  78. nullptr
  79. };
  80. //---------------------------------------------------------------------------------------------------------------------
  81. // Carla Settings keys
  82. #define CARLA_KEY_MAIN_PROJECT_FOLDER "Main/ProjectFolder" /* str */
  83. #define CARLA_KEY_MAIN_USE_PRO_THEME "Main/UseProTheme" /* bool */
  84. #define CARLA_KEY_MAIN_PRO_THEME_COLOR "Main/ProThemeColor" /* str */
  85. #define CARLA_KEY_MAIN_REFRESH_INTERVAL "Main/RefreshInterval" /* int */
  86. #define CARLA_KEY_MAIN_CONFIRM_EXIT "Main/ConfirmExit" /* bool */
  87. #define CARLA_KEY_MAIN_SHOW_LOGS "Main/ShowLogs" /* bool */
  88. #define CARLA_KEY_MAIN_EXPERIMENTAL "Main/Experimental" /* bool */
  89. #define CARLA_KEY_CANVAS_THEME "Canvas/Theme" /* str */
  90. #define CARLA_KEY_CANVAS_SIZE "Canvas/Size" /* str "NxN" */
  91. #define CARLA_KEY_CANVAS_USE_BEZIER_LINES "Canvas/UseBezierLines" /* bool */
  92. #define CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS "Canvas/AutoHideGroups" /* bool */
  93. #define CARLA_KEY_CANVAS_AUTO_SELECT_ITEMS "Canvas/AutoSelectItems" /* bool */
  94. #define CARLA_KEY_CANVAS_EYE_CANDY "Canvas/EyeCandy2" /* bool */
  95. #define CARLA_KEY_CANVAS_FANCY_EYE_CANDY "Canvas/FancyEyeCandy" /* bool */
  96. #define CARLA_KEY_CANVAS_USE_OPENGL "Canvas/UseOpenGL" /* bool */
  97. #define CARLA_KEY_CANVAS_ANTIALIASING "Canvas/Antialiasing" /* enum */
  98. #define CARLA_KEY_CANVAS_HQ_ANTIALIASING "Canvas/HQAntialiasing" /* bool */
  99. #define CARLA_KEY_CANVAS_INLINE_DISPLAYS "Canvas/InlineDisplays" /* bool */
  100. #define CARLA_KEY_CANVAS_FULL_REPAINTS "Canvas/FullRepaints" /* bool */
  101. #define CARLA_KEY_ENGINE_DRIVER_PREFIX "Engine/Driver-"
  102. #define CARLA_KEY_ENGINE_AUDIO_DRIVER "Engine/AudioDriver" /* str */
  103. #define CARLA_KEY_ENGINE_PROCESS_MODE "Engine/ProcessMode" /* enum */
  104. #define CARLA_KEY_ENGINE_TRANSPORT_MODE "Engine/TransportMode" /* enum */
  105. #define CARLA_KEY_ENGINE_TRANSPORT_EXTRA "Engine/TransportExtra" /* str */
  106. #define CARLA_KEY_ENGINE_FORCE_STEREO "Engine/ForceStereo" /* bool */
  107. #define CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES "Engine/PreferPluginBridges" /* bool */
  108. #define CARLA_KEY_ENGINE_PREFER_UI_BRIDGES "Engine/PreferUiBridges" /* bool */
  109. #define CARLA_KEY_ENGINE_MANAGE_UIS "Engine/ManageUIs" /* bool */
  110. #define CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP "Engine/UIsAlwaysOnTop" /* bool */
  111. #define CARLA_KEY_ENGINE_MAX_PARAMETERS "Engine/MaxParameters" /* int */
  112. #define CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT "Engine/UiBridgesTimeout" /* int */
  113. #define CARLA_KEY_OSC_ENABLED "OSC/Enabled"
  114. #define CARLA_KEY_OSC_TCP_PORT_ENABLED "OSC/TCPEnabled"
  115. #define CARLA_KEY_OSC_TCP_PORT_NUMBER "OSC/TCPNumber"
  116. #define CARLA_KEY_OSC_TCP_PORT_RANDOM "OSC/TCPRandom"
  117. #define CARLA_KEY_OSC_UDP_PORT_ENABLED "OSC/UDPEnabled"
  118. #define CARLA_KEY_OSC_UDP_PORT_NUMBER "OSC/UDPNumber"
  119. #define CARLA_KEY_OSC_UDP_PORT_RANDOM "OSC/UDPRandom"
  120. #define CARLA_KEY_PATHS_AUDIO "Paths/Audio"
  121. #define CARLA_KEY_PATHS_MIDI "Paths/MIDI"
  122. #define CARLA_KEY_PATHS_LADSPA "Paths/LADSPA"
  123. #define CARLA_KEY_PATHS_DSSI "Paths/DSSI"
  124. #define CARLA_KEY_PATHS_LV2 "Paths/LV2"
  125. #define CARLA_KEY_PATHS_VST2 "Paths/VST2"
  126. #define CARLA_KEY_PATHS_VST3 "Paths/VST3"
  127. #define CARLA_KEY_PATHS_SF2 "Paths/SF2"
  128. #define CARLA_KEY_PATHS_SFZ "Paths/SFZ"
  129. #define CARLA_KEY_WINE_EXECUTABLE "Wine/Executable" /* str */
  130. #define CARLA_KEY_WINE_AUTO_PREFIX "Wine/AutoPrefix" /* bool */
  131. #define CARLA_KEY_WINE_FALLBACK_PREFIX "Wine/FallbackPrefix" /* str */
  132. #define CARLA_KEY_WINE_RT_PRIO_ENABLED "Wine/RtPrioEnabled" /* bool */
  133. #define CARLA_KEY_WINE_BASE_RT_PRIO "Wine/BaseRtPrio" /* int */
  134. #define CARLA_KEY_WINE_SERVER_RT_PRIO "Wine/ServerRtPrio" /* int */
  135. #define CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES "Experimental/PluginBridges" /* bool */
  136. #define CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES "Experimental/WineBridges" /* bool */
  137. #define CARLA_KEY_EXPERIMENTAL_JACK_APPS "Experimental/JackApplications" /* bool */
  138. #define CARLA_KEY_EXPERIMENTAL_EXPORT_LV2 "Experimental/ExportLV2" /* bool */
  139. #define CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR "Experimental/PreventBadBehaviour" /* bool */
  140. #define CARLA_KEY_EXPERIMENTAL_LOAD_LIB_GLOBAL "Experimental/LoadLibGlobal" /* bool */
  141. // if pro theme is on and color is black
  142. #define CARLA_KEY_CUSTOM_PAINTING "UseCustomPainting" /* bool */
  143. //---------------------------------------------------------------------------------------------------------------------
  144. // Carla Settings defaults
  145. // Main
  146. #define CARLA_DEFAULT_MAIN_PROJECT_FOLDER HOME
  147. #define CARLA_DEFAULT_MAIN_USE_PRO_THEME true
  148. #define CARLA_DEFAULT_MAIN_PRO_THEME_COLOR "Black"
  149. #define CARLA_DEFAULT_MAIN_REFRESH_INTERVAL 20
  150. #define CARLA_DEFAULT_MAIN_CONFIRM_EXIT true
  151. #define CARLA_DEFAULT_MAIN_SHOW_LOGS bool(not WINDOWS)
  152. #define CARLA_DEFAULT_MAIN_EXPERIMENTAL false
  153. // Canvas
  154. #define CARLA_DEFAULT_CANVAS_THEME "Modern Dark"
  155. #define CARLA_DEFAULT_CANVAS_SIZE "3100x2400"
  156. #define CARLA_DEFAULT_CANVAS_SIZE_WIDTH 3100
  157. #define CARLA_DEFAULT_CANVAS_SIZE_HEIGHT 2400
  158. #define CARLA_DEFAULT_CANVAS_USE_BEZIER_LINES true
  159. #define CARLA_DEFAULT_CANVAS_AUTO_HIDE_GROUPS true
  160. #define CARLA_DEFAULT_CANVAS_AUTO_SELECT_ITEMS false
  161. #define CARLA_DEFAULT_CANVAS_EYE_CANDY true
  162. #define CARLA_DEFAULT_CANVAS_FANCY_EYE_CANDY false
  163. #define CARLA_DEFAULT_CANVAS_USE_OPENGL false
  164. #define CARLA_DEFAULT_CANVAS_ANTIALIASING CANVAS_ANTIALIASING_SMALL
  165. #define CARLA_DEFAULT_CANVAS_HQ_ANTIALIASING false
  166. #define CARLA_DEFAULT_CANVAS_INLINE_DISPLAYS false
  167. #define CARLA_DEFAULT_CANVAS_FULL_REPAINTS false
  168. // Engine
  169. #define CARLA_DEFAULT_FORCE_STEREO false
  170. #define CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES false
  171. #define CARLA_DEFAULT_PREFER_UI_BRIDGES true
  172. #define CARLA_DEFAULT_MANAGE_UIS true
  173. #define CARLA_DEFAULT_UIS_ALWAYS_ON_TOP false
  174. #define CARLA_DEFAULT_MAX_PARAMETERS MAX_DEFAULT_PARAMETERS
  175. #define CARLA_DEFAULT_UI_BRIDGES_TIMEOUT 4000
  176. #define CARLA_DEFAULT_AUDIO_BUFFER_SIZE 512
  177. #define CARLA_DEFAULT_AUDIO_SAMPLE_RATE 44100
  178. #define CARLA_DEFAULT_AUDIO_TRIPLE_BUFFER false
  179. #if defined(CARLA_OS_WIN)
  180. # define CARLA_DEFAULT_AUDIO_DRIVER "DirectSound"
  181. #elif defined(CARLA_OS_MAC)
  182. # define CARLA_DEFAULT_AUDIO_DRIVER "CoreAudio"
  183. #else
  184. // if os.path.exists("/usr/bin/jackd") or os.path.exists("/usr/bin/jackdbus"):
  185. # define CARLA_DEFAULT_AUDIO_DRIVER "JACK"
  186. // # define CARLA_DEFAULT_AUDIO_DRIVER "PulseAudio"
  187. #endif
  188. // #if CARLA_DEFAULT_AUDIO_DRIVER == "JACK"
  189. // # define CARLA_DEFAULT_PROCESS_MODE ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS
  190. // # define CARLA_DEFAULT_TRANSPORT_MODE ENGINE_TRANSPORT_MODE_JACK
  191. // #else
  192. # define CARLA_DEFAULT_PROCESS_MODE ENGINE_PROCESS_MODE_PATCHBAY
  193. # define CARLA_DEFAULT_TRANSPORT_MODE ENGINE_TRANSPORT_MODE_INTERNAL
  194. // #endif
  195. // OSC
  196. #define CARLA_DEFAULT_OSC_ENABLED !(not WINDOWS)
  197. #define CARLA_DEFAULT_OSC_TCP_PORT_ENABLED true
  198. #define CARLA_DEFAULT_OSC_TCP_PORT_NUMBER 22752
  199. #define CARLA_DEFAULT_OSC_TCP_PORT_RANDOM false
  200. #define CARLA_DEFAULT_OSC_UDP_PORT_ENABLED true
  201. #define CARLA_DEFAULT_OSC_UDP_PORT_NUMBER 22752
  202. #define CARLA_DEFAULT_OSC_UDP_PORT_RANDOM false
  203. // Wine
  204. #define CARLA_DEFAULT_WINE_EXECUTABLE "wine"
  205. #define CARLA_DEFAULT_WINE_AUTO_PREFIX true
  206. #define CARLA_DEFAULT_WINE_FALLBACK_PREFIX os.path.expanduser("~/.wine")
  207. #define CARLA_DEFAULT_WINE_RT_PRIO_ENABLED true
  208. #define CARLA_DEFAULT_WINE_BASE_RT_PRIO 15
  209. #define CARLA_DEFAULT_WINE_SERVER_RT_PRIO 10
  210. // Experimental
  211. #define CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES false
  212. #define CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES false
  213. #define CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS false
  214. #define CARLA_DEFAULT_EXPERIMENTAL_LV2_EXPORT false
  215. #define CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR false
  216. #define CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL false
  217. //---------------------------------------------------------------------------------------------------------------------
  218. // Global Carla object
  219. struct CarlaObject {
  220. QMainWindow* gui; // Host Window
  221. bool nogui; // Skip UI
  222. bool term; // Terminated by OS signal
  223. CarlaObject()
  224. : gui(nullptr),
  225. nogui(false),
  226. term(false) {}
  227. };
  228. extern CarlaObject gCarla;
  229. //---------------------------------------------------------------------------------------------------------------------
  230. // Signal handler
  231. /*
  232. void signalHandler(const int sig)
  233. {
  234. if (sig == SIGINT || sig == SIGTERM)
  235. {
  236. gCarla.term = true;
  237. if (gCarla.gui != nullptr)
  238. gCarla.gui.SIGTERM.emit();
  239. }
  240. else if (sig == SIGUSR1)
  241. {
  242. if (gCarla.gui != nullptr)
  243. gCarla.gui.SIGUSR1.emit();
  244. }
  245. }
  246. */
  247. inline void setUpSignals()
  248. {
  249. /*
  250. signal(SIGINT, signalHandler);
  251. signal(SIGTERM, signalHandler);
  252. signal(SIGUSR1, signalHandler);
  253. */
  254. }
  255. //---------------------------------------------------------------------------------------------------------------------
  256. // Handle some basic command-line arguments shared between all carla variants
  257. inline
  258. QString handleInitialCommandLineArguments(const int argc, char* argv[])
  259. {
  260. static const QStringList listArgsNoGUI = { "-n", "--n", "-no-gui", "--no-gui", "-nogui", "--nogui" };
  261. static const QStringList listArgsHelp = { "-h", "--h", "-help", "--help" };
  262. static const QStringList listArgsVersion = { "-v", "--v", "-version", "--version" };
  263. QString initName(argv[0]); // = os.path.basename(file) if (file is not None and os.path.dirname(file) in PATH) else sys.argv[0]
  264. // libPrefix = None
  265. for (int i=1; i<argc; ++i)
  266. {
  267. const QString arg(argv[i]);
  268. if (arg.startsWith("--with-appname="))
  269. {
  270. // initName = os.path.basename(arg.replace("--with-appname=", ""));
  271. }
  272. else if (arg.startsWith("--with-libprefix=") || arg == "--gdb")
  273. {
  274. pass();
  275. }
  276. else if (listArgsNoGUI.contains(arg))
  277. {
  278. gCarla.nogui = true;
  279. }
  280. else if (listArgsHelp.contains(arg))
  281. {
  282. carla_stdout("Usage: %s [OPTION]... [FILE|URL]", initName);
  283. carla_stdout("");
  284. carla_stdout(" where FILE can be a Carla project or preset file to be loaded, or URL if using Carla-Control");
  285. carla_stdout("");
  286. carla_stdout(" and OPTION can be one or more of the following:");
  287. carla_stdout("");
  288. carla_stdout(" --gdb \t Run Carla inside gdb.");
  289. carla_stdout(" -n,--no-gui \t Run Carla headless, don't show UI.");
  290. carla_stdout("");
  291. carla_stdout(" -h,--help \t Print this help text and exit.");
  292. carla_stdout(" -v,--version\t Print version information and exit.");
  293. carla_stdout("");
  294. std::exit(0);
  295. }
  296. else if (listArgsVersion.contains(arg))
  297. {
  298. /*
  299. QString pathBinaries, pathResources = getPaths();
  300. */
  301. carla_stdout("Using Carla version %s", CARLA_VERSION_STRING);
  302. /*
  303. carla_stdout(" Qt version: %s", QT_VERSION_STR);
  304. carla_stdout(" Binary dir: %s", pathBinaries.toUtf8());
  305. carla_stdout(" Resources dir: %s", pathResources.toUtf8());
  306. */
  307. std::exit(0);
  308. }
  309. }
  310. return initName;
  311. }
  312. #if 0
  313. //---------------------------------------------------------------------------------------------------------------------
  314. // Get Icon from user theme, using our own as backup (Oxygen)
  315. def getIcon(icon, size = 16):
  316. return QIcon.fromTheme(icon, QIcon(":/%ix%i/%s.png" % (size, size, icon)))
  317. //---------------------------------------------------------------------------------------------------------------------
  318. // QLineEdit and QPushButton combo
  319. def getAndSetPath(parent, lineEdit):
  320. newPath = QFileDialog.getExistingDirectory(parent, parent.tr("Set Path"), lineEdit.text(), QFileDialog.ShowDirsOnly)
  321. if newPath:
  322. lineEdit.setText(newPath)
  323. return newPath
  324. #endif
  325. //---------------------------------------------------------------------------------------------------------------------
  326. // Check if a string array contains a string
  327. static inline
  328. bool stringArrayContainsString(const char* const* const stringArray, const char* const string) noexcept
  329. {
  330. for (uint i=0; stringArray[i] != nullptr; ++i)
  331. {
  332. if (std::strcmp(stringArray[i], string) == 0)
  333. return true;
  334. }
  335. return false;
  336. }
  337. static inline
  338. void fillQStringListFromStringArray(QStringList& list, const char* const* const stringArray)
  339. {
  340. uint count = 0;
  341. // count number of strings first
  342. for (; stringArray[count] != nullptr; ++count) {}
  343. // allocate list
  344. list.reserve(count);
  345. // fill in strings
  346. for (count = 0; stringArray[count] != nullptr; ++count)
  347. list.replace(count, stringArray[count]);
  348. }
  349. //---------------------------------------------------------------------------------------------------------------------
  350. // Backwards-compatible horizontalAdvance/width call, depending on qt version
  351. static inline
  352. int fontMetricsHorizontalAdvance(const QFontMetrics& fm, const QString& s)
  353. {
  354. #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
  355. return fm.horizontalAdvance(s);
  356. #else
  357. return fm.width(s);
  358. #endif
  359. }
  360. //---------------------------------------------------------------------------------------------------------------------
  361. // Custom QString class with a few extra methods
  362. class QCarlaString : public QString
  363. {
  364. public:
  365. QCarlaString()
  366. : QString() {}
  367. QCarlaString(const char* const ch)
  368. : QString(ch) {}
  369. QCarlaString(const QString& s)
  370. : QString(s) {}
  371. inline bool isNotEmpty() const
  372. {
  373. return !isEmpty();
  374. }
  375. inline QCarlaString& operator=(const char* const ch)
  376. {
  377. return (*this = fromUtf8(ch));
  378. }
  379. };
  380. #if 0
  381. //---------------------------------------------------------------------------------------------------------------------
  382. // Custom QMessageBox which resizes itself to fit text
  383. class QMessageBoxWithBetterWidth(QMessageBox):
  384. def __init__(self, parent):
  385. QMessageBox.__init__(self, parent)
  386. def showEvent(self, event):
  387. fontMetrics = self.fontMetrics()
  388. lines = self.text().strip().split("\n") + self.informativeText().strip().split("\n")
  389. if len(lines) > 0:
  390. width = 0
  391. for line in lines:
  392. width = max(fontMetrics.width(line), width)
  393. self.layout().setColumnMinimumWidth(2, width + 12)
  394. QMessageBox.showEvent(self, event)
  395. #endif
  396. //---------------------------------------------------------------------------------------------------------------------
  397. // Safer QSettings class, which does not throw if type mismatches
  398. class QSafeSettings : public QSettings
  399. {
  400. public:
  401. QSafeSettings()
  402. : QSettings() {}
  403. QSafeSettings(const QString organizationName, const QString applicationName)
  404. : QSettings(organizationName, applicationName) {}
  405. bool valueBool(const QString key, const bool defaultValue) const
  406. {
  407. QVariant var(value(key, defaultValue));
  408. CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::Bool), defaultValue);
  409. return var.isValid() ? var.toBool() : defaultValue;
  410. }
  411. uint valueUInt(const QString key, const uint defaultValue) const
  412. {
  413. QVariant var(value(key, defaultValue));
  414. CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::UInt), defaultValue);
  415. return var.isValid() ? var.toUInt() : defaultValue;
  416. }
  417. double valueDouble(const QString key, const double defaultValue) const
  418. {
  419. QVariant var(value(key, defaultValue));
  420. CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::Double), defaultValue);
  421. return var.isValid() ? var.toDouble() : defaultValue;
  422. }
  423. QString valueString(const QString key, const QString defaultValue) const
  424. {
  425. QVariant var(value(key, defaultValue));
  426. CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::String), defaultValue);
  427. return var.isValid() ? var.toString() : defaultValue;
  428. }
  429. QByteArray valueByteArray(const QString key, const QByteArray defaultValue = QByteArray()) const
  430. {
  431. QVariant var(value(key, defaultValue));
  432. CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::ByteArray), defaultValue);
  433. return var.isValid() ? var.toByteArray() : defaultValue;
  434. }
  435. QStringList valueStringList(const QString key, const QStringList defaultValue = QStringList()) const
  436. {
  437. QVariant var(value(key, defaultValue));
  438. CARLA_SAFE_ASSERT_RETURN(var.convert(QVariant::StringList), defaultValue);
  439. return var.isValid() ? var.toStringList() : defaultValue;
  440. }
  441. };
  442. #if 0
  443. //---------------------------------------------------------------------------------------------------------------------
  444. // Custom MessageBox
  445. def CustomMessageBox(parent, icon, title, text,
  446. extraText="",
  447. buttons=QMessageBox.Yes|QMessageBox.No,
  448. defButton=QMessageBox.No):
  449. msgBox = QMessageBoxWithBetterWidth(parent)
  450. msgBox.setIcon(icon)
  451. msgBox.setWindowTitle(title)
  452. msgBox.setText(text)
  453. msgBox.setInformativeText(extraText)
  454. msgBox.setStandardButtons(buttons)
  455. msgBox.setDefaultButton(defButton)
  456. return msgBox.exec_()
  457. #endif
  458. //---------------------------------------------------------------------------------------------------------------------
  459. #endif // CARLA_SHARED_HPP_INCLUDED