mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-21 01:42:15 -07:00
Lint things. Set focus back to deckView after selecting a card to enable keyboard navigation. Bump scrollbar to top when selecting a new card. Update card info on hover. Layout cleanups Add +- to buttons. Merge buttons into card picture. Cleanup size, min 2 cards by default in rows Support layout settings config and set min to 525 so two cols are visible by default for printings, when opened Move Printing Selector to before Deck, and visible true Null safety for setCard. Turn down the dropshadow a little. Make PrintingSelector dockable, don't duplicate sets when bumping them to the front of the list. When swapping cards between mainboard and sideboard, use preferred printing if no uuid is available (i.e. null). Reorder includes... Unwonk an include. Give the card widget a snazzy drop shadow, appease the linter gods. Handle jumping between segments Remember scale factor when initializing new widgets. Cleanup Select Card works (Not M->SB tho) Resize word-wrapped label properly. Fix the layouting, mostly. remove tx Build Fix Squashed Commits Load and store redirects properly. Layouting is fun :) * Group PrintingSelectorCardDisplayWidgets into distinct containers for alignment purposes. Override resizeEvent() properly. Word wrap properly. Keep widget sizes uniform for aesthetic reasons (grid pattern). Label stuff, center card picture widget, allow cardSizeSlider to scale down. Replace cards which have no uuid in the decklist when first selecting a printing. Add buttons for previous and next card in DeckList. Add a card size slider. Move sort options initialization to implementation file. Explicitly nullptr the parent for the PrintingSelector. Address PR comments (minor cleanups). Hook up to the rows removed signal to update card counts properly. Include QDebug. Add labels to the mainboard/sideboard button boxes. Implement a search bar. Expand node recursively when we add a new card. Only create image widgets for the printing selector if it is visible in order to not slow down image loading. Minor Tweaks Invert decklist export logic to write out setName, collectorNumber, providerId value if it is NOT empty. Linting. Update CardCounts properly, update PrintingSelector on Database selection. Initialize sideboard card count label properly. Split mainboard/sideboard display and increment/decrement buttons. Add button to sort all sortOptions by ascending or descending order. Add option to sort by release date in ascending or descending order. Add PrintingSelector to database view. Display placeholder image before loading. Fix deckEditor crash on mainboard/sideboard swap by correcting column index to providerId instead of shortName. Include currentZoneName, fix the column when updating from DeckView indexChanged to be UUID and not setShortName so cards are properly fetched again. The most minor linter change you've ever seen. Null checks are important. Linter again. Linter and refactor to providerId. Sort properly, (We don't need a map, we need a list, a map won't be ordered right [i.e. 1, 10, 11, 2, 3, 4, ..., 9]) Sort alphabetically or by preference. Hook printingSelector up to the CardInfoFrameWidget. Allow info from CardFrame to be retrieved, properly initialize PrintingSelector again. Refactors to reflect CardInfoPicture becoming CardInfoPictureWidget. Make PrintingSelector re-usable by introducing setCard(). Make PrintingSelector use the CardFrame, not the database index. Add a new selector widget for printings.
359 lines
No EOL
11 KiB
C++
359 lines
No EOL
11 KiB
C++
#ifndef DECKLIST_H
|
|
#define DECKLIST_H
|
|
|
|
#include <QMap>
|
|
#include <QVector>
|
|
|
|
// Required on Mac. Forward declaration doesn't work. Don't ask why.
|
|
#include <QtCore/QXmlStreamReader>
|
|
#include <QtCore/QXmlStreamWriter>
|
|
#include <common/pb/move_card_to_zone.pb.h>
|
|
|
|
class CardDatabase;
|
|
class QIODevice;
|
|
class QTextStream;
|
|
|
|
class InnerDecklistNode;
|
|
|
|
#define DECK_ZONE_MAIN "main"
|
|
#define DECK_ZONE_SIDE "side"
|
|
#define DECK_ZONE_TOKENS "tokens"
|
|
|
|
class SideboardPlan
|
|
{
|
|
private:
|
|
QString name;
|
|
QList<MoveCard_ToZone> moveList;
|
|
|
|
public:
|
|
explicit SideboardPlan(const QString &_name = QString(),
|
|
const QList<MoveCard_ToZone> &_moveList = QList<MoveCard_ToZone>());
|
|
bool readElement(QXmlStreamReader *xml);
|
|
void write(QXmlStreamWriter *xml);
|
|
|
|
QString getName() const
|
|
{
|
|
return name;
|
|
}
|
|
const QList<MoveCard_ToZone> &getMoveList() const
|
|
{
|
|
return moveList;
|
|
}
|
|
void setMoveList(const QList<MoveCard_ToZone> &_moveList);
|
|
};
|
|
|
|
enum DeckSortMethod
|
|
{
|
|
ByNumber,
|
|
ByName,
|
|
Default
|
|
};
|
|
|
|
class AbstractDecklistNode
|
|
{
|
|
protected:
|
|
InnerDecklistNode *parent;
|
|
DeckSortMethod sortMethod;
|
|
|
|
public:
|
|
explicit AbstractDecklistNode(InnerDecklistNode *_parent = nullptr);
|
|
virtual ~AbstractDecklistNode() = default;
|
|
virtual void setSortMethod(DeckSortMethod method)
|
|
{
|
|
sortMethod = method;
|
|
}
|
|
virtual QString getName() const = 0;
|
|
virtual QString getCardProviderId() const = 0;
|
|
virtual QString getCardSetShortName() const = 0;
|
|
virtual QString getCardCollectorNumber() const = 0;
|
|
[[nodiscard]] virtual bool isDeckHeader() const = 0;
|
|
InnerDecklistNode *getParent() const
|
|
{
|
|
return parent;
|
|
}
|
|
int depth() const;
|
|
virtual int height() const = 0;
|
|
virtual bool compare(AbstractDecklistNode *other) const = 0;
|
|
|
|
virtual bool readElement(QXmlStreamReader *xml) = 0;
|
|
virtual void writeElement(QXmlStreamWriter *xml) = 0;
|
|
};
|
|
|
|
class InnerDecklistNode : public AbstractDecklistNode, public QList<AbstractDecklistNode *>
|
|
{
|
|
QString name;
|
|
QString cardSetShortName;
|
|
QString cardCollectorNumber;
|
|
QString cardProviderId;
|
|
class compareFunctor;
|
|
|
|
public:
|
|
explicit InnerDecklistNode(QString _name = QString(), InnerDecklistNode *_parent = nullptr)
|
|
: AbstractDecklistNode(_parent), name(std::move(_name))
|
|
{
|
|
}
|
|
explicit InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = nullptr);
|
|
~InnerDecklistNode() override;
|
|
void setSortMethod(DeckSortMethod method) override;
|
|
[[nodiscard]] QString getName() const override
|
|
{
|
|
return name;
|
|
}
|
|
void setName(const QString &_name)
|
|
{
|
|
name = _name;
|
|
}
|
|
static QString visibleNameFromName(const QString &_name);
|
|
[[nodiscard]] virtual QString getVisibleName() const;
|
|
[[nodiscard]] QString getCardProviderId() const override
|
|
{
|
|
return cardProviderId;
|
|
}
|
|
void setCardProviderId(const QString &_cardProviderId)
|
|
{
|
|
cardProviderId = _cardProviderId;
|
|
}
|
|
[[nodiscard]] QString getCardSetShortName() const override
|
|
{
|
|
return cardSetShortName;
|
|
}
|
|
void setCardSetShortName(const QString &_cardSetShortName)
|
|
{
|
|
cardSetShortName = _cardSetShortName;
|
|
}
|
|
[[nodiscard]] QString getCardCollectorNumber() const override
|
|
{
|
|
return cardCollectorNumber;
|
|
}
|
|
void setCardCollectorNumber(const QString &_cardCollectorNumber)
|
|
{
|
|
cardCollectorNumber = _cardCollectorNumber;
|
|
}
|
|
[[nodiscard]] bool isDeckHeader() const override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void clearTree();
|
|
AbstractDecklistNode *findChild(const QString &_name);
|
|
AbstractDecklistNode *findCardChildByNameAndProviderId(const QString &_name, const QString &_providerId);
|
|
int height() const override;
|
|
int recursiveCount(bool countTotalCards = false) const;
|
|
bool compare(AbstractDecklistNode *other) const override;
|
|
bool compareNumber(AbstractDecklistNode *other) const;
|
|
bool compareName(AbstractDecklistNode *other) const;
|
|
QVector<QPair<int, int>> sort(Qt::SortOrder order = Qt::AscendingOrder);
|
|
|
|
bool readElement(QXmlStreamReader *xml) override;
|
|
void writeElement(QXmlStreamWriter *xml) override;
|
|
};
|
|
|
|
class AbstractDecklistCardNode : public AbstractDecklistNode
|
|
{
|
|
public:
|
|
explicit AbstractDecklistCardNode(InnerDecklistNode *_parent = nullptr) : AbstractDecklistNode(_parent)
|
|
{
|
|
}
|
|
virtual int getNumber() const = 0;
|
|
virtual void setNumber(int _number) = 0;
|
|
QString getName() const override = 0;
|
|
virtual void setName(const QString &_name) = 0;
|
|
virtual QString getCardProviderId() const override = 0;
|
|
virtual void setCardProviderId(const QString &_cardProviderId) = 0;
|
|
virtual QString getCardSetShortName() const override = 0;
|
|
virtual void setCardSetShortName(const QString &_cardSetShortName) = 0;
|
|
virtual QString getCardCollectorNumber() const override = 0;
|
|
virtual void setCardCollectorNumber(const QString &_cardSetNumber) = 0;
|
|
int height() const override
|
|
{
|
|
return 0;
|
|
}
|
|
bool compare(AbstractDecklistNode *other) const override;
|
|
bool compareNumber(AbstractDecklistNode *other) const;
|
|
bool compareName(AbstractDecklistNode *other) const;
|
|
|
|
bool readElement(QXmlStreamReader *xml) override;
|
|
void writeElement(QXmlStreamWriter *xml) override;
|
|
};
|
|
|
|
class DecklistCardNode : public AbstractDecklistCardNode
|
|
{
|
|
QString name;
|
|
int number;
|
|
QString cardSetShortName;
|
|
QString cardSetNumber;
|
|
QString cardProviderId;
|
|
|
|
public:
|
|
explicit DecklistCardNode(QString _name = QString(),
|
|
int _number = 1,
|
|
InnerDecklistNode *_parent = nullptr,
|
|
QString _cardSetShortName = QString(),
|
|
QString _cardSetNumber = QString(),
|
|
QString _cardProviderId = QString())
|
|
: AbstractDecklistCardNode(_parent), name(std::move(_name)), number(_number),
|
|
cardSetShortName(std::move(_cardSetShortName)), cardSetNumber(std::move(_cardSetNumber)),
|
|
cardProviderId(std::move(_cardProviderId))
|
|
{
|
|
}
|
|
explicit DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent);
|
|
int getNumber() const override
|
|
{
|
|
return number;
|
|
}
|
|
void setNumber(int _number) override
|
|
{
|
|
number = _number;
|
|
}
|
|
QString getName() const override
|
|
{
|
|
return name;
|
|
}
|
|
void setName(const QString &_name) override
|
|
{
|
|
name = _name;
|
|
}
|
|
QString getCardProviderId() const override
|
|
{
|
|
return cardProviderId;
|
|
}
|
|
void setCardProviderId(const QString &_providerId) override
|
|
{
|
|
cardProviderId = _providerId;
|
|
}
|
|
|
|
QString getCardSetShortName() const override
|
|
{
|
|
return cardSetShortName;
|
|
}
|
|
void setCardSetShortName(const QString &_cardSetShortName) override
|
|
{
|
|
cardSetShortName = _cardSetShortName;
|
|
}
|
|
QString getCardCollectorNumber() const override
|
|
{
|
|
return cardSetNumber;
|
|
}
|
|
void setCardCollectorNumber(const QString &_cardSetNumber) override
|
|
{
|
|
cardSetNumber = _cardSetNumber;
|
|
}
|
|
[[nodiscard]] bool isDeckHeader() const override
|
|
{
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class DeckList : public QObject
|
|
{
|
|
Q_OBJECT
|
|
private:
|
|
QString name, comments;
|
|
QString deckHash;
|
|
QMap<QString, SideboardPlan *> sideboardPlans;
|
|
InnerDecklistNode *root;
|
|
void getCardListHelper(InnerDecklistNode *node, QSet<QString> &result) const;
|
|
InnerDecklistNode *getZoneObjFromName(const QString &zoneName);
|
|
|
|
protected:
|
|
virtual QString getCardZoneFromName(const QString /*cardName*/, QString currentZoneName)
|
|
{
|
|
return currentZoneName;
|
|
};
|
|
virtual QString getCompleteCardName(const QString &cardName) const
|
|
{
|
|
return cardName;
|
|
};
|
|
|
|
signals:
|
|
void deckHashChanged();
|
|
|
|
public slots:
|
|
void setName(const QString &_name = QString())
|
|
{
|
|
name = _name;
|
|
}
|
|
void setComments(const QString &_comments = QString())
|
|
{
|
|
comments = _comments;
|
|
}
|
|
|
|
public:
|
|
explicit DeckList();
|
|
DeckList(const DeckList &other);
|
|
explicit DeckList(const QString &nativeString);
|
|
~DeckList() override;
|
|
QString getName() const
|
|
{
|
|
return name;
|
|
}
|
|
QString getComments() const
|
|
{
|
|
return comments;
|
|
}
|
|
QList<MoveCard_ToZone> getCurrentSideboardPlan();
|
|
void setCurrentSideboardPlan(const QList<MoveCard_ToZone> &plan);
|
|
const QMap<QString, SideboardPlan *> &getSideboardPlans() const
|
|
{
|
|
return sideboardPlans;
|
|
}
|
|
|
|
bool readElement(QXmlStreamReader *xml);
|
|
void write(QXmlStreamWriter *xml);
|
|
bool loadFromXml(QXmlStreamReader *xml);
|
|
bool loadFromString_Native(const QString &nativeString);
|
|
QString writeToString_Native();
|
|
bool loadFromFile_Native(QIODevice *device);
|
|
bool saveToFile_Native(QIODevice *device);
|
|
bool loadFromStream_Plain(QTextStream &stream);
|
|
bool loadFromFile_Plain(QIODevice *device);
|
|
bool saveToStream_Plain(QTextStream &stream, bool prefixSideboardCards, bool slashTappedOutSplitCards);
|
|
bool saveToFile_Plain(QIODevice *device, bool prefixSideboardCards = true, bool slashTappedOutSplitCards = false);
|
|
QString writeToString_Plain(bool prefixSideboardCards = true, bool slashTappedOutSplitCards = false);
|
|
|
|
void cleanList();
|
|
bool isEmpty() const
|
|
{
|
|
return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty();
|
|
}
|
|
QStringList getCardList() const;
|
|
|
|
int getSideboardSize() const;
|
|
|
|
QString getDeckHash() const
|
|
{
|
|
return deckHash;
|
|
}
|
|
void updateDeckHash();
|
|
|
|
InnerDecklistNode *getRoot() const
|
|
{
|
|
return root;
|
|
}
|
|
DecklistCardNode *addCard(const QString &cardName,
|
|
const QString &zoneName,
|
|
const QString &cardSetName = QString(),
|
|
const QString &cardSetCollectorNumber = QString(),
|
|
const QString &cardProviderId = QString());
|
|
bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = nullptr);
|
|
|
|
/**
|
|
* Calls a given function object for each card in the deck. It must
|
|
* take a InnerDecklistNode* as its first argument and a
|
|
* DecklistCardNode* as its second.
|
|
*/
|
|
template <typename Callback> void forEachCard(Callback &callback) const
|
|
{
|
|
// Support for this is only possible if the internal structure
|
|
// doesn't get more complicated.
|
|
for (int i = 0; i < root->size(); i++) {
|
|
const InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
|
|
for (int j = 0; j < node->size(); j++) {
|
|
const DecklistCardNode *card = dynamic_cast<DecklistCardNode *>(node->at(j));
|
|
callback(node, card);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif |