mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-30 18:43:55 -07:00
[Move refactor] Reparent orphan classes (#6236)
* Move orphaned classes to their correct parent folders. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
1ef07309d6
commit
d9c65d4ae0
143 changed files with 171 additions and 169 deletions
|
|
@ -6,10 +6,9 @@
|
|||
|
||||
#ifndef INTERFACE_JSON_DECK_PARSER_H
|
||||
#define INTERFACE_JSON_DECK_PARSER_H
|
||||
#include "../../../deck/deck_loader.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
|
||||
class IJsonDeckParser
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,303 +0,0 @@
|
|||
#include "sets_model.h"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
SetsModel::SetsModel(CardDatabase *_db, QObject *parent) : QAbstractTableModel(parent), sets(_db->getSetList())
|
||||
{
|
||||
sets.sortByKey();
|
||||
for (const CardSetPtr &set : sets) {
|
||||
if (set->getEnabled())
|
||||
enabledSets.insert(set);
|
||||
}
|
||||
}
|
||||
|
||||
SetsModel::~SetsModel() = default;
|
||||
|
||||
int SetsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
else
|
||||
return sets.size();
|
||||
}
|
||||
|
||||
QVariant SetsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || (index.column() >= NUM_COLS) || (index.row() >= rowCount()))
|
||||
return QVariant();
|
||||
|
||||
CardSetPtr set = sets[index.row()];
|
||||
|
||||
if (index.column() == EnabledCol) {
|
||||
switch (role) {
|
||||
case SortRole:
|
||||
return enabledSets.contains(set) ? "1" : "0";
|
||||
case Qt::CheckStateRole:
|
||||
return static_cast<int>(enabledSets.contains(set) ? Qt::Checked : Qt::Unchecked);
|
||||
case Qt::DisplayRole:
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
if (role != Qt::DisplayRole && role != SortRole)
|
||||
return QVariant();
|
||||
|
||||
switch (index.column()) {
|
||||
case SortKeyCol:
|
||||
return QString("%1").arg(set->getSortKey(), 8, 10, QChar('0'));
|
||||
case IsKnownCol:
|
||||
return set->getIsKnown();
|
||||
case SetTypeCol:
|
||||
return set->getSetType();
|
||||
case ShortNameCol:
|
||||
return set->getShortName();
|
||||
case LongNameCol:
|
||||
return set->getLongName();
|
||||
case ReleaseDateCol:
|
||||
return set->getReleaseDate().toString(Qt::ISODate);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
bool SetsModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (role == Qt::CheckStateRole && index.column() == EnabledCol) {
|
||||
toggleRow(index.row(), value == Qt::Checked);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant SetsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole) || (orientation != Qt::Horizontal))
|
||||
return QVariant();
|
||||
switch (section) {
|
||||
case SortKeyCol:
|
||||
return QString("Key"); /* no tr() for translations needed, column just used for sorting --> hidden */
|
||||
case IsKnownCol:
|
||||
return QString(
|
||||
"Is known"); /* no tr() for translations needed, column is just used for sorting --> hidden */
|
||||
case EnabledCol:
|
||||
return tr("Enabled");
|
||||
case SetTypeCol:
|
||||
return tr("Set type");
|
||||
case ShortNameCol:
|
||||
return tr("Set code");
|
||||
case LongNameCol:
|
||||
return tr("Long name");
|
||||
case ReleaseDateCol:
|
||||
return tr("Release date");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags SetsModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||
|
||||
if (index.column() == EnabledCol)
|
||||
flags |= Qt::ItemIsUserCheckable;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
Qt::DropActions SetsModel::supportedDropActions() const
|
||||
{
|
||||
return Qt::MoveAction;
|
||||
}
|
||||
|
||||
QMimeData *SetsModel::mimeData(const QModelIndexList &indexes) const
|
||||
{
|
||||
if (indexes.isEmpty())
|
||||
return 0;
|
||||
|
||||
SetsMimeData *result = new SetsMimeData(indexes[0].row());
|
||||
return qobject_cast<QMimeData *>(result);
|
||||
}
|
||||
|
||||
bool SetsModel::dropMimeData(const QMimeData *data,
|
||||
Qt::DropAction action,
|
||||
int row,
|
||||
int /*column*/,
|
||||
const QModelIndex &parent)
|
||||
{
|
||||
if (action != Qt::MoveAction)
|
||||
return false;
|
||||
if (row == -1) {
|
||||
if (!parent.isValid())
|
||||
return false;
|
||||
row = parent.row();
|
||||
}
|
||||
int oldRow = qobject_cast<const SetsMimeData *>(data)->getOldRow();
|
||||
if (oldRow < row)
|
||||
row--;
|
||||
|
||||
swapRows(oldRow, row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetsModel::toggleRow(int row, bool enable)
|
||||
{
|
||||
CardSetPtr temp = sets.at(row);
|
||||
|
||||
if (enable)
|
||||
enabledSets.insert(temp);
|
||||
else
|
||||
enabledSets.remove(temp);
|
||||
|
||||
emit dataChanged(index(row, EnabledCol), index(row, EnabledCol));
|
||||
}
|
||||
|
||||
void SetsModel::toggleRow(int row)
|
||||
{
|
||||
CardSetPtr tmp = sets.at(row);
|
||||
|
||||
if (tmp == nullptr)
|
||||
return;
|
||||
|
||||
if (enabledSets.contains(tmp))
|
||||
enabledSets.remove(tmp);
|
||||
else
|
||||
enabledSets.insert(tmp);
|
||||
|
||||
emit dataChanged(index(row, EnabledCol), index(row, EnabledCol));
|
||||
}
|
||||
|
||||
void SetsModel::toggleAll(bool enabled)
|
||||
{
|
||||
enabledSets.clear();
|
||||
|
||||
if (enabled)
|
||||
for (CardSetPtr set : sets)
|
||||
enabledSets.insert(set);
|
||||
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
|
||||
}
|
||||
|
||||
void SetsModel::swapRows(int oldRow, int newRow)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), oldRow, oldRow);
|
||||
CardSetPtr temp = sets.takeAt(oldRow);
|
||||
endRemoveRows();
|
||||
|
||||
beginInsertRows(QModelIndex(), newRow, newRow);
|
||||
sets.insert(newRow, temp);
|
||||
endInsertRows();
|
||||
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
|
||||
}
|
||||
|
||||
void SetsModel::restoreOriginalOrder()
|
||||
{
|
||||
int numRows = rowCount();
|
||||
sets.defaultSort();
|
||||
emit dataChanged(index(0, 0), index(numRows - 1, columnCount() - 1));
|
||||
}
|
||||
|
||||
void SetsModel::sort(int column, Qt::SortOrder order)
|
||||
{
|
||||
QMultiMap<QString, CardSetPtr> setMap;
|
||||
int numRows = rowCount();
|
||||
int row;
|
||||
|
||||
for (row = 0; row < numRows; ++row)
|
||||
setMap.insert(index(row, column).data(SetsModel::SortRole).toString(), sets.at(row));
|
||||
|
||||
QList<CardSetPtr> tmp = setMap.values();
|
||||
sets.clear();
|
||||
if (order == Qt::AscendingOrder) {
|
||||
for (row = 0; row < tmp.size(); row++) {
|
||||
sets.append(tmp.at(row));
|
||||
}
|
||||
} else {
|
||||
for (row = tmp.size() - 1; row >= 0; row--) {
|
||||
sets.append(tmp.at(row));
|
||||
}
|
||||
}
|
||||
|
||||
emit dataChanged(index(0, 0), index(numRows - 1, columnCount() - 1));
|
||||
}
|
||||
|
||||
void SetsModel::save(CardDatabase *db)
|
||||
{
|
||||
// order
|
||||
for (int i = 0; i < sets.size(); i++)
|
||||
sets[i]->setSortKey(static_cast<unsigned int>(i + 1));
|
||||
|
||||
// enabled sets
|
||||
for (const CardSetPtr &set : sets)
|
||||
set->setEnabled(enabledSets.contains(set));
|
||||
|
||||
sets.sortByKey();
|
||||
|
||||
db->notifyEnabledSetsChanged();
|
||||
}
|
||||
|
||||
void SetsModel::restore(CardDatabase *db)
|
||||
{
|
||||
// order
|
||||
sets = db->getSetList();
|
||||
sets.sortByKey();
|
||||
|
||||
// enabled sets
|
||||
enabledSets.clear();
|
||||
for (const CardSetPtr &set : sets) {
|
||||
if (set->getEnabled())
|
||||
enabledSets.insert(set);
|
||||
}
|
||||
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
|
||||
}
|
||||
|
||||
QStringList SetsModel::mimeTypes() const
|
||||
{
|
||||
return QStringList() << "application/x-cockatricecardset";
|
||||
}
|
||||
|
||||
SetsDisplayModel::SetsDisplayModel(QObject *parent) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
void SetsDisplayModel::fetchMore(const QModelIndex &index)
|
||||
{
|
||||
int itemsToFetch = sourceModel()->rowCount(index);
|
||||
|
||||
beginInsertRows(QModelIndex(), 0, itemsToFetch - 1);
|
||||
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
bool SetsDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
auto typeIndex = sourceModel()->index(sourceRow, SetsModel::SetTypeCol, sourceParent);
|
||||
auto nameIndex = sourceModel()->index(sourceRow, SetsModel::LongNameCol, sourceParent);
|
||||
auto shortNameIndex = sourceModel()->index(sourceRow, SetsModel::ShortNameCol, sourceParent);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
const auto filter = filterRegularExpression();
|
||||
#else
|
||||
const auto filter = filterRegExp();
|
||||
#endif
|
||||
|
||||
return (sourceModel()->data(typeIndex).toString().contains(filter) ||
|
||||
sourceModel()->data(nameIndex).toString().contains(filter) ||
|
||||
sourceModel()->data(shortNameIndex).toString().contains(filter));
|
||||
}
|
||||
|
||||
bool SetsDisplayModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
QString leftString = sourceModel()->data(left, SetsModel::SortRole).toString();
|
||||
QString rightString = sourceModel()->data(right, SetsModel::SortRole).toString();
|
||||
|
||||
return QString::localeAwareCompare(leftString, rightString) < 0;
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
/**
|
||||
* @file sets_model.h
|
||||
* @ingroup CardDatabaseModels
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef SETSMODEL_H
|
||||
#define SETSMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QMimeData>
|
||||
#include <QSet>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <libcockatrice/card/card_database/card_database.h>
|
||||
|
||||
class SetsProxyModel;
|
||||
|
||||
class SetsMimeData : public QMimeData
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
int oldRow;
|
||||
|
||||
public:
|
||||
SetsMimeData(int _oldRow) : oldRow(_oldRow)
|
||||
{
|
||||
}
|
||||
int getOldRow() const
|
||||
{
|
||||
return oldRow;
|
||||
}
|
||||
QStringList formats() const
|
||||
{
|
||||
return QStringList() << "application/x-cockatricecardset";
|
||||
}
|
||||
};
|
||||
|
||||
class SetsModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class SetsProxyModel;
|
||||
|
||||
private:
|
||||
static const int NUM_COLS = 7;
|
||||
CardSetList sets;
|
||||
QSet<CardSetPtr> enabledSets;
|
||||
|
||||
public:
|
||||
enum SetsColumns
|
||||
{
|
||||
SortKeyCol,
|
||||
IsKnownCol,
|
||||
EnabledCol,
|
||||
LongNameCol,
|
||||
ShortNameCol,
|
||||
SetTypeCol,
|
||||
ReleaseDateCol,
|
||||
PriorityCol
|
||||
};
|
||||
enum Role
|
||||
{
|
||||
SortRole = Qt::UserRole
|
||||
};
|
||||
|
||||
explicit SetsModel(CardDatabase *_db, QObject *parent = nullptr);
|
||||
~SetsModel() override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return NUM_COLS;
|
||||
}
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
bool
|
||||
dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
QStringList mimeTypes() const override;
|
||||
void swapRows(int oldRow, int newRow);
|
||||
void toggleRow(int row, bool enable);
|
||||
void toggleRow(int row);
|
||||
void toggleAll(bool);
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
|
||||
void save(CardDatabase *db);
|
||||
void restore(CardDatabase *db);
|
||||
void restoreOriginalOrder();
|
||||
};
|
||||
|
||||
class SetsDisplayModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SetsDisplayModel(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
void fetchMore(const QModelIndex &index) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include "spoiler_background_updater.h"
|
||||
|
||||
#include "../../interface/window_main.h"
|
||||
#include "../../main.h"
|
||||
#include "../../../../interface/window_main.h"
|
||||
#include "../../../../main.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCryptographicHash>
|
||||
|
|
@ -1,727 +0,0 @@
|
|||
#include "deck_list_model.h"
|
||||
|
||||
#include "../main.h"
|
||||
#include "deck_loader.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QFont>
|
||||
#include <QPrinter>
|
||||
#include <QProgressDialog>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocument>
|
||||
#include <QTextStream>
|
||||
#include <QTextTable>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
DeckListModel::DeckListModel(QObject *parent)
|
||||
: QAbstractItemModel(parent), lastKnownColumn(1), lastKnownOrder(Qt::AscendingOrder)
|
||||
{
|
||||
deckList = new DeckLoader;
|
||||
deckList->setParent(this);
|
||||
connect(deckList, &DeckLoader::deckLoaded, this, &DeckListModel::rebuildTree);
|
||||
connect(deckList, &DeckLoader::deckHashChanged, this, &DeckListModel::deckHashChanged);
|
||||
root = new InnerDecklistNode;
|
||||
}
|
||||
|
||||
DeckListModel::~DeckListModel()
|
||||
{
|
||||
delete root;
|
||||
}
|
||||
|
||||
QString DeckListModel::getGroupCriteriaForCard(CardInfoPtr info) const
|
||||
{
|
||||
if (!info) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
switch (activeGroupCriteria) {
|
||||
case DeckListModelGroupCriteria::MAIN_TYPE:
|
||||
return info->getMainCardType();
|
||||
case DeckListModelGroupCriteria::MANA_COST:
|
||||
return info->getCmc();
|
||||
case DeckListModelGroupCriteria::COLOR:
|
||||
return info->getColors() == "" ? "Colorless" : info->getColors();
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void DeckListModel::rebuildTree()
|
||||
{
|
||||
beginResetModel();
|
||||
root->clearTree();
|
||||
|
||||
InnerDecklistNode *listRoot = deckList->getRoot();
|
||||
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
auto *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
auto *node = new InnerDecklistNode(currentZone->getName(), root);
|
||||
|
||||
for (int j = 0; j < currentZone->size(); j++) {
|
||||
auto *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
|
||||
// TODO: better sanity checking
|
||||
if (currentCard == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(currentCard->getName());
|
||||
QString groupCriteria = getGroupCriteriaForCard(info);
|
||||
|
||||
auto *groupNode = dynamic_cast<InnerDecklistNode *>(node->findChild(groupCriteria));
|
||||
|
||||
if (!groupNode) {
|
||||
groupNode = new InnerDecklistNode(groupCriteria, node);
|
||||
}
|
||||
|
||||
new DecklistModelCardNode(currentCard, groupNode);
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int DeckListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
// debugIndexInfo("rowCount", parent);
|
||||
auto *node = getNode<InnerDecklistNode *>(parent);
|
||||
if (node) {
|
||||
return node->size();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int DeckListModel::columnCount(const QModelIndex & /*parent*/) const
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
QVariant DeckListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
// debugIndexInfo("data", index);
|
||||
if (!index.isValid()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (index.column() >= columnCount()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto *temp = static_cast<AbstractDecklistNode *>(index.internalPointer());
|
||||
auto *card = dynamic_cast<DecklistModelCardNode *>(temp);
|
||||
if (card == nullptr) {
|
||||
const auto *node = dynamic_cast<InnerDecklistNode *>(temp);
|
||||
switch (role) {
|
||||
case Qt::FontRole: {
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
return f;
|
||||
}
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole: {
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
return node->recursiveCount(true);
|
||||
case 1: {
|
||||
if (role == Qt::DisplayRole)
|
||||
return node->getVisibleName();
|
||||
return node->getName();
|
||||
}
|
||||
case 2: {
|
||||
return node->getCardSetShortName();
|
||||
}
|
||||
case 3: {
|
||||
return node->getCardCollectorNumber();
|
||||
}
|
||||
case 4: {
|
||||
return node->getCardProviderId();
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
case Qt::UserRole + 1:
|
||||
return false;
|
||||
case Qt::BackgroundRole: {
|
||||
int color = 90 + 60 * node->depth();
|
||||
return QBrush(QColor(color, 255, color));
|
||||
}
|
||||
case Qt::ForegroundRole: {
|
||||
return QBrush(QColor(0, 0, 0));
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole: {
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
return card->getNumber();
|
||||
case 1:
|
||||
return card->getName();
|
||||
case 2:
|
||||
return card->getCardSetShortName();
|
||||
case 3:
|
||||
return card->getCardCollectorNumber();
|
||||
case 4:
|
||||
return card->getCardProviderId();
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
case Qt::UserRole + 1:
|
||||
return true;
|
||||
case Qt::BackgroundRole: {
|
||||
int color = 255 - (index.row() % 2) * 30;
|
||||
return QBrush(QColor(color, color, color));
|
||||
}
|
||||
case Qt::ForegroundRole: {
|
||||
return QBrush(QColor(0, 0, 0));
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariant DeckListModel::headerData(const int section, const Qt::Orientation orientation, const int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole) || (orientation != Qt::Horizontal)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (section >= columnCount()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
switch (section) {
|
||||
case 0:
|
||||
return tr("Count");
|
||||
case 1:
|
||||
return tr("Card");
|
||||
case 2:
|
||||
return tr("Set");
|
||||
case 3:
|
||||
return tr("Number");
|
||||
case 4:
|
||||
return tr("Provider ID");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex DeckListModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
// debugIndexInfo("index", parent);
|
||||
if (!hasIndex(row, column, parent)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto *parentNode = getNode<InnerDecklistNode *>(parent);
|
||||
return row >= parentNode->size() ? QModelIndex() : createIndex(row, column, parentNode->at(row));
|
||||
}
|
||||
|
||||
QModelIndex DeckListModel::parent(const QModelIndex &ind) const
|
||||
{
|
||||
if (!ind.isValid()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return nodeToIndex(static_cast<AbstractDecklistNode *>(ind.internalPointer())->getParent());
|
||||
}
|
||||
|
||||
Qt::ItemFlags DeckListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return Qt::NoItemFlags;
|
||||
}
|
||||
|
||||
Qt::ItemFlags result = Qt::ItemIsEnabled;
|
||||
result |= Qt::ItemIsSelectable;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DeckListModel::emitRecursiveUpdates(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index);
|
||||
emitRecursiveUpdates(index.parent());
|
||||
}
|
||||
|
||||
bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, const int role)
|
||||
{
|
||||
auto *node = getNode<DecklistModelCardNode *>(index);
|
||||
if (!node || (role != Qt::EditRole)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
node->setNumber(value.toInt());
|
||||
break;
|
||||
case 1:
|
||||
node->setName(value.toString());
|
||||
break;
|
||||
case 2:
|
||||
node->setCardSetShortName(value.toString());
|
||||
break;
|
||||
case 3:
|
||||
node->setCardCollectorNumber(value.toString());
|
||||
break;
|
||||
case 4:
|
||||
node->setCardProviderId(value.toString());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
emitRecursiveUpdates(index);
|
||||
deckList->refreshDeckHash();
|
||||
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeckListModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
auto *node = getNode<InnerDecklistNode *>(parent);
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (row + count > node->size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
for (int i = 0; i < count; i++) {
|
||||
AbstractDecklistNode *toDelete = node->takeAt(row);
|
||||
if (auto *temp = dynamic_cast<DecklistModelCardNode *>(toDelete)) {
|
||||
deckList->deleteNode(temp->getDataNode());
|
||||
}
|
||||
delete toDelete;
|
||||
}
|
||||
endRemoveRows();
|
||||
|
||||
if (node->empty() && (node != root)) {
|
||||
removeRows(parent.row(), 1, parent.parent());
|
||||
} else {
|
||||
emitRecursiveUpdates(parent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
InnerDecklistNode *DeckListModel::createNodeIfNeeded(const QString &name, InnerDecklistNode *parent)
|
||||
{
|
||||
auto *newNode = dynamic_cast<InnerDecklistNode *>(parent->findChild(name));
|
||||
if (!newNode) {
|
||||
beginInsertRows(nodeToIndex(parent), parent->size(), parent->size());
|
||||
newNode = new InnerDecklistNode(name, parent);
|
||||
endInsertRows();
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
|
||||
DecklistModelCardNode *DeckListModel::findCardNode(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId,
|
||||
const QString &cardNumber) const
|
||||
{
|
||||
InnerDecklistNode *zoneNode = dynamic_cast<InnerDecklistNode *>(root->findChild(zoneName));
|
||||
if (!zoneNode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(cardName);
|
||||
if (!info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString groupCriteria = getGroupCriteriaForCard(info);
|
||||
InnerDecklistNode *groupNode = dynamic_cast<InnerDecklistNode *>(zoneNode->findChild(groupCriteria));
|
||||
if (!groupNode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dynamic_cast<DecklistModelCardNode *>(
|
||||
groupNode->findCardChildByNameProviderIdAndNumber(cardName, providerId, cardNumber));
|
||||
}
|
||||
|
||||
QModelIndex DeckListModel::findCard(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId,
|
||||
const QString &cardNumber) const
|
||||
{
|
||||
DecklistModelCardNode *cardNode = findCardNode(cardName, zoneName, providerId, cardNumber);
|
||||
if (!cardNode) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return nodeToIndex(cardNode);
|
||||
}
|
||||
|
||||
QModelIndex DeckListModel::addPreferredPrintingCard(const QString &cardName, const QString &zoneName, bool abAddAnyway)
|
||||
{
|
||||
ExactCard card = CardDatabaseManager::query()->getCard({cardName});
|
||||
|
||||
if (!card) {
|
||||
if (abAddAnyway) {
|
||||
// We need to keep this card added no matter what
|
||||
// This is usually called from tab_deck_editor
|
||||
// So we'll create a new CardInfo with the name
|
||||
// and default values for all fields
|
||||
card = ExactCard(CardInfo::newInstance(cardName));
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return addCard(card, zoneName);
|
||||
}
|
||||
|
||||
QModelIndex DeckListModel::addCard(const ExactCard &card, const QString &zoneName)
|
||||
{
|
||||
if (!card) {
|
||||
return {};
|
||||
}
|
||||
|
||||
InnerDecklistNode *zoneNode = createNodeIfNeeded(zoneName, root);
|
||||
|
||||
CardInfoPtr cardInfo = card.getCardPtr();
|
||||
PrintingInfo printingInfo = card.getPrinting();
|
||||
|
||||
QString groupCriteria = getGroupCriteriaForCard(cardInfo);
|
||||
InnerDecklistNode *groupNode = createNodeIfNeeded(groupCriteria, zoneNode);
|
||||
|
||||
const QModelIndex parentIndex = nodeToIndex(groupNode);
|
||||
auto *cardNode = dynamic_cast<DecklistModelCardNode *>(groupNode->findCardChildByNameProviderIdAndNumber(
|
||||
card.getName(), printingInfo.getUuid(), printingInfo.getProperty("num")));
|
||||
const auto cardSetName = printingInfo.getSet().isNull() ? "" : printingInfo.getSet()->getCorrectedShortName();
|
||||
|
||||
if (!cardNode) {
|
||||
// Determine the correct index
|
||||
int insertRow = findSortedInsertRow(groupNode, cardInfo);
|
||||
|
||||
auto *decklistCard = deckList->addCard(cardInfo->getName(), zoneName, insertRow, cardSetName,
|
||||
printingInfo.getProperty("num"), printingInfo.getProperty("uuid"));
|
||||
|
||||
beginInsertRows(parentIndex, insertRow, insertRow);
|
||||
cardNode = new DecklistModelCardNode(decklistCard, groupNode, insertRow);
|
||||
endInsertRows();
|
||||
} else {
|
||||
cardNode->setNumber(cardNode->getNumber() + 1);
|
||||
cardNode->setCardSetShortName(cardSetName);
|
||||
cardNode->setCardCollectorNumber(printingInfo.getProperty("num"));
|
||||
cardNode->setCardProviderId(printingInfo.getProperty("uuid"));
|
||||
deckList->refreshDeckHash();
|
||||
}
|
||||
sort(lastKnownColumn, lastKnownOrder);
|
||||
emitRecursiveUpdates(parentIndex);
|
||||
return nodeToIndex(cardNode);
|
||||
}
|
||||
|
||||
int DeckListModel::findSortedInsertRow(InnerDecklistNode *parent, CardInfoPtr cardInfo) const
|
||||
{
|
||||
if (!cardInfo) {
|
||||
return parent->size(); // fallback: append at end
|
||||
}
|
||||
|
||||
for (int i = 0; i < parent->size(); ++i) {
|
||||
auto *existingCard = dynamic_cast<DecklistModelCardNode *>(parent->at(i));
|
||||
if (!existingCard)
|
||||
continue;
|
||||
|
||||
bool lessThan = false;
|
||||
switch (lastKnownColumn) {
|
||||
case 0: // ByNumber
|
||||
lessThan = lastKnownOrder == Qt::AscendingOrder
|
||||
? cardInfo->getProperty("collectorNumber") < existingCard->getCardCollectorNumber()
|
||||
: cardInfo->getProperty("collectorNumber") > existingCard->getCardCollectorNumber();
|
||||
break;
|
||||
case 1: // ByName
|
||||
default:
|
||||
lessThan = lastKnownOrder == Qt::AscendingOrder
|
||||
? cardInfo->getName().localeAwareCompare(existingCard->getName()) < 0
|
||||
: cardInfo->getName().localeAwareCompare(existingCard->getName()) > 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lessThan)
|
||||
return i;
|
||||
}
|
||||
|
||||
return parent->size(); // insert at end if no earlier match
|
||||
}
|
||||
|
||||
QModelIndex DeckListModel::nodeToIndex(AbstractDecklistNode *node) const
|
||||
{
|
||||
if (node == nullptr || node == root) {
|
||||
return {};
|
||||
}
|
||||
|
||||
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;
|
||||
int columns = columnCount();
|
||||
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 = 0; j < columns; ++j) {
|
||||
from << createIndex(fromRow, j, temp);
|
||||
to << createIndex(toRow, j, temp);
|
||||
}
|
||||
}
|
||||
changePersistentIndexList(from, to);
|
||||
|
||||
// Recursion
|
||||
for (int i = node->size() - 1; i >= 0; --i) {
|
||||
auto *subNode = dynamic_cast<InnerDecklistNode *>(node->at(i));
|
||||
if (subNode) {
|
||||
sortHelper(subNode, order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckListModel::sort(int column, Qt::SortOrder order)
|
||||
{
|
||||
lastKnownColumn = column;
|
||||
lastKnownOrder = order;
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
DeckSortMethod sortMethod;
|
||||
switch (column) {
|
||||
case 0:
|
||||
sortMethod = ByNumber;
|
||||
break;
|
||||
case 1:
|
||||
sortMethod = ByName;
|
||||
break;
|
||||
default:
|
||||
sortMethod = ByName;
|
||||
}
|
||||
|
||||
root->setSortMethod(sortMethod);
|
||||
sortHelper(root, order);
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria newCriteria)
|
||||
{
|
||||
activeGroupCriteria = newCriteria;
|
||||
rebuildTree();
|
||||
}
|
||||
|
||||
void DeckListModel::cleanList()
|
||||
{
|
||||
setDeckList(new DeckLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _deck The deck. Takes ownership of the object
|
||||
*/
|
||||
void DeckListModel::setDeckList(DeckLoader *_deck)
|
||||
{
|
||||
deckList->deleteLater();
|
||||
deckList = _deck;
|
||||
deckList->setParent(this);
|
||||
connect(deckList, &DeckLoader::deckLoaded, this, &DeckListModel::rebuildTree);
|
||||
connect(deckList, &DeckLoader::deckHashChanged, this, &DeckListModel::deckHashChanged);
|
||||
rebuildTree();
|
||||
}
|
||||
|
||||
QList<ExactCard> DeckListModel::getCards() const
|
||||
{
|
||||
QList<ExactCard> cards;
|
||||
DeckList *decklist = getDeckList();
|
||||
if (!decklist) {
|
||||
return cards;
|
||||
}
|
||||
InnerDecklistNode *listRoot = decklist->getRoot();
|
||||
if (!listRoot)
|
||||
return cards;
|
||||
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
if (!currentZone)
|
||||
continue;
|
||||
for (int j = 0; j < currentZone->size(); j++) {
|
||||
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
if (!currentCard)
|
||||
continue;
|
||||
for (int k = 0; k < currentCard->getNumber(); ++k) {
|
||||
ExactCard card = CardDatabaseManager::query()->getCard(currentCard->toCardRef());
|
||||
if (card) {
|
||||
cards.append(card);
|
||||
} else {
|
||||
qDebug() << "Card not found in database!";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cards;
|
||||
}
|
||||
|
||||
QList<ExactCard> DeckListModel::getCardsForZone(const QString &zoneName) const
|
||||
{
|
||||
QList<ExactCard> cards;
|
||||
DeckList *decklist = getDeckList();
|
||||
if (!decklist) {
|
||||
return cards;
|
||||
}
|
||||
InnerDecklistNode *listRoot = decklist->getRoot();
|
||||
if (!listRoot)
|
||||
return cards;
|
||||
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
if (!currentZone)
|
||||
continue;
|
||||
if (currentZone->getName() == zoneName) {
|
||||
for (int j = 0; j < currentZone->size(); j++) {
|
||||
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
if (!currentCard)
|
||||
continue;
|
||||
for (int k = 0; k < currentCard->getNumber(); ++k) {
|
||||
ExactCard card = CardDatabaseManager::query()->getCard(currentCard->toCardRef());
|
||||
if (card) {
|
||||
cards.append(card);
|
||||
} else {
|
||||
qDebug() << "Card not found in database!";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cards;
|
||||
}
|
||||
|
||||
QList<QString> *DeckListModel::getZones() const
|
||||
{
|
||||
QList<QString> *zones = new QList<QString>();
|
||||
DeckList *decklist = getDeckList();
|
||||
if (!decklist) {
|
||||
return zones;
|
||||
}
|
||||
InnerDecklistNode *listRoot = decklist->getRoot();
|
||||
if (!listRoot)
|
||||
return zones;
|
||||
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
if (!currentZone)
|
||||
continue;
|
||||
zones->append(currentZone->getName());
|
||||
}
|
||||
return zones;
|
||||
}
|
||||
|
||||
void DeckListModel::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node)
|
||||
{
|
||||
const int totalColumns = 2;
|
||||
|
||||
if (node->height() == 1) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(11);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(0);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QTextTable *table = cursor->insertTable(node->size() + 1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
auto *card = dynamic_cast<AbstractDecklistCardNode *>(node->at(i));
|
||||
|
||||
QTextCharFormat cellCharFormat;
|
||||
cellCharFormat.setFontPointSize(9);
|
||||
|
||||
QTextTableCell cell = table->cellAt(i, 0);
|
||||
cell.setFormat(cellCharFormat);
|
||||
QTextCursor cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(QString("%1 ").arg(card->getNumber()));
|
||||
|
||||
cell = table->cellAt(i, 1);
|
||||
cell.setFormat(cellCharFormat);
|
||||
cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(card->getName());
|
||||
}
|
||||
} else if (node->height() == 2) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(14);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(10);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QVector<QTextLength> constraints;
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
constraints << QTextLength(QTextLength::PercentageLength, 100.0 / totalColumns);
|
||||
}
|
||||
tableFormat.setColumnWidthConstraints(constraints);
|
||||
|
||||
QTextTable *table = cursor->insertTable(1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
QTextCursor cellCursor = table->cellAt(0, (i * totalColumns) / node->size()).lastCursorPosition();
|
||||
printDeckListNode(&cellCursor, dynamic_cast<InnerDecklistNode *>(node->at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
cursor->movePosition(QTextCursor::End);
|
||||
}
|
||||
|
||||
void DeckListModel::printDeckList(QPrinter *printer)
|
||||
{
|
||||
QTextDocument doc;
|
||||
|
||||
QFont font("Serif");
|
||||
font.setStyleHint(QFont::Serif);
|
||||
doc.setDefaultFont(font);
|
||||
|
||||
QTextCursor cursor(&doc);
|
||||
|
||||
QTextBlockFormat headerBlockFormat;
|
||||
QTextCharFormat headerCharFormat;
|
||||
headerCharFormat.setFontPointSize(16);
|
||||
headerCharFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(deckList->getName());
|
||||
|
||||
headerCharFormat.setFontPointSize(12);
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(deckList->getComments());
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
for (int i = 0; i < root->size(); i++) {
|
||||
cursor.insertHtml("<br><img src=theme:hr.jpg>");
|
||||
// cursor.insertHtml("<hr>");
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
printDeckListNode(&cursor, dynamic_cast<InnerDecklistNode *>(root->at(i)));
|
||||
}
|
||||
|
||||
doc.print(printer);
|
||||
}
|
||||
|
|
@ -1,267 +0,0 @@
|
|||
#ifndef DECKLISTMODEL_H
|
||||
#define DECKLISTMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QList>
|
||||
#include <libcockatrice/card/card_printing/exact_card.h>
|
||||
#include <libcockatrice/deck_list/abstract_deck_list_card_node.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_list_card_node.h>
|
||||
|
||||
class DeckLoader;
|
||||
class CardDatabase;
|
||||
class QPrinter;
|
||||
class QTextCursor;
|
||||
|
||||
/**
|
||||
* @brief Specifies the criteria used to group cards in the DeckListModel.
|
||||
*/
|
||||
enum DeckListModelGroupCriteria
|
||||
{
|
||||
MAIN_TYPE, /**< Group cards by their main type (e.g., creature, instant). */
|
||||
MANA_COST, /**< Group cards by their mana cost. */
|
||||
COLOR /**< Group cards by their color identity. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @class DecklistModelCardNode
|
||||
* @ingroup DeckModels
|
||||
* @brief Adapter node that wraps a DecklistCardNode for use in the DeckListModel tree.
|
||||
*
|
||||
* This class forwards all property accessors (name, number, provider ID, set info, etc.)
|
||||
* to the underlying DecklistCardNode. It exists so the model can represent cards
|
||||
* in the same hierarchy as InnerDecklistNode containers.
|
||||
*/
|
||||
class DecklistModelCardNode : public AbstractDecklistCardNode
|
||||
{
|
||||
private:
|
||||
DecklistCardNode *dataNode; /**< Pointer to the underlying data node. */
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a model node wrapping a DecklistCardNode.
|
||||
* @param _dataNode The underlying DecklistCardNode to wrap.
|
||||
* @param _parent The parent InnerDecklistNode in the model tree.
|
||||
* @param position Optional position to insert in parent (-1 appends at end).
|
||||
*/
|
||||
DecklistModelCardNode(DecklistCardNode *_dataNode, InnerDecklistNode *_parent, int position = -1)
|
||||
: AbstractDecklistCardNode(_parent, position), dataNode(_dataNode)
|
||||
{
|
||||
}
|
||||
int getNumber() const override
|
||||
{
|
||||
return dataNode->getNumber();
|
||||
}
|
||||
void setNumber(int _number) override
|
||||
{
|
||||
dataNode->setNumber(_number);
|
||||
}
|
||||
QString getName() const override
|
||||
{
|
||||
return dataNode->getName();
|
||||
}
|
||||
void setName(const QString &_name) override
|
||||
{
|
||||
dataNode->setName(_name);
|
||||
}
|
||||
QString getCardProviderId() const override
|
||||
{
|
||||
return dataNode->getCardProviderId();
|
||||
}
|
||||
void setCardProviderId(const QString &_cardProviderId) override
|
||||
{
|
||||
dataNode->setCardProviderId(_cardProviderId);
|
||||
}
|
||||
QString getCardSetShortName() const override
|
||||
{
|
||||
return dataNode->getCardSetShortName();
|
||||
}
|
||||
void setCardSetShortName(const QString &_cardSetShortName) override
|
||||
{
|
||||
dataNode->setCardSetShortName(_cardSetShortName);
|
||||
}
|
||||
QString getCardCollectorNumber() const override
|
||||
{
|
||||
return dataNode->getCardCollectorNumber();
|
||||
}
|
||||
void setCardCollectorNumber(const QString &_cardSetNumber) override
|
||||
{
|
||||
dataNode->setCardCollectorNumber(_cardSetNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the underlying data node.
|
||||
* @return Pointer to the DecklistCardNode wrapped by this node.
|
||||
*/
|
||||
DecklistCardNode *getDataNode() const
|
||||
{
|
||||
return dataNode;
|
||||
}
|
||||
[[nodiscard]] bool isDeckHeader() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @class DeckListModel
|
||||
* @ingroup DeckModels
|
||||
* @brief Qt model representing a decklist for use in views (tree/table).
|
||||
*
|
||||
* DeckListModel is a QAbstractItemModel that exposes the structure of a deck
|
||||
* (zones and cards) to Qt views. It organizes cards hierarchically under
|
||||
* InnerDecklistNode containers and supports grouping, sorting, adding/removing
|
||||
* cards, and printing decklists.
|
||||
*
|
||||
* Signals:
|
||||
* - deckHashChanged(): emitted when the deck contents change in a way that
|
||||
* affects its hash.
|
||||
*
|
||||
* Slots:
|
||||
* - rebuildTree(): rebuilds the model structure from the underlying DeckLoader.
|
||||
* - printDeckList(): renders the decklist to a QPrinter.
|
||||
*/
|
||||
class DeckListModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
/**
|
||||
* @brief Rebuilds the model tree from the underlying DeckLoader.
|
||||
*
|
||||
* This updates all indices and ensures the model reflects the current
|
||||
* state of the deck.
|
||||
*/
|
||||
void rebuildTree();
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Prints the decklist to the provided QPrinter.
|
||||
* @param printer The printer to render the decklist to.
|
||||
*/
|
||||
void printDeckList(QPrinter *printer);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Emitted whenever the deck hash changes due to modifications in the model.
|
||||
*/
|
||||
void deckHashChanged();
|
||||
|
||||
public:
|
||||
explicit DeckListModel(QObject *parent = nullptr);
|
||||
~DeckListModel() override;
|
||||
|
||||
/**
|
||||
* @brief Returns the root index of the model.
|
||||
* @return QModelIndex representing the root node.
|
||||
*/
|
||||
QModelIndex getRoot() const
|
||||
{
|
||||
return nodeToIndex(root);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns the value of the grouping category for a card based on the current criteria.
|
||||
* @param info Pointer to card information.
|
||||
* @return String representing the value of the current grouping criteria for the card.
|
||||
*/
|
||||
QString getGroupCriteriaForCard(CardInfoPtr info) const;
|
||||
|
||||
// Qt model overrides
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent) override;
|
||||
|
||||
/**
|
||||
* @brief Finds a card by name, zone, and optional identifiers.
|
||||
* @param cardName The card's name.
|
||||
* @param zoneName The zone to search in (main/side/etc.).
|
||||
* @param providerId Optional provider-specific ID.
|
||||
* @param cardNumber Optional collector number.
|
||||
* @return QModelIndex of the card, or invalid index if not found.
|
||||
*/
|
||||
QModelIndex findCard(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId = "",
|
||||
const QString &cardNumber = "") const;
|
||||
|
||||
/**
|
||||
* @brief Adds a card using the preferred printing if available.
|
||||
*
|
||||
* @param cardName Name of the card to add.
|
||||
* @param zoneName Zone to insert the card into.
|
||||
* @param abAddAnyway Whether to add the card even if resolution fails.
|
||||
* @return QModelIndex pointing to the newly inserted card node.
|
||||
*/
|
||||
QModelIndex addPreferredPrintingCard(const QString &cardName, const QString &zoneName, bool abAddAnyway);
|
||||
|
||||
/**
|
||||
* @brief Adds an ExactCard to the specified zone.
|
||||
* @param card The card to add.
|
||||
* @param zoneName The zone to insert the card into.
|
||||
* @return QModelIndex pointing to the newly inserted card node.
|
||||
*/
|
||||
QModelIndex addCard(const ExactCard &card, const QString &zoneName);
|
||||
|
||||
/**
|
||||
* @brief Determines the sorted insertion row for a card.
|
||||
* @param parent The parent node where the card will be inserted.
|
||||
* @param cardInfo The card info to insert.
|
||||
* @return Row index where the card should be inserted to maintain sort order.
|
||||
*/
|
||||
int findSortedInsertRow(InnerDecklistNode *parent, CardInfoPtr cardInfo) const;
|
||||
|
||||
void sort(int column, Qt::SortOrder order) override;
|
||||
|
||||
/**
|
||||
* @brief Removes all cards and resets the model.
|
||||
*/
|
||||
void cleanList();
|
||||
DeckLoader *getDeckList() const
|
||||
{
|
||||
return deckList;
|
||||
}
|
||||
void setDeckList(DeckLoader *_deck);
|
||||
|
||||
QList<ExactCard> getCards() const;
|
||||
QList<ExactCard> getCardsForZone(const QString &zoneName) const;
|
||||
QList<QString> *getZones() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the criteria used to group cards in the model.
|
||||
* @param newCriteria The new grouping criteria.
|
||||
*/
|
||||
void setActiveGroupCriteria(DeckListModelGroupCriteria newCriteria);
|
||||
|
||||
private:
|
||||
DeckLoader *deckList; /**< Pointer to the deck loader providing the underlying data. */
|
||||
InnerDecklistNode *root; /**< Root node of the model tree. */
|
||||
DeckListModelGroupCriteria activeGroupCriteria = DeckListModelGroupCriteria::MAIN_TYPE;
|
||||
int lastKnownColumn; /**< Last column used for sorting. */
|
||||
Qt::SortOrder lastKnownOrder; /**< Last known sort order. */
|
||||
|
||||
InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent);
|
||||
QModelIndex nodeToIndex(AbstractDecklistNode *node) const;
|
||||
DecklistModelCardNode *findCardNode(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId = "",
|
||||
const QString &cardNumber = "") const;
|
||||
void emitRecursiveUpdates(const QModelIndex &index);
|
||||
void sortHelper(InnerDecklistNode *node, Qt::SortOrder order);
|
||||
|
||||
void printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node);
|
||||
|
||||
template <typename T> T getNode(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return dynamic_cast<T>(root);
|
||||
return dynamic_cast<T>(static_cast<AbstractDecklistNode *>(index.internalPointer()));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,607 +0,0 @@
|
|||
#include "deck_loader.h"
|
||||
|
||||
#include "../main.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFutureWatcher>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
#include <QtConcurrentRun>
|
||||
#include <libcockatrice/card/card_database/card_database.h>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_list_card_node.h>
|
||||
|
||||
const QStringList DeckLoader::ACCEPTED_FILE_EXTENSIONS = {"*.cod", "*.dec", "*.dek", "*.txt", "*.mwDeck"};
|
||||
|
||||
const QStringList DeckLoader::FILE_NAME_FILTERS = {
|
||||
tr("Common deck formats (%1)").arg(ACCEPTED_FILE_EXTENSIONS.join(" ")), tr("All files (*.*)")};
|
||||
|
||||
DeckLoader::DeckLoader() : DeckList(), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const QString &nativeString)
|
||||
: DeckList(nativeString), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const DeckList &other)
|
||||
: DeckList(other), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const DeckLoader &other)
|
||||
: DeckList(other), lastFileName(other.lastFileName), lastFileFormat(other.lastFileFormat),
|
||||
lastRemoteDeckId(other.lastRemoteDeckId)
|
||||
{
|
||||
}
|
||||
|
||||
bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = loadFromFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat: {
|
||||
result = loadFromFile_Native(&file);
|
||||
qCInfo(DeckLoaderLog) << "Loaded from" << fileName << "-" << result;
|
||||
if (!result) {
|
||||
qCInfo(DeckLoaderLog) << "Retrying as plain format";
|
||||
file.seek(0);
|
||||
result = loadFromFile_Plain(&file);
|
||||
fmt = PlainTextFormat;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
if (userRequest) {
|
||||
updateLastLoadedTimestamp(fileName, fmt);
|
||||
}
|
||||
|
||||
emit deckLoaded();
|
||||
}
|
||||
|
||||
qCInfo(DeckLoaderLog) << "Deck was loaded -" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeckLoader::loadFromFileAsync(const QString &fileName, FileFormat fmt, bool userRequest)
|
||||
{
|
||||
auto *watcher = new QFutureWatcher<bool>(this);
|
||||
|
||||
connect(watcher, &QFutureWatcher<bool>::finished, this, [this, watcher, fileName, fmt, userRequest]() {
|
||||
const bool result = watcher->result();
|
||||
watcher->deleteLater();
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
if (userRequest) {
|
||||
updateLastLoadedTimestamp(fileName, fmt);
|
||||
}
|
||||
emit deckLoaded();
|
||||
}
|
||||
|
||||
emit loadFinished(result);
|
||||
});
|
||||
|
||||
QFuture<bool> future = QtConcurrent::run([=, this]() {
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
return loadFromFile_Plain(&file);
|
||||
case CockatriceFormat: {
|
||||
bool result = false;
|
||||
result = loadFromFile_Native(&file);
|
||||
if (!result) {
|
||||
file.seek(0);
|
||||
return loadFromFile_Plain(&file);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
watcher->setFuture(future);
|
||||
return true; // Return immediately to indicate the async task was started
|
||||
}
|
||||
|
||||
bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId)
|
||||
{
|
||||
bool result = loadFromString_Native(nativeString);
|
||||
if (result) {
|
||||
lastFileName = QString();
|
||||
lastFileFormat = CockatriceFormat;
|
||||
lastRemoteDeckId = remoteDeckId;
|
||||
|
||||
emit deckLoaded();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = saveToFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
}
|
||||
|
||||
file.flush();
|
||||
file.close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, FileFormat fmt)
|
||||
{
|
||||
QFileInfo fileInfo(fileName);
|
||||
if (!fileInfo.exists()) {
|
||||
qCWarning(DeckLoaderLog) << "File does not exist:" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
QDateTime originalTimestamp = fileInfo.lastModified();
|
||||
|
||||
// Open the file for writing
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to open file for writing:" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
// Perform file modifications
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = saveToFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
setLastLoadedTimestamp(QDateTime::currentDateTime().toString());
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
}
|
||||
|
||||
file.close(); // Close the file to ensure changes are flushed
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
|
||||
// Re-open the file and set the original timestamp
|
||||
if (!file.open(QIODevice::ReadWrite)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to re-open file to set timestamp:" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.setFileTime(originalTimestamp, QFileDevice::FileModificationTime)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to set modification time for file:" << fileName;
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static QString getDomainForWebsite(DeckLoader::DecklistWebsite website)
|
||||
{
|
||||
switch (website) {
|
||||
case DeckLoader::DecklistOrg:
|
||||
return "www.decklist.org";
|
||||
case DeckLoader::DecklistXyz:
|
||||
return "www.decklist.xyz";
|
||||
default:
|
||||
qCWarning(DeckLoaderLog) << "Invalid decklist website enum:" << website;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the card to the String that represents it in the decklist export
|
||||
*/
|
||||
static QString toDecklistExportString(const DecklistCardNode *card)
|
||||
{
|
||||
QString cardString;
|
||||
// Get the number of cards and add the card name
|
||||
cardString += QString::number(card->getNumber());
|
||||
// Add a space between card num and name
|
||||
cardString += "%20";
|
||||
// Add card name
|
||||
cardString += card->getName();
|
||||
|
||||
if (!card->getCardSetShortName().isNull()) {
|
||||
cardString += "%20";
|
||||
cardString += "(" + card->getCardSetShortName() + ")";
|
||||
}
|
||||
if (!card->getCardCollectorNumber().isNull()) {
|
||||
cardString += "%20";
|
||||
cardString += card->getCardCollectorNumber();
|
||||
}
|
||||
|
||||
// Add a return at the end of the card
|
||||
cardString += "%0A";
|
||||
|
||||
return cardString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export deck to decklist function, called to format the deck in a way to be sent to a server
|
||||
* @param website The website we're sending the deck to
|
||||
*/
|
||||
QString DeckLoader::exportDeckToDecklist(DecklistWebsite website)
|
||||
{
|
||||
// Add the base url
|
||||
QString deckString = "https://" + getDomainForWebsite(website) + "/?";
|
||||
// Create two strings to pass to function
|
||||
QString mainBoardCards, sideBoardCards;
|
||||
|
||||
// Set up the function to call
|
||||
auto formatDeckListForExport = [&mainBoardCards, &sideBoardCards](const auto *node, const auto *card) {
|
||||
// Get the card name
|
||||
CardInfoPtr dbCard = CardDatabaseManager::query()->getCardInfo(card->getName());
|
||||
if (!dbCard || dbCard->getIsToken()) {
|
||||
// If it's a token, we don't care about the card.
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a sideboard card.
|
||||
if (node->getName() == DECK_ZONE_SIDE) {
|
||||
sideBoardCards += toDecklistExportString(card);
|
||||
} else {
|
||||
// If it's a mainboard card, do the same thing, but for the mainboard card string
|
||||
mainBoardCards += toDecklistExportString(card);
|
||||
}
|
||||
};
|
||||
|
||||
// call our struct function for each card in the deck
|
||||
forEachCard(formatDeckListForExport);
|
||||
// Remove the extra return at the end of the last cards
|
||||
mainBoardCards.chop(3);
|
||||
sideBoardCards.chop(3);
|
||||
// if after we've called it for each card, and the strings are empty, we know that
|
||||
// there were no non-token cards in the deck, so show an error message.
|
||||
if ((QString::compare(mainBoardCards, "", Qt::CaseInsensitive) == 0) &&
|
||||
(QString::compare(sideBoardCards, "", Qt::CaseInsensitive) == 0)) {
|
||||
return "";
|
||||
}
|
||||
// return a string with the url for decklist export
|
||||
deckString += "deckmain=" + mainBoardCards + "&deckside=" + sideBoardCards;
|
||||
return deckString;
|
||||
}
|
||||
|
||||
// This struct is here to support the forEachCard function call, defined in decklist.
|
||||
// It requires a function to be called for each card, and it will set the providerId to the preferred printing.
|
||||
struct SetProviderIdToPreferred
|
||||
{
|
||||
// Main operator for struct, allowing the foreachcard to work.
|
||||
SetProviderIdToPreferred()
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const InnerDecklistNode *node, DecklistCardNode *card) const
|
||||
{
|
||||
Q_UNUSED(node);
|
||||
PrintingInfo preferredPrinting = CardDatabaseManager::query()->getPreferredPrinting(card->getName());
|
||||
QString providerId = preferredPrinting.getUuid();
|
||||
QString setShortName = preferredPrinting.getSet()->getShortName();
|
||||
QString collectorNumber = preferredPrinting.getProperty("num");
|
||||
|
||||
card->setCardProviderId(providerId);
|
||||
card->setCardCollectorNumber(collectorNumber);
|
||||
card->setCardSetShortName(setShortName);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This function iterates through each card in the decklist and sets the providerId
|
||||
* on each card based on its set name and collector number.
|
||||
*/
|
||||
void DeckLoader::setProviderIdToPreferredPrinting()
|
||||
{
|
||||
// Set up the struct to call.
|
||||
SetProviderIdToPreferred setProviderIdToPreferred;
|
||||
|
||||
// Call the forEachCard method for each card in the deck
|
||||
forEachCard(setProviderIdToPreferred);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the providerId on each card in the decklist based on its set name and collector number.
|
||||
*/
|
||||
void DeckLoader::resolveSetNameAndNumberToProviderID()
|
||||
{
|
||||
auto setProviderId = [](const auto node, const auto card) {
|
||||
Q_UNUSED(node);
|
||||
// Retrieve the providerId based on setName and collectorNumber
|
||||
QString providerId =
|
||||
CardDatabaseManager::getInstance()
|
||||
->query()
|
||||
->getSpecificPrinting(card->getName(), card->getCardSetShortName(), card->getCardCollectorNumber())
|
||||
.getUuid();
|
||||
|
||||
// Set the providerId on the card
|
||||
card->setCardProviderId(providerId);
|
||||
};
|
||||
|
||||
forEachCard(setProviderId);
|
||||
}
|
||||
|
||||
// This struct is here to support the forEachCard function call, defined in decklist.
|
||||
// It requires a function to be called for each card, and it will set the providerId.
|
||||
struct ClearSetNameNumberAndProviderId
|
||||
{
|
||||
// Main operator for struct, allowing the foreachcard to work.
|
||||
ClearSetNameNumberAndProviderId()
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const InnerDecklistNode *node, DecklistCardNode *card) const
|
||||
{
|
||||
Q_UNUSED(node);
|
||||
// Set the providerId on the card
|
||||
card->setCardSetShortName(nullptr);
|
||||
card->setCardCollectorNumber(nullptr);
|
||||
card->setCardProviderId(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the set name and numbers on each card in the decklist.
|
||||
*/
|
||||
void DeckLoader::clearSetNamesAndNumbers()
|
||||
{
|
||||
auto clearSetNameAndNumber = [](const auto node, auto card) {
|
||||
Q_UNUSED(node)
|
||||
// Set the providerId on the card
|
||||
card->setCardSetShortName(nullptr);
|
||||
card->setCardCollectorNumber(nullptr);
|
||||
card->setCardProviderId(nullptr);
|
||||
};
|
||||
|
||||
forEachCard(clearSetNameAndNumber);
|
||||
}
|
||||
|
||||
DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName)
|
||||
{
|
||||
if (fileName.endsWith(".cod", Qt::CaseInsensitive)) {
|
||||
return CockatriceFormat;
|
||||
}
|
||||
return PlainTextFormat;
|
||||
}
|
||||
|
||||
void DeckLoader::saveToClipboard(bool addComments, bool addSetNameAndNumber) const
|
||||
{
|
||||
QString buffer;
|
||||
QTextStream stream(&buffer);
|
||||
saveToStream_Plain(stream, addComments, addSetNameAndNumber);
|
||||
QApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||
QApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||
}
|
||||
|
||||
bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments, bool addSetNameAndNumber) const
|
||||
{
|
||||
if (addComments) {
|
||||
saveToStream_DeckHeader(out);
|
||||
}
|
||||
|
||||
// loop zones
|
||||
for (int i = 0; i < getRoot()->size(); i++) {
|
||||
const auto *zoneNode = dynamic_cast<InnerDecklistNode *>(getRoot()->at(i));
|
||||
|
||||
saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber);
|
||||
|
||||
// end of zone
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeckLoader::saveToStream_DeckHeader(QTextStream &out) const
|
||||
{
|
||||
if (!getName().isEmpty()) {
|
||||
out << "// " << getName() << "\n\n";
|
||||
}
|
||||
|
||||
if (!getComments().isEmpty()) {
|
||||
QStringList commentRows = getComments().split(QRegularExpression("\n|\r\n|\r"));
|
||||
for (const QString &row : commentRows) {
|
||||
out << "// " << row << "\n";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void DeckLoader::saveToStream_DeckZone(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
bool addComments,
|
||||
bool addSetNameAndNumber) const
|
||||
{
|
||||
// group cards by card type and count the subtotals
|
||||
QMultiMap<QString, DecklistCardNode *> cardsByType;
|
||||
QMap<QString, int> cardTotalByType;
|
||||
int cardTotal = 0;
|
||||
|
||||
for (int j = 0; j < zoneNode->size(); j++) {
|
||||
auto *card = dynamic_cast<DecklistCardNode *>(zoneNode->at(j));
|
||||
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(card->getName());
|
||||
QString cardType = info ? info->getMainCardType() : "unknown";
|
||||
|
||||
cardsByType.insert(cardType, card);
|
||||
|
||||
if (cardTotalByType.contains(cardType)) {
|
||||
cardTotalByType[cardType] += card->getNumber();
|
||||
} else {
|
||||
cardTotalByType[cardType] = card->getNumber();
|
||||
}
|
||||
|
||||
cardTotal += card->getNumber();
|
||||
}
|
||||
|
||||
if (addComments) {
|
||||
out << "// " << cardTotal << " " << zoneNode->getVisibleName() << "\n";
|
||||
}
|
||||
|
||||
// print cards to stream
|
||||
for (const QString &cardType : cardsByType.uniqueKeys()) {
|
||||
if (addComments) {
|
||||
out << "// " << cardTotalByType[cardType] << " " << cardType << "\n";
|
||||
}
|
||||
|
||||
QList<DecklistCardNode *> cards = cardsByType.values(cardType);
|
||||
|
||||
saveToStream_DeckZoneCards(out, zoneNode, cards, addComments, addSetNameAndNumber);
|
||||
|
||||
if (addComments) {
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments,
|
||||
bool addSetNameAndNumber) const
|
||||
{
|
||||
// QMultiMap sorts values in reverse order
|
||||
for (int i = cards.size() - 1; i >= 0; --i) {
|
||||
DecklistCardNode *card = cards[i];
|
||||
|
||||
if (zoneNode->getName() == DECK_ZONE_SIDE && addComments) {
|
||||
out << "SB: ";
|
||||
}
|
||||
|
||||
if (card->getNumber()) {
|
||||
out << card->getNumber();
|
||||
}
|
||||
if (!card->getName().isNull() && !card->getName().isEmpty()) {
|
||||
out << " " << card->getName();
|
||||
}
|
||||
if (addSetNameAndNumber) {
|
||||
if (!card->getCardSetShortName().isNull() && !card->getCardSetShortName().isEmpty()) {
|
||||
out << " "
|
||||
<< "(" << card->getCardSetShortName() << ")";
|
||||
}
|
||||
if (!card->getCardCollectorNumber().isNull()) {
|
||||
out << " " << card->getCardCollectorNumber();
|
||||
}
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool DeckLoader::convertToCockatriceFormat(QString fileName)
|
||||
{
|
||||
// Change the file extension to .cod
|
||||
QFileInfo fileInfo(fileName);
|
||||
QString newFileName = QDir::toNativeSeparators(fileInfo.path() + "/" + fileInfo.completeBaseName() + ".cod");
|
||||
|
||||
// Open the new file for writing
|
||||
QFile file(newFileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to open file for writing:" << newFileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
// Perform file modifications based on the detected format
|
||||
switch (getFormatFromName(fileName)) {
|
||||
case PlainTextFormat:
|
||||
// Save in Cockatrice's native format
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed.";
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
qCWarning(DeckLoaderLog) << "Unsupported file format for conversion:" << fileName;
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
// Delete the old file if conversion was successful
|
||||
if (result) {
|
||||
if (!QFile::remove(fileName)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to delete original file:" << fileName;
|
||||
} else {
|
||||
qCInfo(DeckLoaderLog) << "Original file deleted successfully:" << fileName;
|
||||
}
|
||||
lastFileName = newFileName;
|
||||
lastFileFormat = CockatriceFormat;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneName)
|
||||
{
|
||||
CardInfoPtr card = CardDatabaseManager::query()->getCardInfo(cardName);
|
||||
|
||||
if (card && card->getIsToken()) {
|
||||
return DECK_ZONE_TOKENS;
|
||||
}
|
||||
|
||||
return currentZoneName;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCompleteCardName(const QString &cardName) const
|
||||
{
|
||||
if (CardDatabaseManager::getInstance()) {
|
||||
ExactCard temp = CardDatabaseManager::query()->guessCard({cardName});
|
||||
if (temp) {
|
||||
return temp.getName();
|
||||
}
|
||||
}
|
||||
|
||||
return cardName;
|
||||
}
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
/**
|
||||
* @file deck_loader.h
|
||||
* @ingroup ImportExport
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DECK_LOADER_H
|
||||
#define DECK_LOADER_H
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DeckLoaderLog, "deck_loader")
|
||||
|
||||
class DeckLoader : public DeckList
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void deckLoaded();
|
||||
void loadFinished(bool success);
|
||||
|
||||
public:
|
||||
enum FileFormat
|
||||
{
|
||||
PlainTextFormat,
|
||||
CockatriceFormat
|
||||
};
|
||||
|
||||
/**
|
||||
* Supported file extensions for decklist files
|
||||
*/
|
||||
static const QStringList ACCEPTED_FILE_EXTENSIONS;
|
||||
|
||||
/**
|
||||
* For use with `QFileDialog::setNameFilters`
|
||||
*/
|
||||
static const QStringList FILE_NAME_FILTERS;
|
||||
|
||||
enum DecklistWebsite
|
||||
{
|
||||
DecklistOrg,
|
||||
DecklistXyz
|
||||
};
|
||||
|
||||
private:
|
||||
QString lastFileName;
|
||||
FileFormat lastFileFormat;
|
||||
int lastRemoteDeckId;
|
||||
|
||||
public:
|
||||
DeckLoader();
|
||||
explicit DeckLoader(const QString &nativeString);
|
||||
explicit DeckLoader(const DeckList &other);
|
||||
DeckLoader(const DeckLoader &other);
|
||||
const QString &getLastFileName() const
|
||||
{
|
||||
return lastFileName;
|
||||
}
|
||||
void setLastFileName(const QString &_lastFileName)
|
||||
{
|
||||
lastFileName = _lastFileName;
|
||||
}
|
||||
FileFormat getLastFileFormat() const
|
||||
{
|
||||
return lastFileFormat;
|
||||
}
|
||||
int getLastRemoteDeckId() const
|
||||
{
|
||||
return lastRemoteDeckId;
|
||||
}
|
||||
|
||||
bool hasNotBeenLoaded() const
|
||||
{
|
||||
return getLastFileName().isEmpty() && getLastRemoteDeckId() == -1;
|
||||
}
|
||||
|
||||
void clearSetNamesAndNumbers();
|
||||
static FileFormat getFormatFromName(const QString &fileName);
|
||||
|
||||
bool loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest = false);
|
||||
bool loadFromFileAsync(const QString &fileName, FileFormat fmt, bool userRequest);
|
||||
bool loadFromRemote(const QString &nativeString, int remoteDeckId);
|
||||
bool saveToFile(const QString &fileName, FileFormat fmt);
|
||||
bool updateLastLoadedTimestamp(const QString &fileName, FileFormat fmt);
|
||||
QString exportDeckToDecklist(DecklistWebsite website);
|
||||
void setProviderIdToPreferredPrinting();
|
||||
|
||||
void resolveSetNameAndNumberToProviderID();
|
||||
|
||||
void saveToClipboard(bool addComments = true, bool addSetNameAndNumber = true) const;
|
||||
|
||||
// overload
|
||||
bool saveToStream_Plain(QTextStream &out, bool addComments = true, bool addSetNameAndNumber = true) const;
|
||||
bool convertToCockatriceFormat(QString fileName);
|
||||
|
||||
protected:
|
||||
void saveToStream_DeckHeader(QTextStream &out) const;
|
||||
void saveToStream_DeckZone(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
bool addComments = true,
|
||||
bool addSetNameAndNumber = true) const;
|
||||
void saveToStream_DeckZoneCards(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments = true,
|
||||
bool addSetNameAndNumber = true) const;
|
||||
[[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override;
|
||||
[[nodiscard]] QString getCompleteCardName(const QString &cardName) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
#ifndef DLG_CONNECT_H
|
||||
#define DLG_CONNECT_H
|
||||
|
||||
#include "../server/handle_public_servers.h"
|
||||
#include "../server/user/user_info_connection.h"
|
||||
#include "../interface/widgets/server/handle_public_servers.h"
|
||||
#include "../interface/widgets/server/user/user_info_connection.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "dlg_edit_tokens.h"
|
||||
|
||||
#include "../client/get_text_with_max.h"
|
||||
#include "../interface/widgets/utility/get_text_with_max.h"
|
||||
#include "../main.h"
|
||||
|
||||
#include <QAction>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef DLG_FILTER_GAMES_H
|
||||
#define DLG_FILTER_GAMES_H
|
||||
|
||||
#include "../server/games_model.h"
|
||||
#include "../interface/widgets/server/games_model.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include "dlg_load_deck.h"
|
||||
|
||||
#include "../deck/deck_loader.h"
|
||||
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck"))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "dlg_load_deck_from_clipboard.h"
|
||||
|
||||
#include "../deck/deck_loader.h"
|
||||
#include "dlg_settings.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
|
@ -12,6 +11,7 @@
|
|||
#include <QPushButton>
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "dlg_load_remote_deck.h"
|
||||
|
||||
#include "../interface/widgets/server/remote/remote_decklist_tree_widget.h"
|
||||
#include "../main.h"
|
||||
#include "../server/remote/remote_decklist_tree_widget.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
#include "dlg_manage_sets.h"
|
||||
|
||||
#include "../client/network/sets_model.h"
|
||||
#include "../deck/custom_line_edit.h"
|
||||
#include "../interface/card_picture_loader/card_picture_loader.h"
|
||||
#include "../interface/widgets/utility/custom_line_edit.h"
|
||||
#include "../main.h"
|
||||
|
||||
#include <QAction>
|
||||
|
|
@ -21,6 +20,7 @@
|
|||
#include <QTreeView>
|
||||
#include <algorithm>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/card/card_database/model/card_set/card_sets_model.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
#define SORT_RESET -1
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "dlg_select_set_for_cards.h"
|
||||
|
||||
#include "../deck/deck_loader.h"
|
||||
#include "../interface/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../interface/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "dlg_select_set_for_cards.h"
|
||||
|
|
@ -17,6 +16,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <algorithm>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <qdrag.h>
|
||||
#include <qevent.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef DLG_SELECT_SET_FOR_CARDS_H
|
||||
#define DLG_SELECT_SET_FOR_CARDS_H
|
||||
|
||||
#include "../deck/deck_list_model.h"
|
||||
#include "../interface/widgets/general/layout_containers/flow_widget.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
|
|
@ -17,6 +16,7 @@
|
|||
#include <QMap>
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
class SetEntryWidget; // Forward declaration
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dlg_settings.h"
|
||||
|
||||
#include "../client/get_text_with_max.h"
|
||||
#include "../client/network/release_channel.h"
|
||||
#include "../client/network/spoiler_background_updater.h"
|
||||
#include "../client/network/update/card_spoiler/spoiler_background_updater.h"
|
||||
#include "../client/network/update/client/release_channel.h"
|
||||
#include "../client/sound_engine.h"
|
||||
#include "../deck/custom_line_edit.h"
|
||||
#include "../interface/card_picture_loader/card_picture_loader.h"
|
||||
#include "../interface/theme_manager.h"
|
||||
#include "../interface/utility/sequence_edit.h"
|
||||
#include "../interface/widgets/general/background_sources.h"
|
||||
#include "../interface/widgets/utility/custom_line_edit.h"
|
||||
#include "../interface/widgets/utility/get_text_with_max.h"
|
||||
#include "../interface/widgets/utility/sequence_edit.h"
|
||||
#include "../main.h"
|
||||
#include "../tabs/tab_supervisor.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "dlg_update.h"
|
||||
|
||||
#include "../client/network/client_update_checker.h"
|
||||
#include "../client/network/release_channel.h"
|
||||
#include "../client/network/update/client/client_update_checker.h"
|
||||
#include "../client/network/update/client/release_channel.h"
|
||||
#include "../interface/window_main.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef DLG_UPDATE_H
|
||||
#define DLG_UPDATE_H
|
||||
|
||||
#include "../client/update_downloader.h"
|
||||
#include "../client/network/update/client/update_downloader.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLoggingCategory>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "filter_builder.h"
|
||||
|
||||
#include "../deck/custom_line_edit.h"
|
||||
#include "../interface/widgets/utility/custom_line_edit.h"
|
||||
#include "filter_card.h"
|
||||
|
||||
#include <QComboBox>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COUNTER_H
|
||||
#define COUNTER_H
|
||||
|
||||
#include "../../interface/tearoff_menu.h"
|
||||
#include "../../interface/widgets/menus/tearoff_menu.h"
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QInputDialog>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "deck_view_container.h"
|
||||
|
||||
#include "../../deck/deck_loader.h"
|
||||
#include "../../dialogs/dlg_load_deck.h"
|
||||
#include "../../dialogs/dlg_load_deck_from_clipboard.h"
|
||||
#include "../../dialogs/dlg_load_deck_from_website.h"
|
||||
|
|
@ -16,6 +15,7 @@
|
|||
#include <google/protobuf/descriptor.h>
|
||||
#include <libcockatrice/card/card_database/card_database.h>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_select.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_ready_start.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_set_sideboard_lock.pb.h>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@
|
|||
#ifndef DECK_VIEW_CONTAINER_H
|
||||
#define DECK_VIEW_CONTAINER_H
|
||||
|
||||
#include "../../deck/deck_loader.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
|
||||
class QVBoxLayout;
|
||||
class AbstractCardItem;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#define MESSAGELOGWIDGET_H
|
||||
|
||||
#include "../../client/translation.h"
|
||||
#include "../../server/chat_view/chat_view.h"
|
||||
#include "../../interface/widgets/server/chat_view/chat_view.h"
|
||||
#include "../zones/logic/card_zone_logic.h"
|
||||
|
||||
#include <libcockatrice/network/server/remote/user_level.h>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COCKATRICE_GRAVE_MENU_H
|
||||
#define COCKATRICE_GRAVE_MENU_H
|
||||
|
||||
#include "../../../interface/tearoff_menu.h"
|
||||
#include "../../../interface/widgets/menus/tearoff_menu.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COCKATRICE_HAND_MENU_H
|
||||
#define COCKATRICE_HAND_MENU_H
|
||||
|
||||
#include "../../../interface/tearoff_menu.h"
|
||||
#include "../../../interface/widgets/menus/tearoff_menu.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COCKATRICE_LIBRARY_MENU_H
|
||||
#define COCKATRICE_LIBRARY_MENU_H
|
||||
|
||||
#include "../../../interface/tearoff_menu.h"
|
||||
#include "../../../interface/widgets/menus/tearoff_menu.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COCKATRICE_PLAYER_MENU_H
|
||||
#define COCKATRICE_PLAYER_MENU_H
|
||||
|
||||
#include "../../../interface/tearoff_menu.h"
|
||||
#include "../../../interface/widgets/menus/tearoff_menu.h"
|
||||
#include "../player.h"
|
||||
#include "custom_zone_menu.h"
|
||||
#include "grave_menu.h"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef COCKATRICE_RFG_MENU_H
|
||||
#define COCKATRICE_RFG_MENU_H
|
||||
|
||||
#include "../../../interface/tearoff_menu.h"
|
||||
#include "../../../interface/widgets/menus/tearoff_menu.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#define PLAYER_H
|
||||
|
||||
#include "../../filters/filter_string.h"
|
||||
#include "../../interface/tearoff_menu.h"
|
||||
#include "../../interface/widgets/menus/tearoff_menu.h"
|
||||
#include "../board/abstract_graphics_item.h"
|
||||
#include "../dialogs/dlg_create_token.h"
|
||||
#include "menu/player_menu.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "player_actions.h"
|
||||
|
||||
#include "../../client/get_text_with_max.h"
|
||||
#include "../../interface/widgets/utility/get_text_with_max.h"
|
||||
#include "../../tabs/tab_game.h"
|
||||
#include "../board/card_item.h"
|
||||
#include "../dialogs/dlg_move_top_cards_until.h"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef COCKATRICE_PLAYER_INFO_H
|
||||
#define COCKATRICE_PLAYER_INFO_H
|
||||
|
||||
#include "../../deck/deck_loader.h"
|
||||
#include "../zones/hand_zone.h"
|
||||
#include "../zones/pile_zone.h"
|
||||
#include "../zones/stack_zone.h"
|
||||
|
|
@ -15,6 +14,7 @@
|
|||
#include "player_target.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
||||
|
||||
class PlayerInfo : public QObject
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#include "player_list_widget.h"
|
||||
|
||||
#include "../../interface/pixel_map_generator.h"
|
||||
#include "../../server/user/user_context_menu.h"
|
||||
#include "../../server/user/user_list_manager.h"
|
||||
#include "../../server/user/user_list_widget.h"
|
||||
#include "../../interface/widgets/server/user/user_context_menu.h"
|
||||
#include "../../interface/widgets/server/user/user_list_manager.h"
|
||||
#include "../../interface/widgets/server/user/user_list_widget.h"
|
||||
#include "../../tabs/tab_account.h"
|
||||
#include "../../tabs/tab_game.h"
|
||||
#include "../../tabs/tab_supervisor.h"
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
#include "deck_list_sort_filter_proxy_model.h"
|
||||
|
||||
#include "../../deck/deck_list_model.h"
|
||||
|
||||
bool DeckListSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
auto *src = sourceModel();
|
||||
|
||||
// Inner nodes? -> sort alphabetically by column 1
|
||||
bool leftIsCard = src->data(left, Qt::UserRole + 1).toBool();
|
||||
bool rightIsCard = src->data(right, Qt::UserRole + 1).toBool();
|
||||
|
||||
if (!leftIsCard || !rightIsCard) {
|
||||
QString lName = src->data(left.siblingAtColumn(1), Qt::EditRole).toString();
|
||||
QString rName = src->data(right.siblingAtColumn(1), Qt::EditRole).toString();
|
||||
return lName.localeAwareCompare(rName) < 0;
|
||||
}
|
||||
|
||||
// Both are cards -> apply sort criteria
|
||||
auto *lNode = static_cast<DecklistModelCardNode *>(left.internalPointer());
|
||||
auto *rNode = static_cast<DecklistModelCardNode *>(right.internalPointer());
|
||||
|
||||
CardInfoPtr lInfo = CardDatabaseManager::query()->guessCard({lNode->getName()}).getCardPtr();
|
||||
CardInfoPtr rInfo = CardDatabaseManager::query()->guessCard({rNode->getName()}).getCardPtr();
|
||||
|
||||
// Example: multiple tie-break criteria (colors > cmc > name)
|
||||
for (const QString &crit : sortCriteria) {
|
||||
if (crit == "name") {
|
||||
QString ln = lNode->getName();
|
||||
QString rn = rNode->getName();
|
||||
int cmp = ln.localeAwareCompare(rn);
|
||||
if (cmp != 0)
|
||||
return cmp < 0;
|
||||
} else if (crit == "cmc") {
|
||||
int lc = lInfo ? lInfo->getCmc().toInt() : 0;
|
||||
int rc = rInfo ? rInfo->getCmc().toInt() : 0;
|
||||
if (lc != rc)
|
||||
return lc < rc;
|
||||
} else if (crit == "colors") {
|
||||
QString lr = lInfo ? lInfo->getColors() : QString();
|
||||
QString rr = rInfo ? rInfo->getColors() : QString();
|
||||
int cmp = lr.localeAwareCompare(rr);
|
||||
if (cmp != 0)
|
||||
return cmp < 0;
|
||||
} else if (crit == "maintype") {
|
||||
QString lr = lInfo ? lInfo->getMainCardType() : QString();
|
||||
QString rr = rInfo ? rInfo->getMainCardType() : QString();
|
||||
int cmp = lr.localeAwareCompare(rr);
|
||||
if (cmp != 0)
|
||||
return cmp < 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
* @file deck_list_sort_filter_proxy_model.h
|
||||
* @ingroup DeckEditorCardGroupWidgets
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_DECK_LIST_SORT_FILTER_PROXY_MODEL_H
|
||||
#define COCKATRICE_DECK_LIST_SORT_FILTER_PROXY_MODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
|
||||
class DeckListSortFilterProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeckListSortFilterProxyModel(QObject *parent = nullptr) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void setSortCriteria(const QStringList &criteria)
|
||||
{
|
||||
sortCriteria = criteria;
|
||||
invalidate(); // re-sort
|
||||
}
|
||||
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
private:
|
||||
QStringList sortCriteria;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_DECK_LIST_SORT_FILTER_PROXY_MODEL_H
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#include "card_group_display_widget.h"
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../utility/deck_list_sort_filter_proxy_model.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
#include "../libcockatrice_deck_list/libcockatrice/deck_list/deck_list_model.h"
|
||||
#include "../libcockatrice_deck_list/libcockatrice/deck_list/deck_list_sort_filter_proxy_model.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef CARD_GROUP_DISPLAY_WIDGET_H
|
||||
#define CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../general/display/banner_widget.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
#include "../card_size_widget.h"
|
||||
|
|
@ -16,6 +15,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
class CardGroupDisplayWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "flat_card_group_display_widget.h"
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
#include "../libcockatrice_deck_list/libcockatrice/deck_list/deck_list_model.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#include "overlapped_card_group_display_widget.h"
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/card/card_info_comparator.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *_deckListModel,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#include "deck_card_zone_display_widget.h"
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "card_group_display_widgets/flat_card_group_display_widget.h"
|
||||
#include "card_group_display_widgets/overlapped_card_group_display_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <libcockatrice/card/card_info_comparator.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent,
|
||||
DeckListModel *_deckListModel,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef DECK_CARD_ZONE_DISPLAY_WIDGET_H
|
||||
#define DECK_CARD_ZONE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/layout_containers/overlap_widget.h"
|
||||
#include "../visual_deck_editor/visual_deck_editor_widget.h"
|
||||
|
|
@ -18,6 +17,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
class DeckCardZoneDisplayWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef DECK_ANALYTICS_WIDGET_H
|
||||
#define DECK_ANALYTICS_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../general/layout_containers/flow_widget.h"
|
||||
#include "mana_base_widget.h"
|
||||
#include "mana_curve_widget.h"
|
||||
|
|
@ -18,6 +17,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
class DeckAnalyticsWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "mana_base_widget.h"
|
||||
|
||||
#include "../../../deck/deck_loader.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/display/bar_widget.h"
|
||||
|
||||
|
|
@ -9,6 +8,7 @@
|
|||
#include <libcockatrice/card/card_database/card_database.h>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
|
||||
ManaBaseWidget::ManaBaseWidget(QWidget *parent, DeckListModel *_deckListModel)
|
||||
: QWidget(parent), deckListModel(_deckListModel)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@
|
|||
#ifndef MANA_BASE_WIDGET_H
|
||||
#define MANA_BASE_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
#include <utility>
|
||||
|
||||
class ManaBaseWidget : public QWidget
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "mana_curve_widget.h"
|
||||
|
||||
#include "../../../deck/deck_loader.h"
|
||||
#include "../../../main.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/display/bar_widget.h"
|
||||
|
|
@ -8,6 +7,7 @@
|
|||
#include <libcockatrice/card/card_database/card_database.h>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <unordered_map>
|
||||
|
||||
ManaCurveWidget::ManaCurveWidget(QWidget *parent, DeckListModel *_deckListModel)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
#ifndef MANA_CURVE_WIDGET_H
|
||||
#define MANA_CURVE_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
#include <unordered_map>
|
||||
|
||||
class ManaCurveWidget : public QWidget
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "mana_devotion_widget.h"
|
||||
|
||||
#include "../../../deck/deck_loader.h"
|
||||
#include "../../../main.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/display/bar_widget.h"
|
||||
|
|
@ -9,6 +8,7 @@
|
|||
#include <libcockatrice/card/card_database/card_database.h>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@
|
|||
#ifndef MANA_DEVOTION_WIDGET_H
|
||||
#define MANA_DEVOTION_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
#include <utility>
|
||||
|
||||
class ManaDevotionWidget : public QWidget
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
#ifndef DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H
|
||||
#define DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../deck/custom_line_edit.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../utility/custom_line_edit.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QWidget>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
#ifndef DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||
#define DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||
|
||||
#include "../../../deck/custom_line_edit.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../utility/custom_line_edit.h"
|
||||
#include "../visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||
|
||||
#include <QComboBox>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#include "overlap_widget.h"
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../layouts/flow_layout.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
/**
|
||||
* @class OverlapWidget
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "deck_editor_menu.h"
|
||||
#include "../../../interface/widgets/menus/deck_editor_menu.h"
|
||||
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/settings/shortcuts_settings.h>
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef DECK_EDITOR_MENU_H
|
||||
#define DECK_EDITOR_MENU_H
|
||||
|
||||
#include "../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
#ifndef ALL_ZONES_CARD_AMOUNT_WIDGET_H
|
||||
#define ALL_ZONES_CARD_AMOUNT_WIDGET_H
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../../../deck/deck_loader.h"
|
||||
#include "card_amount_widget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
|
||||
class AllZonesCardAmountWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
#ifndef CARD_AMOUNT_WIDGET_H
|
||||
#define CARD_AMOUNT_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../../../deck/deck_loader.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../general/display/dynamic_font_size_push_button.h"
|
||||
|
||||
|
|
@ -19,6 +17,8 @@
|
|||
#include <QTreeView>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
|
||||
class CardAmountWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef PRINTING_SELECTOR_H
|
||||
#define PRINTING_SELECTOR_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../cards/card_size_widget.h"
|
||||
#include "../general/layout_containers/flow_widget.h"
|
||||
#include "../quick_settings/settings_button_widget.h"
|
||||
|
|
@ -19,6 +18,7 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
#define BATCH_SIZE 10
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H
|
||||
#define PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "printing_selector_card_overlay_widget.h"
|
||||
#include "set_name_and_collectors_number_display_widget.h"
|
||||
|
|
@ -15,6 +14,7 @@
|
|||
#include <QPainter>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
class PrintingSelectorCardDisplayWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef PRINTING_SELECTOR_CARD_OVERLAY_WIDGET_H
|
||||
#define PRINTING_SELECTOR_CARD_OVERLAY_WIDGET_H
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../cards/card_info_picture_widget.h"
|
||||
#include "all_zones_card_amount_widget.h"
|
||||
|
|
@ -15,6 +14,7 @@
|
|||
#include "set_name_and_collectors_number_display_widget.h"
|
||||
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
class PrintingSelectorCardOverlayWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "replay_manager.h"
|
||||
|
||||
#include "../tabs/tab_game.h"
|
||||
#include "../../../tabs/tab_game.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QToolButton>
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
#ifndef REPLAY_MANAGER_H
|
||||
#define REPLAY_MANAGER_H
|
||||
|
||||
#include "network/replay_timeline_widget.h"
|
||||
#include "replay_timeline_widget.h"
|
||||
|
||||
#include <QToolButton>
|
||||
#include <QWidget>
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef REPLAY_TIMELINE_WIDGET
|
||||
#define REPLAY_TIMELINE_WIDGET
|
||||
|
||||
#include "../../game/player/event_processing_options.h"
|
||||
#include "../../../game/player/event_processing_options.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMouseEvent>
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#include "game_selector.h"
|
||||
|
||||
#include "../client/get_text_with_max.h"
|
||||
#include "../dialogs/dlg_create_game.h"
|
||||
#include "../dialogs/dlg_filter_games.h"
|
||||
#include "../interface/widgets/utility/get_text_with_max.h"
|
||||
#include "../tabs/tab_account.h"
|
||||
#include "../tabs/tab_game.h"
|
||||
#include "../tabs/tab_room.h"
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
#include "user_info_box.h"
|
||||
|
||||
#include "../../client/get_text_with_max.h"
|
||||
#include "../../dialogs/dlg_edit_avatar.h"
|
||||
#include "../../dialogs/dlg_edit_password.h"
|
||||
#include "../../dialogs/dlg_edit_user.h"
|
||||
#include "../../interface/pixel_map_generator.h"
|
||||
#include "../../interface/widgets/utility/get_text_with_max.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QGridLayout>
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue