fix for deck list model crash
This commit is contained in:
parent
ec73ffc82b
commit
ecc6f7b20f
4 changed files with 56 additions and 13 deletions
|
@ -55,6 +55,7 @@ AbstractDecklistNode *InnerDecklistNode::findChild(const QString &name)
|
||||||
|
|
||||||
int InnerDecklistNode::height() const
|
int InnerDecklistNode::height() const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(!isEmpty());
|
||||||
return at(0)->height() + 1;
|
return at(0)->height() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,21 +97,36 @@ private:
|
||||||
Qt::SortOrder order;
|
Qt::SortOrder order;
|
||||||
public:
|
public:
|
||||||
compareFunctor(Qt::SortOrder _order) : order(_order) { }
|
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);
|
QVector<QPair<int, int> > result(size());
|
||||||
qSort(begin(), end(), cmp);
|
|
||||||
for (int i = 0; i < size(); i++) {
|
// Initialize temporary list with contents of current list
|
||||||
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(at(i));
|
QVector<QPair<int, AbstractDecklistNode *> > tempList(size());
|
||||||
if (node)
|
for (int i = size() - 1; i >= 0; --i) {
|
||||||
node->sort(order);
|
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)
|
DeckList::DeckList(CardDatabase *_db, QObject *parent)
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define DECKLIST_H
|
#define DECKLIST_H
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QPair>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class CardDatabase;
|
class CardDatabase;
|
||||||
|
@ -38,7 +40,7 @@ public:
|
||||||
int height() const;
|
int height() const;
|
||||||
int recursiveCount(bool countTotalCards = false) const;
|
int recursiveCount(bool countTotalCards = false) const;
|
||||||
bool compare(AbstractDecklistNode *other) 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 {
|
class AbstractDecklistCardNode : public AbstractDecklistNode {
|
||||||
|
|
|
@ -206,7 +206,6 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||||
|
|
||||||
bool DeckListModel::removeRows(int row, int count, const QModelIndex &parent)
|
bool DeckListModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||||
{
|
{
|
||||||
debugIndexInfo("removeRows", parent);
|
|
||||||
InnerDecklistNode *node = getNode<InnerDecklistNode *>(parent);
|
InnerDecklistNode *node = getNode<InnerDecklistNode *>(parent);
|
||||||
if (!node)
|
if (!node)
|
||||||
return false;
|
return false;
|
||||||
|
@ -274,11 +273,36 @@ QModelIndex DeckListModel::nodeToIndex(AbstractDecklistNode *node) const
|
||||||
return createIndex(node->getParent()->indexOf(node), 0, node);
|
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)
|
void DeckListModel::sort(int /*column*/, Qt::SortOrder order)
|
||||||
{
|
{
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
root->sort(order);
|
sortHelper(root, order);
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
DeckListModel(CardDatabase *_db, QObject *parent = 0);
|
DeckListModel(CardDatabase *_db, QObject *parent = 0);
|
||||||
~DeckListModel();
|
~DeckListModel();
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
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 data(const QModelIndex &index, int role) const;
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
@ -50,6 +50,7 @@ private:
|
||||||
InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent);
|
InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent);
|
||||||
QModelIndex nodeToIndex(AbstractDecklistNode *node) const;
|
QModelIndex nodeToIndex(AbstractDecklistNode *node) const;
|
||||||
void emitRecursiveUpdates(const QModelIndex &index);
|
void emitRecursiveUpdates(const QModelIndex &index);
|
||||||
|
void sortHelper(InnerDecklistNode *node, Qt::SortOrder order);
|
||||||
void debugIndexInfo(const QString &func, const QModelIndex &index) const;
|
void debugIndexInfo(const QString &func, const QModelIndex &index) const;
|
||||||
void debugShowTree(InnerDecklistNode *node, int depth) const;
|
void debugShowTree(InnerDecklistNode *node, int depth) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue