mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
Include version & last_tested info
This commit is contained in:
commit
3862ed6a59
@ -1,12 +1,12 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <iostream>
|
#include <QFileInfo>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QProgressDialog>
|
||||||
|
|
||||||
#include "common/path_util.h"
|
#include "common/path_util.h"
|
||||||
#include "compatibility_info.h"
|
#include "compatibility_info.h"
|
||||||
#include <QProgressDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QFileInfo>
|
|
||||||
|
|
||||||
CompatibilityInfoClass::CompatibilityInfoClass()
|
CompatibilityInfoClass::CompatibilityInfoClass()
|
||||||
: m_network_manager(new QNetworkAccessManager(this)) {
|
: m_network_manager(new QNetworkAccessManager(this)) {
|
||||||
@ -19,8 +19,9 @@ CompatibilityInfoClass::~CompatibilityInfoClass() = default;
|
|||||||
|
|
||||||
void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
|
void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
|
||||||
QFileInfo check_file(m_compatibility_filename);
|
QFileInfo check_file(m_compatibility_filename);
|
||||||
const auto modified_delta = check_file.lastModified() - QDateTime::currentDateTime();
|
const auto modified_delta = QDateTime::currentDateTime() - check_file.lastModified();
|
||||||
if (check_file.exists() && check_file.isFile() && std::chrono::duration_cast<std::chrono::minutes>(modified_delta).count() < 60) {
|
if (check_file.exists() && check_file.isFile() &&
|
||||||
|
std::chrono::duration_cast<std::chrono::minutes>(modified_delta).count() < 60) {
|
||||||
if (LoadCompatibilityFile())
|
if (LoadCompatibilityFile())
|
||||||
return;
|
return;
|
||||||
QMessageBox::critical(parent, tr("Error"),
|
QMessageBox::critical(parent, tr("Error"),
|
||||||
@ -46,9 +47,10 @@ void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
|
|||||||
|
|
||||||
if (reply->error() != QNetworkReply::NoError) {
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
QMessageBox::critical(parent, tr("Error"),
|
QMessageBox::critical(
|
||||||
tr("Unable to update compatibility data! Using old compatibility data..."));
|
parent, tr("Error"),
|
||||||
//TODO: Try loading compatibility_file.json again
|
tr("Unable to update compatibility data! Using old compatibility data..."));
|
||||||
|
// Try loading compatibility_file.json again
|
||||||
LoadCompatibilityFile();
|
LoadCompatibilityFile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -87,8 +89,7 @@ void CompatibilityInfoClass::UpdateCompatibilityDatabase(QWidget* parent) {
|
|||||||
|
|
||||||
dialog.reset();
|
dialog.reset();
|
||||||
});
|
});
|
||||||
connect(&dialog, &QProgressDialog::canceled, &future_watcher,
|
connect(&dialog, &QProgressDialog::canceled, &future_watcher, &QFutureWatcher<void>::cancel);
|
||||||
&QFutureWatcher<void>::cancel);
|
|
||||||
dialog.setRange(0, remaining_pages);
|
dialog.setRange(0, remaining_pages);
|
||||||
connect(&future_watcher, &QFutureWatcher<void>::progressValueChanged, &dialog,
|
connect(&future_watcher, &QFutureWatcher<void>::progressValueChanged, &dialog,
|
||||||
&QProgressDialog::setValue);
|
&QProgressDialog::setValue);
|
||||||
@ -117,7 +118,7 @@ void CompatibilityInfoClass::WaitForReply(QNetworkReply* reply) {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
CompatibilityStatus CompatibilityInfoClass::GetCompatibilityStatus(const std::string& serial) {
|
CompatibilityEntry CompatibilityInfoClass::GetCompatibilityInfo(const std::string& serial) {
|
||||||
QString title_id = QString::fromStdString(serial);
|
QString title_id = QString::fromStdString(serial);
|
||||||
if (m_compatibility_database.contains(title_id)) {
|
if (m_compatibility_database.contains(title_id)) {
|
||||||
{
|
{
|
||||||
@ -125,13 +126,18 @@ CompatibilityStatus CompatibilityInfoClass::GetCompatibilityStatus(const std::st
|
|||||||
QString os_string = OSTypeToString.at(static_cast<OSType>(os_int));
|
QString os_string = OSTypeToString.at(static_cast<OSType>(os_int));
|
||||||
QJsonObject compatibility_obj = m_compatibility_database[title_id].toObject();
|
QJsonObject compatibility_obj = m_compatibility_database[title_id].toObject();
|
||||||
if (compatibility_obj.contains(os_string)) {
|
if (compatibility_obj.contains(os_string)) {
|
||||||
return LabelToCompatStatus.at(
|
QJsonObject compatibility_entry_obj = compatibility_obj[os_string].toObject();
|
||||||
compatibility_obj[os_string].toString());
|
CompatibilityEntry compatibility_entry{
|
||||||
|
LabelToCompatStatus.at(compatibility_entry_obj["status"].toString()),
|
||||||
|
compatibility_entry_obj["version"].toString(),
|
||||||
|
QDateTime::fromString(compatibility_entry_obj["last_tested"].toString(),
|
||||||
|
Qt::ISODate)};
|
||||||
|
return compatibility_entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CompatibilityStatus::Unknown;
|
return CompatibilityEntry{CompatibilityStatus::Unknown};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompatibilityInfoClass::LoadCompatibilityFile() {
|
bool CompatibilityInfoClass::LoadCompatibilityFile() {
|
||||||
@ -152,7 +158,6 @@ bool CompatibilityInfoClass::LoadCompatibilityFile() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CompatibilityInfoClass::ExtractCompatibilityInfo(QByteArray response) {
|
void CompatibilityInfoClass::ExtractCompatibilityInfo(QByteArray response) {
|
||||||
QJsonDocument json_doc(QJsonDocument::fromJson(response));
|
QJsonDocument json_doc(QJsonDocument::fromJson(response));
|
||||||
|
|
||||||
@ -187,13 +192,20 @@ void CompatibilityInfoClass::ExtractCompatibilityInfo(QByteArray response) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonValueRef compatibility_object_ref = m_compatibility_database[title_id];
|
// QJson does not support editing nested objects directly..
|
||||||
|
|
||||||
if (compatibility_object_ref.isNull()) {
|
QJsonObject compatibility_obj = m_compatibility_database[title_id].toObject();
|
||||||
compatibility_object_ref = QJsonObject({{current_os, compatibility_status}});
|
|
||||||
} else {
|
QJsonObject compatibility_data{
|
||||||
compatibility_object_ref.toObject()[current_os] = compatibility_status;
|
{{"status", compatibility_status},
|
||||||
}
|
{"last_tested", issue_obj["updated_at"]},
|
||||||
|
{"version", issue_obj["milestone"].isNull()
|
||||||
|
? "unknown"
|
||||||
|
: issue_obj["milestone"].toObject()["title"].toString()}}};
|
||||||
|
|
||||||
|
compatibility_obj[current_os] = compatibility_data;
|
||||||
|
|
||||||
|
m_compatibility_database[title_id] = compatibility_obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,12 @@ enum OSType {
|
|||||||
Last
|
Last
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CompatibilityEntry {
|
||||||
|
CompatibilityStatus status;
|
||||||
|
QString version;
|
||||||
|
QDateTime last_tested;
|
||||||
|
};
|
||||||
|
|
||||||
class CompatibilityInfoClass : public QObject {
|
class CompatibilityInfoClass : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -75,7 +81,7 @@ public:
|
|||||||
~CompatibilityInfoClass();
|
~CompatibilityInfoClass();
|
||||||
void UpdateCompatibilityDatabase(QWidget* parent = nullptr);
|
void UpdateCompatibilityDatabase(QWidget* parent = nullptr);
|
||||||
bool LoadCompatibilityFile();
|
bool LoadCompatibilityFile();
|
||||||
CompatibilityStatus GetCompatibilityStatus(const std::string& serial);
|
CompatibilityEntry GetCompatibilityInfo(const std::string& serial);
|
||||||
void ExtractCompatibilityInfo(QByteArray response);
|
void ExtractCompatibilityInfo(QByteArray response);
|
||||||
static void WaitForReply(QNetworkReply* reply);
|
static void WaitForReply(QNetworkReply* reply);
|
||||||
QNetworkReply* FetchPage(int page_num);
|
QNetworkReply* FetchPage(int page_num);
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
#include "game_list_utils.h"
|
#include "game_list_utils.h"
|
||||||
#include <QToolTip>
|
#include <QToolTip>
|
||||||
|
|
||||||
GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
||||||
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
|
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
|
||||||
QWidget* parent)
|
QWidget* parent)
|
||||||
: QTableWidget(parent), m_game_info(game_info_get), m_compat_info(compat_info_get) {
|
: QTableWidget(parent), m_game_info(game_info_get), m_compat_info(compat_info_get) {
|
||||||
icon_size = Config::getIconSize();
|
icon_size = Config::getIconSize();
|
||||||
@ -22,7 +22,7 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
|||||||
this->verticalScrollBar()->installEventFilter(this);
|
this->verticalScrollBar()->installEventFilter(this);
|
||||||
this->verticalScrollBar()->setSingleStep(20);
|
this->verticalScrollBar()->setSingleStep(20);
|
||||||
this->horizontalScrollBar()->setSingleStep(20);
|
this->horizontalScrollBar()->setSingleStep(20);
|
||||||
this->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
this->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
this->verticalHeader()->setVisible(false);
|
this->verticalHeader()->setVisible(false);
|
||||||
this->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
|
this->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
this->horizontalHeader()->setHighlightSections(false);
|
this->horizontalHeader()->setHighlightSections(false);
|
||||||
@ -44,8 +44,8 @@ GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
|||||||
this->setHorizontalHeaderLabels(headers);
|
this->setHorizontalHeaderLabels(headers);
|
||||||
this->horizontalHeader()->setSortIndicatorShown(true);
|
this->horizontalHeader()->setSortIndicatorShown(true);
|
||||||
this->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
this->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||||
this->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
|
|
||||||
this->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
|
this->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
|
||||||
|
this->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Fixed);
|
||||||
PopulateGameList();
|
PopulateGameList();
|
||||||
|
|
||||||
connect(this, &QTableWidget::currentCellChanged, this, &GameListFrame::onCurrentCellChanged);
|
connect(this, &QTableWidget::currentCellChanged, this, &GameListFrame::onCurrentCellChanged);
|
||||||
@ -108,9 +108,9 @@ void GameListFrame::PopulateGameList() {
|
|||||||
SetTableItem(i, 6, QString::fromStdString(m_game_info->m_games[i].size));
|
SetTableItem(i, 6, QString::fromStdString(m_game_info->m_games[i].size));
|
||||||
SetTableItem(i, 7, QString::fromStdString(m_game_info->m_games[i].version));
|
SetTableItem(i, 7, QString::fromStdString(m_game_info->m_games[i].version));
|
||||||
|
|
||||||
m_game_info->m_games[i].compatibility_status =
|
m_game_info->m_games[i].compatibility =
|
||||||
m_compat_info->GetCompatibilityStatus(m_game_info->m_games[i].serial);
|
m_compat_info->GetCompatibilityInfo(m_game_info->m_games[i].serial);
|
||||||
SetCompatibilityItem(i, 2, m_game_info->m_games[i].compatibility_status);
|
SetCompatibilityItem(i, 2, m_game_info->m_games[i].compatibility);
|
||||||
|
|
||||||
QString playTime = GetPlayTime(m_game_info->m_games[i].serial);
|
QString playTime = GetPlayTime(m_game_info->m_games[i].serial);
|
||||||
if (playTime.isEmpty()) {
|
if (playTime.isEmpty()) {
|
||||||
@ -213,7 +213,7 @@ void GameListFrame::ResizeIcons(int iconSize) {
|
|||||||
this->horizontalHeader()->setSectionResizeMode(8, QHeaderView::ResizeToContents);
|
this->horizontalHeader()->setSectionResizeMode(8, QHeaderView::ResizeToContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatus status) {
|
void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityEntry entry) {
|
||||||
QTableWidgetItem* item = new QTableWidgetItem();
|
QTableWidgetItem* item = new QTableWidgetItem();
|
||||||
QWidget* widget = new QWidget(this);
|
QWidget* widget = new QWidget(this);
|
||||||
QGridLayout* layout = new QGridLayout(widget);
|
QGridLayout* layout = new QGridLayout(widget);
|
||||||
@ -221,7 +221,7 @@ void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatu
|
|||||||
QColor color;
|
QColor color;
|
||||||
QString tooltip_string;
|
QString tooltip_string;
|
||||||
|
|
||||||
switch (status) {
|
switch (entry.status) {
|
||||||
case Unknown:
|
case Unknown:
|
||||||
color = QStringLiteral("#000000");
|
color = QStringLiteral("#000000");
|
||||||
tooltip_string = tr("Compatibility is untested");
|
tooltip_string = tr("Compatibility is untested");
|
||||||
@ -259,9 +259,9 @@ void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatu
|
|||||||
QLabel* dotLabel = new QLabel("", widget);
|
QLabel* dotLabel = new QLabel("", widget);
|
||||||
dotLabel->setPixmap(circle_pixmap);
|
dotLabel->setPixmap(circle_pixmap);
|
||||||
|
|
||||||
QLabel* label = new QLabel(m_compat_info->CompatStatusToString.at(status), widget);
|
QLabel* label = new QLabel(m_compat_info->CompatStatusToString.at(entry.status), widget);
|
||||||
|
|
||||||
label->setStyleSheet("color: white; font-size: 16px; font-weight: bold;");
|
label->setStyleSheet("color: white; font-size: 12px; font-weight: bold;");
|
||||||
|
|
||||||
// Create shadow effect
|
// Create shadow effect
|
||||||
QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect();
|
QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect();
|
||||||
@ -271,8 +271,13 @@ void GameListFrame::SetCompatibilityItem(int row, int column, CompatibilityStatu
|
|||||||
|
|
||||||
label->setGraphicsEffect(shadowEffect); // Apply shadow effect to the QLabel
|
label->setGraphicsEffect(shadowEffect); // Apply shadow effect to the QLabel
|
||||||
|
|
||||||
layout->addWidget(dotLabel, 0, 0, -1, 4);
|
QLabel* version_label =
|
||||||
layout->addWidget(label, 0, 4, -1, 4);
|
new QLabel(QString("%1, (%2)").arg(entry.last_tested.toString("yyyy-MM-dd"), entry.version), widget);
|
||||||
|
version_label->setStyleSheet("color: white; font-size: 10px;");
|
||||||
|
|
||||||
|
layout->addWidget(dotLabel, 0, 0, -1, 1);
|
||||||
|
layout->addWidget(label, 0, 1, 1, 1);
|
||||||
|
layout->addWidget(version_label, 1, 1, 1, 1);
|
||||||
layout->setAlignment(Qt::AlignLeft);
|
layout->setAlignment(Qt::AlignLeft);
|
||||||
widget->setLayout(layout);
|
widget->setLayout(layout);
|
||||||
widget->setToolTip(tooltip_string);
|
widget->setToolTip(tooltip_string);
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
class GameListFrame : public QTableWidget {
|
class GameListFrame : public QTableWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit GameListFrame(std::shared_ptr<GameInfoClass> game_info_get, std::shared_ptr<CompatibilityInfoClass> compat_info_get, QWidget* parent = nullptr);
|
explicit GameListFrame(std::shared_ptr<GameInfoClass> game_info_get,
|
||||||
|
std::shared_ptr<CompatibilityInfoClass> compat_info_get,
|
||||||
|
QWidget* parent = nullptr);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void GameListFrameClosed();
|
void GameListFrameClosed();
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ public Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
void SetTableItem(int row, int column, QString itemStr);
|
void SetTableItem(int row, int column, QString itemStr);
|
||||||
void SetRegionFlag(int row, int column, QString itemStr);
|
void SetRegionFlag(int row, int column, QString itemStr);
|
||||||
void SetCompatibilityItem(int row, int column, CompatibilityStatus status);
|
void SetCompatibilityItem(int row, int column, CompatibilityEntry entry);
|
||||||
QString GetPlayTime(const std::string& serial);
|
QString GetPlayTime(const std::string& serial);
|
||||||
QList<QAction*> m_columnActs;
|
QList<QAction*> m_columnActs;
|
||||||
GameInfoClass* game_inf_get = nullptr;
|
GameInfoClass* game_inf_get = nullptr;
|
||||||
@ -66,7 +68,7 @@ public:
|
|||||||
case 1:
|
case 1:
|
||||||
return a.name < b.name;
|
return a.name < b.name;
|
||||||
case 2:
|
case 2:
|
||||||
return a.compatibility_status < b.compatibility_status;
|
return a.compatibility.status < b.compatibility.status;
|
||||||
case 3:
|
case 3:
|
||||||
return a.serial.substr(4) < b.serial.substr(4);
|
return a.serial.substr(4) < b.serial.substr(4);
|
||||||
case 4:
|
case 4:
|
||||||
@ -91,7 +93,7 @@ public:
|
|||||||
case 1:
|
case 1:
|
||||||
return a.name > b.name;
|
return a.name > b.name;
|
||||||
case 2:
|
case 2:
|
||||||
return a.compatibility_status > b.compatibility_status;
|
return a.compatibility.status > b.compatibility.status;
|
||||||
case 3:
|
case 3:
|
||||||
return a.serial.substr(4) > b.serial.substr(4);
|
return a.serial.substr(4) > b.serial.substr(4);
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -27,7 +27,7 @@ struct GameInfo {
|
|||||||
std::string fw = "Unknown";
|
std::string fw = "Unknown";
|
||||||
|
|
||||||
std::string play_time = "Unknown";
|
std::string play_time = "Unknown";
|
||||||
CompatibilityStatus compatibility_status = CompatibilityStatus::Unknown;
|
CompatibilityEntry compatibility = CompatibilityEntry{CompatibilityStatus::Unknown};
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameListUtils {
|
class GameListUtils {
|
||||||
|
Loading…
Reference in New Issue
Block a user