25bd5d8adb
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
310 lines
11 KiB
C++
310 lines
11 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library.
|
|
Copyright (c) 2020 - Raw Material Software Limited
|
|
|
|
JUCE is an open source library subject to commercial or open-source
|
|
licensing.
|
|
|
|
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
|
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
|
|
|
End User License Agreement: www.juce.com/juce-6-licence
|
|
Privacy Policy: www.juce.com/juce-privacy-policy
|
|
|
|
Or: You may also use this code under the terms of the GPL v3 (see
|
|
www.gnu.org/licenses).
|
|
|
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
|
DISCLAIMED.
|
|
|
|
==============================================================================
|
|
*/
|
|
#include "../Application/jucer_Headers.h"
|
|
#include "../Application/jucer_Application.h"
|
|
#include "../ProjectSaving/jucer_ProjectExporter.h"
|
|
#include "../Project/UI/jucer_HeaderComponent.h"
|
|
#include "jucer_LicenseController.h"
|
|
|
|
#if ! JUCER_ENABLE_GPL_MODE
|
|
#include "jucer_LicenseWebview.h"
|
|
#include "jucer_LicenseThread.h"
|
|
#endif
|
|
|
|
//==============================================================================
|
|
const char* LicenseState::licenseTypeToString (LicenseState::Type type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case Type::notLoggedIn: return "<notLoggedIn>";
|
|
case Type::noLicenseChosenYet: return "<noLicenseChosenYet>";
|
|
case Type::GPL: return "JUCE GPL";
|
|
case Type::personal: return "JUCE Personal";
|
|
case Type::edu: return "JUCE Education";
|
|
case Type::indie: return "JUCE Indie";
|
|
case Type::pro: return "JUCE Pro";
|
|
default: return "<unknown>";
|
|
}
|
|
}
|
|
|
|
static const char* getLicenseStateValue (LicenseState::Type type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case LicenseState::Type::GPL: return "GPL";
|
|
case LicenseState::Type::personal: return "personal";
|
|
case LicenseState::Type::edu: return "edu";
|
|
case LicenseState::Type::indie: return "indie";
|
|
case LicenseState::Type::pro: return "pro";
|
|
case LicenseState::Type::notLoggedIn:
|
|
case LicenseState::Type::noLicenseChosenYet:
|
|
default: return nullptr;
|
|
}
|
|
}
|
|
|
|
static LicenseState::Type getLicenseTypeFromValue (const String& d)
|
|
{
|
|
if (d == getLicenseStateValue (LicenseState::Type::GPL)) return LicenseState::Type::GPL;
|
|
if (d == getLicenseStateValue (LicenseState::Type::personal)) return LicenseState::Type::personal;
|
|
if (d == getLicenseStateValue (LicenseState::Type::edu)) return LicenseState::Type::edu;
|
|
if (d == getLicenseStateValue (LicenseState::Type::indie)) return LicenseState::Type::indie;
|
|
if (d == getLicenseStateValue (LicenseState::Type::pro)) return LicenseState::Type::pro;
|
|
return LicenseState::Type::noLicenseChosenYet;
|
|
}
|
|
|
|
#if ! JUCER_ENABLE_GPL_MODE
|
|
struct LicenseController::ModalCompletionCallback : ModalComponentManager::Callback
|
|
{
|
|
ModalCompletionCallback (LicenseController& controller) : owner (controller) {}
|
|
void modalStateFinished (int returnValue) override { owner.modalStateFinished (returnValue); }
|
|
LicenseController& owner;
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModalCompletionCallback)
|
|
};
|
|
#endif
|
|
|
|
//==============================================================================
|
|
LicenseController::LicenseController()
|
|
: state (licenseStateFromSettings (ProjucerApplication::getApp().settings->getGlobalProperties()))
|
|
{
|
|
#if JUCER_ENABLE_GPL_MODE
|
|
state.type = LicenseState::Type::GPL;
|
|
state.username = "GPL mode";
|
|
#endif
|
|
}
|
|
|
|
LicenseController::~LicenseController()
|
|
{
|
|
#if ! JUCER_ENABLE_GPL_MODE
|
|
thread.reset();
|
|
closeWebview (-1);
|
|
#endif
|
|
}
|
|
|
|
LicenseState LicenseController::getState() const noexcept
|
|
{
|
|
LicenseState projucerState = state;
|
|
|
|
// if the user has never logged in before and the user is running from command line
|
|
// then we have no way to ask the user to log in, so fallback to GPL mode
|
|
if (guiNotInitialisedYet
|
|
&& (state.type == LicenseState::Type::notLoggedIn
|
|
|| state.type == LicenseState::Type::noLicenseChosenYet))
|
|
{
|
|
projucerState.type = LicenseState::Type::GPL;
|
|
projucerState.username = "GPL mode";
|
|
}
|
|
|
|
return projucerState;
|
|
}
|
|
|
|
void LicenseController::startWebviewIfNeeded()
|
|
{
|
|
if (guiNotInitialisedYet)
|
|
{
|
|
guiNotInitialisedYet = false;
|
|
auto stateParam = getState();
|
|
listeners.call ([&] (StateChangedCallback& l) { l.licenseStateChanged (stateParam); });
|
|
}
|
|
|
|
#if ! JUCER_ENABLE_GPL_MODE
|
|
if (thread == nullptr)
|
|
thread.reset (new LicenseThread (*this, false));
|
|
#endif
|
|
}
|
|
|
|
void LicenseController::logout()
|
|
{
|
|
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
|
|
|
|
#if ! JUCER_ENABLE_GPL_MODE
|
|
thread.reset();
|
|
updateState ({});
|
|
|
|
#if ! (JUCE_LINUX || JUCE_BSD)
|
|
WebBrowserComponent::clearCookies();
|
|
#endif
|
|
|
|
thread.reset (new LicenseThread (*this, false));
|
|
#endif
|
|
}
|
|
|
|
void LicenseController::chooseNewLicense()
|
|
{
|
|
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
|
|
|
|
#if ! JUCER_ENABLE_GPL_MODE
|
|
thread.reset();
|
|
thread.reset (new LicenseThread (*this, true));
|
|
#endif
|
|
}
|
|
|
|
//==============================================================================
|
|
#if ! JUCER_ENABLE_GPL_MODE
|
|
void LicenseController::closeWebview (int result)
|
|
{
|
|
if (licenseWebview != nullptr)
|
|
licenseWebview->exitModalState (result);
|
|
}
|
|
|
|
void LicenseController::modalStateFinished (int result)
|
|
{
|
|
licenseWebview = nullptr;
|
|
|
|
if (result == -1 && (state.type == LicenseState::Type::notLoggedIn
|
|
|| state.type == LicenseState::Type::noLicenseChosenYet))
|
|
JUCEApplication::getInstance()->systemRequestedQuit();
|
|
}
|
|
|
|
void LicenseController::ensureLicenseWebviewIsOpenWithPage (const String& param)
|
|
{
|
|
if (licenseWebview != nullptr)
|
|
{
|
|
licenseWebview->goToURL (param);
|
|
licenseWebview->toFront (true);
|
|
}
|
|
else
|
|
{
|
|
#if ! (JUCE_LINUX || JUCE_BSD)
|
|
WebBrowserComponent::clearCookies();
|
|
#endif
|
|
|
|
licenseWebview = new LicenseWebview (new ModalCompletionCallback (*this), param);
|
|
}
|
|
}
|
|
|
|
void LicenseController::queryWebview (const String& startURL, const String& valueToQuery,
|
|
HashMap<String, String>& result)
|
|
{
|
|
ensureLicenseWebviewIsOpenWithPage (startURL);
|
|
|
|
licenseWebview->setPageCallback ([this,valueToQuery,&result] (const String& cmd, const HashMap<String, String>& params)
|
|
{
|
|
if (valueToQuery.isEmpty() || cmd == valueToQuery)
|
|
{
|
|
result.clear();
|
|
|
|
for (HashMap<String, String>::Iterator it = params.begin(); it != params.end(); ++it)
|
|
result.set (it.getKey(), it.getValue());
|
|
|
|
if (thread != nullptr && ! thread->threadShouldExit())
|
|
thread->finished.signal();
|
|
}
|
|
});
|
|
|
|
licenseWebview->setNewWindowCallback ([this, &result] (const String& url)
|
|
{
|
|
if (url.endsWith ("get-juce/indie") || url.endsWith ("get-juce/pro"))
|
|
{
|
|
result.clear();
|
|
result.set ("page-redirect", url);
|
|
|
|
if (thread != nullptr && ! thread->threadShouldExit())
|
|
thread->finished.signal();
|
|
}
|
|
});
|
|
}
|
|
#endif
|
|
|
|
void LicenseController::updateState (const LicenseState& newState)
|
|
{
|
|
auto& props = ProjucerApplication::getApp().settings->getGlobalProperties();
|
|
|
|
state = newState;
|
|
licenseStateToSettings (state, props);
|
|
auto stateParam = getState();
|
|
listeners.call ([&] (StateChangedCallback& l) { l.licenseStateChanged (stateParam); });
|
|
}
|
|
|
|
LicenseState LicenseController::licenseStateFromOldSettings (XmlElement* licenseXml)
|
|
{
|
|
LicenseState result;
|
|
result.type = getLicenseTypeFromValue (licenseXml->getChildElementAllSubText ("type", {}));
|
|
result.username = licenseXml->getChildElementAllSubText ("username", {});
|
|
result.email = licenseXml->getChildElementAllSubText ("email", {});
|
|
result.authToken = licenseXml->getChildElementAllSubText ("authToken", {});
|
|
|
|
MemoryOutputStream imageData;
|
|
Base64::convertFromBase64 (imageData, licenseXml->getChildElementAllSubText ("avatar", {}));
|
|
result.avatar = ImageFileFormat::loadFrom (imageData.getData(), imageData.getDataSize());
|
|
|
|
return result;
|
|
}
|
|
|
|
LicenseState LicenseController::licenseStateFromSettings (PropertiesFile& props)
|
|
{
|
|
if (auto licenseXml = props.getXmlValue ("license"))
|
|
{
|
|
// this is here for backwards compatibility with old-style settings files using XML text elements
|
|
if (licenseXml->getChildElementAllSubText ("type", {}) != String())
|
|
{
|
|
auto stateFromOldSettings = licenseStateFromOldSettings (licenseXml.get());
|
|
|
|
licenseStateToSettings (stateFromOldSettings, props);
|
|
|
|
return stateFromOldSettings;
|
|
}
|
|
|
|
LicenseState result;
|
|
result.type = getLicenseTypeFromValue (licenseXml->getStringAttribute ("type", {}));
|
|
result.username = licenseXml->getStringAttribute ("username", {});
|
|
result.email = licenseXml->getStringAttribute ("email", {});
|
|
result.authToken = licenseXml->getStringAttribute ("authToken", {});
|
|
|
|
MemoryOutputStream imageData;
|
|
Base64::convertFromBase64 (imageData, licenseXml->getStringAttribute ("avatar", {}));
|
|
result.avatar = ImageFileFormat::loadFrom (imageData.getData(), imageData.getDataSize());
|
|
|
|
return result;
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
void LicenseController::licenseStateToSettings (const LicenseState& state, PropertiesFile& props)
|
|
{
|
|
props.removeValue ("license");
|
|
|
|
if (state.type != LicenseState::Type::notLoggedIn && state.username.isNotEmpty())
|
|
{
|
|
XmlElement licenseXml ("license");
|
|
|
|
if (auto* typeString = getLicenseStateValue (state.type))
|
|
licenseXml.setAttribute ("type", typeString);
|
|
|
|
licenseXml.setAttribute ("username", state.username);
|
|
licenseXml.setAttribute ("email", state.email);
|
|
licenseXml.setAttribute ("authToken", state.authToken);
|
|
|
|
MemoryOutputStream imageData;
|
|
if (state.avatar.isValid() && PNGImageFormat().writeImageToStream (state.avatar, imageData))
|
|
licenseXml.setAttribute ("avatar", Base64::toBase64 (imageData.getData(), imageData.getDataSize()));
|
|
|
|
props.setValue ("license", &licenseXml);
|
|
}
|
|
|
|
props.saveIfNeeded();
|
|
}
|