mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-05 20:39:59 -08:00
[DeckList] Make DeckList not a QObject (#6383)
This commit is contained in:
@@ -424,7 +424,6 @@ void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck)
|
|||||||
deckLoader->setParent(this);
|
deckLoader->setParent(this);
|
||||||
deckModel->setDeckList(deckLoader->getDeckList());
|
deckModel->setDeckList(deckLoader->getDeckList());
|
||||||
connect(deckLoader, &DeckLoader::deckLoaded, deckModel, &DeckListModel::rebuildTree);
|
connect(deckLoader, &DeckLoader::deckLoaded, deckModel, &DeckListModel::rebuildTree);
|
||||||
connect(deckLoader->getDeckList(), &DeckList::deckHashChanged, deckModel, &DeckListModel::deckHashChanged);
|
|
||||||
|
|
||||||
emit requestDeckHistoryClear();
|
emit requestDeckHistoryClear();
|
||||||
historyManagerWidget->setDeckListModel(deckModel);
|
historyManagerWidget->setDeckListModel(deckModel);
|
||||||
@@ -452,7 +451,7 @@ void DeckEditorDeckDockWidget::syncDisplayWidgetsToModel()
|
|||||||
sortDeckModelToDeckView();
|
sortDeckModelToDeckView();
|
||||||
expandAll();
|
expandAll();
|
||||||
|
|
||||||
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList());
|
deckTagsDisplayWidget->setDeckList(deckModel->getDeckList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckEditorDeckDockWidget::sortDeckModelToDeckView()
|
void DeckEditorDeckDockWidget::sortDeckModelToDeckView()
|
||||||
@@ -485,7 +484,7 @@ void DeckEditorDeckDockWidget::cleanDeck()
|
|||||||
emit deckModified();
|
emit deckModified();
|
||||||
emit deckChanged();
|
emit deckChanged();
|
||||||
updateBannerCardComboBox();
|
updateBannerCardComboBox();
|
||||||
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList());
|
deckTagsDisplayWidget->setDeckList(deckModel->getDeckList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckEditorDeckDockWidget::recursiveExpand(const QModelIndex &index)
|
void DeckEditorDeckDockWidget::recursiveExpand(const QModelIndex &index)
|
||||||
|
|||||||
@@ -28,21 +28,15 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_par
|
|||||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||||
|
|
||||||
if (_deckList) {
|
if (_deckList) {
|
||||||
connectDeckList(_deckList);
|
setDeckList(_deckList);
|
||||||
}
|
}
|
||||||
|
|
||||||
layout->addWidget(flowWidget);
|
layout->addWidget(flowWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList)
|
void DeckPreviewDeckTagsDisplayWidget::setDeckList(DeckList *_deckList)
|
||||||
{
|
{
|
||||||
if (deckList) {
|
|
||||||
disconnect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags);
|
|
||||||
}
|
|
||||||
|
|
||||||
deckList = _deckList;
|
deckList = _deckList;
|
||||||
connect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags);
|
|
||||||
|
|
||||||
refreshTags();
|
refreshTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +144,7 @@ void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg()
|
|||||||
QStringList updatedTags = dialog.getActiveTags();
|
QStringList updatedTags = dialog.getActiveTags();
|
||||||
deckList->setTags(updatedTags);
|
deckList->setTags(updatedTags);
|
||||||
deckPreviewWidget->deckLoader->saveToFile(deckPreviewWidget->filePath, DeckLoader::CockatriceFormat);
|
deckPreviewWidget->deckLoader->saveToFile(deckPreviewWidget->filePath, DeckLoader::CockatriceFormat);
|
||||||
|
refreshTags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (parentWidget()) {
|
} else if (parentWidget()) {
|
||||||
@@ -181,6 +176,7 @@ void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg()
|
|||||||
QStringList updatedTags = dialog.getActiveTags();
|
QStringList updatedTags = dialog.getActiveTags();
|
||||||
deckList->setTags(updatedTags);
|
deckList->setTags(updatedTags);
|
||||||
deckEditor->setModified(true);
|
deckEditor->setModified(true);
|
||||||
|
refreshTags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class DeckPreviewDeckTagsDisplayWidget : public QWidget
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList);
|
explicit DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList);
|
||||||
void connectDeckList(DeckList *_deckList);
|
void setDeckList(DeckList *_deckList);
|
||||||
void refreshTags();
|
void refreshTags();
|
||||||
DeckList *deckList;
|
DeckList *deckList;
|
||||||
FlowWidget *flowWidget;
|
FlowWidget *flowWidget;
|
||||||
|
|||||||
@@ -87,6 +87,12 @@ DeckList::DeckList()
|
|||||||
root = new InnerDecklistNode;
|
root = new InnerDecklistNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeckList::DeckList(const DeckList &other)
|
||||||
|
: metadata(other.metadata), sideboardPlans(other.sideboardPlans), root(new InnerDecklistNode(other.getRoot())),
|
||||||
|
cachedDeckHash(other.cachedDeckHash)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
DeckList::DeckList(const QString &nativeString)
|
DeckList::DeckList(const QString &nativeString)
|
||||||
{
|
{
|
||||||
root = new InnerDecklistNode;
|
root = new InnerDecklistNode;
|
||||||
@@ -443,11 +449,8 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
|
|||||||
cardName.replace(diff.key(), diff.value());
|
cardName.replace(diff.key(), diff.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve complete card name, this function does nothing if the name is not found
|
|
||||||
cardName = getCompleteCardName(cardName);
|
|
||||||
|
|
||||||
// Determine the zone (mainboard/sideboard)
|
// Determine the zone (mainboard/sideboard)
|
||||||
QString zoneName = getCardZoneFromName(cardName, sideboard ? DECK_ZONE_SIDE : DECK_ZONE_MAIN);
|
QString zoneName = sideboard ? DECK_ZONE_SIDE : DECK_ZONE_MAIN;
|
||||||
|
|
||||||
// make new entry in decklist
|
// make new entry in decklist
|
||||||
new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), -1, setCode, collectorNumber);
|
new DecklistCardNode(cardName, amount, getZoneObjFromName(zoneName), -1, setCode, collectorNumber);
|
||||||
@@ -708,12 +711,11 @@ QString DeckList::getDeckHash() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates the cached deckHash and emits the deckHashChanged signal.
|
* Invalidates the cached deckHash.
|
||||||
*/
|
*/
|
||||||
void DeckList::refreshDeckHash()
|
void DeckList::refreshDeckHash()
|
||||||
{
|
{
|
||||||
cachedDeckHash = QString();
|
cachedDeckHash = QString();
|
||||||
emit deckHashChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @file decklist.h
|
* @file deck_list.h
|
||||||
* @brief Defines the DeckList class and supporting types for managing a full
|
* @brief Defines the DeckList class and supporting types for managing a full
|
||||||
* deck structure including cards, zones, sideboard plans, and
|
* deck structure including cards, zones, sideboard plans, and
|
||||||
* serialization to/from multiple formats. This is a logic class which
|
* serialization to/from multiple formats. This is a logic class which
|
||||||
@@ -93,7 +93,7 @@ public:
|
|||||||
* @brief Represents a complete deck, including metadata, zones, cards,
|
* @brief Represents a complete deck, including metadata, zones, cards,
|
||||||
* and sideboard plans.
|
* and sideboard plans.
|
||||||
*
|
*
|
||||||
* A DeckList is a QObject wrapper around an `InnerDecklistNode` tree,
|
* A DeckList is a wrapper around an `InnerDecklistNode` tree,
|
||||||
* enriched with metadata like deck name, comments, tags, banner card,
|
* enriched with metadata like deck name, comments, tags, banner card,
|
||||||
* and multiple sideboard plans.
|
* and multiple sideboard plans.
|
||||||
*
|
*
|
||||||
@@ -110,10 +110,6 @@ public:
|
|||||||
* - Owns the root `InnerDecklistNode` tree.
|
* - Owns the root `InnerDecklistNode` tree.
|
||||||
* - Owns `SideboardPlan` instances stored in `sideboardPlans`.
|
* - Owns `SideboardPlan` instances stored in `sideboardPlans`.
|
||||||
*
|
*
|
||||||
* ### Signals:
|
|
||||||
* - @c deckHashChanged() — emitted when the deck contents change.
|
|
||||||
* - @c deckTagsChanged() — emitted when tags are added/removed.
|
|
||||||
*
|
|
||||||
* ### Example workflow:
|
* ### Example workflow:
|
||||||
* ```
|
* ```
|
||||||
* DeckList deck;
|
* DeckList deck;
|
||||||
@@ -123,10 +119,8 @@ public:
|
|||||||
* deck.saveToFile_Native(device);
|
* deck.saveToFile_Native(device);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class DeckList : public QObject
|
class DeckList
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Metadata
|
struct Metadata
|
||||||
{
|
{
|
||||||
@@ -158,37 +152,7 @@ private:
|
|||||||
static void getCardRefListHelper(InnerDecklistNode *item, QList<CardRef> &result);
|
static void getCardRefListHelper(InnerDecklistNode *item, QList<CardRef> &result);
|
||||||
InnerDecklistNode *getZoneObjFromName(const QString &zoneName);
|
InnerDecklistNode *getZoneObjFromName(const QString &zoneName);
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
/**
|
|
||||||
* @brief Map a card name to its zone.
|
|
||||||
* Override in subclasses for format-specific logic.
|
|
||||||
* @param cardName Card being placed.
|
|
||||||
* @param currentZoneName Zone candidate.
|
|
||||||
* @return Zone name to use.
|
|
||||||
*/
|
|
||||||
virtual QString getCardZoneFromName(const QString /*cardName*/, QString currentZoneName)
|
|
||||||
{
|
|
||||||
return currentZoneName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Produce the complete display name of a card.
|
|
||||||
* Override in subclasses to add set suffixes or annotations.
|
|
||||||
* @param cardName Base name.
|
|
||||||
* @return Full display name.
|
|
||||||
*/
|
|
||||||
virtual QString getCompleteCardName(const QString &cardName) const
|
|
||||||
{
|
|
||||||
return cardName;
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
|
||||||
/// Emitted when the deck hash changes.
|
|
||||||
void deckHashChanged();
|
|
||||||
/// Emitted when the deck tags are modified.
|
|
||||||
void deckTagsChanged();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
/// @name Metadata setters
|
/// @name Metadata setters
|
||||||
///@{
|
///@{
|
||||||
void setName(const QString &_name = QString())
|
void setName(const QString &_name = QString())
|
||||||
@@ -202,17 +166,14 @@ public slots:
|
|||||||
void setTags(const QStringList &_tags = QStringList())
|
void setTags(const QStringList &_tags = QStringList())
|
||||||
{
|
{
|
||||||
metadata.tags = _tags;
|
metadata.tags = _tags;
|
||||||
emit deckTagsChanged();
|
|
||||||
}
|
}
|
||||||
void addTag(const QString &_tag)
|
void addTag(const QString &_tag)
|
||||||
{
|
{
|
||||||
metadata.tags.append(_tag);
|
metadata.tags.append(_tag);
|
||||||
emit deckTagsChanged();
|
|
||||||
}
|
}
|
||||||
void clearTags()
|
void clearTags()
|
||||||
{
|
{
|
||||||
metadata.tags.clear();
|
metadata.tags.clear();
|
||||||
emit deckTagsChanged();
|
|
||||||
}
|
}
|
||||||
void setBannerCard(const CardRef &_bannerCard = {})
|
void setBannerCard(const CardRef &_bannerCard = {})
|
||||||
{
|
{
|
||||||
@@ -224,15 +185,13 @@ public slots:
|
|||||||
}
|
}
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
public:
|
|
||||||
/// @brief Construct an empty deck.
|
/// @brief Construct an empty deck.
|
||||||
explicit DeckList();
|
explicit DeckList();
|
||||||
/// @brief Delete copy constructor.
|
/// @brief Copy constructor (deep copies the node tree)
|
||||||
DeckList(const DeckList &) = delete;
|
DeckList(const DeckList &other);
|
||||||
DeckList &operator=(const DeckList &) = delete;
|
|
||||||
/// @brief Construct from a serialized native-format string.
|
/// @brief Construct from a serialized native-format string.
|
||||||
explicit DeckList(const QString &nativeString);
|
explicit DeckList(const QString &nativeString);
|
||||||
~DeckList() override;
|
virtual ~DeckList();
|
||||||
|
|
||||||
/// @name Metadata getters
|
/// @name Metadata getters
|
||||||
/// The individual metadata getters still exist for backwards compatibility.
|
/// The individual metadata getters still exist for backwards compatibility.
|
||||||
|
|||||||
@@ -5,8 +5,11 @@
|
|||||||
DeckListModel::DeckListModel(QObject *parent)
|
DeckListModel::DeckListModel(QObject *parent)
|
||||||
: QAbstractItemModel(parent), lastKnownColumn(1), lastKnownOrder(Qt::AscendingOrder)
|
: QAbstractItemModel(parent), lastKnownColumn(1), lastKnownOrder(Qt::AscendingOrder)
|
||||||
{
|
{
|
||||||
|
// This class will leak the decklist object. We cannot safely delete it in the dtor because the deckList field is a
|
||||||
|
// non-owning pointer and another deckList might have been assigned to it.
|
||||||
|
// `DeckListModel::cleanList` also leaks for the same reason.
|
||||||
|
// TODO: fix the leak
|
||||||
deckList = new DeckList;
|
deckList = new DeckList;
|
||||||
deckList->setParent(this);
|
|
||||||
root = new InnerDecklistNode;
|
root = new InnerDecklistNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,6 +287,7 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, con
|
|||||||
|
|
||||||
emitRecursiveUpdates(index);
|
emitRecursiveUpdates(index);
|
||||||
deckList->refreshDeckHash();
|
deckList->refreshDeckHash();
|
||||||
|
emit deckHashChanged();
|
||||||
|
|
||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
return true;
|
return true;
|
||||||
@@ -422,6 +426,7 @@ QModelIndex DeckListModel::addCard(const ExactCard &card, const QString &zoneNam
|
|||||||
cardNode->setCardCollectorNumber(printingInfo.getProperty("num"));
|
cardNode->setCardCollectorNumber(printingInfo.getProperty("num"));
|
||||||
cardNode->setCardProviderId(printingInfo.getProperty("uuid"));
|
cardNode->setCardProviderId(printingInfo.getProperty("uuid"));
|
||||||
deckList->refreshDeckHash();
|
deckList->refreshDeckHash();
|
||||||
|
emit deckHashChanged();
|
||||||
}
|
}
|
||||||
sort(lastKnownColumn, lastKnownOrder);
|
sort(lastKnownColumn, lastKnownOrder);
|
||||||
emitRecursiveUpdates(parentIndex);
|
emitRecursiveUpdates(parentIndex);
|
||||||
|
|||||||
Reference in New Issue
Block a user