servatrice/cockatrice/src/carddatabasemodel.cpp
Matt Lowe 95104df589 Reverted back to full punctuation
Reverted back. Right now it feels strange to only have simple search.
Really you would want both simple search AND accurate search on, though
this requires twice the checks for each result.
2015-05-01 22:26:44 +02:00

210 lines
6.2 KiB
C++

#include "carddatabasemodel.h"
#include "filtertree.h"
#define CARDDBMODEL_COLUMNS 5
CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, QObject *parent)
: QAbstractListModel(parent), db(_db)
{
connect(db, SIGNAL(cardListChanged()), this, SLOT(updateCardList()));
connect(db, SIGNAL(cardAdded(CardInfo *)), this, SLOT(cardAdded(CardInfo *)));
connect(db, SIGNAL(cardRemoved(CardInfo *)), this, SLOT(cardRemoved(CardInfo *)));
updateCardList();
}
CardDatabaseModel::~CardDatabaseModel()
{
}
int CardDatabaseModel::rowCount(const QModelIndex &/*parent*/) const
{
return cardList.size();
}
int CardDatabaseModel::columnCount(const QModelIndex &/*parent*/) const
{
return CARDDBMODEL_COLUMNS;
}
QVariant CardDatabaseModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if ((index.row() >= cardList.size()) || (index.column() >= CARDDBMODEL_COLUMNS))
return QVariant();
if (role != Qt::DisplayRole && role != SortRole)
return QVariant();
CardInfo *card = cardList.at(index.row());
switch (index.column()){
case NameColumn: return card->getName();
case SetListColumn: {
QStringList setList;
const QList<CardSet *> &sets = card->getSets();
for (int i = 0; i < sets.size(); i++)
{
if(sets[i]->getEnabled())
setList << sets[i]->getShortName();
}
return setList.join(", ");
}
case ManaCostColumn: return role == SortRole ?
QString("%1%2").arg(card->getCmc(), 4, QChar('0')).arg(card->getManaCost()) :
card->getManaCost();
case CardTypeColumn: return card->getCardType();
case PTColumn: return card->getPowTough();
default: return QVariant();
}
}
QVariant CardDatabaseModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation != Qt::Horizontal)
return QVariant();
switch (section) {
case NameColumn: return QString(tr("Name"));
case SetListColumn: return QString(tr("Sets"));
case ManaCostColumn: return QString(tr("Mana cost"));
case CardTypeColumn: return QString(tr("Card type"));
case PTColumn: return QString(tr("P/T"));
default: return QVariant();
}
}
void CardDatabaseModel::updateCardList()
{
beginResetModel();
for (int i = 0; i < cardList.size(); ++i)
disconnect(cardList[i], 0, this, 0);
cardList.clear();
foreach(CardInfo * card, db->getCardList())
{
bool hasSet = false;
foreach(CardSet * set, card->getSets())
{
if(set->getEnabled())
{
hasSet = true;
break;
}
}
if(hasSet)
{
cardList.append(card);
connect(card, SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *)));
}
}
endResetModel();
}
void CardDatabaseModel::cardInfoChanged(CardInfo *card)
{
const int row = cardList.indexOf(card);
if (row == -1)
return;
emit dataChanged(index(row, 0), index(row, CARDDBMODEL_COLUMNS - 1));
}
void CardDatabaseModel::cardAdded(CardInfo *card)
{
beginInsertRows(QModelIndex(), cardList.size(), cardList.size());
cardList.append(card);
connect(card, SIGNAL(cardInfoChanged(CardInfo *)), this, SLOT(cardInfoChanged(CardInfo *)));
endInsertRows();
}
void CardDatabaseModel::cardRemoved(CardInfo *card)
{
const int row = cardList.indexOf(card);
if (row == -1)
return;
beginRemoveRows(QModelIndex(), row, row);
cardList.removeAt(row);
endRemoveRows();
}
CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent)
: QSortFilterProxyModel(parent),
isToken(ShowAll)
{
filterTree = NULL;
setFilterCaseSensitivity(Qt::CaseInsensitive);
setSortCaseSensitivity(Qt::CaseInsensitive);
}
bool CardDatabaseDisplayModel::lessThan(const QModelIndex &left, const QModelIndex &right) const {
QString leftString = sourceModel()->data(left, CardDatabaseModel::SortRole).toString();
QString rightString = sourceModel()->data(right, CardDatabaseModel::SortRole).toString();
if (!cardName.isEmpty() && left.column() == CardDatabaseModel::NameColumn)
{
bool isLeftType = leftString.startsWith(cardName, Qt::CaseInsensitive);
bool isRightType = rightString.startsWith(cardName, Qt::CaseInsensitive);
// test for an exact match: isLeftType && leftString.size() == cardName.size()
// or an exclusive start match: isLeftType && !isRightType
if (isLeftType && (!isRightType || leftString.size() == cardName.size()))
return true;
// same checks for the right string
if (isRightType && (!isLeftType || rightString.size() == cardName.size()))
return false;
}
return QString::localeAwareCompare(leftString, rightString) < 0;
}
bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex & /*sourceParent*/) const
{
CardInfo const *info = static_cast<CardDatabaseModel *>(sourceModel())->getCard(sourceRow);
if (((isToken == ShowTrue) && !info->getIsToken()) || ((isToken == ShowFalse) && info->getIsToken()))
return false;
if (!cardName.isEmpty() && !info->getName().contains(cardName, Qt::CaseInsensitive))
return false;
if (!cardNameSet.isEmpty() && !cardNameSet.contains(info->getName()))
return false;
if (filterTree != NULL)
return filterTree->acceptsCard(info);
return true;
}
void CardDatabaseDisplayModel::clearSearch()
{
cardName.clear();
cardText.clear();
cardTypes.clear();
cardColors.clear();
if (filterTree != NULL)
filterTree->clear();
invalidateFilter();
}
void CardDatabaseDisplayModel::setFilterTree(FilterTree *filterTree)
{
if (this->filterTree != NULL)
disconnect(this->filterTree, 0, this, 0);
this->filterTree = filterTree;
connect(this->filterTree, SIGNAL(changed()), this, SLOT(filterTreeChanged()));
invalidate();
}
void CardDatabaseDisplayModel::filterTreeChanged()
{
invalidate();
}