Fix deck export and mana group ordering (#7729)

This commit is contained in:
Bryce! 2026-11-04 09:43:38 -05:00 • committed by GitHub
parent 2056043104
commit ca2301bc96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 113 additions and 10 deletions

View file

@ -746,7 +746,8 @@ QModelIndex DeckListModel::nodeToIndex(AbstractDecklistNode *node) const
void DeckListModel::sortShadowTree(InnerDecklistNode *node, Qt::SortOrder order)
{
// The mapping is not needed: fresh shadow nodes have no persistent indices yet.
(void)DeckListModelCustomZones::sortWithCustomZonesLast(root, node, order);
(void)DeckListModelCustomZones::sortWithCustomZonesLast(
root, node, order, activeGroupCriteria == DeckListModelGroupCriteria::MANA_COST && lastKnownColumn != 0);
for (int i = node->size() - 1; i >= 0; --i) {
if (auto *subNode = dynamic_cast<InnerDecklistNode *>(node->at(i))) {
@ -759,7 +760,8 @@ void DeckListModel::sortHelper(InnerDecklistNode *node, Qt::SortOrder order)
{
// Sort children (custom zones always sorted after groups within a board) and
// use the movement mapping to update the list of persistent indices.
const auto mapping = DeckListModelCustomZones::sortWithCustomZonesLast(root, node, order);
const auto mapping = DeckListModelCustomZones::sortWithCustomZonesLast(
root, node, order, activeGroupCriteria == DeckListModelGroupCriteria::MANA_COST && lastKnownColumn != 0);
QModelIndexList from, to;
int columns = columnCount();

View file

@ -8,6 +8,8 @@
#include <QHash>
#include <QSharedPointer>
#include <QVector>
#include <algorithm>
#include <cmath>
#include <utility>
namespace DeckListModelCustomZones
@ -111,7 +113,7 @@ QList<QPair<int, int>> plainSort(InnerDecklistNode *node, Qt::SortOrder order)
*
* @return The (preSortRow, finalRow) mapping covering both the sort and the shift.
*/
QList<QPair<int, int>> boardSort(InnerDecklistNode *node, Qt::SortOrder order)
QList<QPair<int, int>> boardSort(InnerDecklistNode *node, Qt::SortOrder order, bool numericGroups)
{
const QVector<QPair<int, int>> sortResult = node->sort(order);
@ -132,6 +134,27 @@ QList<QPair<int, int>> boardSort(InnerDecklistNode *node, Qt::SortOrder order)
}
}
if (numericGroups) {
// Only criteria groups are numeric. Mixing numeric and lexical fallback
// comparisons with custom zone names would not define a strict ordering.
std::sort(groups.begin(), groups.end(), [order](const auto *left, const auto *right) {
const QString leftName = left->getName();
const QString rightName = right->getName();
bool leftIsNumber, rightIsNumber;
const double leftValue = leftName.toDouble(&leftIsNumber);
const double rightValue = rightName.toDouble(&rightIsNumber);
leftIsNumber = leftIsNumber && std::isfinite(leftValue);
rightIsNumber = rightIsNumber && std::isfinite(rightValue);
if (leftIsNumber != rightIsNumber) {
return leftIsNumber;
}
if (leftIsNumber && leftValue != rightValue) {
return order == Qt::AscendingOrder ? leftValue < rightValue : leftValue > rightValue;
}
return order == Qt::AscendingOrder ? leftName < rightName : leftName > rightName;
});
}
QVector<AbstractDecklistNode *> ordered = groups + customZones;
for (int i = 0; i < ordered.size(); ++i) {
node->replace(i, ordered[i]);
@ -147,10 +170,11 @@ QList<QPair<int, int>> boardSort(InnerDecklistNode *node, Qt::SortOrder order)
} // namespace
QList<QPair<int, int>> sortWithCustomZonesLast(InnerDecklistNode *root, InnerDecklistNode *node, Qt::SortOrder order)
QList<QPair<int, int>>
sortWithCustomZonesLast(InnerDecklistNode *root, InnerDecklistNode *node, Qt::SortOrder order, bool numericGroups)
{
const bool isBoardZone = (node != root) && (node->getParent() == root);
return isBoardZone ? boardSort(node, order) : plainSort(node, order);
return isBoardZone ? boardSort(node, order, numericGroups) : plainSort(node, order);
}
} // namespace DeckListModelCustomZones

View file

@ -91,10 +91,15 @@ void mirrorCustomZones(const InnerDecklistNode *deckBoardZone, InnerDecklistNode
* @param root Root of the shadow tree (used to classify board zones).
* @param node The shadow node whose children are reordered.
* @param order Sort order to apply.
* @param numericGroups Compare criteria-group names as mana values. Custom zone
* names and card names retain their normal comparison; nonnumeric groups follow
* numeric groups in either sort direction.
* @return A list of (preSortRow, finalRow) pairs describing how each node moved.
*/
[[nodiscard]] QList<QPair<int, int>>
sortWithCustomZonesLast(InnerDecklistNode *root, InnerDecklistNode *node, Qt::SortOrder order);
[[nodiscard]] QList<QPair<int, int>> sortWithCustomZonesLast(InnerDecklistNode *root,
InnerDecklistNode *node,
Qt::SortOrder order,
bool numericGroups = false);
} // namespace DeckListModelCustomZones