The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

195 lines
6.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 6 technical preview.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For this technical preview, this file is not subject to commercial licensing.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. #pragma once
  14. #include "jucer_LicenseState.h"
  15. //==============================================================================
  16. class LicenseController
  17. {
  18. public:
  19. LicenseController() = default;
  20. //==============================================================================
  21. LicenseState getCurrentState() const noexcept
  22. {
  23. return state;
  24. }
  25. void setState (const LicenseState& newState)
  26. {
  27. state = newState;
  28. licenseStateToSettings (state, getGlobalProperties());
  29. stateListeners.call ([] (LicenseStateListener& l) { l.licenseStateChanged(); });
  30. }
  31. void resetState()
  32. {
  33. setState ({});
  34. }
  35. static LicenseState getGPLState()
  36. {
  37. static auto logoImage = []() -> Image
  38. {
  39. if (auto logo = Drawable::createFromImageData (BinaryData::gpl_logo_svg, BinaryData::gpl_logo_svgSize))
  40. {
  41. auto bounds = logo->getDrawableBounds();
  42. Image image (Image::ARGB, roundToInt (bounds.getWidth()), roundToInt (bounds.getHeight()), true);
  43. Graphics g (image);
  44. logo->draw (g, 1.0f);
  45. return image;
  46. }
  47. jassertfalse;
  48. return {};
  49. }();
  50. return { LicenseState::Type::gpl, {}, {}, logoImage };
  51. }
  52. //==============================================================================
  53. struct LicenseStateListener
  54. {
  55. virtual ~LicenseStateListener() = default;
  56. virtual void licenseStateChanged() = 0;
  57. };
  58. void addListener (LicenseStateListener* listenerToAdd)
  59. {
  60. stateListeners.add (listenerToAdd);
  61. }
  62. void removeListener (LicenseStateListener* listenerToRemove)
  63. {
  64. stateListeners.remove (listenerToRemove);
  65. }
  66. private:
  67. //==============================================================================
  68. static const char* getLicenseStateValue (LicenseState::Type type)
  69. {
  70. switch (type)
  71. {
  72. case LicenseState::Type::gpl: return "GPL";
  73. case LicenseState::Type::personal: return "personal";
  74. case LicenseState::Type::educational: return "edu";
  75. case LicenseState::Type::indie: return "indie";
  76. case LicenseState::Type::pro: return "pro";
  77. case LicenseState::Type::none:
  78. default: break;
  79. }
  80. return nullptr;
  81. }
  82. static LicenseState::Type getLicenseTypeFromValue (const String& d)
  83. {
  84. if (d == getLicenseStateValue (LicenseState::Type::gpl)) return LicenseState::Type::gpl;
  85. if (d == getLicenseStateValue (LicenseState::Type::personal)) return LicenseState::Type::personal;
  86. if (d == getLicenseStateValue (LicenseState::Type::educational)) return LicenseState::Type::educational;
  87. if (d == getLicenseStateValue (LicenseState::Type::indie)) return LicenseState::Type::indie;
  88. if (d == getLicenseStateValue (LicenseState::Type::pro)) return LicenseState::Type::pro;
  89. return LicenseState::Type::none;
  90. }
  91. static Image avatarFromLicenseState (const String& licenseState)
  92. {
  93. MemoryOutputStream imageData;
  94. Base64::convertFromBase64 (imageData, licenseState);
  95. return ImageFileFormat::loadFrom (imageData.getData(), imageData.getDataSize());
  96. }
  97. static String avatarToLicenseState (Image avatarImage)
  98. {
  99. MemoryOutputStream imageData;
  100. if (avatarImage.isValid() && PNGImageFormat().writeImageToStream (avatarImage, imageData))
  101. return Base64::toBase64 (imageData.getData(), imageData.getDataSize());
  102. return {};
  103. }
  104. static LicenseState licenseStateFromSettings (PropertiesFile& props)
  105. {
  106. if (auto licenseXml = props.getXmlValue ("license"))
  107. {
  108. // this is here for backwards compatibility with old-style settings files using XML text elements
  109. if (licenseXml->getChildElementAllSubText ("type", {}).isNotEmpty())
  110. {
  111. auto stateFromOldSettings = [&licenseXml]() -> LicenseState
  112. {
  113. return { getLicenseTypeFromValue (licenseXml->getChildElementAllSubText ("type", {})),
  114. licenseXml->getChildElementAllSubText ("authToken", {}),
  115. licenseXml->getChildElementAllSubText ("username", {}),
  116. avatarFromLicenseState (licenseXml->getStringAttribute ("avatar", {})) };
  117. }();
  118. licenseStateToSettings (stateFromOldSettings, props);
  119. return stateFromOldSettings;
  120. }
  121. return { getLicenseTypeFromValue (licenseXml->getStringAttribute ("type", {})),
  122. licenseXml->getStringAttribute ("authToken", {}),
  123. licenseXml->getStringAttribute ("username", {}),
  124. avatarFromLicenseState (licenseXml->getStringAttribute ("avatar", {})) };
  125. }
  126. return {};
  127. }
  128. static void licenseStateToSettings (const LicenseState& state, PropertiesFile& props)
  129. {
  130. props.removeValue ("license");
  131. if (state.isValid())
  132. {
  133. XmlElement licenseXml ("license");
  134. if (auto* typeString = getLicenseStateValue (state.type))
  135. licenseXml.setAttribute ("type", typeString);
  136. licenseXml.setAttribute ("authToken", state.authToken);
  137. licenseXml.setAttribute ("username", state.username);
  138. licenseXml.setAttribute ("avatar", avatarToLicenseState (state.avatar));
  139. props.setValue ("license", &licenseXml);
  140. }
  141. props.saveIfNeeded();
  142. }
  143. //==============================================================================
  144. #if JUCER_ENABLE_GPL_MODE
  145. LicenseState state = getGPLState();
  146. #else
  147. LicenseState state = licenseStateFromSettings (getGlobalProperties());
  148. #endif
  149. ListenerList<LicenseStateListener> stateListeners;
  150. //==============================================================================
  151. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseController)
  152. };