Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into clean_net
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
commit
061fdc1ada
18
flake.lock
generated
18
flake.lock
generated
@ -23,11 +23,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1717285511,
|
"lastModified": 1719994518,
|
||||||
"narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
|
"narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
|
"rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -75,11 +75,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1718276985,
|
"lastModified": 1720031269,
|
||||||
"narHash": "sha256-u1fA0DYQYdeG+5kDm1bOoGcHtX0rtC7qs2YA2N1X++I=",
|
"narHash": "sha256-rwz8NJZV+387rnWpTYcXaRNvzUSnnF9aHONoJIYmiUQ=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "3f84a279f1a6290ce154c5531378acc827836fbb",
|
"rev": "9f4128e00b0ae8ec65918efeba59db998750ead6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -103,11 +103,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1717664902,
|
"lastModified": 1719259945,
|
||||||
"narHash": "sha256-7XfBuLULizXjXfBYy/VV+SpYMHreNRHk9nKMsm1bgb4=",
|
"narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "pre-commit-hooks.nix",
|
"repo": "pre-commit-hooks.nix",
|
||||||
"rev": "cc4d466cb1254af050ff7bdf47f6d404a7c646d1",
|
"rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -1691,4 +1691,30 @@ QString getPathNameInLocal8bit(const QString& file)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString getUniqueResourceName(const QString& filePath)
|
||||||
|
{
|
||||||
|
auto newFileName = filePath;
|
||||||
|
if (!newFileName.endsWith(".disabled")) {
|
||||||
|
return newFileName; // prioritize enabled mods
|
||||||
|
}
|
||||||
|
newFileName.chop(9);
|
||||||
|
if (!QFile::exists(newFileName)) {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
QFileInfo fileInfo(filePath);
|
||||||
|
auto baseName = fileInfo.completeBaseName();
|
||||||
|
auto path = fileInfo.absolutePath();
|
||||||
|
|
||||||
|
int counter = 1;
|
||||||
|
do {
|
||||||
|
if (counter == 1) {
|
||||||
|
newFileName = FS::PathCombine(path, baseName + ".duplicate");
|
||||||
|
} else {
|
||||||
|
newFileName = FS::PathCombine(path, baseName + ".duplicate" + QString::number(counter));
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
} while (QFile::exists(newFileName));
|
||||||
|
|
||||||
|
return newFileName;
|
||||||
|
}
|
||||||
} // namespace FS
|
} // namespace FS
|
||||||
|
@ -560,4 +560,6 @@ uintmax_t hardLinkCount(const QString& path);
|
|||||||
QString getPathNameInLocal8bit(const QString& file);
|
QString getPathNameInLocal8bit(const QString& file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString getUniqueResourceName(const QString& filePath);
|
||||||
|
|
||||||
} // namespace FS
|
} // namespace FS
|
||||||
|
@ -372,13 +372,13 @@ void InstanceList::undoTrashInstance()
|
|||||||
|
|
||||||
auto top = m_trashHistory.pop();
|
auto top = m_trashHistory.pop();
|
||||||
|
|
||||||
while (QDir(top.polyPath).exists()) {
|
while (QDir(top.path).exists()) {
|
||||||
top.id += "1";
|
top.id += "1";
|
||||||
top.polyPath += "1";
|
top.path += "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Moving" << top.trashPath << "back to" << top.polyPath;
|
qDebug() << "Moving" << top.trashPath << "back to" << top.path;
|
||||||
QFile(top.trashPath).rename(top.polyPath);
|
QFile(top.trashPath).rename(top.path);
|
||||||
|
|
||||||
m_instanceGroupIndex[top.id] = top.groupName;
|
m_instanceGroupIndex[top.id] = top.groupName;
|
||||||
increaseGroupCount(top.groupName);
|
increaseGroupCount(top.groupName);
|
||||||
@ -635,8 +635,8 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id)
|
|||||||
|
|
||||||
QString inst_type = instanceSettings->get("InstanceType").toString();
|
QString inst_type = instanceSettings->get("InstanceType").toString();
|
||||||
|
|
||||||
// NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix
|
// NOTE: Some launcher versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a
|
||||||
// instance
|
// OneSix instance
|
||||||
if (inst_type == "OneSix" || inst_type.isEmpty()) {
|
if (inst_type == "OneSix" || inst_type.isEmpty()) {
|
||||||
inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
|
inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,7 +58,7 @@ enum class GroupsState { NotLoaded, Steady, Dirty };
|
|||||||
|
|
||||||
struct TrashHistoryItem {
|
struct TrashHistoryItem {
|
||||||
QString id;
|
QString id;
|
||||||
QString polyPath;
|
QString path;
|
||||||
QString trashPath;
|
QString trashPath;
|
||||||
QString groupName;
|
QString groupName;
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "minecraft/auth/Parsers.h"
|
#include "minecraft/auth/Parsers.h"
|
||||||
#include "net/Download.h"
|
#include "net/Download.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
#include "net/RawHeaderProxy.h"
|
#include "net/RawHeaderProxy.h"
|
||||||
#include "tasks/Task.h"
|
#include "tasks/Task.h"
|
||||||
|
|
||||||
@ -31,12 +32,15 @@ void EntitlementsStep::perform()
|
|||||||
{ "Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8() } };
|
{ "Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8() } };
|
||||||
|
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Download::makeByteArray(url, m_response);
|
m_request = Net::Download::makeByteArray(url, m_response);
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
|
m_task.reset(new NetJob("EntitlementsStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &EntitlementsStep::onRequestDone);
|
connect(m_task.get(), &Task::finished, this, &EntitlementsStep::onRequestDone);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
qDebug() << "Getting entitlements...";
|
qDebug() << "Getting entitlements...";
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
#include "net/Download.h"
|
#include "net/Download.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
|
|
||||||
class EntitlementsStep : public AuthStep {
|
class EntitlementsStep : public AuthStep {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -22,5 +23,6 @@ class EntitlementsStep : public AuthStep {
|
|||||||
private:
|
private:
|
||||||
QString m_entitlements_request_id;
|
QString m_entitlements_request_id;
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Download::Ptr m_task;
|
Net::Download::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -17,17 +17,20 @@ void GetSkinStep::perform()
|
|||||||
QUrl url(m_data->minecraftProfile.skin.url);
|
QUrl url(m_data->minecraftProfile.skin.url);
|
||||||
|
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Download::makeByteArray(url, m_response);
|
m_request = Net::Download::makeByteArray(url, m_response);
|
||||||
|
|
||||||
|
m_task.reset(new NetJob("GetSkinStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &GetSkinStep::onRequestDone);
|
connect(m_task.get(), &Task::finished, this, &GetSkinStep::onRequestDone);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetSkinStep::onRequestDone()
|
void GetSkinStep::onRequestDone()
|
||||||
{
|
{
|
||||||
if (m_task->error() == QNetworkReply::NoError)
|
if (m_request->error() == QNetworkReply::NoError)
|
||||||
m_data->minecraftProfile.skin.data = *m_response;
|
m_data->minecraftProfile.skin.data = *m_response;
|
||||||
emit finished(AccountTaskState::STATE_WORKING, tr("Got skin"));
|
emit finished(AccountTaskState::STATE_WORKING, tr("Got skin"));
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
#include "net/Download.h"
|
#include "net/Download.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
|
|
||||||
class GetSkinStep : public AuthStep {
|
class GetSkinStep : public AuthStep {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -21,5 +22,6 @@ class GetSkinStep : public AuthStep {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Download::Ptr m_task;
|
Net::Download::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -37,12 +37,15 @@ void LauncherLoginStep::perform()
|
|||||||
};
|
};
|
||||||
|
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Upload::makeByteArray(url, m_response, requestBody.toUtf8());
|
m_request = Net::Upload::makeByteArray(url, m_response, requestBody.toUtf8());
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
|
m_task.reset(new NetJob("LauncherLoginStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &LauncherLoginStep::onRequestDone);
|
connect(m_task.get(), &Task::finished, this, &LauncherLoginStep::onRequestDone);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
qDebug() << "Getting Minecraft access token...";
|
qDebug() << "Getting Minecraft access token...";
|
||||||
}
|
}
|
||||||
@ -50,12 +53,13 @@ void LauncherLoginStep::perform()
|
|||||||
void LauncherLoginStep::onRequestDone()
|
void LauncherLoginStep::onRequestDone()
|
||||||
{
|
{
|
||||||
qCDebug(authCredentials()) << *m_response;
|
qCDebug(authCredentials()) << *m_response;
|
||||||
if (m_task->error() != QNetworkReply::NoError) {
|
if (m_request->error() != QNetworkReply::NoError) {
|
||||||
qWarning() << "Reply error:" << m_task->error();
|
qWarning() << "Reply error:" << m_request->error();
|
||||||
if (Net::isApplicationError(m_task->error())) {
|
if (Net::isApplicationError(m_request->error())) {
|
||||||
emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to get Minecraft access token: %1").arg(m_task->errorString()));
|
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
||||||
|
tr("Failed to get Minecraft access token: %1").arg(m_request->errorString()));
|
||||||
} else {
|
} else {
|
||||||
emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to get Minecraft access token: %1").arg(m_task->errorString()));
|
emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to get Minecraft access token: %1").arg(m_request->errorString()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
#include "net/Upload.h"
|
#include "net/Upload.h"
|
||||||
|
|
||||||
class LauncherLoginStep : public AuthStep {
|
class LauncherLoginStep : public AuthStep {
|
||||||
@ -21,5 +22,6 @@ class LauncherLoginStep : public AuthStep {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Upload::Ptr m_task;
|
Net::Upload::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -67,12 +67,13 @@ void MSADeviceCodeStep::perform()
|
|||||||
{ "Accept", "application/json" },
|
{ "Accept", "application/json" },
|
||||||
};
|
};
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Upload::makeByteArray(url, m_response, payload);
|
m_request = Net::Upload::makeByteArray(url, m_response, payload);
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &MSADeviceCodeStep::deviceAutorizationFinished);
|
m_task.reset(new NetJob("MSADeviceCodeStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ void MSADeviceCodeStep::deviceAutorizationFinished()
|
|||||||
tr("Device authorization failed: %1").arg(rsp.error_description.isEmpty() ? rsp.error : rsp.error_description));
|
tr("Device authorization failed: %1").arg(rsp.error_description.isEmpty() ? rsp.error : rsp.error_description));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_task->wasSuccessful() || m_task->error() != QNetworkReply::NoError) {
|
if (!m_request->wasSuccessful() || m_request->error() != QNetworkReply::NoError) {
|
||||||
emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Failed to retrieve device authorization"));
|
emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Failed to retrieve device authorization"));
|
||||||
qDebug() << *m_response;
|
qDebug() << *m_response;
|
||||||
return;
|
return;
|
||||||
@ -145,8 +146,8 @@ void MSADeviceCodeStep::abort()
|
|||||||
{
|
{
|
||||||
m_expiration_timer.stop();
|
m_expiration_timer.stop();
|
||||||
m_pool_timer.stop();
|
m_pool_timer.stop();
|
||||||
if (m_task) {
|
if (m_request) {
|
||||||
m_task->abort();
|
m_request->abort();
|
||||||
}
|
}
|
||||||
m_is_aborted = true;
|
m_is_aborted = true;
|
||||||
emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Task aborted"));
|
emit finished(AccountTaskState::STATE_FAILED_HARD, tr("Task aborted"));
|
||||||
@ -179,13 +180,13 @@ void MSADeviceCodeStep::authenticateUser()
|
|||||||
{ "Accept", "application/json" },
|
{ "Accept", "application/json" },
|
||||||
};
|
};
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Upload::makeByteArray(url, m_response, payload);
|
m_request = Net::Upload::makeByteArray(url, m_response, payload);
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &MSADeviceCodeStep::authenticationFinished);
|
connect(m_request.get(), &Task::finished, this, &MSADeviceCodeStep::authenticationFinished);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
m_request->setNetwork(APPLICATION->network());
|
||||||
m_task->start();
|
m_request->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AuthenticationResponse {
|
struct AuthenticationResponse {
|
||||||
@ -225,7 +226,7 @@ AuthenticationResponse parseAuthenticationResponse(const QByteArray& data)
|
|||||||
|
|
||||||
void MSADeviceCodeStep::authenticationFinished()
|
void MSADeviceCodeStep::authenticationFinished()
|
||||||
{
|
{
|
||||||
if (m_task->error() == QNetworkReply::TimeoutError) {
|
if (m_request->error() == QNetworkReply::TimeoutError) {
|
||||||
// rfc8628#section-3.5
|
// rfc8628#section-3.5
|
||||||
// "On encountering a connection timeout, clients MUST unilaterally
|
// "On encountering a connection timeout, clients MUST unilaterally
|
||||||
// reduce their polling frequency before retrying. The use of an
|
// reduce their polling frequency before retrying. The use of an
|
||||||
@ -258,7 +259,7 @@ void MSADeviceCodeStep::authenticationFinished()
|
|||||||
tr("Device Access failed: %1").arg(rsp.error_description.isEmpty() ? rsp.error : rsp.error_description));
|
tr("Device Access failed: %1").arg(rsp.error_description.isEmpty() ? rsp.error : rsp.error_description));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_task->wasSuccessful() || m_task->error() != QNetworkReply::NoError) {
|
if (!m_request->wasSuccessful() || m_request->error() != QNetworkReply::NoError) {
|
||||||
startPoolTimer(); // it failed so just try again without increasing the interval
|
startPoolTimer(); // it failed so just try again without increasing the interval
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
#include "net/Upload.h"
|
#include "net/Upload.h"
|
||||||
|
|
||||||
class MSADeviceCodeStep : public AuthStep {
|
class MSADeviceCodeStep : public AuthStep {
|
||||||
@ -72,5 +73,6 @@ class MSADeviceCodeStep : public AuthStep {
|
|||||||
QTimer m_expiration_timer;
|
QTimer m_expiration_timer;
|
||||||
|
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Upload::Ptr m_task;
|
Net::Upload::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -22,37 +22,41 @@ void MinecraftProfileStep::perform()
|
|||||||
{ "Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8() } };
|
{ "Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8() } };
|
||||||
|
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Download::makeByteArray(url, m_response);
|
m_request = Net::Download::makeByteArray(url, m_response);
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
|
m_task.reset(new NetJob("MinecraftProfileStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &MinecraftProfileStep::onRequestDone);
|
connect(m_task.get(), &Task::finished, this, &MinecraftProfileStep::onRequestDone);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinecraftProfileStep::onRequestDone()
|
void MinecraftProfileStep::onRequestDone()
|
||||||
{
|
{
|
||||||
if (m_task->error() == QNetworkReply::ContentNotFoundError) {
|
if (m_request->error() == QNetworkReply::ContentNotFoundError) {
|
||||||
// NOTE: Succeed even if we do not have a profile. This is a valid account state.
|
// NOTE: Succeed even if we do not have a profile. This is a valid account state.
|
||||||
m_data->minecraftProfile = MinecraftProfile();
|
m_data->minecraftProfile = MinecraftProfile();
|
||||||
emit finished(AccountTaskState::STATE_WORKING, tr("Account has no Minecraft profile."));
|
emit finished(AccountTaskState::STATE_WORKING, tr("Account has no Minecraft profile."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_task->error() != QNetworkReply::NoError) {
|
if (m_request->error() != QNetworkReply::NoError) {
|
||||||
qWarning() << "Error getting profile:";
|
qWarning() << "Error getting profile:";
|
||||||
qWarning() << " HTTP Status: " << m_task->replyStatusCode();
|
qWarning() << " HTTP Status: " << m_request->replyStatusCode();
|
||||||
qWarning() << " Internal error no.: " << m_task->error();
|
qWarning() << " Internal error no.: " << m_request->error();
|
||||||
qWarning() << " Error string: " << m_task->errorString();
|
qWarning() << " Error string: " << m_request->errorString();
|
||||||
|
|
||||||
qWarning() << " Response:";
|
qWarning() << " Response:";
|
||||||
qWarning() << QString::fromUtf8(*m_response);
|
qWarning() << QString::fromUtf8(*m_response);
|
||||||
|
|
||||||
if (Net::isApplicationError(m_task->error())) {
|
if (Net::isApplicationError(m_request->error())) {
|
||||||
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
||||||
tr("Minecraft Java profile acquisition failed: %1").arg(m_task->errorString()));
|
tr("Minecraft Java profile acquisition failed: %1").arg(m_request->errorString()));
|
||||||
} else {
|
} else {
|
||||||
emit finished(AccountTaskState::STATE_OFFLINE, tr("Minecraft Java profile acquisition failed: %1").arg(m_task->errorString()));
|
emit finished(AccountTaskState::STATE_OFFLINE,
|
||||||
|
tr("Minecraft Java profile acquisition failed: %1").arg(m_request->errorString()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
#include "net/Download.h"
|
#include "net/Download.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
|
|
||||||
class MinecraftProfileStep : public AuthStep {
|
class MinecraftProfileStep : public AuthStep {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -21,5 +22,6 @@ class MinecraftProfileStep : public AuthStep {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Download::Ptr m_task;
|
Net::Download::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -42,12 +42,15 @@ void XboxAuthorizationStep::perform()
|
|||||||
{ "Accept", "application/json" },
|
{ "Accept", "application/json" },
|
||||||
};
|
};
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8());
|
m_request = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8());
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
|
m_task.reset(new NetJob("XboxAuthorizationStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &XboxAuthorizationStep::onRequestDone);
|
connect(m_task.get(), &Task::finished, this, &XboxAuthorizationStep::onRequestDone);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
qDebug() << "Getting authorization token for " << m_relyingParty;
|
qDebug() << "Getting authorization token for " << m_relyingParty;
|
||||||
}
|
}
|
||||||
@ -55,19 +58,19 @@ void XboxAuthorizationStep::perform()
|
|||||||
void XboxAuthorizationStep::onRequestDone()
|
void XboxAuthorizationStep::onRequestDone()
|
||||||
{
|
{
|
||||||
qCDebug(authCredentials()) << *m_response;
|
qCDebug(authCredentials()) << *m_response;
|
||||||
if (m_task->error() != QNetworkReply::NoError) {
|
if (m_request->error() != QNetworkReply::NoError) {
|
||||||
qWarning() << "Reply error:" << m_task->error();
|
qWarning() << "Reply error:" << m_request->error();
|
||||||
if (Net::isApplicationError(m_task->error())) {
|
if (Net::isApplicationError(m_request->error())) {
|
||||||
if (!processSTSError()) {
|
if (!processSTSError()) {
|
||||||
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
||||||
tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, m_task->error()));
|
tr("Failed to get authorization for %1 services. Error %2.").arg(m_authorizationKind, m_request->error()));
|
||||||
} else {
|
} else {
|
||||||
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
||||||
tr("Unknown STS error for %1 services: %2").arg(m_authorizationKind, m_task->errorString()));
|
tr("Unknown STS error for %1 services: %2").arg(m_authorizationKind, m_request->errorString()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emit finished(AccountTaskState::STATE_OFFLINE,
|
emit finished(AccountTaskState::STATE_OFFLINE,
|
||||||
tr("Failed to get authorization for %1 services: %2").arg(m_authorizationKind, m_task->errorString()));
|
tr("Failed to get authorization for %1 services: %2").arg(m_authorizationKind, m_request->errorString()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -92,7 +95,7 @@ void XboxAuthorizationStep::onRequestDone()
|
|||||||
|
|
||||||
bool XboxAuthorizationStep::processSTSError()
|
bool XboxAuthorizationStep::processSTSError()
|
||||||
{
|
{
|
||||||
if (m_task->error() == QNetworkReply::AuthenticationRequiredError) {
|
if (m_request->error() == QNetworkReply::AuthenticationRequiredError) {
|
||||||
QJsonParseError jsonError;
|
QJsonParseError jsonError;
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(*m_response, &jsonError);
|
QJsonDocument doc = QJsonDocument::fromJson(*m_response, &jsonError);
|
||||||
if (jsonError.error) {
|
if (jsonError.error) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
#include "net/Upload.h"
|
#include "net/Upload.h"
|
||||||
|
|
||||||
class XboxAuthorizationStep : public AuthStep {
|
class XboxAuthorizationStep : public AuthStep {
|
||||||
@ -28,5 +29,6 @@ class XboxAuthorizationStep : public AuthStep {
|
|||||||
QString m_authorizationKind;
|
QString m_authorizationKind;
|
||||||
|
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Upload::Ptr m_task;
|
Net::Upload::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -34,25 +34,28 @@ void XboxProfileStep::perform()
|
|||||||
};
|
};
|
||||||
|
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Download::makeByteArray(url, m_response);
|
m_request = Net::Download::makeByteArray(url, m_response);
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
|
m_task.reset(new NetJob("XboxProfileStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &XboxProfileStep::onRequestDone);
|
connect(m_task.get(), &Task::finished, this, &XboxProfileStep::onRequestDone);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
qDebug() << "Getting Xbox profile...";
|
qDebug() << "Getting Xbox profile...";
|
||||||
}
|
}
|
||||||
|
|
||||||
void XboxProfileStep::onRequestDone()
|
void XboxProfileStep::onRequestDone()
|
||||||
{
|
{
|
||||||
if (m_task->error() != QNetworkReply::NoError) {
|
if (m_request->error() != QNetworkReply::NoError) {
|
||||||
qWarning() << "Reply error:" << m_task->error();
|
qWarning() << "Reply error:" << m_request->error();
|
||||||
qCDebug(authCredentials()) << *m_response;
|
qCDebug(authCredentials()) << *m_response;
|
||||||
if (Net::isApplicationError(m_task->error())) {
|
if (Net::isApplicationError(m_request->error())) {
|
||||||
emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to retrieve the Xbox profile: %1").arg(m_task->errorString()));
|
emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Failed to retrieve the Xbox profile: %1").arg(m_request->errorString()));
|
||||||
} else {
|
} else {
|
||||||
emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to retrieve the Xbox profile: %1").arg(m_task->errorString()));
|
emit finished(AccountTaskState::STATE_OFFLINE, tr("Failed to retrieve the Xbox profile: %1").arg(m_request->errorString()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
#include "net/Download.h"
|
#include "net/Download.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
|
|
||||||
class XboxProfileStep : public AuthStep {
|
class XboxProfileStep : public AuthStep {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -21,5 +22,6 @@ class XboxProfileStep : public AuthStep {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Download::Ptr m_task;
|
Net::Download::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -38,24 +38,27 @@ void XboxUserStep::perform()
|
|||||||
{ "x-xbl-contract-version", "1" }
|
{ "x-xbl-contract-version", "1" }
|
||||||
};
|
};
|
||||||
m_response.reset(new QByteArray());
|
m_response.reset(new QByteArray());
|
||||||
m_task = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8());
|
m_request = Net::Upload::makeByteArray(url, m_response, xbox_auth_data.toUtf8());
|
||||||
m_task->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
m_request->addHeaderProxy(new Net::RawHeaderProxy(headers));
|
||||||
|
|
||||||
|
m_task.reset(new NetJob("XboxUserStep", APPLICATION->network()));
|
||||||
|
m_task->setAskRetry(false);
|
||||||
|
m_task->addNetAction(m_request);
|
||||||
|
|
||||||
connect(m_task.get(), &Task::finished, this, &XboxUserStep::onRequestDone);
|
connect(m_task.get(), &Task::finished, this, &XboxUserStep::onRequestDone);
|
||||||
|
|
||||||
m_task->setNetwork(APPLICATION->network());
|
|
||||||
m_task->start();
|
m_task->start();
|
||||||
qDebug() << "First layer of XBox auth ... commencing.";
|
qDebug() << "First layer of XBox auth ... commencing.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void XboxUserStep::onRequestDone()
|
void XboxUserStep::onRequestDone()
|
||||||
{
|
{
|
||||||
if (m_task->error() != QNetworkReply::NoError) {
|
if (m_request->error() != QNetworkReply::NoError) {
|
||||||
qWarning() << "Reply error:" << m_task->error();
|
qWarning() << "Reply error:" << m_request->error();
|
||||||
if (Net::isApplicationError(m_task->error())) {
|
if (Net::isApplicationError(m_request->error())) {
|
||||||
emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication failed: %1").arg(m_task->errorString()));
|
emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("XBox user authentication failed: %1").arg(m_request->errorString()));
|
||||||
} else {
|
} else {
|
||||||
emit finished(AccountTaskState::STATE_OFFLINE, tr("XBox user authentication failed: %1").arg(m_task->errorString()));
|
emit finished(AccountTaskState::STATE_OFFLINE, tr("XBox user authentication failed: %1").arg(m_request->errorString()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "minecraft/auth/AuthStep.h"
|
#include "minecraft/auth/AuthStep.h"
|
||||||
|
#include "net/NetJob.h"
|
||||||
#include "net/Upload.h"
|
#include "net/Upload.h"
|
||||||
|
|
||||||
class XboxUserStep : public AuthStep {
|
class XboxUserStep : public AuthStep {
|
||||||
@ -21,5 +22,6 @@ class XboxUserStep : public AuthStep {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QByteArray> m_response;
|
std::shared_ptr<QByteArray> m_response;
|
||||||
Net::Upload::Ptr m_task;
|
Net::Upload::Ptr m_request;
|
||||||
|
NetJob::Ptr m_task;
|
||||||
};
|
};
|
||||||
|
@ -159,15 +159,14 @@ bool Resource::enable(EnableAction action)
|
|||||||
if (!path.endsWith(".disabled"))
|
if (!path.endsWith(".disabled"))
|
||||||
return false;
|
return false;
|
||||||
path.chop(9);
|
path.chop(9);
|
||||||
|
|
||||||
if (!file.rename(path))
|
|
||||||
return false;
|
|
||||||
} else {
|
} else {
|
||||||
path += ".disabled";
|
path += ".disabled";
|
||||||
|
if (QFile::exists(path)) {
|
||||||
if (!file.rename(path))
|
path = FS::getUniqueResourceName(path);
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
if (!file.rename(path))
|
||||||
|
return false;
|
||||||
|
|
||||||
setFile(QFileInfo(path));
|
setFile(QFileInfo(path));
|
||||||
|
|
||||||
|
@ -215,9 +215,6 @@ bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, Ena
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto new_id = resource->internal_id();
|
auto new_id = resource->internal_id();
|
||||||
if (m_resources_index.contains(new_id)) {
|
|
||||||
// FIXME: https://github.com/PolyMC/PolyMC/issues/550
|
|
||||||
}
|
|
||||||
|
|
||||||
m_resources_index.remove(old_id);
|
m_resources_index.remove(old_id);
|
||||||
m_resources_index[new_id] = row;
|
m_resources_index[new_id] = row;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "FileSystem.h"
|
||||||
#include "minecraft/mod/Resource.h"
|
#include "minecraft/mod/Resource.h"
|
||||||
|
|
||||||
#include "tasks/Task.h"
|
#include "tasks/Task.h"
|
||||||
@ -50,6 +51,12 @@ class BasicFolderLoadTask : public Task {
|
|||||||
|
|
||||||
m_dir.refresh();
|
m_dir.refresh();
|
||||||
for (auto entry : m_dir.entryInfoList()) {
|
for (auto entry : m_dir.entryInfoList()) {
|
||||||
|
auto filePath = entry.absoluteFilePath();
|
||||||
|
auto newFilePath = FS::getUniqueResourceName(filePath);
|
||||||
|
if (newFilePath != filePath) {
|
||||||
|
FS::move(filePath, newFilePath);
|
||||||
|
entry = QFileInfo(newFilePath);
|
||||||
|
}
|
||||||
auto resource = m_create_func(entry);
|
auto resource = m_create_func(entry);
|
||||||
resource->moveToThread(m_thread_to_spawn_into);
|
resource->moveToThread(m_thread_to_spawn_into);
|
||||||
m_result->resources.insert(resource->internal_id(), resource);
|
m_result->resources.insert(resource->internal_id(), resource);
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "ModFolderLoadTask.h"
|
#include "ModFolderLoadTask.h"
|
||||||
|
|
||||||
|
#include "FileSystem.h"
|
||||||
#include "minecraft/mod/MetadataHandler.h"
|
#include "minecraft/mod/MetadataHandler.h"
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
@ -63,6 +64,12 @@ void ModFolderLoadTask::executeTask()
|
|||||||
// Read JAR files that don't have metadata
|
// Read JAR files that don't have metadata
|
||||||
m_mods_dir.refresh();
|
m_mods_dir.refresh();
|
||||||
for (auto entry : m_mods_dir.entryInfoList()) {
|
for (auto entry : m_mods_dir.entryInfoList()) {
|
||||||
|
auto filePath = entry.absoluteFilePath();
|
||||||
|
auto newFilePath = FS::getUniqueResourceName(filePath);
|
||||||
|
if (newFilePath != filePath) {
|
||||||
|
FS::move(filePath, newFilePath);
|
||||||
|
entry = QFileInfo(newFilePath);
|
||||||
|
}
|
||||||
Mod* mod(new Mod(entry));
|
Mod* mod(new Mod(entry));
|
||||||
|
|
||||||
if (mod->enabled()) {
|
if (mod->enabled()) {
|
||||||
|
@ -172,4 +172,4 @@ void NetJob::emitFailed(QString reason)
|
|||||||
void NetJob::setAskRetry(bool askRetry)
|
void NetJob::setAskRetry(bool askRetry)
|
||||||
{
|
{
|
||||||
m_ask_retry = askRetry;
|
m_ask_retry = askRetry;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This file incorporates work covered by the following copyright and
|
||||||
|
* permission notice:
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#include "BrightTheme.h"
|
#include "BrightTheme.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@ -55,3 +89,7 @@ QString BrightTheme::appStyleSheet()
|
|||||||
{
|
{
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
QString BrightTheme::tooltip()
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This file incorporates work covered by the following copyright and
|
||||||
|
* permission notice:
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FusionTheme.h"
|
#include "FusionTheme.h"
|
||||||
@ -8,6 +42,7 @@ class BrightTheme : public FusionTheme {
|
|||||||
|
|
||||||
QString id() override;
|
QString id() override;
|
||||||
QString name() override;
|
QString name() override;
|
||||||
|
QString tooltip() override;
|
||||||
bool hasStyleSheet() override;
|
bool hasStyleSheet() override;
|
||||||
QString appStyleSheet() override;
|
QString appStyleSheet() override;
|
||||||
bool hasColorScheme() override;
|
bool hasColorScheme() override;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
/*
|
/*
|
||||||
* Prism Launcher - Minecraft Launcher
|
* Prism Launcher - Minecraft Launcher
|
||||||
* Copyright (C) 2022 Tayou <git@tayou.org>
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -285,3 +285,7 @@ QString CustomTheme::qtTheme()
|
|||||||
{
|
{
|
||||||
return m_widgets;
|
return m_widgets;
|
||||||
}
|
}
|
||||||
|
QString CustomTheme::tooltip()
|
||||||
|
{
|
||||||
|
return m_tooltip;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
/*
|
/*
|
||||||
* Prism Launcher - Minecraft Launcher
|
* Prism Launcher - Minecraft Launcher
|
||||||
* Copyright (C) 2022 Tayou <git@tayou.org>
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -44,6 +44,7 @@ class CustomTheme : public ITheme {
|
|||||||
|
|
||||||
QString id() override;
|
QString id() override;
|
||||||
QString name() override;
|
QString name() override;
|
||||||
|
QString tooltip() override;
|
||||||
bool hasStyleSheet() override;
|
bool hasStyleSheet() override;
|
||||||
QString appStyleSheet() override;
|
QString appStyleSheet() override;
|
||||||
bool hasColorScheme() override;
|
bool hasColorScheme() override;
|
||||||
@ -62,4 +63,10 @@ class CustomTheme : public ITheme {
|
|||||||
QString m_id;
|
QString m_id;
|
||||||
QString m_widgets;
|
QString m_widgets;
|
||||||
QString m_qssFilePath;
|
QString m_qssFilePath;
|
||||||
|
/**
|
||||||
|
* The tooltip could be defined in the theme json,
|
||||||
|
* or composed of other fields that could be in there.
|
||||||
|
* like author, license, etc.
|
||||||
|
*/
|
||||||
|
QString m_tooltip = "";
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This file incorporates work covered by the following copyright and
|
||||||
|
* permission notice:
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#include "DarkTheme.h"
|
#include "DarkTheme.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@ -56,3 +90,7 @@ QString DarkTheme::appStyleSheet()
|
|||||||
{
|
{
|
||||||
return "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }";
|
return "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }";
|
||||||
}
|
}
|
||||||
|
QString DarkTheme::tooltip()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This file incorporates work covered by the following copyright and
|
||||||
|
* permission notice:
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FusionTheme.h"
|
#include "FusionTheme.h"
|
||||||
@ -8,6 +42,7 @@ class DarkTheme : public FusionTheme {
|
|||||||
|
|
||||||
QString id() override;
|
QString id() override;
|
||||||
QString name() override;
|
QString name() override;
|
||||||
|
QString tooltip() override;
|
||||||
bool hasStyleSheet() override;
|
bool hasStyleSheet() override;
|
||||||
QString appStyleSheet() override;
|
QString appStyleSheet() override;
|
||||||
bool hasColorScheme() override;
|
bool hasColorScheme() override;
|
||||||
|
@ -44,6 +44,7 @@ class ITheme {
|
|||||||
virtual void apply(bool initial);
|
virtual void apply(bool initial);
|
||||||
virtual QString id() = 0;
|
virtual QString id() = 0;
|
||||||
virtual QString name() = 0;
|
virtual QString name() = 0;
|
||||||
|
virtual QString tooltip() = 0;
|
||||||
virtual bool hasStyleSheet() = 0;
|
virtual bool hasStyleSheet() = 0;
|
||||||
virtual QString appStyleSheet() = 0;
|
virtual QString appStyleSheet() = 0;
|
||||||
virtual QString qtTheme() = 0;
|
virtual QString qtTheme() = 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
/*
|
/*
|
||||||
* Prism Launcher - Minecraft Launcher
|
* Prism Launcher - Minecraft Launcher
|
||||||
* Copyright (C) 2022 Tayou <git@tayou.org>
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
* Copyright (C) 2024 TheKodeToad <TheKodeToad@proton.me>
|
* Copyright (C) 2024 TheKodeToad <TheKodeToad@proton.me>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@ -35,31 +35,16 @@
|
|||||||
*/
|
*/
|
||||||
#include "SystemTheme.h"
|
#include "SystemTheme.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
#include "HintOverrideProxyStyle.h"
|
#include "HintOverrideProxyStyle.h"
|
||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
|
|
||||||
SystemTheme::SystemTheme()
|
SystemTheme::SystemTheme(QString& styleName, bool isSystemTheme)
|
||||||
{
|
{
|
||||||
themeDebugLog() << "Determining System Theme...";
|
themeName = isSystemTheme ? "system" : styleName;
|
||||||
const auto& style = QApplication::style();
|
widgetTheme = styleName;
|
||||||
systemPalette = QApplication::palette();
|
colorPalette = QApplication::palette();
|
||||||
QString lowerThemeName = style->objectName();
|
|
||||||
themeDebugLog() << "System theme seems to be:" << lowerThemeName;
|
|
||||||
QStringList styles = QStyleFactory::keys();
|
|
||||||
for (auto& st : styles) {
|
|
||||||
themeDebugLog() << "Considering theme from theme factory:" << st.toLower();
|
|
||||||
if (st.toLower() == lowerThemeName) {
|
|
||||||
systemTheme = st;
|
|
||||||
themeDebugLog() << "System theme has been determined to be:" << systemTheme;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// fall back to fusion if we can't find the current theme.
|
|
||||||
systemTheme = "Fusion";
|
|
||||||
themeDebugLog() << "System theme not found, defaulted to Fusion";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTheme::apply(bool initial)
|
void SystemTheme::apply(bool initial)
|
||||||
@ -76,22 +61,49 @@ void SystemTheme::apply(bool initial)
|
|||||||
|
|
||||||
QString SystemTheme::id()
|
QString SystemTheme::id()
|
||||||
{
|
{
|
||||||
return "system";
|
return themeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SystemTheme::name()
|
QString SystemTheme::name()
|
||||||
{
|
{
|
||||||
return QObject::tr("System");
|
if (themeName.toLower() == "windowsvista") {
|
||||||
|
return QObject::tr("Windows Vista");
|
||||||
|
} else if (themeName.toLower() == "windows") {
|
||||||
|
return QObject::tr("Windows 9x");
|
||||||
|
} else if (themeName.toLower() == "windows11") {
|
||||||
|
return QObject::tr("Windows 11");
|
||||||
|
} else if (themeName.toLower() == "system") {
|
||||||
|
return QObject::tr("System");
|
||||||
|
} else {
|
||||||
|
return themeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SystemTheme::tooltip()
|
||||||
|
{
|
||||||
|
if (themeName.toLower() == "windowsvista") {
|
||||||
|
return QObject::tr("Widget style trying to look like your win32 theme");
|
||||||
|
} else if (themeName.toLower() == "windows") {
|
||||||
|
return QObject::tr("Windows 9x inspired widget style");
|
||||||
|
} else if (themeName.toLower() == "windows11") {
|
||||||
|
return QObject::tr("WinUI 3 inspired Qt widget style");
|
||||||
|
} else if (themeName.toLower() == "fusion") {
|
||||||
|
return QObject::tr("The default Qt widget style");
|
||||||
|
} else if (themeName.toLower() == "system") {
|
||||||
|
return QObject::tr("Your current system theme");
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SystemTheme::qtTheme()
|
QString SystemTheme::qtTheme()
|
||||||
{
|
{
|
||||||
return systemTheme;
|
return widgetTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPalette SystemTheme::colorScheme()
|
QPalette SystemTheme::colorScheme()
|
||||||
{
|
{
|
||||||
return systemPalette;
|
return colorPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SystemTheme::appStyleSheet()
|
QString SystemTheme::appStyleSheet()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
/*
|
/*
|
||||||
* Prism Launcher - Minecraft Launcher
|
* Prism Launcher - Minecraft Launcher
|
||||||
* Copyright (C) 2022 Tayou <git@tayou.org>
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -38,12 +38,13 @@
|
|||||||
|
|
||||||
class SystemTheme : public ITheme {
|
class SystemTheme : public ITheme {
|
||||||
public:
|
public:
|
||||||
SystemTheme();
|
SystemTheme(QString& themeName, bool isSystemTheme = false);
|
||||||
virtual ~SystemTheme() {}
|
virtual ~SystemTheme() {}
|
||||||
void apply(bool initial) override;
|
void apply(bool initial) override;
|
||||||
|
|
||||||
QString id() override;
|
QString id() override;
|
||||||
QString name() override;
|
QString name() override;
|
||||||
|
QString tooltip() override;
|
||||||
QString qtTheme() override;
|
QString qtTheme() override;
|
||||||
bool hasStyleSheet() override;
|
bool hasStyleSheet() override;
|
||||||
QString appStyleSheet() override;
|
QString appStyleSheet() override;
|
||||||
@ -53,6 +54,7 @@ class SystemTheme : public ITheme {
|
|||||||
QColor fadeColor() override;
|
QColor fadeColor() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPalette systemPalette;
|
QPalette colorPalette;
|
||||||
QString systemTheme;
|
QString widgetTheme;
|
||||||
|
QString themeName;
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
/*
|
/*
|
||||||
* Prism Launcher - Minecraft Launcher
|
* Prism Launcher - Minecraft Launcher
|
||||||
* Copyright (C) 2022 Tayou <git@tayou.org>
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
|
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@ -23,6 +23,8 @@
|
|||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QStyleFactory>
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
#include "ui/themes/BrightTheme.h"
|
#include "ui/themes/BrightTheme.h"
|
||||||
#include "ui/themes/CatPack.h"
|
#include "ui/themes/CatPack.h"
|
||||||
@ -119,14 +121,30 @@ void ThemeManager::initializeIcons()
|
|||||||
|
|
||||||
void ThemeManager::initializeWidgets()
|
void ThemeManager::initializeWidgets()
|
||||||
{
|
{
|
||||||
|
themeDebugLog() << "Determining System Widget Theme...";
|
||||||
|
const auto& style = QApplication::style();
|
||||||
|
currentlySelectedSystemTheme = style->objectName();
|
||||||
|
themeDebugLog() << "System theme seems to be:" << currentlySelectedSystemTheme;
|
||||||
|
|
||||||
themeDebugLog() << "<> Initializing Widget Themes";
|
themeDebugLog() << "<> Initializing Widget Themes";
|
||||||
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<SystemTheme>());
|
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<SystemTheme>(currentlySelectedSystemTheme, true));
|
||||||
auto darkThemeId = addTheme(std::make_unique<DarkTheme>());
|
auto darkThemeId = addTheme(std::make_unique<DarkTheme>());
|
||||||
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
|
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
|
||||||
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<BrightTheme>());
|
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<BrightTheme>());
|
||||||
|
|
||||||
// TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in
|
themeDebugLog() << "<> Initializing System Widget Themes";
|
||||||
// dropdown?)
|
QStringList styles = QStyleFactory::keys();
|
||||||
|
for (auto& st : styles) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
if (QSysInfo::productVersion() != "11" && st == "windows11") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
themeDebugLog() << "Loading System Theme:" << addTheme(std::make_unique<SystemTheme>(st));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: need some way to differentiate same name themes in different subdirectories
|
||||||
|
// (maybe smaller grey text next to theme name in dropdown?)
|
||||||
|
|
||||||
if (!m_applicationThemeFolder.mkpath("."))
|
if (!m_applicationThemeFolder.mkpath("."))
|
||||||
themeWarningLog() << "Couldn't create theme folder";
|
themeWarningLog() << "Couldn't create theme folder";
|
||||||
@ -238,7 +256,11 @@ void ThemeManager::applyCurrentlySelectedTheme(bool initial)
|
|||||||
auto settings = APPLICATION->settings();
|
auto settings = APPLICATION->settings();
|
||||||
setIconTheme(settings->get("IconTheme").toString());
|
setIconTheme(settings->get("IconTheme").toString());
|
||||||
themeDebugLog() << "<> Icon theme set.";
|
themeDebugLog() << "<> Icon theme set.";
|
||||||
setApplicationTheme(settings->get("ApplicationTheme").toString(), initial);
|
auto applicationTheme = settings->get("ApplicationTheme").toString();
|
||||||
|
if (applicationTheme == "") {
|
||||||
|
applicationTheme = currentlySelectedSystemTheme;
|
||||||
|
}
|
||||||
|
setApplicationTheme(applicationTheme, initial);
|
||||||
themeDebugLog() << "<> Application theme set.";
|
themeDebugLog() << "<> Application theme set.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
/*
|
/*
|
||||||
* Prism Launcher - Minecraft Launcher
|
* Prism Launcher - Minecraft Launcher
|
||||||
* Copyright (C) 2022 Tayou <git@tayou.org>
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
|
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@ -64,6 +64,7 @@ class ThemeManager {
|
|||||||
QDir m_applicationThemeFolder{ "themes" };
|
QDir m_applicationThemeFolder{ "themes" };
|
||||||
QDir m_catPacksFolder{ "catpacks" };
|
QDir m_catPacksFolder{ "catpacks" };
|
||||||
std::map<QString, std::unique_ptr<CatPack>> m_cat_packs;
|
std::map<QString, std::unique_ptr<CatPack>> m_cat_packs;
|
||||||
|
QString currentlySelectedSystemTheme;
|
||||||
|
|
||||||
void initializeThemes();
|
void initializeThemes();
|
||||||
void initializeCatPacks();
|
void initializeCatPacks();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
/*
|
/*
|
||||||
* Prism Launcher - Minecraft Launcher
|
* Prism Launcher - Minecraft Launcher
|
||||||
* Copyright (C) 2022 Tayou <git@tayou.org>
|
* Copyright (C) 2024 Tayou <git@tayou.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -151,6 +151,10 @@ void ThemeCustomizationWidget::loadSettings()
|
|||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (auto& theme : themes) {
|
for (auto& theme : themes) {
|
||||||
ui->widgetStyleComboBox->addItem(theme->name(), theme->id());
|
ui->widgetStyleComboBox->addItem(theme->name(), theme->id());
|
||||||
|
if (theme->tooltip() != "") {
|
||||||
|
int index = ui->widgetStyleComboBox->count() - 1;
|
||||||
|
ui->widgetStyleComboBox->setItemData(index, theme->tooltip(), Qt::ToolTipRole);
|
||||||
|
}
|
||||||
if (currentTheme == theme->id()) {
|
if (currentTheme == theme->id()) {
|
||||||
ui->widgetStyleComboBox->setCurrentIndex(idx);
|
ui->widgetStyleComboBox->setCurrentIndex(idx);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user