From ecc6f7b20fb7b13078f570ff026d4d7ce691d055 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Fri, 17 Jul 2009 21:27:38 +0200 Subject: [PATCH] fix for deck list model crash --- cockatrice/src/decklist.cpp | 34 +++++++++++++++++++++++--------- cockatrice/src/decklist.h | 4 +++- cockatrice/src/decklistmodel.cpp | 28 ++++++++++++++++++++++++-- cockatrice/src/decklistmodel.h | 3 ++- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/cockatrice/src/decklist.cpp b/cockatrice/src/decklist.cpp index cfb1cf58..0c4d5db0 100644 --- a/cockatrice/src/decklist.cpp +++ b/cockatrice/src/decklist.cpp @@ -55,6 +55,7 @@ AbstractDecklistNode *InnerDecklistNode::findChild(const QString &name) int InnerDecklistNode::height() const { + Q_ASSERT(!isEmpty()); return at(0)->height() + 1; } @@ -96,21 +97,36 @@ private: Qt::SortOrder order; public: compareFunctor(Qt::SortOrder _order) : order(_order) { } - inline bool operator()(AbstractDecklistNode *a, AbstractDecklistNode *b) const + inline bool operator()(QPair a, QPair b) const { - return (order == Qt::AscendingOrder) ^ (a->compare(b)); + return (order == Qt::AscendingOrder) ^ (a.second->compare(b.second)); } }; -void InnerDecklistNode::sort(Qt::SortOrder order) +QVector > InnerDecklistNode::sort(Qt::SortOrder order) { - compareFunctor cmp(order); - qSort(begin(), end(), cmp); - for (int i = 0; i < size(); i++) { - InnerDecklistNode *node = dynamic_cast(at(i)); - if (node) - node->sort(order); + QVector > result(size()); + + // Initialize temporary list with contents of current list + QVector > tempList(size()); + for (int i = size() - 1; i >= 0; --i) { + tempList[i].first = i; + tempList[i].second = at(i); } + + // Sort temporary list + compareFunctor cmp(order); + qSort(tempList.begin(), tempList.end(), cmp); + + // Map old indexes to new indexes and + // copy temporary list to the current one + for (int i = size() - 1; i >= 0; --i) { + result[i].first = tempList[i].first; + result[i].second = i; + replace(i, tempList[i].second); + } + + return result; } DeckList::DeckList(CardDatabase *_db, QObject *parent) diff --git a/cockatrice/src/decklist.h b/cockatrice/src/decklist.h index 9c962b5a..c4f5c388 100644 --- a/cockatrice/src/decklist.h +++ b/cockatrice/src/decklist.h @@ -2,6 +2,8 @@ #define DECKLIST_H #include +#include +#include #include class CardDatabase; @@ -38,7 +40,7 @@ public: int height() const; int recursiveCount(bool countTotalCards = false) const; bool compare(AbstractDecklistNode *other) const; - void sort(Qt::SortOrder order = Qt::AscendingOrder); + QVector > sort(Qt::SortOrder order = Qt::AscendingOrder); }; class AbstractDecklistCardNode : public AbstractDecklistNode { diff --git a/cockatrice/src/decklistmodel.cpp b/cockatrice/src/decklistmodel.cpp index 4473033c..4b5ed59a 100644 --- a/cockatrice/src/decklistmodel.cpp +++ b/cockatrice/src/decklistmodel.cpp @@ -206,7 +206,6 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, int bool DeckListModel::removeRows(int row, int count, const QModelIndex &parent) { - debugIndexInfo("removeRows", parent); InnerDecklistNode *node = getNode(parent); if (!node) return false; @@ -274,11 +273,36 @@ QModelIndex DeckListModel::nodeToIndex(AbstractDecklistNode *node) const return createIndex(node->getParent()->indexOf(node), 0, node); } +void DeckListModel::sortHelper(InnerDecklistNode *node, Qt::SortOrder order) +{ + // Sort children of node and save the information needed to + // update the list of persistent indexes. + QVector > sortResult = node->sort(order); + + QModelIndexList from, to; + for (int i = sortResult.size() - 1; i >= 0; --i) { + const int fromRow = sortResult[i].first; + const int toRow = sortResult[i].second; + AbstractDecklistNode *temp = node->at(toRow); + for (int j = columnCount(); j; --j) { + from << createIndex(fromRow, 0, temp); + to << createIndex(toRow, 0, temp); + } + } + changePersistentIndexList(from, to); + + // Recursion + for (int i = node->size() - 1; i >= 0; --i) { + InnerDecklistNode *subNode = dynamic_cast(node->at(i)); + if (subNode) + sortHelper(subNode, order); + } +} void DeckListModel::sort(int /*column*/, Qt::SortOrder order) { emit layoutAboutToBeChanged(); - root->sort(order); + sortHelper(root, order); emit layoutChanged(); } diff --git a/cockatrice/src/decklistmodel.h b/cockatrice/src/decklistmodel.h index 82003b43..ba4e6c4f 100644 --- a/cockatrice/src/decklistmodel.h +++ b/cockatrice/src/decklistmodel.h @@ -31,7 +31,7 @@ public: DeckListModel(CardDatabase *_db, QObject *parent = 0); ~DeckListModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &/*parent*/) const { return 2; } + int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return 2; } QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; @@ -50,6 +50,7 @@ private: InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent); QModelIndex nodeToIndex(AbstractDecklistNode *node) const; void emitRecursiveUpdates(const QModelIndex &index); + void sortHelper(InnerDecklistNode *node, Qt::SortOrder order); void debugIndexInfo(const QString &func, const QModelIndex &index) const; void debugShowTree(InnerDecklistNode *node, int depth) const;