Merge pull request #8 from Continuum-Universes-Studio/feature/continuumatrice-product-migration

Feature/continuumatrice product migration
This commit is contained in:
Christian Daniel Jensen 2026-11-03 18:45:57 -07:00 • committed by GitHub
commit 533d2f04c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
150 changed files with 5268 additions and 2563 deletions

View file

@ -90,11 +90,18 @@ bool CardDatabaseDisplayModel::lessThan(const QModelIndex &left, const QModelInd
if (isRightType && (!isLeftType || rightString.size() == cardName.size())) {
return false;
}
} else if (right.column() == CardDatabaseModel::PTColumn && left.column() == CardDatabaseModel::PTColumn) {
// The comparator runs O(n log n) times while the view is sorted, so
// splitting every power/toughness string into a QStringList allocates
// a lot for data that has exactly one separator. Work on views and
// only split the two halves out when both strings are well formed.
} else if (left.column() == right.column() &&
(left.column() == CardDatabaseModel::AttackColumn ||
left.column() == CardDatabaseModel::ArmourColumn ||
left.column() == CardDatabaseModel::HealthColumn)) {
// Compare numeric card statistics as numbers: 9 sorts before 10.
// Values containing expressions retain the existing numeric-prefix
// comparator instead of being forced into an integer type.
return lessThanNumerically(leftString, rightString) < 0;
} else if (right.column() == CardDatabaseModel::AtkHpColumn &&
left.column() == CardDatabaseModel::AtkHpColumn) {
// ATK/HP sorts by Attack first, then Health, both numerically.
// Operate on views to avoid allocations during large database sorts.
const QStringView leftPT = leftString;
const QStringView rightPT = rightString;
const qsizetype leftSlash = leftPT.indexOf(u'/');
@ -103,11 +110,11 @@ bool CardDatabaseDisplayModel::lessThan(const QModelIndex &left, const QModelInd
const bool rightIsWellFormed = rightSlash >= 0 && rightPT.indexOf(u'/', rightSlash + 1) < 0;
if (leftIsWellFormed && rightIsWellFormed) {
const int powerComparison = lessThanNumerically(leftPT.left(leftSlash), rightPT.left(rightSlash));
if (powerComparison != 0) {
return powerComparison < 0;
const int attackComparison = lessThanNumerically(leftPT.left(leftSlash), rightPT.left(rightSlash));
if (attackComparison != 0) {
return attackComparison < 0;
}
// power equal, check toughness
// Attack equal, compare Health
return lessThanNumerically(leftPT.mid(leftSlash + 1), rightPT.mid(rightSlash + 1)) < 0;
}
}

View file

@ -11,7 +11,6 @@
class QObject;
#define CARDDBMODEL_COLUMNS 6
CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, bool _showOnlyCardsFromEnabledSets, QObject *parent)
: QAbstractListModel(parent), db(_db), showOnlyCardsFromEnabledSets(_showOnlyCardsFromEnabledSets)
@ -38,12 +37,12 @@ int CardDatabaseModel::columnCount(const QModelIndex &parent) const
{
// Card rows are leaves, so a valid parent holds no columns. Reporting the
// row width for a card index would claim child cells that do not exist.
return parent.isValid() ? 0 : CARDDBMODEL_COLUMNS;
return parent.isValid() ? 0 : ColumnCount;
}
QVariant CardDatabaseModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() >= cardList.size() || index.column() >= CARDDBMODEL_COLUMNS ||
if (!index.isValid() || index.row() >= cardList.size() || index.column() >= ColumnCount ||
(role != Qt::DisplayRole && role != SortRole)) {
return QVariant();
}
@ -59,10 +58,18 @@ QVariant CardDatabaseModel::data(const QModelIndex &index, int role) const
: card->getManaCost();
case CardTypeColumn:
return card->getCardType();
case PTColumn:
return card->getPowTough();
case AtkHpColumn:
return card->getAtkHp();
case ColorColumn:
return card->getColors();
case IdentityColumn:
return card->getIdentity();
case AttackColumn:
return card->getAttack();
case ArmourColumn:
return card->getArmour();
case HealthColumn:
return card->getHealth();
default:
return QVariant();
}
@ -82,13 +89,21 @@ QVariant CardDatabaseModel::headerData(int section, Qt::Orientation orientation,
case SetListColumn:
return QString(tr("Sets"));
case ManaCostColumn:
return QString(tr("Mana cost"));
return QString(tr("Essence Cost"));
case CardTypeColumn:
return QString(tr("Card type"));
case PTColumn:
return QString(tr("P/T"));
case AtkHpColumn:
return QString(tr("ATK/HP"));
case ColorColumn:
return QString(tr("Color(s)"));
return QString(tr("Essence"));
case IdentityColumn:
return QString(tr("Identity"));
case AttackColumn:
return QString(tr("Attack"));
case ArmourColumn:
return QString(tr("Armour"));
case HealthColumn:
return QString(tr("Health"));
default:
return QVariant();
}
@ -101,7 +116,7 @@ void CardDatabaseModel::cardInfoChanged(const CardInfoPtr &card)
return;
}
emit dataChanged(index(row, 0), index(row, CARDDBMODEL_COLUMNS - 1));
emit dataChanged(index(row, 0), index(row, ColumnCount - 1));
}
bool CardDatabaseModel::checkCardHasAtLeastOneEnabledSet(const CardInfoPtr &card) const

View file

@ -28,9 +28,15 @@ public:
NameColumn,
SetListColumn,
ManaCostColumn,
PTColumn,
AtkHpColumn, // Formerly P/T; keep column index for saved table layouts.
CardTypeColumn,
ColorColumn
ColorColumn,
IdentityColumn,
AttackColumn,
ArmourColumn,
HealthColumn,
ColumnCount,
PTColumn = AtkHpColumn // Compatibility alias for inherited callers.
};
enum Role
{