Commit 39e2bf06 authored by Fabio Bas's avatar Fabio Bas
Browse files

Merge branch 'master' into cmake-overhaul

parents 20b9a538 50ac14e8
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
# GNU systems need to define the Mersenne exponent for the RNG to compile w/o warning
ADD_DEFINITIONS("-DSFMT_MEXP=19937")
ENDIF()
add_subdirectory(common) add_subdirectory(common)
if(WITH_SERVER) if(WITH_SERVER)
add_subdirectory(servatrice) add_subdirectory(servatrice)
......
...@@ -3,158 +3,174 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) ...@@ -3,158 +3,174 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
PROJECT(cockatrice) PROJECT(cockatrice)
SET(cockatrice_SOURCES SET(cockatrice_SOURCES
src/abstractcounter.cpp src/abstractcounter.cpp
src/counter_general.cpp src/counter_general.cpp
src/dlg_creategame.cpp src/dlg_creategame.cpp
src/dlg_filter_games.cpp src/dlg_filter_games.cpp
src/dlg_connect.cpp src/dlg_connect.cpp
src/dlg_create_token.cpp src/dlg_create_token.cpp
src/dlg_edit_tokens.cpp src/dlg_edit_tokens.cpp
src/abstractclient.cpp src/abstractclient.cpp
src/remoteclient.cpp src/remoteclient.cpp
src/main.cpp src/main.cpp
src/window_main.cpp src/window_main.cpp
src/gamesmodel.cpp src/gamesmodel.cpp
src/player.cpp src/player.cpp
src/playertarget.cpp src/playertarget.cpp
src/cardzone.cpp src/cardzone.cpp
src/selectzone.cpp src/selectzone.cpp
src/cardlist.cpp src/cardlist.cpp
src/abstractcarditem.cpp src/abstractcarditem.cpp
src/carditem.cpp src/carditem.cpp
src/tablezone.cpp src/tablezone.cpp
src/handzone.cpp src/handzone.cpp
src/handcounter.cpp src/handcounter.cpp
src/carddatabase.cpp src/carddatabase.cpp
src/gameview.cpp src/keysignals.cpp
src/gameselector.cpp src/gameview.cpp
src/decklistmodel.cpp src/gameselector.cpp
src/deck_loader.cpp src/decklistmodel.cpp
src/dlg_load_deck_from_clipboard.cpp src/deck_loader.cpp
src/dlg_load_remote_deck.cpp src/dlg_load_deck_from_clipboard.cpp
src/cardinfowidget.cpp src/dlg_load_remote_deck.cpp
src/messagelogwidget.cpp src/cardinfowidget.cpp
src/zoneviewzone.cpp src/cardframe.cpp
src/zoneviewwidget.cpp src/cardinfopicture.cpp
src/pilezone.cpp src/cardinfotext.cpp
src/stackzone.cpp src/filterbuilder.cpp
src/carddragitem.cpp src/cardfilter.cpp
src/carddatabasemodel.cpp src/filtertreemodel.cpp
src/setsmodel.cpp src/filtertree.cpp
src/window_sets.cpp src/messagelogwidget.cpp
src/abstractgraphicsitem.cpp src/zoneviewzone.cpp
src/abstractcarddragitem.cpp src/zoneviewwidget.cpp
src/dlg_settings.cpp src/pilezone.cpp
src/dlg_cardsearch.cpp src/stackzone.cpp
src/phasestoolbar.cpp src/carddragitem.cpp
src/gamescene.cpp src/carddatabasemodel.cpp
src/arrowitem.cpp src/setsmodel.cpp
src/arrowtarget.cpp src/window_sets.cpp
src/tab.cpp src/abstractgraphicsitem.cpp
src/tab_server.cpp src/abstractcarddragitem.cpp
src/tab_room.cpp src/dlg_settings.cpp
src/tab_message.cpp src/dlg_cardsearch.cpp
src/tab_game.cpp src/phasestoolbar.cpp
src/tab_deck_storage.cpp src/gamescene.cpp
src/tab_replays.cpp src/arrowitem.cpp
src/tab_supervisor.cpp src/arrowtarget.cpp
src/tab_admin.cpp src/tab.cpp
src/tab_userlists.cpp src/tab_server.cpp
src/tab_room.cpp
src/tab_message.cpp
src/tab_game.cpp
src/tab_deck_storage.cpp
src/tab_replays.cpp
src/tab_supervisor.cpp
src/tab_admin.cpp
src/tab_userlists.cpp
src/tab_deck_editor.cpp src/tab_deck_editor.cpp
src/replay_timeline_widget.cpp src/replay_timeline_widget.cpp
src/deckstats_interface.cpp src/deckstats_interface.cpp
src/chatview.cpp src/chatview.cpp
src/userlist.cpp src/userlist.cpp
src/userinfobox.cpp src/userinfobox.cpp
src/user_context_menu.cpp src/user_context_menu.cpp
src/remotedecklist_treewidget.cpp src/remotedecklist_treewidget.cpp
src/remotereplaylist_treewidget.cpp src/remotereplaylist_treewidget.cpp
src/deckview.cpp src/deckview.cpp
src/playerlistwidget.cpp src/playerlistwidget.cpp
src/pixmapgenerator.cpp src/pixmapgenerator.cpp
src/settingscache.cpp src/settingscache.cpp
src/localserver.cpp src/localserver.cpp
src/localserverinterface.cpp src/localserverinterface.cpp
src/localclient.cpp src/localclient.cpp
src/priceupdater.cpp src/priceupdater.cpp
src/qt-json/json.cpp src/qt-json/json.cpp
src/soundengine.cpp src/soundengine.cpp
${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp ${CMAKE_CURRENT_BINARY_DIR}/version_string.cpp
) )
SET(cockatrice_HEADERS SET(cockatrice_HEADERS
src/abstractcounter.h src/abstractcounter.h
src/counter_general.h src/counter_general.h
src/dlg_creategame.h src/dlg_creategame.h
src/dlg_filter_games.h src/dlg_filter_games.h
src/dlg_connect.h src/dlg_connect.h
src/dlg_create_token.h src/dlg_create_token.h
src/dlg_edit_tokens.h src/dlg_edit_tokens.h
src/gamesmodel.h src/gamesmodel.h
src/abstractclient.h src/abstractclient.h
src/remoteclient.h src/remoteclient.h
src/window_main.h src/window_main.h
src/cardzone.h src/cardzone.h
src/selectzone.h src/selectzone.h
src/player.h src/player.h
src/playertarget.h src/playertarget.h
src/abstractcarditem.h src/abstractcarditem.h
src/carditem.h src/carditem.h
src/tablezone.h src/tablezone.h
src/handzone.h src/handzone.h
src/handcounter.h src/handcounter.h
src/carddatabase.h src/carddatabase.h
src/gameview.h src/keysignals.h
src/gameselector.h src/gameview.h
src/decklistmodel.h src/gameselector.h
src/deck_loader.h src/decklistmodel.h
src/dlg_load_deck_from_clipboard.h src/deck_loader.h
src/dlg_load_remote_deck.h src/dlg_load_deck_from_clipboard.h
src/cardinfowidget.h src/dlg_load_remote_deck.h
src/messagelogwidget.h src/cardinfowidget.h
src/zoneviewzone.h src/cardframe.h
src/zoneviewwidget.h src/cardinfopicture.h
src/pilezone.h src/cardinfotext.h
src/stackzone.h src/filterbuilder.h
src/carddragitem.h src/cardfilter.h
src/carddatabasemodel.h src/filtertreemodel.h
src/setsmodel.h src/filtertree.h
src/window_sets.h src/messagelogwidget.h
src/abstractgraphicsitem.h src/zoneviewzone.h
src/abstractcarddragitem.h src/zoneviewwidget.h
src/dlg_settings.h src/pilezone.h
src/dlg_cardsearch.h src/stackzone.h
src/phasestoolbar.h src/carddragitem.h
src/gamescene.h src/carddatabasemodel.h
src/arrowitem.h src/setsmodel.h
src/arrowtarget.h src/window_sets.h
src/tab.h src/abstractgraphicsitem.h
src/tab_server.h src/abstractcarddragitem.h
src/tab_room.h src/dlg_settings.h
src/tab_message.h src/dlg_cardsearch.h
src/tab_game.h src/phasestoolbar.h
src/tab_deck_storage.h src/gamescene.h
src/tab_replays.h src/arrowitem.h
src/tab_supervisor.h src/arrowtarget.h
src/tab_admin.h src/tab.h
src/tab_userlists.h src/tab_server.h
src/tab_room.h
src/tab_message.h
src/tab_game.h
src/tab_deck_storage.h
src/tab_replays.h
src/tab_supervisor.h
src/tab_admin.h
src/tab_userlists.h
src/tab_deck_editor.h src/tab_deck_editor.h
src/replay_timeline_widget.h src/replay_timeline_widget.h
src/deckstats_interface.h src/deckstats_interface.h
src/chatview.h src/chatview.h
src/userlist.h src/userlist.h
src/userinfobox.h src/userinfobox.h
src/user_context_menu.h src/user_context_menu.h
src/remotedecklist_treewidget.h src/remotedecklist_treewidget.h
src/remotereplaylist_treewidget.h src/remotereplaylist_treewidget.h
src/deckview.h src/deckview.h
src/playerlistwidget.h src/playerlistwidget.h
src/settingscache.h src/settingscache.h
src/localserver.h src/localserver.h
src/localserverinterface.h src/localserverinterface.h
src/localclient.h src/localclient.h
src/priceupdater.h src/priceupdater.h
src/soundengine.h src/soundengine.h
src/pending_command.h src/pending_command.h
) )
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
......
#include "carddatabasemodel.h" #include "carddatabasemodel.h"
#include "filtertree.h"
CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, QObject *parent) CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, QObject *parent)
: QAbstractListModel(parent), db(_db) : QAbstractListModel(parent), db(_db)
...@@ -109,6 +110,7 @@ CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent) ...@@ -109,6 +110,7 @@ CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent)
: QSortFilterProxyModel(parent), : QSortFilterProxyModel(parent),
isToken(ShowAll) isToken(ShowAll)
{ {
filterTree = NULL;
setFilterCaseSensitivity(Qt::CaseInsensitive); setFilterCaseSensitivity(Qt::CaseInsensitive);
setSortCaseSensitivity(Qt::CaseInsensitive); setSortCaseSensitivity(Qt::CaseInsensitive);
} }
...@@ -116,7 +118,6 @@ CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent) ...@@ -116,7 +118,6 @@ CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent)
bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex & /*sourceParent*/) const bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex & /*sourceParent*/) const
{ {
CardInfo const *info = static_cast<CardDatabaseModel *>(sourceModel())->getCard(sourceRow); CardInfo const *info = static_cast<CardDatabaseModel *>(sourceModel())->getCard(sourceRow);
if (((isToken == ShowTrue) && !info->getIsToken()) || ((isToken == ShowFalse) && info->getIsToken())) if (((isToken == ShowTrue) && !info->getIsToken()) || ((isToken == ShowFalse) && info->getIsToken()))
return false; return false;
...@@ -144,6 +145,9 @@ bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex ...@@ -144,6 +145,9 @@ bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex
if (!cardTypes.contains(info->getMainCardType())) if (!cardTypes.contains(info->getMainCardType()))
return false; return false;
if (filterTree != NULL)
return filterTree->acceptsCard(info);
return true; return true;
} }
...@@ -153,5 +157,22 @@ void CardDatabaseDisplayModel::clearSearch() ...@@ -153,5 +157,22 @@ void CardDatabaseDisplayModel::clearSearch()
cardText.clear(); cardText.clear();
cardTypes.clear(); cardTypes.clear();
cardColors.clear(); cardColors.clear();
if (filterTree != NULL)
filterTree->clear();
invalidateFilter(); 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();
}
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <QSet> #include <QSet>
#include "carddatabase.h" #include "carddatabase.h"
class FilterTree;
class CardDatabaseModel : public QAbstractListModel { class CardDatabaseModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
public: public:
...@@ -36,8 +38,10 @@ private: ...@@ -36,8 +38,10 @@ private:
FilterBool isToken; FilterBool isToken;
QString cardNameBeginning, cardName, cardText; QString cardNameBeginning, cardName, cardText;
QSet<QString> cardNameSet, cardTypes, cardColors; QSet<QString> cardNameSet, cardTypes, cardColors;
FilterTree *filterTree;
public: public:
CardDatabaseDisplayModel(QObject *parent = 0); CardDatabaseDisplayModel(QObject *parent = 0);
void setFilterTree(FilterTree *filterTree);
void setIsToken(FilterBool _isToken) { isToken = _isToken; invalidate(); } void setIsToken(FilterBool _isToken) { isToken = _isToken; invalidate(); }
void setCardNameBeginning(const QString &_beginning) { cardNameBeginning = _beginning; invalidate(); } void setCardNameBeginning(const QString &_beginning) { cardNameBeginning = _beginning; invalidate(); }
void setCardName(const QString &_cardName) { cardName = _cardName; invalidate(); } void setCardName(const QString &_cardName) { cardName = _cardName; invalidate(); }
...@@ -48,6 +52,8 @@ public: ...@@ -48,6 +52,8 @@ public:
void clearSearch(); void clearSearch();
protected: protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
private slots:
void filterTreeChanged();
}; };
#endif #endif
#include "cardfilter.h"
const char *CardFilter::typeName(Type t)
{
switch (t) {
case TypeAnd:
return "and";
case TypeOr:
return "or";
case TypeAndNot:
return "and not";
case TypeOrNot:
return "or not";
default:
return "";
}
}
const char *CardFilter::attrName(Attr a)
{
switch (a) {
case AttrName:
return "name";
case AttrType:
return "type";
case AttrColor:
return "color";
case AttrText:
return "text";
case AttrSet:
return "set";
case AttrManaCost:
return "mana cost";
default:
return "";
}
}
#ifndef CARDFILTER_H
#define CARDFILTER_H
#include <QString>
class CardFilter {
public:
enum Type {
TypeAnd = 0,
TypeOr,
TypeAndNot,
TypeOrNot,
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
};
private:
enum Type t;
enum Attr a;
QString trm;
public:
CardFilter(QString term, Type type, Attr attr) : trm(term), t(type), a(attr) {};
Type type() const { return t; }
const QString &term() const { return trm; }
Attr attr() const { return a; }
static const char *typeName(Type t);
static const char *attrName(Attr a);
};
#endif
#include "cardframe.h"
#include "carditem.h"
#include "carddatabase.h"
#include "main.h"
#include "cardinfopicture.h"
#include "cardinfotext.h"
CardFrame::CardFrame(int width, int height,
const QString &cardName, QWidget *parent)
: QStackedWidget(parent)
, info(0)
, cardTextOnly(false)
{
setFrameStyle(QFrame::Panel | QFrame::Raised);
setMaximumWidth(width);
setMinimumWidth(width);
setMaximumHeight(height);
setMinimumHeight(height);
pic = new CardInfoPicture(width);
addWidget(pic);
text = new CardInfoText();
addWidget(text);
connect(pic, SIGNAL(hasPictureChanged()), this, SLOT(hasPictureChanged()));
setCard(db->getCard(cardName));
}
void CardFrame::setCard(CardInfo *card)
{
if (info)
disconnect(info, 0, this, 0);
info = card;
connect(info, SIGNAL(destroyed()), this, SLOT(clear()));
text->setCard(info);
pic->setCard(info);
}
void CardFrame::setCard(const QString &cardName)
{
setCard(db->getCard(cardName));
}
void CardFrame::setCard(AbstractCardItem *card)
{
setCard(card->getInfo());
}
void CardFrame::clear()
{
setCard(db->getCard());
}
void CardFrame::hasPictureChanged()
{
if (pic->hasPicture() && !cardTextOnly)
setCurrentWidget(pic);
else
setCurrentWidget(text);
}
#ifndef CARDFRAME_H
#define CARDFRAME_H
#include <QStackedWidget>
class AbstractCardItem;
class CardInfo;
class CardInfoPicture;
class CardInfoText;
class CardFrame : public QStackedWidget {
Q_OBJECT
private:
CardInfo *info;
CardInfoPicture *pic;
CardInfoText *text;
bool cardTextOnly;
public:
CardFrame(int width, int height, const QString &cardName = QString(),
QWidget *parent = 0);
void setCardTextOnly(bool status) { cardTextOnly = status; hasPictureChanged(); }
public slots:
void setCard(CardInfo *card);
void setCard(const QString &cardName);
void setCard(AbstractCardItem *card);
void clear();
private slots:
void hasPictureChanged();
void toggleCardTextOnly() { setCardTextOnly(!cardTextOnly); }
};
#endif
#include "cardinfopicture.h"
#include <QLabel>
#include "carditem.h"
#include "carddatabase.h"
#include "main.h"
CardInfoPicture::CardInfoPicture(int maximumWidth, QWidget *parent)
: QLabel(parent)
, info(0)
, noPicture(true)
{
setMaximumWidth(maximumWidth);
}
void CardInfoPicture::setNoPicture(bool status)
{
if (noPicture != status) {
noPicture = status;
emit hasPictureChanged();
}
}
void CardInfoPicture::setCard(CardInfo *card)
{
if (info)
disconnect(info, 0, this, 0);
info = card;
connect(info, SIGNAL(pixmapUpdated()), this, SLOT(updatePixmap()));
updatePixmap();
}
void CardInfoPicture::updatePixmap()
{
qreal aspectRatio = (qreal) CARD_HEIGHT / (qreal) CARD_WIDTH;
qreal pixmapWidth = this->width();
if (pixmapWidth == 0) {
setNoPicture(true);
return;
}
QPixmap *resizedPixmap = info->getPixmap(QSize(pixmapWidth, pixmapWidth * aspectRatio));
if (resizedPixmap) {
setNoPicture(false);
this->setPixmap(*resizedPixmap);
}
else {
setNoPicture(true);
this->setPixmap(*(db->getCard()->getPixmap(QSize(pixmapWidth, pixmapWidth * aspectRatio))));
}
}
#ifndef CARDINFOPICTURE_H
#define CARDINFOPICTURE_H
#include <QLabel>
class AbstractCardItem;
class CardInfo;
class CardInfoPicture : public QLabel {
Q_OBJECT
signals:
void hasPictureChanged();
private:
CardInfo *info;
bool noPicture;
public:
CardInfoPicture(int maximumWidth, QWidget *parent = 0);
bool hasPicture() const { return !noPicture; }
private:
void setNoPicture(bool status);
public slots:
void setCard(CardInfo *card);
private slots:
void updatePixmap();
};
#endif
#include "cardinfotext.h"
#include <QLabel>
#include <QTextEdit>
#include <QGridLayout>
#include "carditem.h"
#include "carddatabase.h"
#include "main.h"
CardInfoText::CardInfoText(QWidget *parent)
: QFrame(parent)
, info(0)
{
nameLabel1 = new QLabel;
nameLabel2 = new QLabel;
nameLabel2->setWordWrap(true);
manacostLabel1 = new QLabel;
manacostLabel2 = new QLabel;
manacostLabel2->setWordWrap(true);
cardtypeLabel1 = new QLabel;
cardtypeLabel2 = new QLabel;
cardtypeLabel2->setWordWrap(true);
powtoughLabel1 = new QLabel;
powtoughLabel2 = new QLabel;
loyaltyLabel1 = new QLabel;
loyaltyLabel2 = new QLabel;
textLabel = new QTextEdit();
textLabel->setReadOnly(true);
QGridLayout *grid = new QGridLayout(this);
int row = 0;
grid->addWidget(nameLabel1, row, 0);
grid->addWidget(nameLabel2, row++, 1);
grid->addWidget(manacostLabel1, row, 0);
grid->addWidget(manacostLabel2, row++, 1);
grid->addWidget(cardtypeLabel1, row, 0);
grid->addWidget(cardtypeLabel2, row++, 1);
grid->addWidget(powtoughLabel1, row, 0);
grid->addWidget(powtoughLabel2, row++, 1);
grid->addWidget(loyaltyLabel1, row, 0);
grid->addWidget(loyaltyLabel2, row++, 1);
grid->addWidget(textLabel, row, 0, -1, 2);
grid->setRowStretch(row, 1);
grid->setColumnStretch(1, 1);
retranslateUi();
}
void CardInfoText::setCard(CardInfo *card)
{
nameLabel2->setText(card->getName());
manacostLabel2->setText(card->getManaCost());
cardtypeLabel2->setText(card->getCardType());
powtoughLabel2->setText(card->getPowTough());
loyaltyLabel2->setText(card->getLoyalty() > 0 ? QString::number(card->getLoyalty()) : QString());
textLabel->setText(card->getText());
}
void CardInfoText::retranslateUi()
{
nameLabel1->setText(tr("Name:"));
manacostLabel1->setText(tr("Mana cost:"));
cardtypeLabel1->setText(tr("Card type:"));
powtoughLabel1->setText(tr("P / T:"));
loyaltyLabel1->setText(tr("Loyalty:"));
}
#ifndef CARDINFOTEXT_H
#define CARDINFOTEXT_H
#include <QFrame>
class QLabel;
class QTextEdit;
class CardInfo;
class CardInfoText : public QFrame {
Q_OBJECT
private:
QLabel *nameLabel1, *nameLabel2;
QLabel *manacostLabel1, *manacostLabel2;
QLabel *cardtypeLabel1, *cardtypeLabel2;
QLabel *powtoughLabel1, *powtoughLabel2;
QLabel *loyaltyLabel1, *loyaltyLabel2;
QTextEdit *textLabel;
CardInfo *info;
public:
CardInfoText(QWidget *parent = 0);
void retranslateUi();
public slots:
void setCard(CardInfo *card);
};
#endif
...@@ -169,8 +169,7 @@ Qt::ItemFlags DeckListModel::flags(const QModelIndex &index) const ...@@ -169,8 +169,7 @@ Qt::ItemFlags DeckListModel::flags(const QModelIndex &index) const
return 0; return 0;
Qt::ItemFlags result = Qt::ItemIsEnabled; Qt::ItemFlags result = Qt::ItemIsEnabled;
if (getNode<DecklistModelCardNode *>(index)) result |= Qt::ItemIsSelectable;
result |= Qt::ItemIsSelectable;
return result; return result;
} }
...@@ -236,6 +235,38 @@ InnerDecklistNode *DeckListModel::createNodeIfNeeded(const QString &name, InnerD ...@@ -236,6 +235,38 @@ InnerDecklistNode *DeckListModel::createNodeIfNeeded(const QString &name, InnerD
return newNode; return newNode;
} }
DecklistModelCardNode *DeckListModel::findCardNode(const QString &cardName, const QString &zoneName) const
{
InnerDecklistNode *zoneNode, *typeNode;
CardInfo *info;
QString cardType;
zoneNode = dynamic_cast<InnerDecklistNode *>(root->findChild(zoneName));
if(!zoneNode)
return NULL;
info = db->getCard(cardName);
if(!info)
return NULL;
cardType = info->getMainCardType();
typeNode = dynamic_cast<InnerDecklistNode *>(zoneNode->findChild(cardType));
if(!typeNode)
return NULL;
return dynamic_cast<DecklistModelCardNode *>(typeNode->findChild(cardName));
}
QModelIndex DeckListModel::findCard(const QString &cardName, const QString &zoneName) const
{
DecklistModelCardNode *cardNode;
cardNode = findCardNode(cardName, zoneName);
if(!cardNode)
return QModelIndex();
return nodeToIndex(cardNode);
}
QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneName) QModelIndex DeckListModel::addCard(const QString &cardName, const QString &zoneName)
{ {
InnerDecklistNode *zoneNode = createNodeIfNeeded(zoneName, root); InnerDecklistNode *zoneNode = createNodeIfNeeded(zoneName, root);
......
...@@ -45,6 +45,7 @@ public: ...@@ -45,6 +45,7 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const; Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role); bool setData(const QModelIndex &index, const QVariant &value, int role);
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
QModelIndex findCard(const QString &cardName, const QString &zoneName) const;
QModelIndex addCard(const QString &cardName, const QString &zoneName); QModelIndex addCard(const QString &cardName, const QString &zoneName);
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
void cleanList(); void cleanList();
...@@ -56,6 +57,7 @@ private: ...@@ -56,6 +57,7 @@ private:
InnerDecklistNode *root; InnerDecklistNode *root;
InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent); InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent);
QModelIndex nodeToIndex(AbstractDecklistNode *node) const; QModelIndex nodeToIndex(AbstractDecklistNode *node) const;
DecklistModelCardNode *findCardNode(const QString &cardName, const QString &zoneName) const;
void emitRecursiveUpdates(const QModelIndex &index); void emitRecursiveUpdates(const QModelIndex &index);
void sortHelper(InnerDecklistNode *node, Qt::SortOrder order); void sortHelper(InnerDecklistNode *node, Qt::SortOrder order);
......
#include "filterbuilder.h"
#include <QHBoxLayout>
#include <QComboBox>
#include <QPushButton>
#include <QLineEdit>
#include "cardfilter.h"
FilterBuilder::FilterBuilder(QWidget *parent)
: QFrame(parent)
{
int i;
QVBoxLayout *layout = new QVBoxLayout;
QHBoxLayout *addFilter = new QHBoxLayout;
filterCombo = new QComboBox;
for (i = 0; i < CardFilter::AttrEnd; i++)
filterCombo->addItem(
tr(CardFilter::attrName(static_cast<CardFilter::Attr>(i))),
QVariant(i)
);
typeCombo = new QComboBox;
for (i = 0; i < CardFilter::TypeEnd; i++)
typeCombo->addItem(
tr(CardFilter::typeName(static_cast<CardFilter::Type>(i))),
QVariant(i)
);
QPushButton *ok = new QPushButton("+");
ok->setMaximumSize(20, 20);
addFilter->addWidget(ok);
addFilter->addWidget(typeCombo);
addFilter->addWidget(filterCombo, Qt::AlignLeft);
edit = new QLineEdit;
edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
layout->addLayout(addFilter);
layout->addWidget(edit);
setFrameStyle(QFrame::Panel | QFrame::Raised);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
connect(edit, SIGNAL(returnPressed()), this, SLOT(emit_add()));
connect(ok, SIGNAL(released()), this, SLOT(emit_add()));
connect(filterCombo, SIGNAL(currentIndexChanged(int)), edit, SLOT(clear()));
fltr = NULL;
}
FilterBuilder::~FilterBuilder()
{
destroyFilter();
}
void FilterBuilder::destroyFilter()
{
if (fltr)
delete fltr;
}
static int comboCurrentIntData(const QComboBox *combo)
{
return combo->itemData(combo->currentIndex()).toInt();
}
void FilterBuilder::emit_add()
{
QString txt;
txt = edit->text();
if (txt.length() < 1)
return;
destroyFilter();
fltr = new CardFilter(txt,
static_cast<CardFilter::Type>(comboCurrentIntData(typeCombo)),
static_cast<CardFilter::Attr>(comboCurrentIntData(filterCombo)));
emit add(fltr);
edit->clear();
}
#ifndef FILTERBUILDER_H
#define FILTERBUILDER_H
#include <QFrame>
class QCheckBox;
class QComboBox;
class QLineEdit;
class CardFilter;
class FilterBuilder : public QFrame {
Q_OBJECT
private:
QComboBox *typeCombo;
QComboBox *filterCombo;
QLineEdit *edit;
CardFilter *fltr;
void destroyFilter();
public:
FilterBuilder(QWidget *parent = 0);
~FilterBuilder();
signals:
void add(const CardFilter *f);
public slots:
private slots:
void emit_add();
protected:
};
#endif
#include "filtertree.h"
#include "cardfilter.h"
#include "carddatabase.h"
#include <QList>
template <class T>
FilterTreeNode *FilterTreeBranch<T>::nodeAt(int i) const
{
return ((childNodes.size() > i)? childNodes.at(i) : NULL);
}
template <class T>
void FilterTreeBranch<T>::deleteAt(int i)
{
preRemoveChild(this, i);
delete childNodes.takeAt(i);
postRemoveChild(this, i);
nodeChanged();
}
template <class T>
int FilterTreeBranch<T>::childIndex(const FilterTreeNode *node) const
{
FilterTreeNode *unconst;
T downcasted;
/* to do the dynamic cast to T we will lose const'ness, but we can
* trust QList::indexOf */
unconst = (FilterTreeNode *) node;
downcasted = dynamic_cast<T>(unconst);
if (downcasted == NULL)
return -1;
return childNodes.indexOf(downcasted);
}
template <class T>
FilterTreeBranch<T>::~FilterTreeBranch()
{
while (!childNodes.isEmpty())
delete childNodes.takeFirst();
}
const FilterItemList *LogicMap::findTypeList(CardFilter::Type type) const
{
QList<FilterItemList *>::const_iterator i;
for (i = childNodes.constBegin(); i != childNodes.constEnd(); i++)
if ((*i)->type == type)
return *i;
return NULL;
}
FilterItemList *LogicMap::typeList(CardFilter::Type type)
{
QList<FilterItemList *>::iterator i;
int count;
count = 0;
for (i = childNodes.begin(); i != childNodes.end(); i++) {
if ((*i)->type == type)
break;
count++;
}
if (i == childNodes.end()) {
preInsertChild(this, count);
i = childNodes.insert(i, new FilterItemList(type, this));
postInsertChild(this, count);
nodeChanged();
}
return *i;
}
FilterTreeNode *LogicMap::parent() const
{
return p;
}
int FilterItemList::termIndex(const QString &term) const
{
int i;
for (i = 0; i < childNodes.count(); i++)
if ((childNodes.at(i))->term == term)
return i;
return -1;
}
FilterTreeNode *FilterItemList::termNode(const QString &term)
{
int i, count;
FilterItem *fi;
i = termIndex(term);
if (i < 0) {
fi = new FilterItem(term, this);
count = childNodes.count();
preInsertChild(this, count);
childNodes.append(fi);
postInsertChild(this, count);
nodeChanged();
return fi;
}
return childNodes.at(i);
}
bool FilterItemList::testTypeAnd(const CardInfo *info, CardFilter::Attr attr) const
{
QList<FilterItem *>::const_iterator i;
for (i = childNodes.constBegin(); i != childNodes.constEnd(); i++) {
if (!(*i)->isEnabled())
continue;
if (!(*i)->acceptCardAttr(info, attr))
return false;
}
return true;
}
bool FilterItemList::testTypeAndNot(const CardInfo *info, CardFilter::Attr attr) const
{
// if any one in the list is true, return false
return !testTypeOr(info, attr);
}
bool FilterItemList::testTypeOr(const CardInfo *info, CardFilter::Attr attr) const
{
QList<FilterItem *>::const_iterator i;
for (i = childNodes.constBegin(); i != childNodes.constEnd(); i++) {
if (!(*i)->isEnabled())
continue;
if ((*i)->acceptCardAttr(info, attr))
return true;
}
return false;
}
bool FilterItemList::testTypeOrNot(const CardInfo *info, CardFilter::Attr attr) const
{
// if any one in the list is false, return true
return !testTypeAnd(info, attr);
}
bool FilterItem::acceptName(const CardInfo *info) const
{
return info->getName().contains(term, Qt::CaseInsensitive);
}
bool FilterItem::acceptType(const CardInfo *info) const
{
return info->getCardType().contains(term, Qt::CaseInsensitive);
}
bool FilterItem::acceptColor(const CardInfo *info) 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 FilterItem::acceptText(const CardInfo *info) const
{
return info->getText().contains(term, Qt::CaseInsensitive);
}
bool FilterItem::acceptSet(const CardInfo *info) 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 FilterItem::acceptManaCost(const CardInfo *info) const
{
return (info->getManaCost() == term);
}
bool FilterItem::acceptCardAttr(const CardInfo *info, CardFilter::Attr attr) const
{
bool status;
switch (attr) {
case CardFilter::AttrName:
status = acceptName(info);
break;
case CardFilter::AttrType:
status = acceptType(info);
break;
case CardFilter::AttrColor:
status = acceptColor(info);
break;
case CardFilter::AttrText:
status = acceptText(info);
break;
case CardFilter::AttrSet:
status = acceptSet(info);
break;
case CardFilter::AttrManaCost:
status = acceptManaCost(info);
break;
default:
status = true; /* ignore this attribute */
}
return status;
}
/* need to define these here to make QT happy, otherwise
* moc doesnt find some of the FilterTreeBranch symbols.
*/
FilterTree::FilterTree() {}
FilterTree::~FilterTree() {}
LogicMap *FilterTree::attrLogicMap(CardFilter::Attr attr)
{
QList<LogicMap *>::iterator i;
int count;
count = 0;
for (i = childNodes.begin(); i != childNodes.end(); i++) {
if ((*i)->attr == attr)
break;
count++;
}
if (i == childNodes.end()) {
preInsertChild(this, count);
i = childNodes.insert(i, new LogicMap(attr, this));
postInsertChild(this, count);
nodeChanged();
}
return *i;
}
FilterItemList *FilterTree::attrTypeList(CardFilter::Attr attr,
CardFilter::Type type)
{
return attrLogicMap(attr)->typeList(type);
}
int FilterTree::findTermIndex(CardFilter::Attr attr, CardFilter::Type type,
const QString &term)
{
attrTypeList(attr, type)->termIndex(term);
}
int FilterTree::findTermIndex(const CardFilter *f)
{
return findTermIndex(f->attr(), f->type(), f->term());
}
FilterTreeNode *FilterTree::termNode(CardFilter::Attr attr, CardFilter::Type type,
const QString &term)
{
return attrTypeList(attr, type)->termNode(term);
}
FilterTreeNode *FilterTree::termNode(const CardFilter *f)
{
return termNode(f->attr(), f->type(), f->term());
}
FilterTreeNode *FilterTree::attrTypeNode(CardFilter::Attr attr,
CardFilter::Type type)
{
return attrTypeList(attr, type);
}
bool FilterTree::testAttr(const CardInfo *info, const LogicMap *lm) const
{
const FilterItemList *fil;
bool status;
status = true;
fil = lm->findTypeList(CardFilter::TypeAnd);
if (fil != NULL && fil->isEnabled() && !fil->testTypeAnd(info, lm->attr))
return false;
fil = lm->findTypeList(CardFilter::TypeAndNot);
if (fil != NULL && fil->isEnabled() && !fil->testTypeAndNot(info, lm->attr))
return false;
fil = lm->findTypeList(CardFilter::TypeOr);
if (fil != NULL && fil->isEnabled()) {
status = false;
// if this is true we can return because it is OR'd with the OrNot list
if (fil->testTypeOr(info, lm->attr))
return true;
}
fil = lm->findTypeList(CardFilter::TypeOrNot);
if (fil != NULL && fil->isEnabled() && fil->testTypeOrNot(info, lm->attr))
return true;
return status;
}
bool FilterTree::acceptsCard(const CardInfo *info) const
{
QList<LogicMap *>::const_iterator i;
for (i = childNodes.constBegin(); i != childNodes.constEnd(); i++)
if ((*i)->isEnabled() && !testAttr(info, *i))
return false;
return true;
}
void FilterTree::clear()
{
while(childCount() > 0)
deleteAt(0);
}
#ifndef FILTERTREE_H
#define FILTERTREE_H
#include <QList>
#include <QMap>
#include <QObject>
#include "cardfilter.h"
class CardInfo;
class FilterTreeNode {
private:
bool enabled;
public:
FilterTreeNode() : enabled(true) {}
virtual bool isEnabled() const { return enabled; }
virtual void enable() { enabled = true; nodeChanged(); }
virtual void disable() { enabled = false; nodeChanged(); }
virtual FilterTreeNode *parent() const { return NULL; }
virtual FilterTreeNode *nodeAt(int i) const { return NULL; }
virtual void deleteAt(int i) {}
virtual int childCount() const { return 0; }
virtual int childIndex(const FilterTreeNode *node) const { return -1; }
virtual int index() const { return (parent() != NULL)? parent()->childIndex(this) : -1; }
virtual QString text() const { return QString(textCStr()); }
virtual bool isLeaf() const { return false; }
virtual const char *textCStr() const { return ""; }
virtual void nodeChanged() const {
if (parent() != NULL) parent()->nodeChanged();
}
virtual void preInsertChild(const FilterTreeNode *p, int i) const {
if (parent() != NULL) parent()->preInsertChild(p, i);
}
virtual void postInsertChild(const FilterTreeNode *p, int i) const {
if (parent() != NULL) parent()->postInsertChild(p, i);
}
virtual void preRemoveChild(const FilterTreeNode *p, int i) const {
if (parent() != NULL) parent()->preRemoveChild(p, i);
}
virtual void postRemoveChild(const FilterTreeNode *p, int i) const {
if (parent() != NULL) parent()->postRemoveChild(p, i);
}
};
template <class T>
class FilterTreeBranch : public FilterTreeNode {
protected:
QList<T> childNodes;
public:
~FilterTreeBranch();
FilterTreeNode *nodeAt(int i) const;
void deleteAt(int i);
int childCount() const { return childNodes.size(); }
int childIndex(const FilterTreeNode *node) const;
};
class FilterItemList;
class FilterTree;
class LogicMap : public FilterTreeBranch<FilterItemList *> {
private:
FilterTree *const p;
public:
const CardFilter::Attr attr;
LogicMap(CardFilter::Attr a, FilterTree *parent)
: attr(a), p(parent) {}
const FilterItemList *findTypeList(CardFilter::Type type) const;
FilterItemList *typeList(CardFilter::Type type);
FilterTreeNode *parent() const;
const char* textCStr() const { return CardFilter::attrName(attr); }
};
class FilterItem;
class FilterItemList : public FilterTreeBranch<FilterItem *> {
private:
LogicMap *const p;
public:
const CardFilter::Type type;
FilterItemList(CardFilter::Type t, LogicMap *parent)
: type(t), p(parent) {}
CardFilter::Attr attr() const { return p->attr; }
FilterTreeNode *parent() const { return p; }
int termIndex(const QString &term) const;
FilterTreeNode *termNode(const QString &term);
const char *textCStr() const { return CardFilter::typeName(type); }
bool testTypeAnd(const CardInfo *info, CardFilter::Attr attr) const;
bool testTypeAndNot(const CardInfo *info, CardFilter::Attr attr) const;
bool testTypeOr(const CardInfo *info, CardFilter::Attr attr) const;
bool testTypeOrNot(const CardInfo *info, CardFilter::Attr attr) const;
};
class FilterItem : public FilterTreeNode {
private:
FilterItemList *const p;
public:
const QString term;
FilterItem(QString trm, FilterItemList *parent)
: p(parent), term(trm) {}
CardFilter::Attr attr() const { return p->attr(); }
CardFilter::Type type() const { return p->type; }
FilterTreeNode *parent() const { return p; }
QString text() const { return term; }
const char *textCStr() const { return term.toStdString().c_str(); }
bool isLeaf() const { return true; }
bool acceptName(const CardInfo *info) const;
bool acceptType(const CardInfo *info) const;
bool acceptColor(const CardInfo *info) const;
bool acceptText(const CardInfo *info) const;
bool acceptSet(const CardInfo *info) const;
bool acceptManaCost(const CardInfo *info) const;
bool acceptCardAttr(const CardInfo *info, CardFilter::Attr attr) const;
};
class FilterTree : public QObject, public FilterTreeBranch<LogicMap *> {
Q_OBJECT
signals:
void preInsertRow(const FilterTreeNode *parent, int i) const;
void postInsertRow(const FilterTreeNode *parent, int i) const;
void preRemoveRow(const FilterTreeNode *parent, int i) const;
void postRemoveRow(const FilterTreeNode *parent, int i) const;
void changed() const;
private:
LogicMap *attrLogicMap(CardFilter::Attr attr);
FilterItemList *attrTypeList(CardFilter::Attr attr,
CardFilter::Type type);
bool testAttr(const CardInfo *info, const LogicMap *lm) const;
void nodeChanged() const { emit changed(); }
void preInsertChild(const FilterTreeNode *p, int i) const { emit preInsertRow(p, i); }
void postInsertChild(const FilterTreeNode *p, int i) const { emit postInsertRow(p, i); }
void preRemoveChild(const FilterTreeNode *p, int i) const { emit preRemoveRow(p, i); }
void postRemoveChild(const FilterTreeNode *p, int i) const { emit postRemoveRow(p, i); }
public:
FilterTree();
~FilterTree();
int findTermIndex(CardFilter::Attr attr, CardFilter::Type type,
const QString &term);
int findTermIndex(const CardFilter *f);
FilterTreeNode *termNode(CardFilter::Attr attr, CardFilter::Type type,
const QString &term);
FilterTreeNode *termNode(const CardFilter *f);
FilterTreeNode *attrTypeNode(CardFilter::Attr attr,
CardFilter::Type type);
const char *textCStr() { return "root"; }
int index() const { return 0; }
bool acceptsCard(const CardInfo *info) const;
void clear();
};
#endif
#include <QFont>
#include "filtertreemodel.h"
#include "filtertree.h"
#include "cardfilter.h"
FilterTreeModel::FilterTreeModel(QObject *parent)
: QAbstractItemModel(parent)
{
fTree = new FilterTree;
connect(fTree,
SIGNAL(preInsertRow(const FilterTreeNode *, int)),
this, SLOT(proxyBeginInsertRow(const FilterTreeNode *, int)));
connect(fTree,
SIGNAL(postInsertRow(const FilterTreeNode *, int)),
this, SLOT(proxyEndInsertRow(const FilterTreeNode *, int)));
connect(fTree,
SIGNAL(preRemoveRow(const FilterTreeNode *, int)),
this, SLOT(proxyBeginRemoveRow(const FilterTreeNode *, int)));
connect(fTree,
SIGNAL(postRemoveRow(const FilterTreeNode *, int)),
this, SLOT(proxyEndRemoveRow(const FilterTreeNode *, int)));
}
FilterTreeModel::~FilterTreeModel()
{
delete fTree;
}
void FilterTreeModel::proxyBeginInsertRow(const FilterTreeNode *node, int i)
{
int idx;
idx = node->index();
if (idx >= 0)
beginInsertRows(createIndex(idx, 0, (void *) node), i, i);
}
void FilterTreeModel::proxyEndInsertRow(const FilterTreeNode *node, int)
{
int idx;
idx = node->index();
if (idx >= 0)
endInsertRows();
}
void FilterTreeModel::proxyBeginRemoveRow(const FilterTreeNode *node, int i)
{
int idx;
idx = node->index();
if (idx >= 0)
beginRemoveRows(createIndex(idx, 0, (void *) node), i, i);
}
void FilterTreeModel::proxyEndRemoveRow(const FilterTreeNode *node, int)
{
int idx;
idx = node->index();
if (idx >= 0)
endRemoveRows();
}
FilterTreeNode *FilterTreeModel::indexToNode(const QModelIndex &idx) const
{
void *ip;
FilterTreeNode *node;
if (!idx.isValid())
return fTree;
ip = idx.internalPointer();
if (ip == NULL)
return fTree;
node = static_cast<FilterTreeNode *>(ip);
return node;
}
void FilterTreeModel::addFilter(const CardFilter *f)
{
emit layoutAboutToBeChanged();
fTree->termNode(f);
emit layoutChanged();
}
int FilterTreeModel::rowCount(const QModelIndex &parent) const
{
const FilterTreeNode *node;
int result;
if (parent.column() > 0)
return 0;
node = indexToNode(parent);
if (node)
result = node->childCount();
else
result = 0;
return result;
}
int FilterTreeModel::columnCount(const QModelIndex &/*parent*/) const
{
return 1;
}
QVariant FilterTreeModel::data(const QModelIndex &index, int role) const
{
const FilterTreeNode *node;
if (!index.isValid())
return QVariant();
if (index.column() >= columnCount())
return QVariant();
node = indexToNode(index);
if (node == NULL)
return QVariant();
switch (role) {
case Qt::FontRole:
if (!node->isLeaf()) {
QFont f;
f.setBold(true);
return f;
}
break;
case Qt::DisplayRole:
case Qt::EditRole:
case Qt::ToolTipRole:
case Qt::StatusTipRole:
case Qt::WhatsThisRole:
if(!node->isLeaf())
return tr(node->textCStr());
else
return node->text();
case Qt::CheckStateRole:
if (node->isEnabled())
return Qt::Checked;
else
return Qt::Unchecked;
default:
return QVariant();
}
return QVariant();
}
bool FilterTreeModel::setData(const QModelIndex &index,
const QVariant &value, int role)
{
FilterTreeNode *node;
if (!index.isValid())
return false;
if (index.column() >= columnCount())
return false;
if (role != Qt::CheckStateRole )
return false;
node = indexToNode(index);
if (node == NULL || node == fTree)
return false;
Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
if (state == Qt::Checked)
node->enable();
else
node->disable();
emit dataChanged(index, index);
return true;
}
Qt::ItemFlags FilterTreeModel::flags(const QModelIndex &index) const
{
const FilterTreeNode *node;
Qt::ItemFlags result;
if (!index.isValid())
return 0;
node = indexToNode(index);
if (node == NULL)
return 0;
result = Qt::ItemIsEnabled;
if (node == fTree)
return result;
result |= Qt::ItemIsSelectable;
result |= Qt::ItemIsUserCheckable;
return result;
}
QModelIndex FilterTreeModel::nodeIndex(const FilterTreeNode *node, int row, int column) const
{
FilterTreeNode *child;
if (column > 0 || row >= node->childCount())
return QModelIndex();
child = node->nodeAt(row);
return createIndex(row, column, child);
}
QModelIndex FilterTreeModel::index(int row, int column,
const QModelIndex &parent) const
{
const FilterTreeNode *node;
if (!hasIndex(row, column, parent))
return QModelIndex();
node = indexToNode(parent);
if (node == NULL)
return QModelIndex();
return nodeIndex(node, row, column);
}
QModelIndex FilterTreeModel::parent(const QModelIndex &ind) const
{
const FilterTreeNode *node;
FilterTreeNode *parent;
int row;
QModelIndex idx;
if (!ind.isValid())
return QModelIndex();
node = indexToNode(ind);
if (node == NULL || node == fTree)
return QModelIndex();
parent = node->parent();
if (parent) {
row = parent->index();
if (row < 0)
return QModelIndex();
idx = createIndex(row, 0, parent);
return idx;
}
return QModelIndex();
}
bool FilterTreeModel::removeRows(int row, int count, const QModelIndex & parent)
{
FilterTreeNode *node;
int i, last;
last = row+count-1;
if (!parent.isValid() || count < 1 || row < 0)
return false;
node = indexToNode(parent);
if (node == NULL || last >= node->childCount())
return false;
for (i = 0; i < count; i++)
node->deleteAt(row);
if (node != fTree && node->childCount() < 1)
return removeRow(parent.row(), parent.parent());
return true;
}
#ifndef FILTERTREEMODEL_H
#define FILTERTREEMODEL_H
#include <QAbstractItemModel>
class FilterTree;
class CardFilter;
class FilterTreeNode;
class FilterTreeModel : public QAbstractItemModel {
Q_OBJECT
private:
FilterTree *fTree;
public slots:
void addFilter(const CardFilter *f);
private slots:
void proxyBeginInsertRow(const FilterTreeNode *, int);
void proxyEndInsertRow(const FilterTreeNode *, int);
void proxyBeginRemoveRow(const FilterTreeNode *, int);
void proxyEndRemoveRow(const FilterTreeNode *, int);
private:
FilterTreeNode *indexToNode(const QModelIndex &idx) const;
QModelIndex nodeIndex(const FilterTreeNode *node, int row, int column) const;
public:
FilterTreeModel(QObject *parent = 0);
~FilterTreeModel();
FilterTree *filterTree() const { return fTree; }
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole);
Qt::ItemFlags flags(const QModelIndex &index) const;
QModelIndex parent(const QModelIndex &ind) const;
QModelIndex index(int row, int column,
const QModelIndex &parent) const;
bool removeRows(int row, int count, const QModelIndex & parent);
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment