feat: set prioritization by set type (#5097)

* feat: prefer 'Core' and 'Expansion' sets for prioritization

* rework set prioritization

* clean up priority enum

* formatting

* revert changes to CockatriceXml3Parser

* re-add missing null check

* remove priority fallback ternary from CardSet model

* make defaultSort logic easier to follow

* revert changes to v3 card database xsd

* remove unused invisible priority col from sets dialog

* move draft innovation and duel deck sets to secondary prio

* minor fixes

* change PriorityFallback to 1

* make priority optional in xml

* remove PriorityUndefined and set PriorityFallback to 0

* set priority when not found to PriorityOther

in case a new set type is added it's unlikey we want it sorted first,
it'll probably be a new product so it's probably best to sort it with
the funny things

* simplify sort function

---------

Co-authored-by: tooomm <tooomm@users.noreply.github.com>
Co-authored-by: ebbit1q <ebbit1q@gmail.com>
This commit is contained in:
J. Cameron McDonald 2024-12-01 18:59:00 -06:00 committed by GitHub
parent 5156495b47
commit b9ed9a6c0b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 128 additions and 36 deletions

View file

@ -195,6 +195,13 @@ void SetsModel::swapRows(int oldRow, int newRow)
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
}
void SetsModel::restoreOriginalOrder()
{
int numRows = rowCount();
sets.defaultSort();
emit dataChanged(index(0, 0), index(numRows - 1, columnCount() - 1));
}
void SetsModel::sort(int column, Qt::SortOrder order)
{
QMultiMap<QString, CardSetPtr> setMap;

View file

@ -49,7 +49,8 @@ public:
LongNameCol,
ShortNameCol,
SetTypeCol,
ReleaseDateCol
ReleaseDateCol,
PriorityCol
};
enum Role
{
@ -80,6 +81,7 @@ public:
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
void save(CardDatabase *db);
void restore(CardDatabase *db);
void restoreOriginalOrder();
};
class SetsDisplayModel : public QSortFilterProxyModel

View file

@ -102,6 +102,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
view->sortByColumn(SetsModel::SortKeyCol, Qt::AscendingOrder);
view->setColumnHidden(SetsModel::SortKeyCol, true);
view->setColumnHidden(SetsModel::IsKnownCol, true);
view->setColumnHidden(SetsModel::PriorityCol, true);
view->setRootIsDecorated(false);
connect(view->header(), SIGNAL(sectionClicked(int)), this, SLOT(actSort(int)));
@ -254,7 +255,7 @@ void WndSets::actRestore()
void WndSets::actRestoreOriginalOrder()
{
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
model->sort(model->ReleaseDateCol, Qt::DescendingOrder);
model->restoreOriginalOrder();
sortWarning->setVisible(false);
}

View file

@ -23,8 +23,9 @@ const char *CardDatabase::TOKENS_SETNAME = "TK";
CardSet::CardSet(const QString &_shortName,
const QString &_longName,
const QString &_setType,
const QDate &_releaseDate)
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType)
const QDate &_releaseDate,
const CardSet::Priority _priority)
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType), priority(_priority)
{
loadSetOptions();
}
@ -32,9 +33,10 @@ CardSet::CardSet(const QString &_shortName,
CardSetPtr CardSet::newInstance(const QString &_shortName,
const QString &_longName,
const QString &_setType,
const QDate &_releaseDate)
const QDate &_releaseDate,
const Priority _priority)
{
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate));
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate, _priority));
// ptr->setSmartPointer(ptr);
return ptr;
}
@ -195,25 +197,31 @@ void SetList::markAllAsKnown()
void SetList::guessSortKeys()
{
// sort by release date DESC; invalid dates to the bottom.
QDate distantFuture(2050, 1, 1);
int aHundredYears = 36500;
defaultSort();
for (int i = 0; i < size(); ++i) {
CardSetPtr set = at(i);
if (set.isNull()) {
qDebug() << "guessSortKeys set is null";
continue;
}
QDate date = set->getReleaseDate();
if (date.isNull()) {
set->setSortKey(static_cast<unsigned int>(aHundredYears));
} else {
set->setSortKey(static_cast<unsigned int>(date.daysTo(distantFuture)));
}
set->setSortKey(i);
}
}
void SetList::defaultSort()
{
std::sort(begin(), end(), [](const CardSetPtr &a, const CardSetPtr &b) {
// Sort by priority, then by release date, then by short name
if (a->getPriority() != b->getPriority()) {
return a->getPriority() < b->getPriority(); // lowest first
} else if (a->getReleaseDate() != b->getReleaseDate()) {
return a->getReleaseDate() > b->getReleaseDate(); // most recent first
} else {
return a->getShortName() < b->getShortName(); // alphabetically
}
});
}
CardInfoPerSet::CardInfoPerSet(const CardSetPtr &_set) : set(_set)
{
}

View file

@ -29,22 +29,36 @@ Q_DECLARE_METATYPE(CardInfoPtr)
class CardSet : public QList<CardInfoPtr>
{
public:
enum Priority
{
PriorityFallback = 0,
PriorityPrimary = 10,
PrioritySecondary = 20,
PriorityReprint = 30,
PriorityOther = 40,
PriorityLowest = 100,
};
private:
QString shortName, longName;
unsigned int sortKey;
QDate releaseDate;
QString setType;
Priority priority;
bool enabled, isknown;
public:
explicit CardSet(const QString &_shortName = QString(),
const QString &_longName = QString(),
const QString &_setType = QString(),
const QDate &_releaseDate = QDate());
const QDate &_releaseDate = QDate(),
const Priority _priority = PriorityFallback);
static CardSetPtr newInstance(const QString &_shortName = QString(),
const QString &_longName = QString(),
const QString &_setType = QString(),
const QDate &_releaseDate = QDate());
const QDate &_releaseDate = QDate(),
const Priority _priority = PriorityFallback);
QString getCorrectedShortName() const;
QString getShortName() const
{
@ -62,6 +76,10 @@ public:
{
return releaseDate;
}
Priority getPriority() const
{
return priority;
}
void setLongName(const QString &_longName)
{
longName = _longName;
@ -74,6 +92,10 @@ public:
{
releaseDate = _releaseDate;
}
void setPriority(const Priority _priority)
{
priority = _priority;
}
void loadSetOptions();
int getSortKey() const
@ -113,6 +135,7 @@ public:
int getEnabledSetsNum();
int getUnknownSetsNum();
QStringList getUnknownSetsNames();
void defaultSort();
};
class CardInfoPerSet

View file

@ -10,7 +10,8 @@ void ICardDatabaseParser::clearSetlist()
CardSetPtr ICardDatabaseParser::internalAddSet(const QString &setName,
const QString &longName,
const QString &setType,
const QDate &releaseDate)
const QDate &releaseDate,
const CardSet::Priority priority)
{
if (sets.contains(setName)) {
return sets.value(setName);
@ -20,8 +21,9 @@ CardSetPtr ICardDatabaseParser::internalAddSet(const QString &setName,
newSet->setLongName(longName);
newSet->setSetType(setType);
newSet->setReleaseDate(releaseDate);
newSet->setPriority(priority);
sets.insert(setName, newSet);
emit addSet(newSet);
return newSet;
}
}

View file

@ -32,7 +32,8 @@ protected:
CardSetPtr internalAddSet(const QString &setName,
const QString &longName = "",
const QString &setType = "",
const QDate &releaseDate = QDate());
const QDate &releaseDate = QDate(),
const CardSet::Priority priority = CardSet::PriorityFallback);
signals:
virtual void addCard(CardInfoPtr card) = 0;
virtual void addSet(CardSetPtr set) = 0;
@ -40,4 +41,4 @@ signals:
Q_DECLARE_INTERFACE(ICardDatabaseParser, "ICardDatabaseParser")
#endif
#endif

View file

@ -77,6 +77,7 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
if (xmlName == "set") {
QString shortName, longName, setType;
QDate releaseDate;
short priority;
while (!xml.atEnd()) {
if (xml.readNext() == QXmlStreamReader::EndElement) {
break;
@ -92,6 +93,8 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
} else if (xmlName == "releasedate") {
releaseDate =
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
} else if (xmlName == "priority") {
priority = xml.readElementText(QXmlStreamReader::IncludeChildElements).toShort();
} else if (!xmlName.isEmpty()) {
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xmlName
<< ", trying to continue anyway";
@ -99,7 +102,7 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
}
}
internalAddSet(shortName, longName, setType, releaseDate);
internalAddSet(shortName, longName, setType, releaseDate, static_cast<CardSet::Priority>(priority));
}
}
}
@ -249,6 +252,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSetPtr &set
xml.writeTextElement("longname", set->getLongName());
xml.writeTextElement("settype", set->getSetType());
xml.writeTextElement("releasedate", set->getReleaseDate().toString(Qt::ISODate));
xml.writeTextElement("priority", QString::number(set->getPriority()));
xml.writeEndElement();
return xml;