metaforce/hecl-gui/SysReqTableView.cpp

331 lines
10 KiB
C++
Raw Normal View History

#include "SysReqTableView.hpp"
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>
#include <QHeaderView>
2018-01-01 20:21:45 -08:00
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
2018-01-02 16:24:45 -08:00
#include <QDomDocument>
2018-01-01 20:21:45 -08:00
#include <QProcess>
2018-01-09 22:19:48 -08:00
#include <QStorageInfo>
#include "FindBlender.hpp"
#include <QDebug>
#if _WIN32
2017-12-26 20:10:44 -08:00
#include <Windows.h>
#include <VersionHelpers.h>
#else
#include <unistd.h>
#endif
#if __APPLE__
#include "MacOSSystemVersion.hpp"
2017-12-26 20:10:44 -08:00
#elif _WIN32
2018-12-07 21:19:40 -08:00
static QString GetWindowsVersionString() {
if (IsWindows10OrGreater())
return QObject::tr("Windows 10");
2018-12-07 21:19:40 -08:00
else if (IsWindows8Point1OrGreater())
return QObject::tr("Windows 8.1");
2018-12-07 21:19:40 -08:00
else if (IsWindows8OrGreater())
return QObject::tr("Windows 8");
2018-12-07 21:19:40 -08:00
else if (IsWindows7SP1OrGreater())
return QObject::tr("Windows 7 SP1");
2018-12-07 21:19:40 -08:00
else if (IsWindows7OrGreater())
return QObject::tr("Windows 7");
2018-12-07 21:19:40 -08:00
else if (IsWindowsVistaOrGreater())
return QObject::tr("Windows Vista");
2018-12-07 21:19:40 -08:00
else if (IsWindowsXPOrGreater())
return QObject::tr("Windows XP");
2018-12-07 21:19:40 -08:00
else
return QObject::tr("Windows Old And Won't Work");
2017-12-26 20:10:44 -08:00
}
#endif
2018-12-07 21:19:40 -08:00
SysReqTableModel::SysReqTableModel(QObject* parent) : QAbstractTableModel(parent) {
2018-01-01 20:21:45 -08:00
#ifdef __linux__
QFile file(QStringLiteral("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"));
2018-12-07 21:19:40 -08:00
if (file.open(QFile::ReadOnly)) {
const QString str(QString::fromUtf8(file.readAll()));
2018-12-07 21:19:40 -08:00
m_cpuSpeed = str.toInt() / 1000;
m_cpuSpeedStr = tr("%1 GHz").arg(m_cpuSpeed / 1000.0);
2018-12-07 21:19:40 -08:00
}
2018-01-02 16:24:45 -08:00
#elif defined(__APPLE__)
2018-12-07 21:19:40 -08:00
QProcess spProc;
spProc.start(QStringLiteral("system_profiler"), {QStringLiteral("-xml"), QStringLiteral("SPHardwareDataType")},
QProcess::ReadOnly);
2018-12-07 21:19:40 -08:00
spProc.waitForFinished();
QDomDocument spDoc;
spDoc.setContent(spProc.readAll());
QDomElement spDocElem = spDoc.documentElement();
QDomElement n = spDocElem.firstChildElement(QStringLiteral("array"))
.firstChildElement(QStringLiteral("dict"))
.firstChildElement(QStringLiteral("key"));
while (!n.isNull() && n.text() != QStringLiteral("_items")) {
n = n.nextSiblingElement(QStringLiteral("key"));
}
2018-12-07 21:19:40 -08:00
if (!n.isNull()) {
n = n.nextSiblingElement(QStringLiteral("array"))
.firstChildElement(QStringLiteral("dict"))
.firstChildElement(QStringLiteral("key"));
while (!n.isNull() && n.text() != QStringLiteral("current_processor_speed")) {
n = n.nextSiblingElement(QStringLiteral("key"));
}
2018-12-07 21:19:40 -08:00
if (!n.isNull()) {
n = n.nextSiblingElement(QStringLiteral("string"));
const double speed = n.text().split(QLatin1Char{' '}).front().toDouble();
2018-12-07 21:19:40 -08:00
m_cpuSpeed = uint64_t(speed * 1000.0);
m_cpuSpeedStr = tr("%1 GHz").arg(speed);
2018-01-02 16:24:45 -08:00
}
2018-12-07 21:19:40 -08:00
}
2018-01-09 22:19:48 -08:00
#elif _WIN32
2018-12-07 21:19:40 -08:00
HKEY hkey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _SYS_STR("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0,
KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) {
DWORD MHz;
DWORD size = sizeof(MHz);
if (RegQueryValueEx(hkey, _SYS_STR("~MHz"), nullptr, nullptr, (LPBYTE)&MHz, &size) == ERROR_SUCCESS) {
m_cpuSpeed = uint64_t(MHz);
m_cpuSpeedStr = tr("%1 GHz").arg(MHz / 1000.f, 1, 'f', 1);
2018-01-09 22:19:48 -08:00
}
2018-12-07 21:19:40 -08:00
}
RegCloseKey(hkey);
2018-01-01 20:21:45 -08:00
#else
2018-12-07 21:19:40 -08:00
/* This only works for Skylake+ */
int regs[4] = {};
zeus::getCpuInfo(0, regs);
if (regs[0] >= 0x16) {
zeus::getCpuInfo(0x16, regs);
m_cpuSpeed = uint64_t(regs[0]);
}
m_cpuSpeedStr = tr("%1 GHz").arg(m_cpuSpeed / 1000.f);
2018-01-01 20:21:45 -08:00
#endif
#if _WIN32
2018-12-07 21:19:40 -08:00
ULONGLONG memSize;
GetPhysicallyInstalledSystemMemory(&memSize);
m_memorySize = memSize * 1024;
#else
2018-12-07 21:19:40 -08:00
m_memorySize = uint64_t(sysconf(_SC_PHYS_PAGES)) * sysconf(_SC_PAGESIZE);
#endif
m_memorySizeStr = tr("%1 GiB").arg(m_memorySize / 1024.f / 1024.f / 1024.f);
#ifdef __APPLE__
2018-12-07 21:19:40 -08:00
GetMacOSSystemVersion(m_macosMajor, m_macosMinor, m_macosPatch);
if (m_macosPatch == 0) {
m_osVersion = tr("macOS %1.%2").arg(m_macosMajor, m_macosMinor);
} else {
2020-04-16 15:15:37 -07:00
m_osVersion = tr("macOS %1.%2.%3")
.arg(QString::number(m_macosMajor), QString::number(m_macosMinor), QString::number(m_macosPatch));
}
2017-12-26 20:10:44 -08:00
#elif _WIN32
2018-12-07 21:19:40 -08:00
m_win7SP1OrGreater = IsWindows7SP1OrGreater();
m_osVersion = GetWindowsVersionString();
2018-01-01 20:21:45 -08:00
#elif __linux__
m_osVersion = tr("Linux");
#endif
2018-12-07 21:19:40 -08:00
hecl::blender::FindBlender(m_blendMajor, m_blendMinor);
if (m_blendMajor) {
m_blendVersionStr = tr("Blender %1.%2").arg(QString::number(m_blendMajor), QString::number(m_blendMinor));
} else {
m_blendVersionStr = tr("Not Found");
}
2018-01-09 22:19:48 -08:00
}
2018-12-07 21:19:40 -08:00
void SysReqTableModel::updateFreeDiskSpace(const QString& path) {
if (path.isEmpty()) {
m_freeDiskSpace = 0;
m_freeDiskSpaceStr = tr("<Set Working Directory>");
2018-12-07 21:19:40 -08:00
} else {
m_freeDiskSpace = QStorageInfo(path).bytesFree();
m_freeDiskSpaceStr = tr("%1 GB").arg(m_freeDiskSpace / 1000.f / 1000.f / 1000.f, 1, 'f', 1);
2018-12-07 21:19:40 -08:00
}
emit dataChanged(index(3, 0), index(3, 0));
}
2018-12-07 21:19:40 -08:00
int SysReqTableModel::rowCount(const QModelIndex& parent) const { return 7; }
2018-12-07 21:19:40 -08:00
int SysReqTableModel::columnCount(const QModelIndex& parent) const { return 2; }
2018-12-07 21:19:40 -08:00
QVariant SysReqTableModel::data(const QModelIndex& index, int role) const {
if (role != Qt::DisplayRole && role != Qt::UserRole) {
return {};
}
2018-12-07 21:19:40 -08:00
if (role == Qt::UserRole) {
switch (index.row()) {
case 0:
return true;
case 1:
return m_cpuSpeed >= 1500;
case 2:
return m_memorySize >= 0xC0000000;
case 3:
return m_freeDiskSpace >= qint64(5) * 1000 * 1000 * 1000;
case 4:
#ifdef __APPLE__
2018-12-07 21:19:40 -08:00
return m_macosMajor > 10 || m_macosMinor >= 9;
2017-12-26 20:10:44 -08:00
#elif defined(_WIN32)
2018-12-07 21:19:40 -08:00
return m_win7SP1OrGreater;
#else
2018-12-07 21:19:40 -08:00
return true;
#endif
2018-12-07 21:19:40 -08:00
case 5:
return isBlenderVersionOk();
}
2018-12-07 21:19:40 -08:00
} else {
if (index.column() == 0) {
/* Recommended */
switch (index.row()) {
case 0:
#if ZEUS_ARCH_X86 || ZEUS_ARCH_X86_64
return tr("x86_64");
#else
2018-12-07 21:19:40 -08:00
return {};
#endif
2018-12-07 21:19:40 -08:00
case 1:
return tr("1.5 GHz");
2018-12-07 21:19:40 -08:00
case 2:
return tr("3 GiB");
2018-12-07 21:19:40 -08:00
case 3:
return tr("5 GB (MP1)");
2018-12-07 21:19:40 -08:00
case 4:
#ifdef __APPLE__
return tr("macOS 10.9");
2017-12-26 20:10:44 -08:00
#elif defined(_WIN32)
return tr("Windows 7 SP1");
2018-01-01 20:21:45 -08:00
#elif defined(__linux__)
return tr("Linux");
#else
2018-12-07 21:19:40 -08:00
return {};
#endif
2018-12-07 21:19:40 -08:00
case 5:
2019-12-22 15:40:18 -08:00
return tr("Blender 2.81");
2018-12-07 21:19:40 -08:00
}
} else if (index.column() == 1) {
/* Your System */
switch (index.row()) {
case 0:
#if ZEUS_ARCH_X86 || ZEUS_ARCH_X86_64
2018-12-07 21:19:40 -08:00
return CurArchitectureString;
#else
2018-12-07 21:19:40 -08:00
return {};
#endif
2018-12-07 21:19:40 -08:00
case 1:
return m_cpuSpeedStr;
case 2:
return m_memorySizeStr;
case 3:
return m_freeDiskSpaceStr;
case 4:
return m_osVersion;
case 5:
return m_blendVersionStr;
}
}
2018-12-07 21:19:40 -08:00
}
return {};
}
2018-12-07 21:19:40 -08:00
QVariant SysReqTableModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role != Qt::DisplayRole) {
return {};
}
2018-12-07 21:19:40 -08:00
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
default:
return tr("Recommended");
2018-12-07 21:19:40 -08:00
case 1:
return tr("Your System");
}
2018-12-07 21:19:40 -08:00
} else {
switch (section) {
case 0:
default:
return tr("Architecture");
2018-12-07 21:19:40 -08:00
case 1:
return tr("CPU Speed");
2018-12-07 21:19:40 -08:00
case 2:
return tr("Memory");
2018-12-07 21:19:40 -08:00
case 3:
return tr("Disk Space");
2018-12-07 21:19:40 -08:00
case 4:
return tr("OS");
2018-12-07 21:19:40 -08:00
case 5:
return tr("Blender");
2018-12-07 21:19:40 -08:00
case 6:
return tr("Vector ISA");
}
2018-12-07 21:19:40 -08:00
}
}
2018-12-07 21:19:40 -08:00
void SysReqTableView::paintEvent(QPaintEvent* e) {
int tableWidth = columnWidth(0) + columnWidth(1);
int tableX = verticalHeader()->width() + columnViewportPosition(0);
int tableY = horizontalHeader()->height();
for (int i = 0; i < 6; ++i) {
QWidget* w = std::get<0>(m_backgroundWidgets[i]);
2018-01-09 22:19:48 -08:00
2018-12-07 21:19:40 -08:00
QPalette pal = palette();
if (m_model.data(m_model.index(i, 0), Qt::UserRole).toBool())
2019-07-19 21:25:42 -07:00
pal.setColor(QPalette::Window, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f));
2018-12-07 21:19:40 -08:00
else
2019-07-19 21:25:42 -07:00
pal.setColor(QPalette::Window, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f));
2018-12-07 21:19:40 -08:00
w->setPalette(pal);
2018-01-09 22:19:48 -08:00
2018-12-07 21:19:40 -08:00
QSequentialAnimationGroup* animation = std::get<1>(m_backgroundWidgets[i]);
QPropertyAnimation* pAnimation = static_cast<QPropertyAnimation*>(animation->animationAt(1));
bool& running = std::get<2>(m_backgroundWidgets[i]);
if (!running) {
w->setGeometry(QRect(tableX, tableY + rowViewportPosition(i), 0, rowHeight(i)));
pAnimation->setStartValue(QRect(tableX, tableY + rowViewportPosition(i), 0, rowHeight(i)));
pAnimation->setEndValue(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i)));
animation->start();
running = true;
}
2018-12-07 21:19:40 -08:00
if (animation->state() == QAbstractAnimation::State::Running)
pAnimation->setEndValue(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i)));
else
w->setGeometry(QRect(tableX, tableY + rowViewportPosition(i), tableWidth, rowHeight(i)));
}
QTableView::paintEvent(e);
}
2018-12-07 21:19:40 -08:00
SysReqTableView::SysReqTableView(QWidget* parent) : QTableView(parent), m_vectorISATable(this) {
setModel(&m_model);
setIndexWidget(m_model.index(6, 0), &m_vectorISATable);
setSpan(6, 0, 1, 2);
2018-12-07 21:19:40 -08:00
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
setFocusPolicy(Qt::NoFocus);
2018-12-07 21:19:40 -08:00
for (int i = 0; i < 6; ++i) {
QWidget* w = new QWidget(this);
std::get<0>(m_backgroundWidgets[i]) = w;
2018-12-07 21:19:40 -08:00
QPalette pal = palette();
if (m_model.data(m_model.index(i, 0), Qt::UserRole).toBool())
2019-07-19 21:25:42 -07:00
pal.setColor(QPalette::Window, QColor::fromRgbF(0.f, 1.f, 0.f, 0.2f));
2018-12-07 21:19:40 -08:00
else
2019-07-19 21:25:42 -07:00
pal.setColor(QPalette::Window, QColor::fromRgbF(1.f, 0.f, 0.f, 0.2f));
2018-12-07 21:19:40 -08:00
w->setAutoFillBackground(true);
w->setPalette(pal);
w->lower();
w->show();
2018-12-07 21:19:40 -08:00
QPropertyAnimation* animation = new QPropertyAnimation(w, "geometry", this);
animation->setDuration(2000);
animation->setEasingCurve(QEasingCurve::Type::InOutCubic);
2018-12-07 21:19:40 -08:00
QSequentialAnimationGroup* seq = new QSequentialAnimationGroup(this);
std::get<1>(m_backgroundWidgets[i]) = seq;
seq->addPause(i * 100);
seq->addAnimation(animation);
}
}