Turn Card, Settings and Utility into libraries.

Took 4 hours 3 minutes

Took 2 minutes

Took 38 seconds

Took 5 minutes

Took 5 minutes

Took 9 minutes


Took 15 minutes
This commit is contained in:
Lukas Brübach 2025-10-02 17:41:07 +02:00
parent 30e6b52783
commit 53d80efab8
262 changed files with 1025 additions and 918 deletions

View file

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.16)
project(Utility VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(UTILITY_SOURCES
src/key_signals.cpp
src/levenshtein.cpp
src/logger.cpp
)
set(UTILITY_HEADERS
include/utility/key_signals.h
include/utility/levenshtein.h
include/utility/logger.h
include/utility/macros.h
)
qt_add_library(utility STATIC
${UTILITY_SOURCES}
${UTILITY_HEADERS}
)
target_include_directories(utility
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
)
target_link_libraries(utility
PUBLIC ${COCKATRICE_QT_MODULES}
)

View file

@ -0,0 +1,36 @@
/**
* @file key_signals.h
* @ingroup Core
* @ingroup UI
* @brief TODO: Document this.
*/
#ifndef KEYSIGNALS_H
#define KEYSIGNALS_H
#include <QEvent>
#include <QObject>
class KeySignals : public QObject
{
Q_OBJECT
signals:
void onEnter();
void onCtrlEnter();
void onCtrlAltEnter();
void onShiftLeft();
void onShiftRight();
void onDelete();
void onCtrlAltMinus();
void onCtrlAltEqual();
void onCtrlAltLBracket();
void onCtrlAltRBracket();
void onShiftS();
void onCtrlC();
protected:
bool eventFilter(QObject *, QEvent *event) override;
};
#endif

View file

@ -0,0 +1,14 @@
/**
* @file levenshtein.h
* @ingroup Core
* @brief TODO: Document this.
*/
#ifndef LEVENSHTEIN_H
#define LEVENSHTEIN_H
#include <QString>
int levenshteinDistance(const QString &s1, const QString &s2);
#endif // LEVENSHTEIN_H

View file

@ -0,0 +1,72 @@
/**
* @file logger.h
* @ingroup Core
* @brief TODO: Document this.
*/
#ifndef LOGGER_H
#define LOGGER_H
#include <QFile>
#include <QMutex>
#include <QString>
#include <QTextStream>
#include <QVector>
#if defined(Q_PROCESSOR_X86_32)
#define BUILD_ARCHITECTURE "32-bit"
#elif defined(Q_PROCESSOR_X86_64)
#define BUILD_ARCHITECTURE "64-bit"
#elif defined(Q_PROCESSOR_ARM)
#define BUILD_ARCHITECTURE "ARM"
#else
#define BUILD_ARCHITECTURE "unknown"
#endif
class Logger : public QObject
{
Q_OBJECT
public:
static Logger &getInstance()
{
static Logger instance;
return instance;
}
void logToFile(bool enabled);
void log(QtMsgType type, const QMessageLogContext &ctx, const QString &message);
QString getClientVersion();
QString getClientOperatingSystem();
QString getSystemArchitecture();
QString getSystemLocale();
QString getClientInstallInfo();
QList<QString> getLogBuffer()
{
return logBuffer;
}
private:
Logger();
~Logger() override;
// Singleton - Don't implement copy constructor and assign operator
Logger(Logger const &);
void operator=(Logger const &);
bool logToFileEnabled;
QTextStream fileStream;
QFile fileHandle;
QList<QString> logBuffer;
QMutex mutex;
protected:
void openLogfileSession();
void closeLogfileSession();
protected slots:
void internalLog(const QString &message);
signals:
void logEntryAdded(const QString &message);
};
#endif

View file

@ -0,0 +1,17 @@
#ifndef COCKATRICE_MACROS_H
#define COCKATRICE_MACROS_H
#include <QtGlobal>
// Qt6.7 changed how stateChanged functionality
// of QCheckBoxes work.
// See https://doc.qt.io/qt-6/qcheckbox.html#checkStateChanged
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
#define QT_STATE_CHANGED checkStateChanged
#define QT_STATE_CHANGED_T Qt::CheckState
#else
#define QT_STATE_CHANGED stateChanged
#define QT_STATE_CHANGED_T int
#endif
#endif // COCKATRICE_MACROS_H

View file

@ -0,0 +1,74 @@
#include "../include/utility/key_signals.h"
#include <QKeyEvent>
bool KeySignals::eventFilter(QObject * /*object*/, QEvent *event)
{
QKeyEvent *kevent;
if (event->type() != QEvent::KeyPress)
return false;
kevent = static_cast<QKeyEvent *>(event);
switch (kevent->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
emit onCtrlAltEnter();
else if (kevent->modifiers() & Qt::ControlModifier)
emit onCtrlEnter();
else
emit onEnter();
break;
case Qt::Key_Right:
if (kevent->modifiers() & Qt::ShiftModifier)
emit onShiftRight();
break;
case Qt::Key_Left:
if (kevent->modifiers() & Qt::ShiftModifier)
emit onShiftLeft();
break;
case Qt::Key_Delete:
case Qt::Key_Backspace:
emit onDelete();
break;
case Qt::Key_Minus:
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
emit onCtrlAltMinus();
break;
case Qt::Key_Equal:
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
emit onCtrlAltEqual();
break;
case Qt::Key_BracketLeft:
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
emit onCtrlAltLBracket();
break;
case Qt::Key_BracketRight:
if (kevent->modifiers().testFlag(Qt::AltModifier) && kevent->modifiers().testFlag(Qt::ControlModifier))
emit onCtrlAltRBracket();
break;
case Qt::Key_S:
if (kevent->modifiers() & Qt::ShiftModifier)
emit onShiftS();
break;
case Qt::Key_C:
if (kevent->modifiers() & Qt::ControlModifier)
emit onCtrlC();
break;
default:
return false;
}
return false;
}

View file

@ -0,0 +1,25 @@
#include "../include/utility/levenshtein.h"
#include <algorithm>
#include <vector>
int levenshteinDistance(const QString &s1, const QString &s2)
{
int len1 = s1.size();
int len2 = s2.size();
std::vector<std::vector<int>> dp(len1 + 1, std::vector<int>(len2 + 1));
for (int i = 0; i <= len1; i++)
dp[i][0] = i;
for (int j = 0; j <= len2; j++)
dp[0][j] = j;
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1;
dp[i][j] = std::min({dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost});
}
}
return dp[len1][len2];
}

View file

@ -0,0 +1,142 @@
#include "../include/utility/logger.h"
#include "version_string.h"
#include <QApplication>
#include <QDateTime>
#include <QLocale>
#include <QSysInfo>
#include <iostream>
#define LOGGER_MAX_ENTRIES 128
#define LOGGER_FILENAME "qdebug.txt"
Logger::Logger() : logToFileEnabled(false)
{
logBuffer.append(getClientVersion());
logBuffer.append(getSystemArchitecture());
logBuffer.append(getSystemLocale());
logBuffer.append(getClientInstallInfo());
logBuffer.append(QString("-").repeated(75));
std::cerr << getClientVersion().toStdString() << std::endl;
std::cerr << getSystemArchitecture().toStdString() << std::endl;
std::cerr << getSystemLocale().toStdString() << std::endl;
std::cerr << getClientInstallInfo().toStdString() << std::endl;
}
Logger::~Logger()
{
closeLogfileSession();
logBuffer.clear();
}
void Logger::logToFile(bool enabled)
{
if (enabled) {
openLogfileSession();
} else {
closeLogfileSession();
}
}
QString Logger::getClientVersion()
{
return "Client Version: " + QString::fromStdString(VERSION_STRING);
}
void Logger::openLogfileSession()
{
if (logToFileEnabled) {
return;
}
fileHandle.setFileName(LOGGER_FILENAME);
fileHandle.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
fileStream.setDevice(&fileHandle);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
fileStream << "Log session started at " << QDateTime::currentDateTime().toString() << Qt::endl;
fileStream << getClientVersion() << Qt::endl;
fileStream << getSystemArchitecture() << Qt::endl;
fileStream << getClientInstallInfo() << Qt::endl;
#else
fileStream << "Log session started at " << QDateTime::currentDateTime().toString() << endl;
fileStream << getClientVersion() << endl;
fileStream << getSystemArchitecture() << endl;
fileStream << getClientInstallInfo() << endl;
#endif
logToFileEnabled = true;
}
void Logger::closeLogfileSession()
{
if (!logToFileEnabled)
return;
logToFileEnabled = false;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
fileStream << "Log session closed at " << QDateTime::currentDateTime().toString() << Qt::endl;
#else
fileStream << "Log session closed at " << QDateTime::currentDateTime().toString() << endl;
#endif
fileHandle.close();
}
void Logger::log(QtMsgType /* type */, const QMessageLogContext & /* ctx */, const QString &message)
{
QMetaObject::invokeMethod(this, "internalLog", Qt::QueuedConnection, Q_ARG(const QString &, message));
}
void Logger::internalLog(const QString &message)
{
QMutexLocker locker(&mutex);
logBuffer.append(message);
if (logBuffer.size() > LOGGER_MAX_ENTRIES) {
logBuffer.removeAt(1);
}
emit logEntryAdded(message);
std::cerr << message.toStdString() << std::endl; // Print to stdout
if (logToFileEnabled) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
fileStream << message << Qt::endl; // Print to fileStream
#else
fileStream << message << endl; // Print to fileStream
#endif
}
}
QString Logger::getSystemArchitecture()
{
QString result;
if (!getClientOperatingSystem().isEmpty()) {
// We don't want translatable strings in the 'Debug Log' for easier troubleshooting
result.append(QString("Client Operating System: ") + getClientOperatingSystem() + "\n");
}
result.append(QString("Build Architecture: ") + QString::fromStdString(BUILD_ARCHITECTURE) + "\n");
result.append(QString("Qt Version: ") + QT_VERSION_STR);
return result;
}
QString Logger::getClientOperatingSystem()
{
return QSysInfo::prettyProductName();
}
QString Logger::getSystemLocale()
{
QString result(QString("System Locale: ") + QLocale().name());
return result;
}
QString Logger::getClientInstallInfo()
{
// don't rely on settingsCache->getIsPortableBuild() since the logger is initialized earlier
bool isPortable = QFile::exists(qApp->applicationDirPath() + "/portable.dat");
QString result(QString("Install Mode: ") + (isPortable ? "Portable" : "Standard"));
return result;
}