fix for deck list model crash

This commit is contained in:
Max-Wilhelm Bruker 2009-07-17 21:27:38 +02:00
parent ec73ffc82b
commit ecc6f7b20f
4 changed files with 56 additions and 13 deletions

View file

@ -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<int, AbstractDecklistNode *> a, QPair<int, AbstractDecklistNode *> 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<QPair<int, int> > InnerDecklistNode::sort(Qt::SortOrder order)
{
compareFunctor cmp(order);
qSort(begin(), end(), cmp);
for (int i = 0; i < size(); i++) {
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(at(i));
if (node)
node->sort(order);
QVector<QPair<int, int> > result(size());
// Initialize temporary list with contents of current list
QVector<QPair<int, AbstractDecklistNode *> > 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)

View file

@ -2,6 +2,8 @@
#define DECKLIST_H
#include <QList>
#include <QVector>
#include <QPair>
#include <QObject>
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<QPair<int, int> > sort(Qt::SortOrder order = Qt::AscendingOrder);
};
class AbstractDecklistCardNode : public AbstractDecklistNode {

View file

@ -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<InnerDecklistNode *>(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<QPair<int, int> > 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<InnerDecklistNode *>(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();
}

View file

@ -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;