From b0b244a342da64adbb8928798e2aa2399ff7ac7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Fri, 13 Jun 2025 01:58:21 +0200 Subject: [PATCH] Functional stuff. --- .../card_group_display_widget.cpp | 31 +++-- .../card_group_display_widget.h | 1 + .../flat_card_group_display_widget.cpp | 16 ++- .../overlapped_card_group_display_widget.cpp | 13 ++ .../cards/deck_card_zone_display_widget.cpp | 124 +++++++++--------- .../cards/deck_card_zone_display_widget.h | 4 + .../visual_deck_editor_widget.cpp | 17 ++- .../visual_deck_editor_widget.h | 2 + cockatrice/src/deck/deck_list_model.cpp | 40 +++++- cockatrice/src/deck/deck_list_model.h | 1 + 10 files changed, 167 insertions(+), 82 deletions(-) diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp index b6a4264bc..eb84af2e7 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp @@ -28,17 +28,17 @@ CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent, layout->addWidget(banner); qInfo() << "Tracked index (default CardGroupDisplayWidget): " << cardGroupCategory << " (" << zoneName << ")" - << "_trackedIndex.isValid()=" << _trackedIndex.isValid() - << "row=" << _trackedIndex.row() - << "column=" << _trackedIndex.column() - << "parent(row)=" << _trackedIndex.parent().row() - << "parent(column)=" << _trackedIndex.parent().column(); + << "_trackedIndex.isValid()=" << _trackedIndex.isValid() << "row=" << _trackedIndex.row() + << "column=" << _trackedIndex.column() << "parent(row)=" << _trackedIndex.parent().row() + << "parent(column)=" << _trackedIndex.parent().column(); - connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition); - connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval); + // CardGroupDisplayWidget::updateCardDisplays(); + + // connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition); + // connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval); } -QWidget* CardGroupDisplayWidget::constructWidgetForIndex(int rowIndex) +QWidget *CardGroupDisplayWidget::constructWidgetForIndex(int rowIndex) { QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(rowIndex, 0, trackedIndex)); @@ -73,13 +73,15 @@ void CardGroupDisplayWidget::updateCardDisplays() void CardGroupDisplayWidget::onCardAddition(const QModelIndex &parent, int first, int last) { + if (!trackedIndex.isValid()) { + emit cleanupRequested(this); + return; + } if (parent == trackedIndex) { qInfo() << "Tracked index (default CardGroupDisplayWidget): " << cardGroupCategory << " (" << zoneName << ")" - << "_trackedIndex.isValid()=" << trackedIndex.isValid() - << "row=" << trackedIndex.row() - << "column=" << trackedIndex.column() - << "parent(row)=" << trackedIndex.parent().row() - << "parent(column)=" << trackedIndex.parent().column(); + << "_trackedIndex.isValid()=" << trackedIndex.isValid() << "row=" << trackedIndex.row() + << "column=" << trackedIndex.column() << "parent(row)=" << trackedIndex.parent().row() + << "parent(column)=" << trackedIndex.parent().column(); qInfo() << "Card addition to " << cardGroupCategory; for (int i = first; i <= last; i++) { insertIntoLayout(constructWidgetForIndex(i), i); @@ -101,6 +103,9 @@ void CardGroupDisplayWidget::onCardRemoval(const QModelIndex &parent, int first, indexToWidgetMap.remove(idx); } } + if (!trackedIndex.isValid()) { + emit cleanupRequested(this); + } } } diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h index 244d4f5c9..f6179f0d6 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.h @@ -47,6 +47,7 @@ public slots: signals: void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); void cardHovered(CardInfoPtr card); + void cleanupRequested(CardGroupDisplayWidget *cardGroupDisplayWidget); protected: QVBoxLayout *layout; diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp index a3f0fe392..1aaed191e 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp @@ -31,12 +31,24 @@ FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent, banner->setBuddy(flowWidget); layout->addWidget(flowWidget); + + for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) { + FlatCardGroupDisplayWidget::removeFromLayout(indexToWidgetMap.value(idx)); + indexToWidgetMap.value(idx)->deleteLater(); + indexToWidgetMap.remove(idx); + } + qInfo() << "Initialized a flat CardGroupDisplayWidget"; FlatCardGroupDisplayWidget::updateCardDisplays(); // connect(deckListModel, &DeckListModel::dataChanged, this, &FlatCardGroupDisplayWidget::updateCardDisplays); + disconnect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition); + disconnect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval); + + connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &FlatCardGroupDisplayWidget::onCardAddition); + connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &FlatCardGroupDisplayWidget::onCardRemoval); } -QWidget* FlatCardGroupDisplayWidget::constructWidgetForIndex(int row) +QWidget *FlatCardGroupDisplayWidget::constructWidgetForIndex(int row) { QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(row, 0, trackedIndex)); @@ -59,8 +71,6 @@ QWidget* FlatCardGroupDisplayWidget::constructWidgetForIndex(int row) return widget; } - - void FlatCardGroupDisplayWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); diff --git a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp index 4c0687a37..3565a14df 100644 --- a/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp @@ -30,11 +30,24 @@ OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *pare banner->setBuddy(overlapWidget); layout->addWidget(overlapWidget); + + for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) { + OverlappedCardGroupDisplayWidget::removeFromLayout(indexToWidgetMap.value(idx)); + indexToWidgetMap.value(idx)->deleteLater(); + indexToWidgetMap.remove(idx); + } + qInfo() << "Initialized an overlap CardGroupDisplayWidget"; OverlappedCardGroupDisplayWidget::updateCardDisplays(); connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, this, [this]() { overlapWidget->adjustMaxColumnsAndRows(); }); + + disconnect(deckListModel, &QAbstractItemModel::rowsInserted, this, &CardGroupDisplayWidget::onCardAddition); + disconnect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &CardGroupDisplayWidget::onCardRemoval); + + connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &OverlappedCardGroupDisplayWidget::onCardAddition); + connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &OverlappedCardGroupDisplayWidget::onCardRemoval); } void OverlappedCardGroupDisplayWidget::resizeEvent(QResizeEvent *event) diff --git a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp index d165982f4..c44b69c62 100644 --- a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp @@ -45,50 +45,80 @@ DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent, << "parent(row)=" << _trackedIndex.parent().row() << "parent(column)=" << _trackedIndex.parent().column() << "parent(valid)=" << _trackedIndex.parent().isValid(); } - qInfo() << "Cleaning up invalid card group " << displayWidget->cardGroupCategory << " from " << displayWidget->zoneName; + +void DeckCardZoneDisplayWidget::cleanupInvalidCardGroup(CardGroupDisplayWidget *displayWidget) +{ + qInfo() << "Cleaning up invalid card group " << displayWidget->cardGroupCategory << " from " + << displayWidget->zoneName; + cardGroupLayout->removeWidget(displayWidget); + for (auto idx : indexToWidgetMap.keys()) { + if (!idx.isValid()) { + indexToWidgetMap.remove(idx); + } + } + displayWidget->deleteLater(); qInfo() << "Cleaned."; +} + +void DeckCardZoneDisplayWidget::constructAppropriateWidget(QPersistentModelIndex index) +{ + auto categoryName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); + if (indexToWidgetMap.contains(index)) { qInfo() << categoryName << " is already contained in the index to widget map"; + return; + } else { qInfo() << categoryName << " needs a widget"; + } + if (displayType == "overlap") { qInfo() << "It's getting an overlap widget."; + auto *display_widget = new OverlappedCardGroupDisplayWidget( + cardGroupContainer, deckListModel, index, zoneName, categoryName, activeGroupCriteria, activeSortCriteria, + subBannerOpacity, cardSizeWidget); + connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, + SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); + connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); + connect(display_widget, &CardGroupDisplayWidget::cleanupRequested, this, + &DeckCardZoneDisplayWidget::cleanupInvalidCardGroup); + cardGroupLayout->addWidget(display_widget); + indexToWidgetMap.insert(index, display_widget); + } else if (displayType == "flat") { qInfo() << "Getting a flat widget for christmas"; + auto *display_widget = + new FlatCardGroupDisplayWidget(cardGroupContainer, deckListModel, index, zoneName, categoryName, + activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); + connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, + SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); + connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); + connect(display_widget, &CardGroupDisplayWidget::cleanupRequested, this, + &DeckCardZoneDisplayWidget::cleanupInvalidCardGroup); + cardGroupLayout->addWidget(display_widget); + indexToWidgetMap.insert(index, display_widget); + } +} + +void DeckCardZoneDisplayWidget::displayCards() +{ qInfo() << "Constructing Group Display Widgets for Zone Display widget"; qInfo() << deckListModel->data(trackedIndex.sibling(trackedIndex.row(), 1), Qt::EditRole).toString() << " has " << deckListModel->rowCount(trackedIndex.sibling(trackedIndex.row(), 0)) << " entries."; + for (int i = 0; i < deckListModel->rowCount(trackedIndex); ++i) { + QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, trackedIndex)); + constructAppropriateWidget(index); + } +} void DeckCardZoneDisplayWidget::onCategoryAddition(const QModelIndex &parent, int first, int last) { + if (!trackedIndex.isValid()) { + emit requestCleanup(this); + } if (parent == trackedIndex) { qInfo() << deckListModel->data(trackedIndex.sibling(trackedIndex.row(), 1), Qt::EditRole).toString() << " zone thinks it has a new category"; for (int i = first; i <= last; i++) { QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, trackedIndex)); - if (indexToWidgetMap.contains(index)) { - continue; - } - - auto categoryName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); - qInfo() << categoryName; - - if (displayType == "overlap") { - auto *display_widget = new OverlappedCardGroupDisplayWidget( - cardGroupContainer, deckListModel, index, zoneName, categoryName, - activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), - this, SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); - connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - cardGroupLayout->addWidget(display_widget); - indexToWidgetMap.insert(index, display_widget); - } else if (displayType == "flat") { - auto *display_widget = new FlatCardGroupDisplayWidget( - cardGroupContainer, deckListModel, index, zoneName, categoryName, - activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), - this, SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); - connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - cardGroupLayout->addWidget(display_widget); - indexToWidgetMap.insert(index, display_widget); - } + constructAppropriateWidget(index); } } } @@ -105,6 +135,9 @@ void DeckCardZoneDisplayWidget::onCategoryRemoval(const QModelIndex &parent, int indexToWidgetMap.remove(idx); } } + if (!trackedIndex.isValid()) { + emit requestCleanup(this); + } } void DeckCardZoneDisplayWidget::resizeEvent(QResizeEvent *event) @@ -126,42 +159,7 @@ void DeckCardZoneDisplayWidget::onHover(CardInfoPtr card) emit cardHovered(card); } -void DeckCardZoneDisplayWidget::displayCards() -{ - qInfo() << "Constructing Group Display Widgets for Zone Display widget"; - qInfo() << deckListModel->data(trackedIndex.sibling(trackedIndex.row(), 1), Qt::EditRole).toString() << " has " << deckListModel->rowCount(trackedIndex.sibling(trackedIndex.row(), 0)) << " entries."; - for (int i = 0; i < deckListModel->rowCount(trackedIndex); ++i) { - QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, trackedIndex)); - - if (indexToWidgetMap.contains(index)) { - continue; - } - auto categoryName = deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(); - qInfo() << categoryName; - - if (displayType == "overlap") { - auto *display_widget = new OverlappedCardGroupDisplayWidget( - cardGroupContainer, deckListModel, index, zoneName, categoryName, - activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, - SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); - connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - cardGroupLayout->addWidget(display_widget); - indexToWidgetMap.insert(index, display_widget); - } else if (displayType == "flat") { - auto *display_widget = new FlatCardGroupDisplayWidget( - cardGroupContainer, deckListModel, index, zoneName, categoryName, - activeGroupCriteria, activeSortCriteria, subBannerOpacity, cardSizeWidget); - connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this, - SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *))); - connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr))); - cardGroupLayout->addWidget(display_widget); - indexToWidgetMap.insert(index, display_widget); - } - } -} - -void DeckCardZoneDisplayWidget::refreshDisplayType(const DisplayType &_displayType) +void DeckCardZoneDisplayWidget::refreshDisplayType(const QString &_displayType) { displayType = _displayType; QLayoutItem *item; diff --git a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h index 2c0f9c929..7da726023 100644 --- a/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h +++ b/cockatrice/src/client/ui/widgets/cards/deck_card_zone_display_widget.h @@ -6,6 +6,7 @@ #include "../general/display/banner_widget.h" #include "../general/layout_containers/overlap_widget.h" #include "../visual_deck_editor/visual_deck_editor_widget.h" +#include "card_group_display_widgets/card_group_display_widget.h" #include "card_info_picture_with_text_overlay_widget.h" #include "card_size_widget.h" @@ -36,6 +37,8 @@ public: public slots: void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card); void onHover(CardInfoPtr card); + void cleanupInvalidCardGroup(CardGroupDisplayWidget *displayWidget); + void constructAppropriateWidget(QPersistentModelIndex index); void displayCards(); void refreshDisplayType(const DisplayType &displayType); void onActiveGroupCriteriaChanged(QString activeGroupCriteria); @@ -48,6 +51,7 @@ signals: void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card, QString zoneName); void cardHovered(CardInfoPtr card); void activeSortCriteriaChanged(QStringList activeSortCriteria); + void requestCleanup(DeckCardZoneDisplayWidget *displayWidget); private: QString activeGroupCriteria; diff --git a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp index b73cdf028..8a954c666 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp @@ -198,8 +198,19 @@ void VisualDeckEditorWidget::retranslateUi() displayTypeButton->setToolTip( tr("Change how cards are displayed within zones (i.e. overlapped or fully visible.)")); } + +void VisualDeckEditorWidget::cleanupInvalidZones(DeckCardZoneDisplayWidget *displayWidget) +{ qInfo() << "Cleaning up invalid card zone " << displayWidget->zoneName; + zoneContainerLayout->removeWidget(displayWidget); + for (auto idx : indexToWidgetMap.keys()) { + if (!idx.isValid()) { + indexToWidgetMap.remove(idx); + } + } + displayWidget->deleteLater(); qInfo() << "Cleaned."; +} void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first, int last) { @@ -218,6 +229,8 @@ void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first activeSortCriteria, 20, 10, cardSizeWidget); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this, &VisualDeckEditorWidget::onCardClick); + connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::requestCleanup, this, + &VisualDeckEditorWidget::cleanupInvalidZones); connect(this, &VisualDeckEditorWidget::activeSortCriteriaChanged, zoneDisplayWidget, &DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged); connect(this, &VisualDeckEditorWidget::activeGroupCriteriaChanged, zoneDisplayWidget, @@ -249,7 +262,7 @@ void VisualDeckEditorWidget::onCardRemoval(const QModelIndex &parent, int first, void VisualDeckEditorWidget::constructZoneWidgetsFromDeckListModel() { qInfo() << "Constructing zone widgets"; - for (int i = 0; i < deckListModel->rowCount(deckListModel->parent(QModelIndex())); ++i) { + for (int i = 0; i < deckListModel->rowCount(deckListModel->parent(QModelIndex())); i++) { QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, deckListModel->getRoot())); if (indexToWidgetMap.contains(index)) { @@ -263,6 +276,8 @@ void VisualDeckEditorWidget::constructZoneWidgetsFromDeckListModel() activeSortCriteria, 20, 10, cardSizeWidget); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover); connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this, &VisualDeckEditorWidget::onCardClick); + connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::requestCleanup, this, + &VisualDeckEditorWidget::cleanupInvalidZones); connect(this, &VisualDeckEditorWidget::activeSortCriteriaChanged, zoneDisplayWidget, &DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged); connect(this, &VisualDeckEditorWidget::activeGroupCriteriaChanged, zoneDisplayWidget, diff --git a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h index b8f195baa..d62b2ca42 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h +++ b/cockatrice/src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.h @@ -17,6 +17,7 @@ #include #include +class DeckCardZoneDisplayWidget; enum class DisplayType { Flat, @@ -41,6 +42,7 @@ public slots: void decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight); void updateZoneWidgets(); void updateDisplayType(); + void cleanupInvalidZones(DeckCardZoneDisplayWidget *displayWidget); void onCardAddition(const QModelIndex &parent, int first, int last); void onCardRemoval(const QModelIndex &parent, int first, int last); void constructZoneWidgetsFromDeckListModel(); diff --git a/cockatrice/src/deck/deck_list_model.cpp b/cockatrice/src/deck/deck_list_model.cpp index eeb7c49da..444c56e9c 100644 --- a/cockatrice/src/deck/deck_list_model.cpp +++ b/cockatrice/src/deck/deck_list_model.cpp @@ -410,7 +410,10 @@ QModelIndex DeckListModel::addCard(const QString &cardName, if (!cardNode) { auto *decklistCard = deckList->addCard(cardInfo->getName(), zoneName, cardSetName, cardInfoSet.getProperty("num"), cardInfoSet.getProperty("uuid")); - beginInsertRows(parentIndex, static_cast(cardTypeNode->size()), static_cast(cardTypeNode->size())); + // Determine the correct index + int insertRow = findSortedInsertRow(cardTypeNode, cardNode); + + beginInsertRows(parentIndex, insertRow, insertRow); cardNode = new DecklistModelCardNode(decklistCard, cardTypeNode); endInsertRows(); } else { @@ -420,11 +423,44 @@ QModelIndex DeckListModel::addCard(const QString &cardName, cardNode->setCardProviderId(cardInfoSet.getProperty("uuid")); deckList->refreshDeckHash(); } - sort(lastKnownColumn, lastKnownOrder); + // sort(lastKnownColumn, lastKnownOrder); emitRecursiveUpdates(parentIndex); return nodeToIndex(cardNode); } +int DeckListModel::findSortedInsertRow(InnerDecklistNode *parent, AbstractDecklistNode *newNode) const +{ + auto *newCard = dynamic_cast(newNode); + if (!newCard) + return parent->size(); // fallback: append at end + + for (int i = 0; i < parent->size(); ++i) { + auto *existingCard = dynamic_cast(parent->at(i)); + if (!existingCard) + continue; + + bool lessThan = false; + switch (lastKnownColumn) { + case 0: // ByNumber + lessThan = lastKnownOrder == Qt::AscendingOrder + ? newCard->getCardCollectorNumber() < existingCard->getCardCollectorNumber() + : newCard->getCardCollectorNumber() > existingCard->getCardCollectorNumber(); + break; + case 1: // ByName + default: + lessThan = lastKnownOrder == Qt::AscendingOrder + ? newCard->getName().localeAwareCompare(existingCard->getName()) < 0 + : newCard->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) { diff --git a/cockatrice/src/deck/deck_list_model.h b/cockatrice/src/deck/deck_list_model.h index 3bca6f3df..d4129bb19 100644 --- a/cockatrice/src/deck/deck_list_model.h +++ b/cockatrice/src/deck/deck_list_model.h @@ -115,6 +115,7 @@ public: const CardInfoPerSet &cardInfoSet, const QString &zoneName, bool abAddAnyway = false); + int findSortedInsertRow(InnerDecklistNode *parent, AbstractDecklistNode *newNode) const; void sort(int column, Qt::SortOrder order) override; void cleanList(); DeckLoader *getDeckList() const