Merge branch 'develop' into launcher-log-page
This commit is contained in:
commit
836c558c6c
42 changed files with 332 additions and 120 deletions
|
@ -796,6 +796,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||||
// The cat
|
// The cat
|
||||||
m_settings->registerSetting("TheCat", false);
|
m_settings->registerSetting("TheCat", false);
|
||||||
m_settings->registerSetting("CatOpacity", 100);
|
m_settings->registerSetting("CatOpacity", 100);
|
||||||
|
m_settings->registerSetting("CatFit", "fit");
|
||||||
|
|
||||||
m_settings->registerSetting("StatusBarVisible", true);
|
m_settings->registerSetting("StatusBarVisible", true);
|
||||||
|
|
||||||
|
|
|
@ -893,6 +893,8 @@ SET(LAUNCHER_SOURCES
|
||||||
ui/themes/ThemeManager.h
|
ui/themes/ThemeManager.h
|
||||||
ui/themes/CatPack.cpp
|
ui/themes/CatPack.cpp
|
||||||
ui/themes/CatPack.h
|
ui/themes/CatPack.h
|
||||||
|
ui/themes/CatPainter.cpp
|
||||||
|
ui/themes/CatPainter.h
|
||||||
|
|
||||||
# Processes
|
# Processes
|
||||||
LaunchController.h
|
LaunchController.h
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#pragma once
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace SysInfo {
|
namespace SysInfo {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#include <QAnyStringView>
|
#include <QAnyStringView>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
|
@ -159,7 +159,7 @@ bool loadAssetsIndexJson(const QString& assetsId, const QString& path, AssetsInd
|
||||||
if (key == "hash") {
|
if (key == "hash") {
|
||||||
object.hash = value.toString();
|
object.hash = value.toString();
|
||||||
} else if (key == "size") {
|
} else if (key == "size") {
|
||||||
object.size = value.toDouble();
|
object.size = value.toLongLong();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -462,7 +462,7 @@ void Component::waitLoadMeta()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Component::setUpdateAction(UpdateAction action)
|
void Component::setUpdateAction(const UpdateAction& action)
|
||||||
{
|
{
|
||||||
m_updateAction = action;
|
m_updateAction = action;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ class Component : public QObject, public ProblemProvider {
|
||||||
|
|
||||||
void waitLoadMeta();
|
void waitLoadMeta();
|
||||||
|
|
||||||
void setUpdateAction(UpdateAction action);
|
void setUpdateAction(const UpdateAction& action);
|
||||||
void clearUpdateAction();
|
void clearUpdateAction();
|
||||||
UpdateAction getUpdateAction();
|
UpdateAction getUpdateAction();
|
||||||
|
|
||||||
|
|
|
@ -570,7 +570,7 @@ void ComponentUpdateTask::performUpdateActions()
|
||||||
component->setVersion(cv.targetVersion);
|
component->setVersion(cv.targetVersion);
|
||||||
component->waitLoadMeta();
|
component->waitLoadMeta();
|
||||||
},
|
},
|
||||||
[&component, &instance](const UpdateActionLatestRecommendedCompatible lrc) {
|
[&component, &instance](const UpdateActionLatestRecommendedCompatible& lrc) {
|
||||||
qCDebug(instanceProfileResolveC)
|
qCDebug(instanceProfileResolveC)
|
||||||
<< instance->name() << "|"
|
<< instance->name() << "|"
|
||||||
<< "UpdateActionLatestRecommendedCompatible" << component->getID() << ":" << component->getVersion()
|
<< "UpdateActionLatestRecommendedCompatible" << component->getID() << ":" << component->getVersion()
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void tokenToJSONV3(QJsonObject& parent, Token t, const char* tokenName)
|
void tokenToJSONV3(QJsonObject& parent, const Token& t, const char* tokenName)
|
||||||
{
|
{
|
||||||
if (!t.persistent) {
|
if (!t.persistent) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -87,7 +87,7 @@ ModPlatform::Dependency GetModDependenciesTask::getOverride(const ModPlatform::D
|
||||||
{
|
{
|
||||||
if (auto isQuilt = m_loaderType & ModPlatform::Quilt; isQuilt || m_loaderType & ModPlatform::Fabric) {
|
if (auto isQuilt = m_loaderType & ModPlatform::Quilt; isQuilt || m_loaderType & ModPlatform::Fabric) {
|
||||||
auto overide = ModPlatform::getOverrideDeps();
|
auto overide = ModPlatform::getOverrideDeps();
|
||||||
auto over = std::find_if(overide.cbegin(), overide.cend(), [dep, providerName, isQuilt](auto o) {
|
auto over = std::find_if(overide.cbegin(), overide.cend(), [dep, providerName, isQuilt](const auto& o) {
|
||||||
return o.provider == providerName && dep.addonId == (isQuilt ? o.fabric : o.quilt);
|
return o.provider == providerName && dep.addonId == (isQuilt ? o.fabric : o.quilt);
|
||||||
});
|
});
|
||||||
if (over != overide.cend()) {
|
if (over != overide.cend()) {
|
||||||
|
@ -207,8 +207,9 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
|
||||||
if (!pDep->version.addonId.isValid()) {
|
if (!pDep->version.addonId.isValid()) {
|
||||||
if (m_loaderType & ModPlatform::Quilt) { // falback for quilt
|
if (m_loaderType & ModPlatform::Quilt) { // falback for quilt
|
||||||
auto overide = ModPlatform::getOverrideDeps();
|
auto overide = ModPlatform::getOverrideDeps();
|
||||||
auto over = std::find_if(overide.cbegin(), overide.cend(),
|
auto over = std::find_if(overide.cbegin(), overide.cend(), [dep, provider](const auto& o) {
|
||||||
[dep, provider](auto o) { return o.provider == provider.name && dep.addonId == o.quilt; });
|
return o.provider == provider.name && dep.addonId == o.quilt;
|
||||||
|
});
|
||||||
if (over != overide.cend()) {
|
if (over != overide.cend()) {
|
||||||
removePack(dep.addonId);
|
removePack(dep.addonId);
|
||||||
addTask(prepareDependencyTask({ over->fabric, dep.type }, provider.name, level));
|
addTask(prepareDependencyTask({ over->fabric, dep.type }, provider.name, level));
|
||||||
|
|
|
@ -45,3 +45,4 @@ void loadIndexedPack(IndexedPack& m, QJsonObject& obj);
|
||||||
} // namespace ATLauncher
|
} // namespace ATLauncher
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ATLauncher::IndexedPack)
|
Q_DECLARE_METATYPE(ATLauncher::IndexedPack)
|
||||||
|
Q_DECLARE_METATYPE(QList<ATLauncher::IndexedVersion>)
|
|
@ -391,7 +391,7 @@ QString PackInstallTask::getVersionForLoader(QString uid)
|
||||||
return m_version.loader.version;
|
return m_version.loader.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PackInstallTask::detectLibrary(VersionLibrary library)
|
QString PackInstallTask::detectLibrary(const VersionLibrary& library)
|
||||||
{
|
{
|
||||||
// Try to detect what the library is
|
// Try to detect what the library is
|
||||||
if (!library.server.isEmpty() && library.server.split("/").length() >= 3) {
|
if (!library.server.isEmpty() && library.server.split("/").length() >= 3) {
|
||||||
|
|
|
@ -105,7 +105,7 @@ class PackInstallTask : public InstanceTask {
|
||||||
private:
|
private:
|
||||||
QString getDirForModType(ModType type, QString raw);
|
QString getDirForModType(ModType type, QString raw);
|
||||||
QString getVersionForLoader(QString uid);
|
QString getVersionForLoader(QString uid);
|
||||||
QString detectLibrary(VersionLibrary library);
|
QString detectLibrary(const VersionLibrary& library);
|
||||||
|
|
||||||
bool createLibrariesComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile);
|
bool createLibrariesComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile);
|
||||||
bool createPackComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile);
|
bool createPackComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile);
|
||||||
|
|
|
@ -140,3 +140,11 @@ void Flame::loadIndexedPackVersions(Flame::IndexedPack& pack, QJsonArray& arr)
|
||||||
pack.versions = unsortedVersions;
|
pack.versions = unsortedVersions;
|
||||||
pack.versionsLoaded = true;
|
pack.versionsLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Flame::getVersionDisplayString(const IndexedVersion& version) -> QString
|
||||||
|
{
|
||||||
|
auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : "";
|
||||||
|
auto mcVersion =
|
||||||
|
!version.mcVersion.isEmpty() && !version.version.contains(version.mcVersion) ? QObject::tr(" for %1").arg(version.mcVersion) : "";
|
||||||
|
return QString("%1%2%3").arg(version.version, mcVersion, release_type);
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,9 @@ struct IndexedPack {
|
||||||
void loadIndexedPack(IndexedPack& m, QJsonObject& obj);
|
void loadIndexedPack(IndexedPack& m, QJsonObject& obj);
|
||||||
void loadIndexedInfo(IndexedPack&, QJsonObject&);
|
void loadIndexedInfo(IndexedPack&, QJsonObject&);
|
||||||
void loadIndexedPackVersions(IndexedPack& m, QJsonArray& arr);
|
void loadIndexedPackVersions(IndexedPack& m, QJsonArray& arr);
|
||||||
|
|
||||||
|
auto getVersionDisplayString(const IndexedVersion&) -> QString;
|
||||||
} // namespace Flame
|
} // namespace Flame
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Flame::IndexedPack)
|
Q_DECLARE_METATYPE(Flame::IndexedPack)
|
||||||
|
Q_DECLARE_METATYPE(QList<Flame::IndexedVersion>)
|
||||||
|
|
|
@ -183,4 +183,14 @@ auto loadIndexedVersion(QJsonObject& obj) -> ModpackVersion
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto getVersionDisplayString(const ModpackVersion& version) -> QString
|
||||||
|
{
|
||||||
|
auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : "";
|
||||||
|
auto mcVersion = !version.gameVersion.isEmpty() && !version.name.contains(version.gameVersion)
|
||||||
|
? QObject::tr(" for %1").arg(version.gameVersion)
|
||||||
|
: "";
|
||||||
|
auto versionStr = !version.name.contains(version.version) ? version.version : "";
|
||||||
|
return QString("%1%2 — %3%4").arg(version.name, mcVersion, versionStr, release_type);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Modrinth
|
} // namespace Modrinth
|
||||||
|
|
|
@ -120,7 +120,10 @@ auto loadIndexedVersion(QJsonObject&) -> ModpackVersion;
|
||||||
|
|
||||||
auto validateDownloadUrl(QUrl) -> bool;
|
auto validateDownloadUrl(QUrl) -> bool;
|
||||||
|
|
||||||
|
auto getVersionDisplayString(const ModpackVersion&) -> QString;
|
||||||
|
|
||||||
} // namespace Modrinth
|
} // namespace Modrinth
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Modrinth::Modpack)
|
Q_DECLARE_METATYPE(Modrinth::Modpack)
|
||||||
Q_DECLARE_METATYPE(Modrinth::ModpackVersion)
|
Q_DECLARE_METATYPE(Modrinth::ModpackVersion)
|
||||||
|
Q_DECLARE_METATYPE(QList<Modrinth::ModpackVersion>)
|
||||||
|
|
|
@ -102,9 +102,10 @@ ExportPackDialog::ExportPackDialog(MinecraftInstancePtr instance, QWidget* paren
|
||||||
|
|
||||||
MinecraftInstance* mcInstance = dynamic_cast<MinecraftInstance*>(instance.get());
|
MinecraftInstance* mcInstance = dynamic_cast<MinecraftInstance*>(instance.get());
|
||||||
if (mcInstance) {
|
if (mcInstance) {
|
||||||
for (auto& resourceModel : mcInstance->resourceLists())
|
for (auto resourceModel : mcInstance->resourceLists()) {
|
||||||
if (resourceModel->indexDir().exists())
|
if (resourceModel && resourceModel->indexDir().exists())
|
||||||
m_proxy->ignoreFilesWithPath().insert(instanceRoot.relativeFilePath(resourceModel->indexDir().absolutePath()));
|
m_proxy->ignoreFilesWithPath().insert(instanceRoot.relativeFilePath(resourceModel->indexDir().absolutePath()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->files->setModel(m_proxy);
|
m_ui->files->setModel(m_proxy);
|
||||||
|
|
|
@ -139,6 +139,9 @@ void MSALoginDialog::onTaskFailed(QString reason)
|
||||||
void MSALoginDialog::authorizeWithBrowser(const QUrl& url)
|
void MSALoginDialog::authorizeWithBrowser(const QUrl& url)
|
||||||
{
|
{
|
||||||
ui->stackedWidget2->setCurrentIndex(1);
|
ui->stackedWidget2->setCurrentIndex(1);
|
||||||
|
ui->stackedWidget2->adjustSize();
|
||||||
|
ui->stackedWidget2->updateGeometry();
|
||||||
|
this->adjustSize();
|
||||||
ui->loginButton->setToolTip(QString("<div style='width: 200px;'>%1</div>").arg(url.toString()));
|
ui->loginButton->setToolTip(QString("<div style='width: 200px;'>%1</div>").arg(url.toString()));
|
||||||
m_url = url;
|
m_url = url;
|
||||||
}
|
}
|
||||||
|
@ -173,6 +176,9 @@ void paintQR(QPainter& painter, const QSize sz, const QString& data, QColor fg)
|
||||||
void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, [[maybe_unused]] int expiresIn)
|
void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, [[maybe_unused]] int expiresIn)
|
||||||
{
|
{
|
||||||
ui->stackedWidget->setCurrentIndex(1);
|
ui->stackedWidget->setCurrentIndex(1);
|
||||||
|
ui->stackedWidget->adjustSize();
|
||||||
|
ui->stackedWidget->updateGeometry();
|
||||||
|
this->adjustSize();
|
||||||
|
|
||||||
const auto linkString = QString("<a href=\"%1\">%2</a>").arg(url, url);
|
const auto linkString = QString("<a href=\"%1\">%2</a>").arg(url, url);
|
||||||
if (url == "https://www.microsoft.com/link" && !code.isEmpty()) {
|
if (url == "https://www.microsoft.com/link" && !code.isEmpty()) {
|
||||||
|
@ -196,12 +202,18 @@ void MSALoginDialog::authorizeWithBrowserWithExtra(QString url, QString code, [[
|
||||||
void MSALoginDialog::onDeviceFlowStatus(QString status)
|
void MSALoginDialog::onDeviceFlowStatus(QString status)
|
||||||
{
|
{
|
||||||
ui->stackedWidget->setCurrentIndex(0);
|
ui->stackedWidget->setCurrentIndex(0);
|
||||||
|
ui->stackedWidget->adjustSize();
|
||||||
|
ui->stackedWidget->updateGeometry();
|
||||||
|
this->adjustSize();
|
||||||
ui->status->setText(status);
|
ui->status->setText(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSALoginDialog::onAuthFlowStatus(QString status)
|
void MSALoginDialog::onAuthFlowStatus(QString status)
|
||||||
{
|
{
|
||||||
ui->stackedWidget2->setCurrentIndex(0);
|
ui->stackedWidget2->setCurrentIndex(0);
|
||||||
|
ui->stackedWidget2->adjustSize();
|
||||||
|
ui->stackedWidget2->updateGeometry();
|
||||||
|
this->adjustSize();
|
||||||
ui->status2->setText(status);
|
ui->status2->setText(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
#include "VisualGroup.h"
|
#include "VisualGroup.h"
|
||||||
|
#include "ui/themes/CatPainter.h"
|
||||||
#include "ui/themes/ThemeManager.h"
|
#include "ui/themes/ThemeManager.h"
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
|
@ -78,6 +79,9 @@ InstanceView::~InstanceView()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_groups);
|
qDeleteAll(m_groups);
|
||||||
m_groups.clear();
|
m_groups.clear();
|
||||||
|
if (m_cat) {
|
||||||
|
m_cat->deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceView::setModel(QAbstractItemModel* model)
|
void InstanceView::setModel(QAbstractItemModel* model)
|
||||||
|
@ -172,7 +176,7 @@ void InstanceView::updateScrollbar()
|
||||||
|
|
||||||
void InstanceView::updateGeometries()
|
void InstanceView::updateGeometries()
|
||||||
{
|
{
|
||||||
geometryCache.clear();
|
m_geometryCache.clear();
|
||||||
|
|
||||||
QMap<LocaleString, VisualGroup*> cats;
|
QMap<LocaleString, VisualGroup*> cats;
|
||||||
|
|
||||||
|
@ -186,8 +190,8 @@ void InstanceView::updateGeometries()
|
||||||
cat->update();
|
cat->update();
|
||||||
} else {
|
} else {
|
||||||
auto cat = new VisualGroup(groupName, this);
|
auto cat = new VisualGroup(groupName, this);
|
||||||
if (fVisibility) {
|
if (m_fVisibility) {
|
||||||
cat->collapsed = fVisibility(groupName);
|
cat->collapsed = m_fVisibility(groupName);
|
||||||
}
|
}
|
||||||
cats.insert(groupName, cat);
|
cats.insert(groupName, cat);
|
||||||
cat->update();
|
cat->update();
|
||||||
|
@ -436,11 +440,15 @@ void InstanceView::mouseDoubleClickEvent(QMouseEvent* event)
|
||||||
|
|
||||||
void InstanceView::setPaintCat(bool visible)
|
void InstanceView::setPaintCat(bool visible)
|
||||||
{
|
{
|
||||||
m_catVisible = visible;
|
if (m_cat) {
|
||||||
if (visible)
|
disconnect(m_cat, &CatPainter::updateFrame, this, nullptr);
|
||||||
m_catPixmap.load(APPLICATION->themeManager()->getCatPack());
|
delete m_cat;
|
||||||
else
|
m_cat = nullptr;
|
||||||
m_catPixmap = QPixmap();
|
}
|
||||||
|
if (visible) {
|
||||||
|
m_cat = new CatPainter(APPLICATION->themeManager()->getCatPack(), this);
|
||||||
|
connect(m_cat, &CatPainter::updateFrame, this, [this] { viewport()->update(); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
|
void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||||
|
@ -449,19 +457,8 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||||
|
|
||||||
QPainter painter(this->viewport());
|
QPainter painter(this->viewport());
|
||||||
|
|
||||||
if (m_catVisible) {
|
if (m_cat) {
|
||||||
painter.setOpacity(APPLICATION->settings()->get("CatOpacity").toFloat() / 100);
|
m_cat->paint(&painter, this->viewport()->rect());
|
||||||
int widWidth = this->viewport()->width();
|
|
||||||
int widHeight = this->viewport()->height();
|
|
||||||
if (m_catPixmap.width() < widWidth)
|
|
||||||
widWidth = m_catPixmap.width();
|
|
||||||
if (m_catPixmap.height() < widHeight)
|
|
||||||
widHeight = m_catPixmap.height();
|
|
||||||
auto pixmap = m_catPixmap.scaled(widWidth, widHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
||||||
QRect rectOfPixmap = pixmap.rect();
|
|
||||||
rectOfPixmap.moveBottomRight(this->viewport()->rect().bottomRight());
|
|
||||||
painter.drawPixmap(rectOfPixmap.topLeft(), pixmap);
|
|
||||||
painter.setOpacity(1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStyleOptionViewItem option;
|
QStyleOptionViewItem option;
|
||||||
|
@ -711,8 +708,8 @@ QRect InstanceView::geometryRect(const QModelIndex& index) const
|
||||||
}
|
}
|
||||||
|
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
if (geometryCache.contains(row)) {
|
if (m_geometryCache.contains(row)) {
|
||||||
return *geometryCache[row];
|
return *m_geometryCache[row];
|
||||||
}
|
}
|
||||||
|
|
||||||
const VisualGroup* cat = category(index);
|
const VisualGroup* cat = category(index);
|
||||||
|
@ -727,7 +724,7 @@ QRect InstanceView::geometryRect(const QModelIndex& index) const
|
||||||
out.setTop(cat->verticalPosition() + cat->headerHeight() + 5 + cat->rowTopOf(index));
|
out.setTop(cat->verticalPosition() + cat->headerHeight() + 5 + cat->rowTopOf(index));
|
||||||
out.setLeft(m_spacing + x * (itemWidth() + m_spacing));
|
out.setLeft(m_spacing + x * (itemWidth() + m_spacing));
|
||||||
out.setSize(itemDelegate()->sizeHint(option, index));
|
out.setSize(itemDelegate()->sizeHint(option, index));
|
||||||
geometryCache.insert(row, new QRect(out));
|
m_geometryCache.insert(row, new QRect(out));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "VisualGroup.h"
|
#include "VisualGroup.h"
|
||||||
|
#include "ui/themes/CatPainter.h"
|
||||||
|
|
||||||
struct InstanceViewRoles {
|
struct InstanceViewRoles {
|
||||||
enum { GroupRole = Qt::UserRole, ProgressValueRole, ProgressMaximumRole };
|
enum { GroupRole = Qt::UserRole, ProgressValueRole, ProgressMaximumRole };
|
||||||
|
@ -56,7 +57,7 @@ class InstanceView : public QAbstractItemView {
|
||||||
void setModel(QAbstractItemModel* model) override;
|
void setModel(QAbstractItemModel* model) override;
|
||||||
|
|
||||||
using visibilityFunction = std::function<bool(const QString&)>;
|
using visibilityFunction = std::function<bool(const QString&)>;
|
||||||
void setSourceOfGroupCollapseStatus(visibilityFunction f) { fVisibility = f; }
|
void setSourceOfGroupCollapseStatus(visibilityFunction f) { m_fVisibility = f; }
|
||||||
|
|
||||||
/// return geometry rectangle occupied by the specified model item
|
/// return geometry rectangle occupied by the specified model item
|
||||||
QRect geometryRect(const QModelIndex& index) const;
|
QRect geometryRect(const QModelIndex& index) const;
|
||||||
|
@ -116,7 +117,7 @@ class InstanceView : public QAbstractItemView {
|
||||||
friend struct VisualGroup;
|
friend struct VisualGroup;
|
||||||
QList<VisualGroup*> m_groups;
|
QList<VisualGroup*> m_groups;
|
||||||
|
|
||||||
visibilityFunction fVisibility;
|
visibilityFunction m_fVisibility;
|
||||||
|
|
||||||
// geometry
|
// geometry
|
||||||
int m_leftMargin = 5;
|
int m_leftMargin = 5;
|
||||||
|
@ -127,9 +128,8 @@ class InstanceView : public QAbstractItemView {
|
||||||
int m_itemWidth = 100;
|
int m_itemWidth = 100;
|
||||||
int m_currentItemsPerRow = -1;
|
int m_currentItemsPerRow = -1;
|
||||||
int m_currentCursorColumn = -1;
|
int m_currentCursorColumn = -1;
|
||||||
mutable QCache<int, QRect> geometryCache;
|
mutable QCache<int, QRect> m_geometryCache;
|
||||||
bool m_catVisible = false;
|
CatPainter* m_cat = nullptr;
|
||||||
QPixmap m_catPixmap;
|
|
||||||
|
|
||||||
// point where the currently active mouse action started in geometry coordinates
|
// point where the currently active mouse action started in geometry coordinates
|
||||||
QPoint m_pressedPosition;
|
QPoint m_pressedPosition;
|
||||||
|
|
|
@ -292,11 +292,8 @@ void ModrinthManagedPackPage::parseManagedPack()
|
||||||
ui->versionsComboBox->clear();
|
ui->versionsComboBox->clear();
|
||||||
ui->versionsComboBox->blockSignals(false);
|
ui->versionsComboBox->blockSignals(false);
|
||||||
|
|
||||||
for (auto version : m_pack.versions) {
|
for (const auto& version : m_pack.versions) {
|
||||||
QString name = version.version;
|
QString name = Modrinth::getVersionDisplayString(version);
|
||||||
|
|
||||||
if (!version.name.contains(version.version))
|
|
||||||
name = QString("%1 — %2").arg(version.name, version.version);
|
|
||||||
|
|
||||||
// NOTE: the id from version isn't the same id in the modpack format spec...
|
// NOTE: the id from version isn't the same id in the modpack format spec...
|
||||||
// e.g. HexMC's 4.4.0 has versionId 4.0.0 in the modpack index..............
|
// e.g. HexMC's 4.4.0 has versionId 4.0.0 in the modpack index..............
|
||||||
|
@ -489,8 +486,8 @@ void FlameManagedPackPage::parseManagedPack()
|
||||||
ui->versionsComboBox->clear();
|
ui->versionsComboBox->clear();
|
||||||
ui->versionsComboBox->blockSignals(false);
|
ui->versionsComboBox->blockSignals(false);
|
||||||
|
|
||||||
for (auto version : m_pack.versions) {
|
for (const auto& version : m_pack.versions) {
|
||||||
QString name = version.version;
|
QString name = Flame::getVersionDisplayString(version);
|
||||||
|
|
||||||
if (version.fileId == m_inst->getManagedPackVersionID().toInt())
|
if (version.fileId == m_inst->getManagedPackVersionID().toInt())
|
||||||
name = tr("%1 (Current)").arg(name);
|
name = tr("%1 (Current)").arg(name);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#pragma once
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
|
@ -37,9 +37,9 @@ void McResolver::pingWithDomainSRV(QString domain, int port)
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& firstRecord = records.at(0);
|
const auto& firstRecord = records.at(0);
|
||||||
QString domain = firstRecord.target();
|
QString newDomain = firstRecord.target();
|
||||||
int port = firstRecord.port();
|
int newPort = firstRecord.port();
|
||||||
pingWithDomainA(domain, port);
|
pingWithDomainA(newDomain, newPort);
|
||||||
});
|
});
|
||||||
|
|
||||||
lookup->lookup();
|
lookup->lookup();
|
||||||
|
|
|
@ -68,7 +68,10 @@ bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParen
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||||
ATLauncher::IndexedPack pack = sourceModel()->data(index, Qt::UserRole).value<ATLauncher::IndexedPack>();
|
QVariant raw = sourceModel()->data(index, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<ATLauncher::IndexedPack>());
|
||||||
|
auto pack = raw.value<ATLauncher::IndexedPack>();
|
||||||
|
|
||||||
if (searchTerm.startsWith("#"))
|
if (searchTerm.startsWith("#"))
|
||||||
return QString::number(pack.id) == searchTerm.mid(1);
|
return QString::number(pack.id) == searchTerm.mid(1);
|
||||||
return pack.name.contains(searchTerm, Qt::CaseInsensitive);
|
return pack.name.contains(searchTerm, Qt::CaseInsensitive);
|
||||||
|
@ -76,8 +79,12 @@ bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParen
|
||||||
|
|
||||||
bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
||||||
{
|
{
|
||||||
ATLauncher::IndexedPack leftPack = sourceModel()->data(left, Qt::UserRole).value<ATLauncher::IndexedPack>();
|
QVariant leftRaw = sourceModel()->data(left, Qt::UserRole);
|
||||||
ATLauncher::IndexedPack rightPack = sourceModel()->data(right, Qt::UserRole).value<ATLauncher::IndexedPack>();
|
Q_ASSERT(leftRaw.canConvert<ATLauncher::IndexedPack>());
|
||||||
|
auto leftPack = leftRaw.value<ATLauncher::IndexedPack>();
|
||||||
|
QVariant rightRaw = sourceModel()->data(right, Qt::UserRole);
|
||||||
|
Q_ASSERT(rightRaw.canConvert<ATLauncher::IndexedPack>());
|
||||||
|
auto rightPack = rightRaw.value<ATLauncher::IndexedPack>();
|
||||||
|
|
||||||
if (currentSorting == ByPopularity) {
|
if (currentSorting == ByPopularity) {
|
||||||
return leftPack.position > rightPack.position;
|
return leftPack.position > rightPack.position;
|
||||||
|
|
|
@ -143,7 +143,9 @@ void AtlPage::onSelectionChanged(QModelIndex first, [[maybe_unused]] QModelIndex
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
selected = filterModel->data(first, Qt::UserRole).value<ATLauncher::IndexedPack>();
|
QVariant raw = filterModel->data(first, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<ATLauncher::IndexedPack>());
|
||||||
|
selected = raw.value<ATLauncher::IndexedPack>();
|
||||||
|
|
||||||
ui->packDescription->setHtml(StringUtils::htmlListPatch(selected.description.replace("\n", "<br>")));
|
ui->packDescription->setHtml(StringUtils::htmlListPatch(selected.description.replace("\n", "<br>")));
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ bool ListModel::setData(const QModelIndex& index, const QVariant& value, [[maybe
|
||||||
if (pos >= modpacks.size() || pos < 0 || !index.isValid())
|
if (pos >= modpacks.size() || pos < 0 || !index.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Q_ASSERT(value.canConvert<Flame::IndexedPack>());
|
||||||
modpacks[pos] = value.value<Flame::IndexedPack>();
|
modpacks[pos] = value.value<Flame::IndexedPack>();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -166,7 +166,9 @@ void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelInde
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = listModel->data(curr, Qt::UserRole).value<Flame::IndexedPack>();
|
QVariant raw = listModel->data(curr, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Flame::IndexedPack>());
|
||||||
|
current = raw.value<Flame::IndexedPack>();
|
||||||
|
|
||||||
if (!current.versionsLoaded || m_filterWidget->changed()) {
|
if (!current.versionsLoaded || m_filterWidget->changed()) {
|
||||||
qDebug() << "Loading flame modpack versions";
|
qDebug() << "Loading flame modpack versions";
|
||||||
|
@ -206,13 +208,8 @@ void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelInde
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
#endif
|
#endif
|
||||||
for (auto version : current.versions) {
|
for (const auto& version : current.versions) {
|
||||||
auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : "";
|
ui->versionSelectionBox->addItem(Flame::getVersionDisplayString(version), QVariant(version.downloadUrl));
|
||||||
auto mcVersion = !version.mcVersion.isEmpty() && !version.version.contains(version.mcVersion)
|
|
||||||
? QString(" for %1").arg(version.mcVersion)
|
|
||||||
: "";
|
|
||||||
ui->versionSelectionBox->addItem(QString("%1%2%3").arg(version.version, mcVersion, release_type),
|
|
||||||
QVariant(version.downloadUrl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant current_updated;
|
QVariant current_updated;
|
||||||
|
|
|
@ -103,13 +103,16 @@ void ImportFTBPage::suggestCurrent()
|
||||||
dialog->setSuggestedIconFromFile(FS::PathCombine(selected.path, "folder.jpg"), editedLogoName);
|
dialog->setSuggestedIconFromFile(FS::PathCombine(selected.path, "folder.jpg"), editedLogoName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportFTBPage::onPublicPackSelectionChanged(QModelIndex now, QModelIndex prev)
|
void ImportFTBPage::onPublicPackSelectionChanged(QModelIndex now, QModelIndex)
|
||||||
{
|
{
|
||||||
if (!now.isValid()) {
|
if (!now.isValid()) {
|
||||||
onPackSelectionChanged();
|
onPackSelectionChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Modpack selectedPack = currentModel->data(now, Qt::UserRole).value<Modpack>();
|
|
||||||
|
QVariant raw = currentModel->data(now, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modpack>());
|
||||||
|
auto selectedPack = raw.value<Modpack>();
|
||||||
onPackSelectionChanged(&selectedPack);
|
onPackSelectionChanged(&selectedPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,8 +143,12 @@ FilterModel::FilterModel(QObject* parent) : QSortFilterProxyModel(parent)
|
||||||
|
|
||||||
bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
||||||
{
|
{
|
||||||
Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value<Modpack>();
|
QVariant leftRaw = sourceModel()->data(left, Qt::UserRole);
|
||||||
Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value<Modpack>();
|
Q_ASSERT(leftRaw.canConvert<Modpack>());
|
||||||
|
auto leftPack = leftRaw.value<Modpack>();
|
||||||
|
QVariant rightRaw = sourceModel()->data(right, Qt::UserRole);
|
||||||
|
Q_ASSERT(rightRaw.canConvert<Modpack>());
|
||||||
|
auto rightPack = rightRaw.value<Modpack>();
|
||||||
|
|
||||||
if (m_currentSorting == Sorting::ByGameVersion) {
|
if (m_currentSorting == Sorting::ByGameVersion) {
|
||||||
Version lv(leftPack.mcVersion);
|
Version lv(leftPack.mcVersion);
|
||||||
|
@ -166,7 +170,9 @@ bool FilterModel::filterAcceptsRow([[maybe_unused]] int sourceRow, [[maybe_unuse
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||||
Modpack pack = sourceModel()->data(index, Qt::UserRole).value<Modpack>();
|
QVariant raw = sourceModel()->data(index, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modpack>());
|
||||||
|
auto pack = raw.value<Modpack>();
|
||||||
return pack.name.contains(m_searchTerm, Qt::CaseInsensitive);
|
return pack.name.contains(m_searchTerm, Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,12 @@ FilterModel::FilterModel(QObject* parent) : QSortFilterProxyModel(parent)
|
||||||
|
|
||||||
bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
bool FilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
|
||||||
{
|
{
|
||||||
Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value<Modpack>();
|
QVariant leftRaw = sourceModel()->data(left, Qt::UserRole);
|
||||||
Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value<Modpack>();
|
Q_ASSERT(leftRaw.canConvert<Modpack>());
|
||||||
|
auto leftPack = leftRaw.value<Modpack>();
|
||||||
|
QVariant rightRaw = sourceModel()->data(right, Qt::UserRole);
|
||||||
|
Q_ASSERT(rightRaw.canConvert<Modpack>());
|
||||||
|
auto rightPack = rightRaw.value<Modpack>();
|
||||||
|
|
||||||
if (currentSorting == Sorting::ByGameVersion) {
|
if (currentSorting == Sorting::ByGameVersion) {
|
||||||
Version lv(leftPack.mcVersion);
|
Version lv(leftPack.mcVersion);
|
||||||
|
@ -84,7 +88,9 @@ bool FilterModel::filterAcceptsRow([[maybe_unused]] int sourceRow, [[maybe_unuse
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||||
Modpack pack = sourceModel()->data(index, Qt::UserRole).value<Modpack>();
|
QVariant raw = sourceModel()->data(index, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modpack>());
|
||||||
|
auto pack = raw.value<Modpack>();
|
||||||
if (searchTerm.startsWith("#"))
|
if (searchTerm.startsWith("#"))
|
||||||
return pack.packCode == searchTerm.mid(1);
|
return pack.packCode == searchTerm.mid(1);
|
||||||
return pack.name.contains(searchTerm, Qt::CaseInsensitive);
|
return pack.name.contains(searchTerm, Qt::CaseInsensitive);
|
||||||
|
|
|
@ -233,7 +233,9 @@ void Page::onPublicPackSelectionChanged(QModelIndex now, [[maybe_unused]] QModel
|
||||||
onPackSelectionChanged();
|
onPackSelectionChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Modpack selectedPack = publicFilterModel->data(now, Qt::UserRole).value<Modpack>();
|
QVariant raw = publicFilterModel->data(now, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modpack>());
|
||||||
|
auto selectedPack = raw.value<Modpack>();
|
||||||
onPackSelectionChanged(&selectedPack);
|
onPackSelectionChanged(&selectedPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +245,9 @@ void Page::onThirdPartyPackSelectionChanged(QModelIndex now, [[maybe_unused]] QM
|
||||||
onPackSelectionChanged();
|
onPackSelectionChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Modpack selectedPack = thirdPartyFilterModel->data(now, Qt::UserRole).value<Modpack>();
|
QVariant raw = thirdPartyFilterModel->data(now, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modpack>());
|
||||||
|
auto selectedPack = raw.value<Modpack>();
|
||||||
onPackSelectionChanged(&selectedPack);
|
onPackSelectionChanged(&selectedPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +257,9 @@ void Page::onPrivatePackSelectionChanged(QModelIndex now, [[maybe_unused]] QMode
|
||||||
onPackSelectionChanged();
|
onPackSelectionChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Modpack selectedPack = privateFilterModel->data(now, Qt::UserRole).value<Modpack>();
|
QVariant raw = privateFilterModel->data(now, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modpack>());
|
||||||
|
auto selectedPack = raw.value<Modpack>();
|
||||||
onPackSelectionChanged(&selectedPack);
|
onPackSelectionChanged(&selectedPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +334,9 @@ void Page::onTabChanged(int tab)
|
||||||
currentList->selectionModel()->reset();
|
currentList->selectionModel()->reset();
|
||||||
QModelIndex idx = currentList->currentIndex();
|
QModelIndex idx = currentList->currentIndex();
|
||||||
if (idx.isValid()) {
|
if (idx.isValid()) {
|
||||||
auto pack = currentModel->data(idx, Qt::UserRole).value<Modpack>();
|
QVariant raw = currentModel->data(idx, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modpack>());
|
||||||
|
auto pack = raw.value<Modpack>();
|
||||||
onPackSelectionChanged(&pack);
|
onPackSelectionChanged(&pack);
|
||||||
} else {
|
} else {
|
||||||
onPackSelectionChanged();
|
onPackSelectionChanged();
|
||||||
|
|
|
@ -121,6 +121,7 @@ bool ModpackListModel::setData(const QModelIndex& index, const QVariant& value,
|
||||||
if (pos >= modpacks.size() || pos < 0 || !index.isValid())
|
if (pos >= modpacks.size() || pos < 0 || !index.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Q_ASSERT(value.canConvert<Modrinth::Modpack>());
|
||||||
modpacks[pos] = value.value<Modrinth::Modpack>();
|
modpacks[pos] = value.value<Modrinth::Modpack>();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -137,7 +138,7 @@ void ModpackListModel::performPaginatedSearch()
|
||||||
ResourceAPI::ProjectInfoCallbacks callbacks;
|
ResourceAPI::ProjectInfoCallbacks callbacks;
|
||||||
|
|
||||||
callbacks.on_fail = [this](QString reason) { searchRequestFailed(reason); };
|
callbacks.on_fail = [this](QString reason) { searchRequestFailed(reason); };
|
||||||
callbacks.on_succeed = [this](auto& doc, auto& pack) { searchRequestForOneSucceeded(doc); };
|
callbacks.on_succeed = [this](auto& doc, auto&) { searchRequestForOneSucceeded(doc); };
|
||||||
callbacks.on_abort = [this] {
|
callbacks.on_abort = [this] {
|
||||||
qCritical() << "Search task aborted by an unknown reason!";
|
qCritical() << "Search task aborted by an unknown reason!";
|
||||||
searchRequestFailed("Aborted");
|
searchRequestFailed("Aborted");
|
||||||
|
@ -345,7 +346,7 @@ void ModpackListModel::searchRequestForOneSucceeded(QJsonDocument& doc)
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModpackListModel::searchRequestFailed(QString reason)
|
void ModpackListModel::searchRequestFailed(QString)
|
||||||
{
|
{
|
||||||
auto failed_action = dynamic_cast<NetJob*>(jobPtr.get())->getFailedActions().at(0);
|
auto failed_action = dynamic_cast<NetJob*>(jobPtr.get())->getFailedActions().at(0);
|
||||||
if (failed_action->replyStatusCode() == -1) {
|
if (failed_action->replyStatusCode() == -1) {
|
||||||
|
|
|
@ -150,7 +150,9 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = m_model->data(curr, Qt::UserRole).value<Modrinth::Modpack>();
|
QVariant raw = m_model->data(curr, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Modrinth::Modpack>());
|
||||||
|
current = raw.value<Modrinth::Modpack>();
|
||||||
auto name = current.name;
|
auto name = current.name;
|
||||||
|
|
||||||
if (!current.extraInfoLoaded) {
|
if (!current.extraInfoLoaded) {
|
||||||
|
@ -244,14 +246,8 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
#endif
|
#endif
|
||||||
for (auto version : current.versions) {
|
for (const auto& version : current.versions) {
|
||||||
auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : "";
|
ui->versionSelectionBox->addItem(Modrinth::getVersionDisplayString(version), QVariant(version.id));
|
||||||
auto mcVersion = !version.gameVersion.isEmpty() && !version.name.contains(version.gameVersion)
|
|
||||||
? QString(" for %1").arg(version.gameVersion)
|
|
||||||
: "";
|
|
||||||
auto versionStr = !version.name.contains(version.version) ? version.version : "";
|
|
||||||
ui->versionSelectionBox->addItem(QString("%1%2 — %3%4").arg(version.name, mcVersion, versionStr, release_type),
|
|
||||||
QVariant(version.id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant current_updated;
|
QVariant current_updated;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QMetaType>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace Technic {
|
namespace Technic {
|
||||||
|
|
|
@ -135,7 +135,9 @@ void TechnicPage::onSelectionChanged(QModelIndex first, [[maybe_unused]] QModelI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
current = model->data(first, Qt::UserRole).value<Technic::Modpack>();
|
QVariant raw = model->data(first, Qt::UserRole);
|
||||||
|
Q_ASSERT(raw.canConvert<Technic::Modpack>());
|
||||||
|
current = raw.value<Technic::Modpack>();
|
||||||
suggestCurrent();
|
suggestCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
51
launcher/ui/themes/CatPainter.cpp
Normal file
51
launcher/ui/themes/CatPainter.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (c) 2025 Trial97 <alexandru.tripon97@gmail.com>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ui/themes/CatPainter.h"
|
||||||
|
#include <QPixmap>
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
|
CatPainter::CatPainter(const QString& path, QObject* parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
m_image = QPixmap(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CatPainter::paint(QPainter* painter, const QRect& viewport)
|
||||||
|
{
|
||||||
|
QPixmap frame = m_image;
|
||||||
|
|
||||||
|
auto fit = APPLICATION->settings()->get("CatFit").toString();
|
||||||
|
painter->setOpacity(APPLICATION->settings()->get("CatOpacity").toFloat() / 100);
|
||||||
|
int widWidth = viewport.width();
|
||||||
|
int widHeight = viewport.height();
|
||||||
|
auto aspectMode = Qt::IgnoreAspectRatio;
|
||||||
|
if (fit == "fill") {
|
||||||
|
aspectMode = Qt::KeepAspectRatio;
|
||||||
|
} else if (fit == "fit") {
|
||||||
|
aspectMode = Qt::KeepAspectRatio;
|
||||||
|
if (frame.width() < widWidth)
|
||||||
|
widWidth = frame.width();
|
||||||
|
if (frame.height() < widHeight)
|
||||||
|
widHeight = frame.height();
|
||||||
|
}
|
||||||
|
auto pixmap = frame.scaled(widWidth, widHeight, aspectMode, Qt::SmoothTransformation);
|
||||||
|
QRect rectOfPixmap = pixmap.rect();
|
||||||
|
rectOfPixmap.moveBottomRight(viewport.bottomRight());
|
||||||
|
painter->drawPixmap(rectOfPixmap.topLeft(), pixmap);
|
||||||
|
painter->setOpacity(1.0);
|
||||||
|
};
|
38
launcher/ui/themes/CatPainter.h
Normal file
38
launcher/ui/themes/CatPainter.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (c) 2025 Trial97 <alexandru.tripon97@gmail.com>
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMovie>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class CatPainter : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CatPainter(const QString& path, QObject* parent = nullptr);
|
||||||
|
virtual ~CatPainter() = default;
|
||||||
|
void paint(QPainter*, const QRect&);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void updateFrame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPixmap m_image;
|
||||||
|
};
|
|
@ -97,22 +97,28 @@ void AppearanceWidget::applySettings()
|
||||||
settings->set("ConsoleFont", consoleFontFamily);
|
settings->set("ConsoleFont", consoleFontFamily);
|
||||||
settings->set("ConsoleFontSize", m_ui->fontSizeBox->value());
|
settings->set("ConsoleFontSize", m_ui->fontSizeBox->value());
|
||||||
settings->set("CatOpacity", m_ui->catOpacitySlider->value());
|
settings->set("CatOpacity", m_ui->catOpacitySlider->value());
|
||||||
|
auto catFit = m_ui->catFitComboBox->currentIndex();
|
||||||
|
settings->set("CatFit", catFit == 0 ? "fit" : catFit == 1 ? "fill" : "strech");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppearanceWidget::loadSettings()
|
void AppearanceWidget::loadSettings()
|
||||||
{
|
{
|
||||||
QString fontFamily = APPLICATION->settings()->get("ConsoleFont").toString();
|
SettingsObjectPtr settings = APPLICATION->settings();
|
||||||
|
QString fontFamily = settings->get("ConsoleFont").toString();
|
||||||
QFont consoleFont(fontFamily);
|
QFont consoleFont(fontFamily);
|
||||||
m_ui->consoleFont->setCurrentFont(consoleFont);
|
m_ui->consoleFont->setCurrentFont(consoleFont);
|
||||||
|
|
||||||
bool conversionOk = true;
|
bool conversionOk = true;
|
||||||
int fontSize = APPLICATION->settings()->get("ConsoleFontSize").toInt(&conversionOk);
|
int fontSize = settings->get("ConsoleFontSize").toInt(&conversionOk);
|
||||||
if (!conversionOk) {
|
if (!conversionOk) {
|
||||||
fontSize = 11;
|
fontSize = 11;
|
||||||
}
|
}
|
||||||
m_ui->fontSizeBox->setValue(fontSize);
|
m_ui->fontSizeBox->setValue(fontSize);
|
||||||
|
|
||||||
m_ui->catOpacitySlider->setValue(APPLICATION->settings()->get("CatOpacity").toInt());
|
m_ui->catOpacitySlider->setValue(settings->get("CatOpacity").toInt());
|
||||||
|
|
||||||
|
auto catFit = settings->get("CatFit").toString();
|
||||||
|
m_ui->catFitComboBox->setCurrentIndex(catFit == "fit" ? 0 : catFit == "fill" ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppearanceWidget::retranslateUi()
|
void AppearanceWidget::retranslateUi()
|
||||||
|
@ -245,9 +251,7 @@ void AppearanceWidget::updateConsolePreview()
|
||||||
workCursor.insertBlock();
|
workCursor.insertBlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
print(QString("%1 version: %2\n")
|
print(QString("%1 version: %2\n").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString()), MessageLevel::Launcher);
|
||||||
.arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString()),
|
|
||||||
MessageLevel::Launcher);
|
|
||||||
|
|
||||||
QDate today = QDate::currentDate();
|
QDate today = QDate::currentDate();
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>600</width>
|
||||||
<height>700</height>
|
<height>711</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
|
@ -203,6 +203,53 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="catFitLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="catFitComboBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>77</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fit</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fill</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Stretch</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="catOpacityLabel">
|
<widget class="QLabel" name="catOpacityLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -372,8 +419,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="new">
|
<iconset theme="new"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -389,8 +435,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="centralmods">
|
<iconset theme="centralmods"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -406,8 +451,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="viewfolder">
|
<iconset theme="viewfolder"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -423,8 +467,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="launch">
|
<iconset theme="launch"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -440,8 +483,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="copy">
|
<iconset theme="copy"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -457,8 +499,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="export">
|
<iconset theme="export"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -474,8 +515,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="delete">
|
<iconset theme="delete"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -491,8 +531,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="about">
|
<iconset theme="about"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -508,8 +547,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="settings">
|
<iconset theme="settings"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -525,8 +563,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="cat">
|
<iconset theme="cat"/>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -586,6 +623,7 @@
|
||||||
<tabstop>reloadThemesButton</tabstop>
|
<tabstop>reloadThemesButton</tabstop>
|
||||||
<tabstop>consoleFont</tabstop>
|
<tabstop>consoleFont</tabstop>
|
||||||
<tabstop>fontSizeBox</tabstop>
|
<tabstop>fontSizeBox</tabstop>
|
||||||
|
<tabstop>catFitComboBox</tabstop>
|
||||||
<tabstop>catOpacitySlider</tabstop>
|
<tabstop>catOpacitySlider</tabstop>
|
||||||
<tabstop>consolePreview</tabstop>
|
<tabstop>consolePreview</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
|
|
@ -16,13 +16,20 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
|
||||||
QStyleOptionViewItem opt(option);
|
QStyleOptionViewItem opt(option);
|
||||||
initStyleOption(&opt, index);
|
initStyleOption(&opt, index);
|
||||||
|
|
||||||
|
auto isInstalled = index.data(UserDataTypes::INSTALLED).toBool();
|
||||||
|
auto isChecked = opt.checkState == Qt::Checked;
|
||||||
|
auto isSelected = option.state & QStyle::State_Selected;
|
||||||
|
|
||||||
|
if (!isSelected && !isChecked && isInstalled) {
|
||||||
|
painter->setOpacity(0.4); // Fade out the entire item
|
||||||
|
}
|
||||||
const QStyle* style = opt.widget == nullptr ? QApplication::style() : opt.widget->style();
|
const QStyle* style = opt.widget == nullptr ? QApplication::style() : opt.widget->style();
|
||||||
|
|
||||||
auto rect = opt.rect;
|
auto rect = opt.rect;
|
||||||
|
|
||||||
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
|
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
|
||||||
|
|
||||||
if (option.state & QStyle::State_Selected && style->objectName() != "windowsvista")
|
if (isSelected && style->objectName() != "windowsvista")
|
||||||
painter->setPen(opt.palette.highlightedText().color());
|
painter->setPen(opt.palette.highlightedText().color());
|
||||||
|
|
||||||
if (opt.features & QStyleOptionViewItem::HasCheckIndicator) {
|
if (opt.features & QStyleOptionViewItem::HasCheckIndicator) {
|
||||||
|
@ -68,12 +75,16 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
|
||||||
{ // Title painting
|
{ // Title painting
|
||||||
auto title = index.data(UserDataTypes::TITLE).toString();
|
auto title = index.data(UserDataTypes::TITLE).toString();
|
||||||
|
|
||||||
if (index.data(UserDataTypes::INSTALLED).toBool())
|
|
||||||
title = tr("%1 [installed]").arg(title);
|
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
auto font = opt.font;
|
auto font = opt.font;
|
||||||
|
if (isChecked) {
|
||||||
|
font.setBold(true);
|
||||||
|
}
|
||||||
|
if (isInstalled) {
|
||||||
|
title = tr("%1 [installed]").arg(title);
|
||||||
|
}
|
||||||
|
|
||||||
font.setPointSize(font.pointSize() + 2);
|
font.setPointSize(font.pointSize() + 2);
|
||||||
painter->setFont(font);
|
painter->setFont(font);
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,9 @@ class LinkTask : public Task {
|
||||||
}
|
}
|
||||||
|
|
||||||
FS::create_link* m_lnk;
|
FS::create_link* m_lnk;
|
||||||
[[maybe_unused]] bool m_useHard = false;
|
#if defined Q_OS_WIN32
|
||||||
|
bool m_useHard = false;
|
||||||
|
#endif
|
||||||
bool m_linkRecursive = true;
|
bool m_linkRecursive = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue