From 3202243ed0b30699b9e65be6c07ef928f04eb78f Mon Sep 17 00:00:00 2001 From: sylvanbasilisk Date: Tue, 21 Jan 2014 23:37:22 +0000 Subject: [PATCH] connect filter list functionality to the CardDatabaseDisplayModel class enable/disable check boxes still not functional --- cockatrice/src/carddatabasemodel.cpp | 22 +++- cockatrice/src/carddatabasemodel.h | 6 + cockatrice/src/cardfilter.cpp | 6 + cockatrice/src/cardfilter.h | 5 + cockatrice/src/filterlist.cpp | 179 ++++++++++++++++++++++++++- cockatrice/src/filterlist.h | 28 ++++- cockatrice/src/filterlistmodel.cpp | 23 ++-- cockatrice/src/filterlistmodel.h | 3 +- cockatrice/src/tab_deck_editor.cpp | 1 + 9 files changed, 258 insertions(+), 15 deletions(-) diff --git a/cockatrice/src/carddatabasemodel.cpp b/cockatrice/src/carddatabasemodel.cpp index d63f6bde..559f8cc4 100644 --- a/cockatrice/src/carddatabasemodel.cpp +++ b/cockatrice/src/carddatabasemodel.cpp @@ -1,4 +1,5 @@ #include "carddatabasemodel.h" +#include "filterlist.h" CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, QObject *parent) : QAbstractListModel(parent), db(_db) @@ -109,6 +110,7 @@ CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent) : QSortFilterProxyModel(parent), isToken(ShowAll) { + filterList = NULL; setFilterCaseSensitivity(Qt::CaseInsensitive); setSortCaseSensitivity(Qt::CaseInsensitive); } @@ -116,7 +118,7 @@ CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent) bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex & /*sourceParent*/) const { CardInfo const *info = static_cast(sourceModel())->getCard(sourceRow); - + if (((isToken == ShowTrue) && !info->getIsToken()) || ((isToken == ShowFalse) && info->getIsToken())) return false; @@ -144,6 +146,9 @@ bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex if (!cardTypes.contains(info->getMainCardType())) return false; + if (filterList != NULL) + return filterList->acceptsCard(info); + return true; } @@ -155,3 +160,18 @@ void CardDatabaseDisplayModel::clearSearch() cardColors.clear(); invalidateFilter(); } + +void CardDatabaseDisplayModel::setFilterList(const FilterList *filterList) +{ + if(this->filterList != NULL) + disconnect(this->filterList, 0, this, 0); + + this->filterList = filterList; + connect(this->filterList, SIGNAL(changed()), this, SLOT(filterListChanged())); + invalidate(); +} + +void CardDatabaseDisplayModel::filterListChanged() +{ + invalidate(); +} diff --git a/cockatrice/src/carddatabasemodel.h b/cockatrice/src/carddatabasemodel.h index b2998bfe..ba245b41 100644 --- a/cockatrice/src/carddatabasemodel.h +++ b/cockatrice/src/carddatabasemodel.h @@ -7,6 +7,8 @@ #include #include "carddatabase.h" +class FilterList; + class CardDatabaseModel : public QAbstractListModel { Q_OBJECT public: @@ -36,8 +38,10 @@ private: FilterBool isToken; QString cardNameBeginning, cardName, cardText; QSet cardNameSet, cardTypes, cardColors; + const FilterList *filterList; public: CardDatabaseDisplayModel(QObject *parent = 0); + void setFilterList(const FilterList *filterList); void setIsToken(FilterBool _isToken) { isToken = _isToken; invalidate(); } void setCardNameBeginning(const QString &_beginning) { cardNameBeginning = _beginning; invalidate(); } void setCardName(const QString &_cardName) { cardName = _cardName; invalidate(); } @@ -48,6 +52,8 @@ public: void clearSearch(); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; +private slots: + void filterListChanged(); }; #endif diff --git a/cockatrice/src/cardfilter.cpp b/cockatrice/src/cardfilter.cpp index d6fe790e..27402921 100644 --- a/cockatrice/src/cardfilter.cpp +++ b/cockatrice/src/cardfilter.cpp @@ -25,6 +25,12 @@ const char *CardFilter::attrName(Attr a) return "type"; case AttrColor: return "color"; + case AttrText: + return "text"; + case AttrSet: + return "set"; + case AttrManaCost: + return "mana cost"; default: return ""; } diff --git a/cockatrice/src/cardfilter.h b/cockatrice/src/cardfilter.h index 67395c2d..f4f38771 100644 --- a/cockatrice/src/cardfilter.h +++ b/cockatrice/src/cardfilter.h @@ -13,10 +13,15 @@ public: TypeEnd }; + /* if you add an atribute here you also need to + * add its string representation in attrName */ enum Attr { AttrName = 0, AttrType, AttrColor, + AttrText, + AttrSet, + AttrManaCost, AttrEnd }; diff --git a/cockatrice/src/filterlist.cpp b/cockatrice/src/filterlist.cpp index 35d7a0fc..eaae7d1c 100644 --- a/cockatrice/src/filterlist.cpp +++ b/cockatrice/src/filterlist.cpp @@ -1,5 +1,6 @@ #include "filterlist.h" -#include "CardFilter.h" +#include "cardfilter.h" +#include "carddatabase.h" #include @@ -9,6 +10,17 @@ LogicMap::~LogicMap() delete takeFirst(); } +const FilterItemList *LogicMap::findTypeList(CardFilter::Type type) const +{ + LogicMap::const_iterator i; + + for(i = constBegin(); i != constEnd(); i++) + if ((*i)->type == type) + return *i; + + return NULL; +} + FilterItemList *LogicMap::typeList(CardFilter::Type type) { LogicMap::iterator i; @@ -158,3 +170,168 @@ int FilterList::count(const CardFilter *f) { return count(f->attr(), f->type()); } + +bool FilterList::acceptName(const CardInfo *info, const QString &term) const +{ + return info->getName().contains(term, Qt::CaseInsensitive); +} + +bool FilterList::acceptType(const CardInfo *info, const QString &term) const +{ + return info->getCardType().contains(term, Qt::CaseInsensitive); +} + +bool FilterList::acceptColor(const CardInfo *info, const QString &term) const +{ + QStringList::const_iterator i; + bool status; + + status = false; + for(i = info->getColors().constBegin(); i != info->getColors().constEnd(); i++) + if ((*i).contains(term, Qt::CaseInsensitive)) { + status = true; + break; + } + + return status; +} + +bool FilterList::acceptText(const CardInfo *info, const QString &term) const +{ + return info->getText().contains(term, Qt::CaseInsensitive); +} + +bool FilterList::acceptSet(const CardInfo *info, const QString &term) const +{ + SetList::const_iterator i; + bool status; + + status = false; + for(i = info->getSets().constBegin(); i != info->getSets().constEnd(); i++) + if ((*i)->getShortName() == term + || (*i)->getLongName().contains(term, Qt::CaseInsensitive)) { + status = true; + break; + } + + return status; +} + +bool FilterList::acceptManaCost(const CardInfo *info, const QString &term) const +{ + return (info->getManaCost() == term); +} + +bool FilterList::acceptCardAttr(const CardInfo *info, const QString &term, + CardFilter::Attr attr) const +{ + bool status; + + switch(attr) { + case CardFilter::AttrName: + status = acceptName(info, term); + break; + case CardFilter::AttrType: + status = acceptType(info, term); + break; + case CardFilter::AttrColor: + status = acceptColor(info, term); + break; + case CardFilter::AttrText: + status = acceptText(info, term); + break; + case CardFilter::AttrSet: + status = acceptSet(info, term); + break; + case CardFilter::AttrManaCost: + status = acceptManaCost(info, term); + break; + default: + status = true; /* ignore this attribute */ + } + + return status; +} + +bool FilterList::testTypeAnd(const CardInfo *info, CardFilter::Attr attr, + const FilterItemList *fil) const +{ + FilterItemList::const_iterator i; + + for(i = fil->constBegin(); i != fil->constEnd(); i++) + if(!acceptCardAttr(info, (*i)->term, attr)) + return false; + + return true; +} + +bool FilterList::testTypeAndNot(const CardInfo *info, CardFilter::Attr attr, + const FilterItemList *fil) const +{ + FilterItemList::const_iterator i; + + for(i = fil->constBegin(); i != fil->constEnd(); i++) + if(acceptCardAttr(info, (*i)->term, attr)) + return false; + + return true; +} + +bool FilterList::testTypeOr(const CardInfo *info, CardFilter::Attr attr, + const FilterItemList *filOr, + const FilterItemList *filOrNot) const +{ + FilterItemList::const_iterator i; + bool status; + + if(filOr == NULL && filOrNot == NULL) + return true; + + status = false; + if (filOr != NULL) + for(i = filOr->constBegin(); i != filOr->constEnd(); i++) + if(acceptCardAttr(info, (*i)->term, attr)) { + status = true; + break; + } + if (status != true && filOrNot != NULL) + for(i = filOrNot->constBegin(); i != filOrNot->constEnd(); i++) + if(!acceptCardAttr(info, (*i)->term, attr)) { + status = true; + break; + } + + return status; +} + +bool FilterList::testAttr(const CardInfo *info, const LogicMap *lm) const +{ + bool status; + const FilterItemList *fil, *fil2; + + fil = lm->findTypeList(CardFilter::TypeAnd); + if (fil != NULL && !testTypeAnd(info, lm->attr, fil)) + return false; + + fil = lm->findTypeList(CardFilter::TypeAndNot); + if (fil != NULL && !testTypeAndNot(info, lm->attr, fil)) + return false; + + fil = lm->findTypeList(CardFilter::TypeOr); + fil2 = lm->findTypeList(CardFilter::TypeOrNot); + if (!testTypeOr(info, lm->attr, fil, fil2)) + return false; + + return true; +} + +bool FilterList::acceptsCard(const CardInfo *info) const +{ + QList::const_iterator i; + + for(i = logicAttrs.constBegin(); i != logicAttrs.constEnd(); i++) + if(!testAttr(info, *i)) + return false; + + return true; +} diff --git a/cockatrice/src/filterlist.h b/cockatrice/src/filterlist.h index aed58f7d..98b885bc 100644 --- a/cockatrice/src/filterlist.h +++ b/cockatrice/src/filterlist.h @@ -7,6 +7,8 @@ #include "cardfilter.h" +class CardInfo; + class FilterListNode { private: bool enabled; @@ -38,6 +40,7 @@ public: LogicMap(CardFilter::Attr a, FilterList *parent) : attr(a), p(parent) {} ~LogicMap(); + const FilterItemList *findTypeList(CardFilter::Type type) const; FilterItemList *typeList(CardFilter::Type type); virtual FilterListNode *parent() const; virtual FilterListNode *nodeAt(int i) const; @@ -55,6 +58,7 @@ private: LogicMap *const p; public: const CardFilter::Type type; + FilterItemList(CardFilter::Type t, LogicMap *parent) : type(t), p(parent) {} ~FilterItemList(); @@ -90,6 +94,7 @@ class FilterList : public QObject, public FilterListNode { signals: void preInsertRow(const FilterListNode *parent, int i) const; void postInsertRow(const FilterListNode *parent, int i) const; + void changed() const; private: QList logicAttrs; @@ -98,6 +103,24 @@ private: FilterItemList *attrTypeList(CardFilter::Attr attr, CardFilter::Type type); + bool acceptName(const CardInfo *info, const QString &term) const; + bool acceptType(const CardInfo *info, const QString &term) const; + bool acceptColor(const CardInfo *info, const QString &term) const; + bool acceptCardAttr(const CardInfo *info, const QString &term, + CardFilter::Attr attr) const; + bool acceptText(const CardInfo *info, const QString &term) const; + bool acceptSet(const CardInfo *info, const QString &term) const; + bool acceptManaCost(const CardInfo *info, const QString &term) const; + + bool testTypeAnd(const CardInfo *info, CardFilter::Attr attr, + const FilterItemList *fil) const; + bool testTypeAndNot(const CardInfo *info, CardFilter::Attr attr, + const FilterItemList *fil) const; + bool testTypeOr(const CardInfo *info, CardFilter::Attr attr, + const FilterItemList *filOr, + const FilterItemList *filOrNot) const; + + bool testAttr(const CardInfo *info, const LogicMap *lm) const; public: ~FilterList(); int indexOf(const LogicMap *val) const { return logicAttrs.indexOf((LogicMap *) val); } @@ -117,7 +140,10 @@ public: virtual QString text() const { return QString("root"); } virtual int index() const { return 0; } void preInsertChild(const FilterListNode *p, int i) const { emit preInsertRow(p, i); } - void postInsertChild(const FilterListNode *p, int i) const { emit postInsertRow(p, i); } + void postInsertChild(const FilterListNode *p, int i) const { emit postInsertRow(p, i); emit changed(); } + void emitChanged() const { emit changed(); } + + bool acceptsCard(const CardInfo *info) const; }; #endif diff --git a/cockatrice/src/filterlistmodel.cpp b/cockatrice/src/filterlistmodel.cpp index 6bd84809..a6f2404b 100644 --- a/cockatrice/src/filterlistmodel.cpp +++ b/cockatrice/src/filterlistmodel.cpp @@ -6,18 +6,18 @@ FilterListModel::FilterListModel(QObject *parent) : QAbstractItemModel(parent) { - filterList = new FilterList; - connect(filterList, + fList = new FilterList; + connect(fList, SIGNAL(preInsertRow(const FilterListNode *, int)), this, SLOT(proxyBeginInsertRow(const FilterListNode *, int))); - connect(filterList, + connect(fList, SIGNAL(postInsertRow(const FilterListNode *, int)), this, SLOT(proxyEndInsertRow(const FilterListNode *, int))); } FilterListModel::~FilterListModel() { - delete filterList; + delete fList; } void FilterListModel::proxyBeginInsertRow(const FilterListNode *node, int i) @@ -44,11 +44,11 @@ FilterListNode *FilterListModel::indexToNode(const QModelIndex &idx) const FilterListNode *node; if(!idx.isValid()) - return filterList; + return fList; ip = idx.internalPointer(); if(ip == NULL) - return filterList; + return fList; node = static_cast(ip); return node; @@ -57,7 +57,7 @@ FilterListNode *FilterListModel::indexToNode(const QModelIndex &idx) const void FilterListModel::addFilter(const CardFilter *f) { emit layoutAboutToBeChanged(); - filterList->termNode(f); + fList->termNode(f); emit layoutChanged(); } @@ -135,7 +135,7 @@ bool FilterListModel::setData(const QModelIndex &index, return false; node = indexToNode(index); - if(node == NULL || node == filterList) + if(node == NULL || node == fList) return false; Qt::CheckState state = static_cast(value.toInt()); @@ -161,7 +161,7 @@ Qt::ItemFlags FilterListModel::flags(const QModelIndex &index) const return 0; result = Qt::ItemIsEnabled; - if(node == filterList) + if(node == fList) return result; result |= Qt::ItemIsSelectable; @@ -207,7 +207,7 @@ QModelIndex FilterListModel::parent(const QModelIndex &ind) const return QModelIndex(); node = indexToNode(ind); - if(node == NULL || node == filterList) + if(node == NULL || node == fList) return QModelIndex(); parent = node->parent(); @@ -239,8 +239,9 @@ bool FilterListModel::removeRows(int row, int count, const QModelIndex & parent) for(i = 0; i < count; i++) node->deleteAt(row); endRemoveRows(); + fList->emitChanged(); - if(node != filterList && node->childCount() < 1) + if(node != fList && node->childCount() < 1) return removeRow(parent.row(), parent.parent()); return true; diff --git a/cockatrice/src/filterlistmodel.h b/cockatrice/src/filterlistmodel.h index de25f452..944bb5b7 100644 --- a/cockatrice/src/filterlistmodel.h +++ b/cockatrice/src/filterlistmodel.h @@ -10,7 +10,7 @@ class FilterListNode; class FilterListModel : public QAbstractItemModel { Q_OBJECT private: - FilterList *filterList; + FilterList *fList; public slots: void addFilter(const CardFilter *f); @@ -26,6 +26,7 @@ private: public: FilterListModel(QObject *parent = 0); ~FilterListModel(); + const FilterList *filterList() const { return fList; } int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; diff --git a/cockatrice/src/tab_deck_editor.cpp b/cockatrice/src/tab_deck_editor.cpp index a7aded4c..a1fc1022 100644 --- a/cockatrice/src/tab_deck_editor.cpp +++ b/cockatrice/src/tab_deck_editor.cpp @@ -170,6 +170,7 @@ TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor, QWidget *parent) botFrame->addLayout(searchAndButtons); filterModel = new FilterListModel(); + databaseDisplayModel->setFilterList(filterModel->filterList()); filterView = new QTreeView; filterView->setModel(filterModel); filterView->setMaximumWidth(250);