mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-01-24 18:34:49 -08:00
Compare commits
12 Commits
tooomm-tra
...
2026-01-05
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b86853b65c | ||
|
|
192dac0396 | ||
|
|
85c9d8a9ff | ||
|
|
ee2699413c | ||
|
|
d50297bbe6 | ||
|
|
489ce416c3 | ||
|
|
731c487ccb | ||
|
|
2d5e8deb75 | ||
|
|
746f2af044 | ||
|
|
f16c552d97 | ||
|
|
72a85b58cf | ||
|
|
b88a98b09a |
@@ -156,6 +156,18 @@ function ccachestatsverbose() {
|
||||
|
||||
# Compile
|
||||
if [[ $RUNNER_OS == macOS ]]; then
|
||||
# QTDIR is needed for macOS since we actually only use the cached thin Qt binaries instead of the install-qt-action,
|
||||
# which sets a few environment variables
|
||||
if QTDIR=$(find "$GITHUB_WORKSPACE/Qt" -depth -maxdepth 2 -name macos -type d -print -quit); then
|
||||
echo "found QTDIR at $QTDIR"
|
||||
else
|
||||
echo "could not find QTDIR!"
|
||||
exit 2
|
||||
fi
|
||||
# the qtdir is located at Qt/[qtversion]/macos
|
||||
# we use find to get the first subfolder with the name "macos"
|
||||
# this works independent of the qt version as there should be only one version installed on the runner at a time
|
||||
export QTDIR
|
||||
|
||||
if [[ $TARGET_MACOS_VERSION ]]; then
|
||||
# CMAKE_OSX_DEPLOYMENT_TARGET is a vanilla cmake flag needed to compile to target macOS version
|
||||
|
||||
40
.ci/resolve_latest_aqt_qt_version.sh
Executable file
40
.ci/resolve_latest_aqt_qt_version.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script is used to resolve the latest patch version of Qt using aqtinstall.
|
||||
# It interprets wildcards to get the latest patch version. E.g. "6.6.*" -> "6.6.3".
|
||||
|
||||
# This script is meant to be used by the ci enironment.
|
||||
# It uses the runner's GITHUB_OUTPUT env variable.
|
||||
|
||||
# Usage example: .ci/resolve_latest_aqt_qt_version.sh "6.6.*"
|
||||
|
||||
qt_spec=$1
|
||||
if [[ ! $qt_spec ]]; then
|
||||
echo "usage: $0 [version]"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# If version is already specific (no wildcard), use it as-is
|
||||
if [[ $qt_spec != *"*" ]]; then
|
||||
echo "version $qt_spec is already resolved"
|
||||
echo "version=$qt_spec" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! hash aqt; then
|
||||
echo "aqt could not be found, has aqtinstall been installed?"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Resolve latest patch
|
||||
if ! qt_resolved=$(aqt list-qt mac desktop --spec "$qt_spec" --latest-version); then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "resolved $qt_spec to $qt_resolved"
|
||||
if [[ ! $qt_resolved ]]; then
|
||||
echo "Error: Could not resolve Qt version for $qt_spec"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "version=$qt_resolved" >> "$GITHUB_OUTPUT"
|
||||
25
.ci/thin_macos_qtlib.sh
Executable file
25
.ci/thin_macos_qtlib.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The macos binaries from aqt are fat (universal), so we thin them to the target architecture to reduce the size of
|
||||
# the packages and caches using lipo.
|
||||
|
||||
# This script is meant to be used by the ci enironment on macos runners only.
|
||||
# It uses the runner's GITHUB_WORKSPACE env variable.
|
||||
arch=$(uname -m)
|
||||
nproc=$(sysctl -n hw.ncpu)
|
||||
|
||||
function thin() {
|
||||
local libfile=$1
|
||||
if [[ $(file -b --mime-type "$libfile") == application/x-mach-binary* ]]; then
|
||||
echo "Processing $libfile"
|
||||
lipo "$libfile" -thin "$arch" -output "$libfile"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
export -f thin # export to allow use in xargs
|
||||
export arch
|
||||
set -eo pipefail
|
||||
|
||||
echo "::group::Thinning Qt libraries to $arch using $nproc cores"
|
||||
find "$GITHUB_WORKSPACE/Qt" -type f -print0 | xargs -0 -n1 -P"$nproc" -I{} bash -c "thin '{}'"
|
||||
echo "::endgroup::"
|
||||
54
.github/workflows/desktop-build.yml
vendored
54
.github/workflows/desktop-build.yml
vendored
@@ -262,7 +262,6 @@ jobs:
|
||||
qt_version: 6.6.*
|
||||
qt_arch: clang_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: false # qt caches take too much space for macOS (1.1Gi)
|
||||
cmake_generator: Ninja
|
||||
use_ccache: 1
|
||||
|
||||
@@ -278,7 +277,6 @@ jobs:
|
||||
qt_version: 6.6.*
|
||||
qt_arch: clang_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: false
|
||||
cmake_generator: Ninja
|
||||
use_ccache: 1
|
||||
|
||||
@@ -294,7 +292,6 @@ jobs:
|
||||
qt_version: 6.6.*
|
||||
qt_arch: clang_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: false
|
||||
cmake_generator: Ninja
|
||||
use_ccache: 1
|
||||
|
||||
@@ -307,7 +304,6 @@ jobs:
|
||||
qt_version: 6.6.*
|
||||
qt_arch: clang_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: false
|
||||
cmake_generator: Ninja
|
||||
use_ccache: 1
|
||||
|
||||
@@ -320,7 +316,6 @@ jobs:
|
||||
artifact_name: Windows7-installer
|
||||
qt_version: 5.15.*
|
||||
qt_arch: win64_msvc2019_64
|
||||
cache_qt: true
|
||||
cmake_generator: "Visual Studio 17 2022"
|
||||
cmake_generator_platform: x64
|
||||
|
||||
@@ -334,7 +329,6 @@ jobs:
|
||||
qt_version: 6.6.*
|
||||
qt_arch: win64_msvc2019_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: true
|
||||
cmake_generator: "Visual Studio 17 2022"
|
||||
cmake_generator_platform: x64
|
||||
|
||||
@@ -375,13 +369,57 @@ jobs:
|
||||
key: ccache-${{matrix.runner}}-${{matrix.soc}}-${{matrix.type}}-${{env.BRANCH_NAME}}
|
||||
restore-keys: ccache-${{matrix.runner}}-${{matrix.soc}}-${{matrix.type}}-
|
||||
|
||||
- name: Install Qt ${{matrix.qt_version}}
|
||||
- name: Install aqtinstall
|
||||
if: matrix.os == 'macOS'
|
||||
run: pipx install aqtinstall
|
||||
|
||||
# Checking if there's a newer, uncached version of Qt available to install via aqtinstall
|
||||
- name: Resolve latest Qt patch version
|
||||
if: matrix.os == 'macOS'
|
||||
id: resolve_qt_version
|
||||
shell: bash
|
||||
# Ouputs the version of Qt to install via aqtinstall
|
||||
run: .ci/resolve_latest_aqt_qt_version.sh "${{matrix.qt_version}}"
|
||||
|
||||
- name: Restore thin Qt ${{ steps.resolve_qt_version.outputs.version }} libraries (${{ matrix.soc }} macOS)
|
||||
if: matrix.os == 'macOS'
|
||||
id: restore_qt
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: ${{ github.workspace }}/Qt
|
||||
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
|
||||
|
||||
# Using jurplel/install-qt-action to install Qt without using brew
|
||||
# qt build using vcpkg either just fails or takes too long to build
|
||||
- name: Install fat Qt ${{ steps.resolve_qt_version.outputs.version }} (${{ matrix.soc }} macOS)
|
||||
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
cache: false
|
||||
version: ${{ steps.resolve_qt_version.outputs.version }}
|
||||
arch: ${{matrix.qt_arch}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
dir: ${{github.workspace}}
|
||||
|
||||
- name: Thin Qt libraries (${{ matrix.soc }} macOS)
|
||||
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
||||
run: .ci/thin_macos_qtlib.sh
|
||||
|
||||
- name: Cache thin Qt libraries (${{ matrix.soc }} macOS)
|
||||
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: ${{ github.workspace }}/Qt
|
||||
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
|
||||
|
||||
- name: Install Qt ${{matrix.qt_version}} (Windows)
|
||||
if: matrix.os == 'Windows'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: ${{matrix.qt_version}}
|
||||
arch: ${{matrix.qt_arch}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
cache: ${{matrix.cache_qt}}
|
||||
cache: true
|
||||
|
||||
- name: Setup vcpkg cache
|
||||
id: vcpkg-cache
|
||||
|
||||
@@ -170,6 +170,7 @@ set(cockatrice_SOURCES
|
||||
src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.cpp
|
||||
src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_list_history_manager_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_editor_database_display_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp
|
||||
|
||||
@@ -29,6 +29,11 @@ searches are case insensitive.
|
||||
<dt><u>F</u>ormat:</dt>
|
||||
<dd>[f:standard](#f:standard) <small>(Any deck with format set to standard)</small></dd>
|
||||
|
||||
<dt><u>C</u>omments:</dt>
|
||||
<dd>[c:good](#c:good) <small>(Any deck with comments containing the word good)</small></dd>
|
||||
<dd>[c:good c:deck](#c:good c:deck) <small>(Any deck with comments containing the words good and deck)</small></dd>
|
||||
<dd>[c:"good deck"](#c:%22good deck%22) <small>(Any deck with comments containing the exact phrase "good deck")</small></dd>
|
||||
|
||||
<dt>Deck Contents (Uses [card search expressions](#cardSearchSyntaxHelp)):</dt>
|
||||
<dd><a href="#[[plains]]">[[plains]]</a> <small>(Any deck that contains at least one card with "plains" in its name)</small></dd>
|
||||
<dd><a href="#[[t:legendary]]">[[t:legendary]]</a> <small>(Any deck that contains at least one legendary)</small></dd>
|
||||
|
||||
@@ -13,7 +13,7 @@ QueryPartList <- ComplexQueryPart ( ws ("AND" ws)? ComplexQueryPart)* ws*
|
||||
ComplexQueryPart <- SomewhatComplexQueryPart ws "OR" ws ComplexQueryPart / SomewhatComplexQueryPart
|
||||
SomewhatComplexQueryPart <- [(] QueryPartList [)] / QueryPart
|
||||
|
||||
QueryPart <- NotQuery / DeckContentQuery / DeckNameQuery / FileNameQuery / PathQuery / FormatQuery / GenericQuery
|
||||
QueryPart <- NotQuery / DeckContentQuery / DeckNameQuery / FileNameQuery / PathQuery / FormatQuery / CommentQuery / GenericQuery
|
||||
|
||||
NotQuery <- ('NOT' ws/'-') SomewhatComplexQueryPart
|
||||
|
||||
@@ -25,6 +25,7 @@ DeckNameQuery <- ([Dd] 'eck')? [Nn] 'ame'? [:] String
|
||||
FileNameQuery <- [Ff] ([Nn] / 'ile' ([Nn] 'ame')?) [:] String
|
||||
PathQuery <- [Pp] 'ath'? [:] String
|
||||
FormatQuery <- [Ff] 'ormat'? [:] String
|
||||
CommentQuery <- [Cc] ('omment' 's'?)? [:] String
|
||||
|
||||
GenericQuery <- String
|
||||
|
||||
@@ -166,6 +167,14 @@ static void setupParserRules()
|
||||
};
|
||||
};
|
||||
|
||||
search["CommentQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto value = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
auto comments = deck->deckLoader->getDeck().deckList.getComments();
|
||||
return comments.contains(value, Qt::CaseInsensitive);
|
||||
};
|
||||
};
|
||||
|
||||
search["GenericQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
auto name = std::any_cast<QString>(sv[0]);
|
||||
return [=](const DeckPreviewWidget *deck, const ExtraDeckSearchInfo &) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "card_group_display_widgets/flat_card_group_display_widget.h"
|
||||
#include "card_group_display_widgets/overlapped_card_group_display_widget.h"
|
||||
#include "libcockatrice/card/database/card_database_manager.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <libcockatrice/models/deck_list/deck_list_model.h>
|
||||
@@ -230,10 +231,13 @@ QList<QString> DeckCardZoneDisplayWidget::getGroupCriteriaValueList()
|
||||
{
|
||||
QList<QString> groupCriteriaValues;
|
||||
|
||||
QList<ExactCard> cardsInZone = deckListModel->getCardsForZone(zoneName);
|
||||
QList<const DecklistCardNode *> nodes = deckListModel->getCardNodesForZone(zoneName);
|
||||
|
||||
for (const ExactCard &cardInZone : cardsInZone) {
|
||||
groupCriteriaValues.append(cardInZone.getInfo().getProperty(activeGroupCriteria));
|
||||
for (auto node : nodes) {
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(node->getName());
|
||||
if (info) {
|
||||
groupCriteriaValues.append(info->getProperty(activeGroupCriteria));
|
||||
}
|
||||
}
|
||||
|
||||
groupCriteriaValues.removeDuplicates();
|
||||
|
||||
@@ -19,7 +19,8 @@ AbstractAnalyticsPanelWidget::AbstractAnalyticsPanelWidget(QWidget *parent, Deck
|
||||
bannerAndSettingsLayout->addWidget(bannerWidget, 1);
|
||||
|
||||
// config button
|
||||
configureButton = new QPushButton(tr("Configure"), this);
|
||||
configureButton = new QPushButton(this);
|
||||
configureButton->setIcon(QPixmap("theme:icons/cogwheel"));
|
||||
configureButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
connect(configureButton, &QPushButton::clicked, this, &AbstractAnalyticsPanelWidget::applyConfigFromDialog);
|
||||
bannerAndSettingsLayout->addWidget(configureButton, 0);
|
||||
|
||||
@@ -170,7 +170,7 @@ void DrawProbabilityWidget::updateFilterOptions()
|
||||
|
||||
const auto nodes = analyzer->getModel()->getCardNodes();
|
||||
for (auto *node : nodes) {
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCard({node->getName()}).getCardPtr();
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(node->getName());
|
||||
if (!info) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -12,89 +12,98 @@ DeckListStatisticsAnalyzer::DeckListStatisticsAnalyzer(QObject *parent,
|
||||
DeckListStatisticsAnalyzerConfig _config)
|
||||
: QObject(parent), model(_model), config(_config)
|
||||
{
|
||||
connect(model, &DeckListModel::dataChanged, this, &DeckListStatisticsAnalyzer::analyze);
|
||||
connect(model, &DeckListModel::cardsChanged, this, &DeckListStatisticsAnalyzer::analyze);
|
||||
}
|
||||
|
||||
void DeckListStatisticsAnalyzer::analyze()
|
||||
{
|
||||
clearData();
|
||||
|
||||
QList<ExactCard> cards = model->getCards();
|
||||
QList<const DecklistCardNode *> nodes = model->getCardNodes();
|
||||
|
||||
for (auto card : cards) {
|
||||
auto info = card.getInfo();
|
||||
const int cmc = info.getCmc().toInt();
|
||||
for (auto node : nodes) {
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(node->getName());
|
||||
if (!info) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int amount = node->getNumber();
|
||||
QStringList copiesOfName;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
copiesOfName.append(node->getName());
|
||||
}
|
||||
|
||||
// Convert once
|
||||
QStringList types = info.getMainCardType().split(' ');
|
||||
QStringList subtypes = info.getCardType().split('-').last().split(" ");
|
||||
QString colors = info.getColors();
|
||||
int power = info.getPowTough().split("/").first().toInt();
|
||||
int toughness = info.getPowTough().split("/").last().toInt();
|
||||
const int cmc = info->getCmc().toInt();
|
||||
QStringList types = info->getMainCardType().split(' ');
|
||||
QStringList subtypes = info->getCardType().split('-').last().split(" ");
|
||||
QString colors = info->getColors();
|
||||
int power = info->getPowTough().split("/").first().toInt();
|
||||
int toughness = info->getPowTough().split("/").last().toInt();
|
||||
|
||||
// For each copy of card
|
||||
// ---------------- Mana Curve ----------------
|
||||
if (config.computeManaCurve) {
|
||||
manaCurveMap[cmc]++;
|
||||
manaCurveMap[cmc] += amount;
|
||||
}
|
||||
|
||||
// per-type curve
|
||||
for (auto &t : types) {
|
||||
manaCurveByType[t][cmc]++;
|
||||
manaCurveCardsByType[t][cmc].append(info.getName());
|
||||
manaCurveByType[t][cmc] += amount;
|
||||
manaCurveCardsByType[t][cmc] << copiesOfName;
|
||||
}
|
||||
|
||||
// Per-subtype curve
|
||||
for (auto &st : subtypes) {
|
||||
manaCurveBySubtype[st][cmc]++;
|
||||
manaCurveCardsBySubtype[st][cmc].append(info.getName());
|
||||
manaCurveBySubtype[st][cmc] += amount;
|
||||
manaCurveCardsBySubtype[st][cmc] << copiesOfName;
|
||||
}
|
||||
|
||||
// per-color curve
|
||||
for (auto &c : colors) {
|
||||
manaCurveByColor[c][cmc]++;
|
||||
manaCurveCardsByColor[c][cmc].append(info.getName());
|
||||
manaCurveByColor[c][cmc] += amount;
|
||||
manaCurveCardsByColor[c][cmc] << copiesOfName;
|
||||
}
|
||||
|
||||
// Power/toughness
|
||||
manaCurveByPower[QString::number(power)][cmc]++;
|
||||
manaCurveCardsByPower[QString::number(power)][cmc].append(info.getName());
|
||||
manaCurveByToughness[QString::number(toughness)][cmc]++;
|
||||
manaCurveCardsByToughness[QString::number(toughness)][cmc].append(info.getName());
|
||||
manaCurveByPower[QString::number(power)][cmc] += amount;
|
||||
manaCurveCardsByPower[QString::number(power)][cmc] << copiesOfName;
|
||||
manaCurveByToughness[QString::number(toughness)][cmc] += amount;
|
||||
manaCurveCardsByToughness[QString::number(toughness)][cmc] << copiesOfName;
|
||||
|
||||
// ========== Category Counts ===========
|
||||
for (auto &t : types) {
|
||||
typeCount[t]++;
|
||||
typeCount[t] += amount;
|
||||
}
|
||||
for (auto &st : subtypes) {
|
||||
subtypeCount[st]++;
|
||||
subtypeCount[st] += amount;
|
||||
}
|
||||
for (auto &c : colors) {
|
||||
colorCount[c]++;
|
||||
colorCount[c] += amount;
|
||||
}
|
||||
manaValueCount[cmc]++;
|
||||
manaValueCount[cmc] += amount;
|
||||
|
||||
// ---------------- Mana Base ----------------
|
||||
if (config.computeManaBase) {
|
||||
auto prod = determineManaProduction(info.getText());
|
||||
auto prod = determineManaProduction(info->getText());
|
||||
for (auto it = prod.begin(); it != prod.end(); ++it) {
|
||||
if (it.value() > 0) {
|
||||
productionPipCount[it.key()] += it.value();
|
||||
productionCardCount[it.key()]++;
|
||||
productionPipCount[it.key()] += it.value() * amount;
|
||||
productionCardCount[it.key()] += amount;
|
||||
}
|
||||
manaBaseMap[it.key()] += it.value();
|
||||
manaBaseMap[it.key()] += it.value() * amount;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- Devotion ----------------
|
||||
if (config.computeDevotion) {
|
||||
auto devo = countManaSymbols(info.getManaCost());
|
||||
auto devo = countManaSymbols(info->getManaCost());
|
||||
for (auto &d : devo) {
|
||||
if (d.second > 0) {
|
||||
devotionPipCount[QString(d.first)] += d.second;
|
||||
devotionCardCount[QString(d.first)]++;
|
||||
devotionPipCount[QString(d.first)] += d.second * amount;
|
||||
devotionCardCount[QString(d.first)] += amount;
|
||||
}
|
||||
manaDevotionMap[d.first] += d.second;
|
||||
manaDevotionMap[d.first] += d.second * amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "deck_editor_card_database_dock_widget.h"
|
||||
|
||||
DeckEditorCardDatabaseDockWidget::DeckEditorCardDatabaseDockWidget(AbstractTabDeckEditor *parent) : QDockWidget(parent)
|
||||
{
|
||||
setObjectName("databaseDisplayDock");
|
||||
setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
|
||||
createDatabaseDisplayDock(parent);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void DeckEditorCardDatabaseDockWidget::createDatabaseDisplayDock(AbstractTabDeckEditor *deckEditor)
|
||||
{
|
||||
databaseDisplayWidget = new DeckEditorDatabaseDisplayWidget(this, deckEditor);
|
||||
|
||||
auto *frame = new QVBoxLayout;
|
||||
frame->setObjectName("databaseDisplayFrame");
|
||||
frame->addWidget(databaseDisplayWidget);
|
||||
|
||||
auto *dockContents = new QWidget();
|
||||
dockContents->setObjectName("databaseDisplayDockContents");
|
||||
dockContents->setLayout(frame);
|
||||
setWidget(dockContents);
|
||||
|
||||
installEventFilter(deckEditor);
|
||||
connect(this, &QDockWidget::topLevelChanged, deckEditor, &AbstractTabDeckEditor::dockTopLevelChanged);
|
||||
|
||||
// connect signals
|
||||
connect(databaseDisplayWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, deckEditor,
|
||||
&AbstractTabDeckEditor::updateCard);
|
||||
connect(databaseDisplayWidget, &DeckEditorDatabaseDisplayWidget::addCardToMainDeck, deckEditor,
|
||||
&AbstractTabDeckEditor::actAddCard);
|
||||
connect(databaseDisplayWidget, &DeckEditorDatabaseDisplayWidget::addCardToSideboard, deckEditor,
|
||||
&AbstractTabDeckEditor::actAddCardToSideboard);
|
||||
connect(databaseDisplayWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromMainDeck, deckEditor,
|
||||
&AbstractTabDeckEditor::actDecrementCard);
|
||||
connect(databaseDisplayWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromSideboard, deckEditor,
|
||||
&AbstractTabDeckEditor::actDecrementCardFromSideboard);
|
||||
}
|
||||
|
||||
CardDatabase *DeckEditorCardDatabaseDockWidget::getDatabase() const
|
||||
{
|
||||
return databaseDisplayWidget->databaseModel->getDatabase();
|
||||
}
|
||||
|
||||
void DeckEditorCardDatabaseDockWidget::retranslateUi()
|
||||
{
|
||||
setWindowTitle(tr("Card Database"));
|
||||
}
|
||||
|
||||
void DeckEditorCardDatabaseDockWidget::setFilterTree(FilterTree *filterTree)
|
||||
{
|
||||
databaseDisplayWidget->setFilterTree(filterTree);
|
||||
}
|
||||
|
||||
void DeckEditorCardDatabaseDockWidget::clearAllDatabaseFilters()
|
||||
{
|
||||
databaseDisplayWidget->clearAllDatabaseFilters();
|
||||
}
|
||||
void DeckEditorCardDatabaseDockWidget::highlightAllSearchEdit()
|
||||
{
|
||||
databaseDisplayWidget->searchEdit->setSelection(0, databaseDisplayWidget->searchEdit->text().length());
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef COCKATRICE_DECK_EDITOR_CARD_DATABASE_DOCK_WIDGET_H
|
||||
#define COCKATRICE_DECK_EDITOR_CARD_DATABASE_DOCK_WIDGET_H
|
||||
|
||||
#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
|
||||
class AbstractTabDeckEditor;
|
||||
class CardDatabase;
|
||||
class DeckEditorDatabaseDisplayWidget;
|
||||
class FilterTree;
|
||||
|
||||
class DeckEditorCardDatabaseDockWidget : public QDockWidget
|
||||
{
|
||||
public:
|
||||
explicit DeckEditorCardDatabaseDockWidget(AbstractTabDeckEditor *parent);
|
||||
|
||||
DeckEditorDatabaseDisplayWidget *databaseDisplayWidget;
|
||||
|
||||
CardDatabase *getDatabase() const;
|
||||
void setFilterTree(FilterTree *filterTree);
|
||||
|
||||
public slots:
|
||||
void retranslateUi();
|
||||
void clearAllDatabaseFilters();
|
||||
void highlightAllSearchEdit();
|
||||
|
||||
private:
|
||||
void createDatabaseDisplayDock(AbstractTabDeckEditor *deckEditor);
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_DECK_EDITOR_CARD_DATABASE_DOCK_WIDGET_H
|
||||
@@ -21,10 +21,10 @@ static bool canBeCommander(const CardInfo &cardInfo)
|
||||
cardInfo.getText().contains("can be your commander", Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(AbstractTabDeckEditor *parent)
|
||||
: QWidget(parent), deckEditor(parent)
|
||||
DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(QWidget *parent, AbstractTabDeckEditor *deckEditor)
|
||||
: QWidget(parent), deckEditor(deckEditor)
|
||||
{
|
||||
setObjectName("centralWidget");
|
||||
setObjectName("databaseDisplayWidget");
|
||||
|
||||
centralFrame = new QVBoxLayout(this);
|
||||
centralFrame->setObjectName("centralFrame");
|
||||
|
||||
@@ -23,7 +23,7 @@ class DeckEditorDatabaseDisplayWidget : public QWidget
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeckEditorDatabaseDisplayWidget(AbstractTabDeckEditor *parent);
|
||||
explicit DeckEditorDatabaseDisplayWidget(QWidget *parent, AbstractTabDeckEditor *deckEditor);
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
SearchLineEdit *searchEdit;
|
||||
CardDatabaseModel *databaseModel;
|
||||
|
||||
@@ -154,7 +154,7 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
||||
bannerCardLabel->setText(tr("Banner Card"));
|
||||
bannerCardLabel->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
bannerCardComboBox = new QComboBox(this);
|
||||
connect(getModel(), &DeckListModel::dataChanged, this, [this]() {
|
||||
connect(getModel(), &DeckListModel::cardNodesChanged, this, [this]() {
|
||||
// Delay the update to avoid race conditions
|
||||
QTimer::singleShot(100, this, &DeckEditorDeckDockWidget::updateBannerCardComboBox);
|
||||
});
|
||||
@@ -597,13 +597,12 @@ QModelIndexList DeckEditorDeckDockWidget::getSelectedCardNodeSourceIndices() con
|
||||
return selectedRows;
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::actAddCard(const ExactCard &card, const QString &_zoneName)
|
||||
void DeckEditorDeckDockWidget::actAddCard(const ExactCard &card, const QString &zoneName)
|
||||
{
|
||||
if (!card) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString zoneName = card.getInfo().getIsToken() ? DECK_ZONE_TOKENS : _zoneName;
|
||||
deckStateManager->addCard(card, zoneName);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ DeckStateManager::DeckStateManager(QObject *parent)
|
||||
setModified(true);
|
||||
emit historyChanged();
|
||||
});
|
||||
connect(deckListModel, &DeckListModel::rowsInserted, this, &DeckStateManager::uniqueCardsChanged);
|
||||
connect(deckListModel, &DeckListModel::rowsRemoved, this, &DeckStateManager::uniqueCardsChanged);
|
||||
connect(deckListModel, &DeckListModel::cardNodesChanged, this, &DeckStateManager::uniqueCardsChanged);
|
||||
}
|
||||
|
||||
const DeckList &DeckStateManager::getDeckList() const
|
||||
@@ -174,11 +173,13 @@ QModelIndex DeckStateManager::addCard(const ExactCard &card, const QString &zone
|
||||
return {};
|
||||
}
|
||||
|
||||
QString zone = card.getInfo().getIsToken() ? DECK_ZONE_TOKENS : zoneName;
|
||||
|
||||
QString reason = tr("Added (%1): %2 (%3) %4")
|
||||
.arg(zoneName, card.getName(), card.getPrinting().getSet()->getCorrectedShortName(),
|
||||
.arg(zone, card.getName(), card.getPrinting().getSet()->getCorrectedShortName(),
|
||||
card.getPrinting().getProperty("num"));
|
||||
|
||||
QModelIndex idx = modifyDeck(reason, [&card, &zoneName](auto model) { return model->addCard(card, zoneName); });
|
||||
QModelIndex idx = modifyDeck(reason, [&card, &zone](auto model) { return model->addCard(card, zone); });
|
||||
|
||||
if (idx.isValid()) {
|
||||
emit focusIndexChanged(idx);
|
||||
|
||||
@@ -152,7 +152,7 @@ static bool swapPrinting(DeckListModel *model, const QString &modifiedSet, const
|
||||
return false;
|
||||
}
|
||||
int amount = model->data(idx.siblingAtColumn(DeckListModelColumns::CARD_AMOUNT), Qt::DisplayRole).toInt();
|
||||
model->removeRow(idx.row(), idx.parent());
|
||||
model->removeCardAtIndex(idx);
|
||||
CardInfoPtr cardInfo = CardDatabaseManager::query()->getCardInfo(cardName);
|
||||
PrintingInfo printing = CardDatabaseManager::query()->getSpecificPrinting(cardName, modifiedSet, "");
|
||||
for (int i = 0; i < amount; i++) {
|
||||
|
||||
@@ -152,7 +152,7 @@ static QModelIndex addAndReplacePrintings(DeckListModel *model,
|
||||
// Check if a card without a providerId already exists in the deckModel and replace it, if so.
|
||||
if (existing.isValid() && existing != newCardIndex && replaceProviderless) {
|
||||
model->offsetCountAtIndex(newCardIndex, extraCopies);
|
||||
model->removeRow(existing.row(), existing.parent());
|
||||
model->removeCardAtIndex(existing);
|
||||
}
|
||||
|
||||
// Set Index and Focus as if the user had just clicked the new card and modify the deckEditor saveState
|
||||
|
||||
@@ -90,8 +90,10 @@ void PrintingSelector::retranslateUi()
|
||||
|
||||
void PrintingSelector::printingsInDeckChanged()
|
||||
{
|
||||
// Delay the update to avoid race conditions
|
||||
QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
|
||||
if (SettingsCache::instance().getBumpSetsWithCardsInDeckToTop()) {
|
||||
// Delay the update to avoid race conditions
|
||||
QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,7 +55,7 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
||||
|
||||
deckStateManager = new DeckStateManager(this);
|
||||
|
||||
databaseDisplayDockWidget = new DeckEditorDatabaseDisplayWidget(this);
|
||||
cardDatabaseDockWidget = new DeckEditorCardDatabaseDockWidget(this);
|
||||
deckDockWidget = new DeckEditorDeckDockWidget(this);
|
||||
cardInfoDockWidget = new DeckEditorCardInfoDockWidget(this);
|
||||
filterDockWidget = new DeckEditorFilterDockWidget(this);
|
||||
@@ -68,21 +68,9 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
||||
connect(deckStateManager, &DeckStateManager::isModifiedChanged, this, &AbstractTabDeckEditor::onDeckModified);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::selectedCardChanged, this, &AbstractTabDeckEditor::updateCard);
|
||||
|
||||
// Connect database display signals to this tab
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, this,
|
||||
&AbstractTabDeckEditor::updateCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToMainDeck, this,
|
||||
&AbstractTabDeckEditor::actAddCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToSideboard, this,
|
||||
&AbstractTabDeckEditor::actAddCardToSideboard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromMainDeck, this,
|
||||
&AbstractTabDeckEditor::actDecrementCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromSideboard, this,
|
||||
&AbstractTabDeckEditor::actDecrementCardFromSideboard);
|
||||
|
||||
// Connect filter signals
|
||||
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
||||
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, cardDatabaseDockWidget,
|
||||
&DeckEditorCardDatabaseDockWidget::clearAllDatabaseFilters);
|
||||
|
||||
// Connect shortcut changes
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
@@ -122,7 +110,7 @@ void AbstractTabDeckEditor::addCardHelper(const ExactCard &card, const QString &
|
||||
{
|
||||
deckStateManager->addCard(card, zoneName);
|
||||
|
||||
databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length());
|
||||
cardDatabaseDockWidget->highlightAllSearchEdit();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -544,21 +532,21 @@ void AbstractTabDeckEditor::actExportDeckDecklistXyz()
|
||||
/** @brief Analyzes the deck using DeckStats. */
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||
{
|
||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
auto *interface = new DeckStatsInterface(*cardDatabaseDockWidget->getDatabase(), this);
|
||||
interface->analyzeDeck(deckStateManager->getDeckList());
|
||||
}
|
||||
|
||||
/** @brief Analyzes the deck using TappedOut. */
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
||||
{
|
||||
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
auto *interface = new TappedOutInterface(*cardDatabaseDockWidget->getDatabase(), this);
|
||||
interface->analyzeDeck(deckStateManager->getDeckList());
|
||||
}
|
||||
|
||||
/** @brief Applies a new filter tree to the database display. */
|
||||
void AbstractTabDeckEditor::filterTreeChanged(FilterTree *filterTree)
|
||||
{
|
||||
databaseDisplayDockWidget->setFilterTree(filterTree);
|
||||
cardDatabaseDockWidget->setFilterTree(filterTree);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -571,43 +559,6 @@ void AbstractTabDeckEditor::closeEvent(QCloseEvent *event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Event filter for dock visibility and geometry changes.
|
||||
* @param o Object sending the event.
|
||||
* @param e Event.
|
||||
* @return False always.
|
||||
*/
|
||||
bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::Close) {
|
||||
if (o == cardInfoDockWidget) {
|
||||
aCardInfoDockVisible->setChecked(false);
|
||||
aCardInfoDockFloating->setEnabled(false);
|
||||
} else if (o == deckDockWidget) {
|
||||
aDeckDockVisible->setChecked(false);
|
||||
aDeckDockFloating->setEnabled(false);
|
||||
} else if (o == filterDockWidget) {
|
||||
aFilterDockVisible->setChecked(false);
|
||||
aFilterDockFloating->setEnabled(false);
|
||||
} else if (o == printingSelectorDockWidget) {
|
||||
aPrintingSelectorDockVisible->setChecked(false);
|
||||
aPrintingSelectorDockFloating->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (o == this && e->type() == QEvent::Hide) {
|
||||
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||
layouts.setDeckEditorLayoutState(saveState());
|
||||
layouts.setDeckEditorGeometry(saveGeometry());
|
||||
layouts.setDeckEditorCardSize(cardInfoDockWidget->size());
|
||||
layouts.setDeckEditorFilterSize(filterDockWidget->size());
|
||||
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
||||
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief Shows a confirmation dialog before closing. */
|
||||
bool AbstractTabDeckEditor::confirmClose()
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
||||
#define TAB_GENERIC_DECK_EDITOR_H
|
||||
|
||||
#include "../interface/widgets/deck_editor/deck_editor_card_database_dock_widget.h"
|
||||
#include "../interface/widgets/deck_editor/deck_editor_card_info_dock_widget.h"
|
||||
#include "../interface/widgets/deck_editor/deck_editor_database_display_widget.h"
|
||||
#include "../interface/widgets/deck_editor/deck_editor_deck_dock_widget.h"
|
||||
@@ -27,7 +28,7 @@ class CardInfoFrameWidget;
|
||||
class DeckLoader;
|
||||
class DeckEditorMenu;
|
||||
class DeckEditorCardInfoDockWidget;
|
||||
class DeckEditorDatabaseDisplayWidget;
|
||||
class DeckEditorCardDatabaseDockWidget;
|
||||
class DeckEditorDeckDockWidget;
|
||||
class DeckEditorFilterDockWidget;
|
||||
class DeckEditorPrintingSelectorDockWidget;
|
||||
@@ -126,7 +127,7 @@ public:
|
||||
// UI Elements
|
||||
DeckStateManager *deckStateManager;
|
||||
DeckEditorMenu *deckMenu; ///< Menu for deck operations
|
||||
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget; ///< Database dock
|
||||
DeckEditorCardDatabaseDockWidget *cardDatabaseDockWidget; ///< Database dock
|
||||
DeckEditorCardInfoDockWidget *cardInfoDockWidget; ///< Card info dock
|
||||
DeckEditorDeckDockWidget *deckDockWidget; ///< Deck dock
|
||||
DeckEditorFilterDockWidget *filterDockWidget; ///< Filter dock
|
||||
@@ -245,9 +246,6 @@ protected slots:
|
||||
/** @brief Handles dock close events. */
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
/** @brief Event filter for dock state changes. */
|
||||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
|
||||
/** @brief Slot triggered when a dock visibility changes. Pure virtual. */
|
||||
virtual void dockVisibleTriggered() = 0;
|
||||
|
||||
@@ -295,11 +293,15 @@ protected:
|
||||
virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
||||
|
||||
// UI Menu Elements
|
||||
QMenu *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu, *printingSelectorDockMenu;
|
||||
QMenu *viewMenu, *cardInfoDockMenu, *cardDatabaseDockMenu, *deckDockMenu, *filterDockMenu,
|
||||
*printingSelectorDockMenu;
|
||||
|
||||
QAction *aResetLayout;
|
||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating;
|
||||
QAction *aFilterDockVisible, *aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating;
|
||||
QAction *aCardDatabaseDockVisible, *aCardDatabaseDockFloating;
|
||||
QAction *aDeckDockVisible, *aDeckDockFloating;
|
||||
QAction *aFilterDockVisible, *aFilterDockFloating;
|
||||
QAction *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||
};
|
||||
|
||||
#endif // TAB_GENERIC_DECK_EDITOR_H
|
||||
|
||||
@@ -55,6 +55,7 @@ void TabDeckEditor::createMenus()
|
||||
viewMenu = new QMenu(this);
|
||||
|
||||
cardInfoDockMenu = viewMenu->addMenu(QString());
|
||||
cardDatabaseDockMenu = viewMenu->addMenu(QString());
|
||||
deckDockMenu = viewMenu->addMenu(QString());
|
||||
filterDockMenu = viewMenu->addMenu(QString());
|
||||
printingSelectorDockMenu = viewMenu->addMenu(QString());
|
||||
@@ -67,6 +68,14 @@ void TabDeckEditor::createMenus()
|
||||
aCardInfoDockFloating->setCheckable(true);
|
||||
connect(aCardInfoDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||
|
||||
// Card Database dock
|
||||
aCardDatabaseDockVisible = cardDatabaseDockMenu->addAction(QString());
|
||||
aCardDatabaseDockVisible->setCheckable(true);
|
||||
connect(aCardDatabaseDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||
aCardDatabaseDockFloating = cardDatabaseDockMenu->addAction(QString());
|
||||
aCardDatabaseDockFloating->setCheckable(true);
|
||||
connect(aCardDatabaseDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||
|
||||
// Deck dock
|
||||
aDeckDockVisible = deckDockMenu->addAction(QString());
|
||||
aDeckDockVisible->setCheckable(true);
|
||||
@@ -126,18 +135,22 @@ void TabDeckEditor::retranslateUi()
|
||||
{
|
||||
deckMenu->retranslateUi();
|
||||
cardInfoDockWidget->retranslateUi();
|
||||
cardDatabaseDockWidget->retranslateUi();
|
||||
deckDockWidget->retranslateUi();
|
||||
filterDockWidget->retranslateUi();
|
||||
printingSelectorDockWidget->retranslateUi();
|
||||
|
||||
viewMenu->setTitle(tr("&View"));
|
||||
cardInfoDockMenu->setTitle(tr("Card Info"));
|
||||
cardDatabaseDockMenu->setTitle(tr("Card Database"));
|
||||
deckDockMenu->setTitle(tr("Deck"));
|
||||
filterDockMenu->setTitle(tr("Filters"));
|
||||
printingSelectorDockMenu->setTitle(tr("Printing"));
|
||||
|
||||
aCardInfoDockVisible->setText(tr("Visible"));
|
||||
aCardInfoDockFloating->setText(tr("Floating"));
|
||||
aCardDatabaseDockVisible->setText(tr("Visible"));
|
||||
aCardDatabaseDockFloating->setText(tr("Floating"));
|
||||
aDeckDockVisible->setText(tr("Visible"));
|
||||
aDeckDockFloating->setText(tr("Floating"));
|
||||
aFilterDockVisible->setText(tr("Visible"));
|
||||
@@ -171,7 +184,6 @@ void TabDeckEditor::showPrintingSelector()
|
||||
void TabDeckEditor::loadLayout()
|
||||
{
|
||||
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||
setCentralWidget(databaseDisplayDockWidget);
|
||||
|
||||
auto &layoutState = layouts.getDeckEditorLayoutState();
|
||||
if (layoutState.isNull())
|
||||
@@ -189,16 +201,19 @@ void TabDeckEditor::loadLayout()
|
||||
}
|
||||
|
||||
aCardInfoDockVisible->setChecked(!cardInfoDockWidget->isHidden());
|
||||
aCardDatabaseDockVisible->setChecked(!cardDatabaseDockWidget->isHidden());
|
||||
aFilterDockVisible->setChecked(!filterDockWidget->isHidden());
|
||||
aDeckDockVisible->setChecked(!deckDockWidget->isHidden());
|
||||
aPrintingSelectorDockVisible->setChecked(!printingSelectorDockWidget->isHidden());
|
||||
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
aCardDatabaseDockFloating->setChecked(aCardDatabaseDockVisible->isChecked());
|
||||
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||
aFilterDockFloating->setEnabled(aFilterDockVisible->isChecked());
|
||||
aPrintingSelectorDockFloating->setEnabled(aPrintingSelectorDockVisible->isChecked());
|
||||
|
||||
aCardInfoDockFloating->setChecked(cardInfoDockWidget->isFloating());
|
||||
aCardDatabaseDockFloating->setChecked(cardDatabaseDockWidget->isFloating());
|
||||
aFilterDockFloating->setChecked(filterDockWidget->isFloating());
|
||||
aDeckDockFloating->setChecked(deckDockWidget->isFloating());
|
||||
aPrintingSelectorDockFloating->setChecked(printingSelectorDockWidget->isFloating());
|
||||
@@ -226,27 +241,31 @@ void TabDeckEditor::restartLayout()
|
||||
|
||||
// Update menu checkboxes
|
||||
aCardInfoDockVisible->setChecked(true);
|
||||
aCardDatabaseDockVisible->setChecked(true);
|
||||
aDeckDockVisible->setChecked(true);
|
||||
aFilterDockVisible->setChecked(true);
|
||||
aPrintingSelectorDockVisible->setChecked(!SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference());
|
||||
|
||||
aCardInfoDockFloating->setChecked(false);
|
||||
aCardDatabaseDockFloating->setChecked(false);
|
||||
aDeckDockFloating->setChecked(false);
|
||||
aFilterDockFloating->setChecked(false);
|
||||
aPrintingSelectorDockFloating->setChecked(false);
|
||||
|
||||
setCentralWidget(databaseDisplayDockWidget);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, cardDatabaseDockWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, deckDockWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, cardInfoDockWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, filterDockWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, printingSelectorDockWidget);
|
||||
|
||||
// Show/hide and reset floating
|
||||
cardDatabaseDockWidget->setFloating(false);
|
||||
deckDockWidget->setFloating(false);
|
||||
cardInfoDockWidget->setFloating(false);
|
||||
filterDockWidget->setFloating(false);
|
||||
printingSelectorDockWidget->setFloating(false);
|
||||
|
||||
cardDatabaseDockWidget->setVisible(true);
|
||||
deckDockWidget->setVisible(true);
|
||||
cardInfoDockWidget->setVisible(true);
|
||||
filterDockWidget->setVisible(true);
|
||||
@@ -269,6 +288,9 @@ void TabDeckEditor::freeDocksSize()
|
||||
deckDockWidget->setMinimumSize(minSize);
|
||||
deckDockWidget->setMaximumSize(maxSize);
|
||||
|
||||
cardDatabaseDockWidget->setMinimumSize(minSize);
|
||||
cardDatabaseDockWidget->setMaximumSize(maxSize);
|
||||
|
||||
cardInfoDockWidget->setMinimumSize(minSize);
|
||||
cardInfoDockWidget->setMaximumSize(maxSize);
|
||||
|
||||
@@ -286,6 +308,9 @@ void TabDeckEditor::dockVisibleTriggered()
|
||||
if (o == aCardInfoDockVisible) {
|
||||
cardInfoDockWidget->setHidden(!aCardInfoDockVisible->isChecked());
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
} else if (o == aCardDatabaseDockVisible) {
|
||||
cardDatabaseDockWidget->setHidden(!aCardDatabaseDockVisible->isChecked());
|
||||
aCardDatabaseDockFloating->setEnabled(aCardDatabaseDockVisible->isChecked());
|
||||
} else if (o == aDeckDockVisible) {
|
||||
deckDockWidget->setHidden(!aDeckDockVisible->isChecked());
|
||||
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||
@@ -304,6 +329,8 @@ void TabDeckEditor::dockFloatingTriggered()
|
||||
QObject *o = sender();
|
||||
if (o == aCardInfoDockFloating)
|
||||
cardInfoDockWidget->setFloating(aCardInfoDockFloating->isChecked());
|
||||
else if (o == aCardDatabaseDockFloating)
|
||||
cardDatabaseDockWidget->setFloating(aCardDatabaseDockFloating->isChecked());
|
||||
else if (o == aDeckDockFloating)
|
||||
deckDockWidget->setFloating(aDeckDockFloating->isChecked());
|
||||
else if (o == aFilterDockFloating)
|
||||
@@ -318,6 +345,8 @@ void TabDeckEditor::dockTopLevelChanged(bool topLevel)
|
||||
QObject *o = sender();
|
||||
if (o == cardInfoDockWidget)
|
||||
aCardInfoDockFloating->setChecked(topLevel);
|
||||
else if (o == aCardDatabaseDockFloating)
|
||||
aCardDatabaseDockFloating->setChecked(topLevel);
|
||||
else if (o == deckDockWidget)
|
||||
aDeckDockFloating->setChecked(topLevel);
|
||||
else if (o == filterDockWidget)
|
||||
@@ -338,6 +367,9 @@ bool TabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||
if (o == cardInfoDockWidget) {
|
||||
aCardInfoDockVisible->setChecked(false);
|
||||
aCardInfoDockFloating->setEnabled(false);
|
||||
} else if (o == cardDatabaseDockWidget) {
|
||||
aCardDatabaseDockVisible->setChecked(false);
|
||||
aCardDatabaseDockFloating->setEnabled(false);
|
||||
} else if (o == deckDockWidget) {
|
||||
aDeckDockVisible->setChecked(false);
|
||||
aDeckDockFloating->setEnabled(false);
|
||||
|
||||
@@ -6,9 +6,9 @@ TabVisualDatabaseDisplay::TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor
|
||||
{
|
||||
deckEditor = new TabDeckEditor(_tabSupervisor);
|
||||
deckEditor->setHidden(true);
|
||||
visualDatabaseDisplayWidget =
|
||||
new VisualDatabaseDisplayWidget(this, deckEditor, deckEditor->databaseDisplayDockWidget->databaseModel,
|
||||
deckEditor->databaseDisplayDockWidget->databaseDisplayModel);
|
||||
visualDatabaseDisplayWidget = new VisualDatabaseDisplayWidget(
|
||||
this, deckEditor, deckEditor->cardDatabaseDockWidget->databaseDisplayWidget->databaseModel,
|
||||
deckEditor->cardDatabaseDockWidget->databaseDisplayWidget->databaseDisplayModel);
|
||||
|
||||
setCentralWidget(visualDatabaseDisplayWidget);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ TabDeckEditorVisual::TabDeckEditorVisual(TabSupervisor *_tabSupervisor) : Abstra
|
||||
refreshShortcuts();
|
||||
|
||||
loadLayout();
|
||||
databaseDisplayDockWidget->setHidden(true);
|
||||
cardDatabaseDockWidget->setHidden(true);
|
||||
}
|
||||
|
||||
/** @brief Creates the central frame containing the tab container. */
|
||||
@@ -62,9 +62,9 @@ void TabDeckEditorVisual::createCentralFrame()
|
||||
centralFrame = new QVBoxLayout;
|
||||
centralWidget->setLayout(centralFrame);
|
||||
|
||||
tabContainer = new TabDeckEditorVisualTabWidget(centralWidget, this, deckStateManager->getModel(),
|
||||
databaseDisplayDockWidget->databaseModel,
|
||||
databaseDisplayDockWidget->databaseDisplayModel);
|
||||
tabContainer = new TabDeckEditorVisualTabWidget(
|
||||
centralWidget, this, deckStateManager->getModel(), cardDatabaseDockWidget->databaseDisplayWidget->databaseModel,
|
||||
cardDatabaseDockWidget->databaseDisplayWidget->databaseDisplayModel);
|
||||
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardChanged, this,
|
||||
&TabDeckEditorVisual::changeModelIndexAndCardInfo);
|
||||
|
||||
@@ -74,25 +74,27 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
|
||||
|
||||
searchKeySignals.setObjectName("searchKeySignals");
|
||||
connect(searchEdit, &SearchLineEdit::textChanged, this, &VisualDatabaseDisplayWidget::updateSearch);
|
||||
connect(&searchKeySignals, &KeySignals::onEnter, deckEditor->databaseDisplayDockWidget,
|
||||
|
||||
DeckEditorDatabaseDisplayWidget *databaseDisplayWidget = deckEditor->cardDatabaseDockWidget->databaseDisplayWidget;
|
||||
connect(&searchKeySignals, &KeySignals::onEnter, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltEqual, deckEditor->databaseDisplayDockWidget,
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltEqual, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltRBracket, deckEditor->databaseDisplayDockWidget,
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltRBracket, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltMinus, deckEditor->databaseDisplayDockWidget,
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltMinus, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::actDecrementCardFromMainDeck);
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltLBracket, deckEditor->databaseDisplayDockWidget,
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltLBracket, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::actDecrementCardFromSideboard);
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltEnter, deckEditor->databaseDisplayDockWidget,
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlAltEnter, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlEnter, deckEditor->databaseDisplayDockWidget,
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlEnter, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlC, deckEditor->databaseDisplayDockWidget,
|
||||
connect(&searchKeySignals, &KeySignals::onCtrlC, databaseDisplayWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::copyDatabaseCellContents);
|
||||
connect(help, &QAction::triggered, this, [this] { createSearchSyntaxHelpWindow(searchEdit); });
|
||||
|
||||
databaseView = deckEditor->databaseDisplayDockWidget->getDatabaseView();
|
||||
databaseView = databaseDisplayWidget->getDatabaseView();
|
||||
databaseView->setFocusProxy(searchEdit);
|
||||
databaseView->setItemDelegate(nullptr);
|
||||
databaseView->setVisible(false);
|
||||
|
||||
@@ -81,13 +81,30 @@ void VisualDeckEditorSampleHandWidget::updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
static QList<ExactCard> cardNodesToExactCards(QList<const DecklistCardNode *> nodes)
|
||||
{
|
||||
QList<ExactCard> cards;
|
||||
for (auto node : nodes) {
|
||||
ExactCard card = CardDatabaseManager::query()->getCard(node->toCardRef());
|
||||
if (card) {
|
||||
for (int k = 0; k < node->getNumber(); ++k) {
|
||||
cards.append(card);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Card not found in database!";
|
||||
}
|
||||
}
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
QList<ExactCard> VisualDeckEditorSampleHandWidget::getRandomCards(int amountToGet)
|
||||
{
|
||||
QList<ExactCard> randomCards;
|
||||
if (!deckListModel)
|
||||
return randomCards;
|
||||
|
||||
QList<ExactCard> mainDeckCards = deckListModel->getCardsForZone(DECK_ZONE_MAIN);
|
||||
QList<ExactCard> mainDeckCards = cardNodesToExactCards(deckListModel->getCardNodesForZone(DECK_ZONE_MAIN));
|
||||
|
||||
if (mainDeckCards.isEmpty())
|
||||
return randomCards;
|
||||
|
||||
@@ -154,7 +154,13 @@ You will not be able to manage printing preferences on a per-deck basis, or see
|
||||
You will have to use the Set Manager, available through Card Database -> Manage Sets.
|
||||
|
||||
Are you sure you would like to enable this feature?</source>
|
||||
<translation>L'activation de cette fonction désactivera l'utilisation du sélecteur d'impression.Vous ne pourrez plus gérer les préférences d'impression pour chaque deck ni voir les impressions sélectionnées par d'autres joueurs.Vous devrez utiliser le Gestionnaire d'extensions, accessible via Base de données de cartes -> Gérer les extensions.Êtes-vous sûr de vouloir activer cette fonction ?</translation>
|
||||
<translation>L'activation de cette fonction désactivera l'utilisation du sélecteur d'impression.
|
||||
|
||||
Vous ne pourrez plus gérer les préférences d'impression pour chaque deck ni voir les impressions sélectionnées par d'autres joueurs.
|
||||
|
||||
Vous devrez utiliser le Gestionnaire d'extensions, accessible via Base de données de cartes -> Gérer les extensions.
|
||||
|
||||
Êtes-vous sûr de vouloir activer cette fonction ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="src/interface/widgets/dialogs/dlg_settings.cpp" line="668"/>
|
||||
@@ -165,7 +171,13 @@ You can now choose printings on a per-deck basis in the Deck Editor and configur
|
||||
You can also use the Set Manager to adjust custom sort order for printings in the Printing Selector (other sort orders like alphabetical or release date are available).
|
||||
|
||||
Are you sure you would like to disable this feature?</source>
|
||||
<translation>Désactiver cette fonction activera le sélecteur d'impression.Vous pouvez désormais choisir les impressions pour chaque deck dans l'éditeur de deck et configurer l'impression ajoutée par défaut en l'épinglant dans le sélecteur d'impression.Vous pouvez également utiliser le gestionnaire de d'extension pour personnaliser l'ordre de tri des impressions dans le sélecteur d'impression (d'autres ordres de tri, comme l'ordre alphabétique ou la date de parution, sont disponibles).Êtes-vous sûr de vouloir désactiver cette fonction ?</translation>
|
||||
<translation>Désactiver cette fonction activera le sélecteur d'impression.
|
||||
|
||||
Vous pouvez désormais choisir les impressions pour chaque deck dans l'éditeur de deck et configurer l'impression ajoutée par défaut en l'épinglant dans le sélecteur d'impression.
|
||||
|
||||
Vous pouvez également utiliser le gestionnaire de d'extension pour personnaliser l'ordre de tri des impressions dans le sélecteur d'impression (d'autres ordres de tri, comme l'ordre alphabétique ou la date de parution, sont disponibles).
|
||||
|
||||
Êtes-vous sûr de vouloir désactiver cette fonction ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="src/interface/widgets/dialogs/dlg_settings.cpp" line="677"/>
|
||||
@@ -2784,7 +2796,13 @@ https://archidekt.com/decks/9999999
|
||||
https://deckstats.net/decks/99999/9999999-your-deck-name/en
|
||||
https://moxfield.com/decks/XYZxx-XYZ99Yyy-xyzXzzz
|
||||
https://tappedout.net/mtg-decks/your-deck-name/</source>
|
||||
<translation>L'URL fournie n'est pas reconnue comme une URL de deck valide.Les URL de deck valides ressemblent à ceci :https://archidekt.com/decks/9999999https://deckstats.net/decks/99999/9999999-your-deck-name/enhttps://moxfield.com/decks/XYZxx-XYZ99Yyy-xyzXzzzhttps://tappedout.net/mtg-decks/your-deck-name/</translation>
|
||||
<translation>L'URL fournie n'est pas reconnue comme une URL de deck valide.
|
||||
Les URL de deck valides ressemblent à ceci:
|
||||
|
||||
https://archidekt.com/decks/9999999
|
||||
https://deckstats.net/decks/99999/9999999-your-deck-name/en
|
||||
https://moxfield.com/decks/XYZxx-XYZ99Yyy-xyzXzzz
|
||||
https://tappedout.net/mtg-decks/your-deck-name/</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
||||
@@ -12,6 +12,15 @@ DeckListModel::DeckListModel(QObject *parent)
|
||||
DeckListModel::DeckListModel(QObject *parent, const QSharedPointer<DeckList> &deckList) : DeckListModel(parent)
|
||||
{
|
||||
setDeckList(deckList);
|
||||
|
||||
// forward change signals
|
||||
connect(this, &DeckListModel::cardAddedAt, this, &DeckListModel::cardsChanged);
|
||||
connect(this, &DeckListModel::cardRemoved, this, &DeckListModel::cardsChanged);
|
||||
connect(this, &DeckListModel::deckReplaced, this, &DeckListModel::cardsChanged);
|
||||
|
||||
connect(this, &DeckListModel::cardNodeAddedAt, this, &DeckListModel::cardNodesChanged);
|
||||
connect(this, &DeckListModel::cardNodeRemoved, this, &DeckListModel::cardNodesChanged);
|
||||
connect(this, &DeckListModel::deckReplaced, this, &DeckListModel::cardNodesChanged);
|
||||
}
|
||||
|
||||
DeckListModel::~DeckListModel()
|
||||
@@ -421,6 +430,7 @@ QModelIndex DeckListModel::addCard(const ExactCard &card, const QString &zoneNam
|
||||
card.getName(), printingInfo.getUuid(), printingInfo.getProperty("num")));
|
||||
const auto cardSetName = printingInfo.getSet().isNull() ? "" : printingInfo.getSet()->getCorrectedShortName();
|
||||
|
||||
bool cardNodeAdded = false;
|
||||
if (!cardNode) {
|
||||
// Determine the correct index
|
||||
int insertRow = findSortedInsertRow(groupNode, cardInfo);
|
||||
@@ -432,6 +442,8 @@ QModelIndex DeckListModel::addCard(const ExactCard &card, const QString &zoneNam
|
||||
beginInsertRows(parentIndex, insertRow, insertRow);
|
||||
cardNode = new DecklistModelCardNode(decklistCard, groupNode, insertRow);
|
||||
endInsertRows();
|
||||
|
||||
cardNodeAdded = true;
|
||||
} else {
|
||||
cardNode->setNumber(cardNode->getNumber() + 1);
|
||||
cardNode->setCardSetShortName(cardSetName);
|
||||
@@ -444,6 +456,10 @@ QModelIndex DeckListModel::addCard(const ExactCard &card, const QString &zoneNam
|
||||
emitRecursiveUpdates(parentIndex);
|
||||
auto index = nodeToIndex(cardNode);
|
||||
|
||||
if (cardNodeAdded) {
|
||||
emit cardNodeAddedAt(index);
|
||||
}
|
||||
|
||||
emit cardAddedAt(index);
|
||||
|
||||
return index;
|
||||
@@ -468,17 +484,42 @@ bool DeckListModel::offsetCountAtIndex(const QModelIndex &idx, int offset)
|
||||
|
||||
if (newCount <= 0) {
|
||||
removeRow(idx.row(), idx.parent());
|
||||
emit cardNodeRemoved();
|
||||
} else {
|
||||
setData(numberIndex, newCount, Qt::EditRole);
|
||||
}
|
||||
|
||||
if (offset > 0) {
|
||||
emit cardAddedAt(idx);
|
||||
} else if (offset < 0) {
|
||||
emit cardRemoved();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeckListModel::removeCardAtIndex(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *node = static_cast<AbstractDecklistNode *>(idx.internalPointer());
|
||||
auto *card = dynamic_cast<DecklistModelCardNode *>(node);
|
||||
|
||||
if (!card) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = removeRow(idx.row(), idx.parent());
|
||||
|
||||
if (success) {
|
||||
emit cardRemoved();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int DeckListModel::findSortedInsertRow(const InnerDecklistNode *parent, const CardInfoPtr &cardInfo) const
|
||||
{
|
||||
if (!cardInfo) {
|
||||
@@ -608,35 +649,6 @@ void DeckListModel::forEachCard(const std::function<void(InnerDecklistNode *, De
|
||||
deckList->forEachCard(func);
|
||||
}
|
||||
|
||||
static QList<ExactCard> cardNodesToExactCards(QList<const DecklistCardNode *> nodes)
|
||||
{
|
||||
QList<ExactCard> cards;
|
||||
for (auto node : nodes) {
|
||||
ExactCard card = CardDatabaseManager::query()->getCard(node->toCardRef());
|
||||
if (card) {
|
||||
for (int k = 0; k < node->getNumber(); ++k) {
|
||||
cards.append(card);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Card not found in database!";
|
||||
}
|
||||
}
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
QList<ExactCard> DeckListModel::getCards() const
|
||||
{
|
||||
auto nodes = deckList->getCardNodes();
|
||||
return cardNodesToExactCards(nodes);
|
||||
}
|
||||
|
||||
QList<ExactCard> DeckListModel::getCardsForZone(const QString &zoneName) const
|
||||
{
|
||||
auto nodes = deckList->getCardNodes({zoneName});
|
||||
return cardNodesToExactCards(nodes);
|
||||
}
|
||||
|
||||
QList<const DecklistCardNode *> DeckListModel::getCardNodes() const
|
||||
{
|
||||
return deckList->getCardNodes();
|
||||
|
||||
@@ -197,6 +197,12 @@ public:
|
||||
* InnerDecklistNode containers and supports grouping, sorting, adding/removing
|
||||
* cards, and printing decklists.
|
||||
*
|
||||
* Outside code should refrain from modifying the model with methods inherited from QAbstractItemModel, such as with
|
||||
* `setData` or `removeRow`.
|
||||
* Instead, use the custom methods on this class to modify the model, such as `addCard`, `offsetCountAtIndex`, or
|
||||
* `removeCardAtIndex`.
|
||||
* This ensures the custom signals for this class are correctly emitted.
|
||||
*
|
||||
* Signals:
|
||||
* - deckHashChanged(): emitted when the deck contents change in a way that
|
||||
* affects its hash.
|
||||
@@ -231,6 +237,11 @@ signals:
|
||||
*/
|
||||
void deckHashChanged();
|
||||
|
||||
/**
|
||||
* @brief Emitted whenever the cards in the deck changes. This includes when the deck is replaced.
|
||||
*/
|
||||
void cardsChanged();
|
||||
|
||||
/**
|
||||
* @brief Emitted whenever a card is added to the deck, regardless of whether it's an entirely new card or an
|
||||
* existing card that got incremented.
|
||||
@@ -238,6 +249,28 @@ signals:
|
||||
*/
|
||||
void cardAddedAt(const QModelIndex &index);
|
||||
|
||||
/**
|
||||
* @brief Emitted whenever a card is removed from the deck, regardless of whether a card node was removed or an
|
||||
* existing card got decremented.
|
||||
*/
|
||||
void cardRemoved();
|
||||
|
||||
/**
|
||||
* @brief Emitted whenever a card node is added or removed. This includes when the deck is replaced.
|
||||
*/
|
||||
void cardNodesChanged();
|
||||
|
||||
/**
|
||||
* @brief Emitted whenever a new card node is added.
|
||||
* @param index The index of the card node that got added.
|
||||
*/
|
||||
void cardNodeAddedAt(const QModelIndex &index);
|
||||
|
||||
/**
|
||||
* @brief Emitted whenever a card node is removed.
|
||||
*/
|
||||
void cardNodeRemoved();
|
||||
|
||||
/**
|
||||
* @brief Emitted whenever the deck in the model has been replaced with a new one
|
||||
*/
|
||||
@@ -311,6 +344,13 @@ public:
|
||||
*/
|
||||
bool offsetCountAtIndex(const QModelIndex &idx, int offset);
|
||||
|
||||
/**
|
||||
* @brief Removes the card node at the index
|
||||
* @param idx The index of a card node. No-ops if the index is invalid or not a card node.
|
||||
* @return Whether the node was removed.
|
||||
*/
|
||||
bool removeCardAtIndex(const QModelIndex &idx);
|
||||
|
||||
/**
|
||||
* @brief Removes all cards and resets the model.
|
||||
*/
|
||||
@@ -329,16 +369,6 @@ public:
|
||||
*/
|
||||
void forEachCard(const std::function<void(InnerDecklistNode *, DecklistCardNode *)> &func);
|
||||
|
||||
/**
|
||||
* @brief Creates a list consisting of the entries of the model mapped into ExactCards (with each entry looked up
|
||||
* in the card database).
|
||||
* If a card node has number > 1, it will be added that many times to the list.
|
||||
* If an entry's card is not found in the card database, that entry will be left out of the list.
|
||||
* @return An ordered list of ExactCards
|
||||
*/
|
||||
[[nodiscard]] QList<ExactCard> getCards() const;
|
||||
[[nodiscard]] QList<ExactCard> getCardsForZone(const QString &zoneName) const;
|
||||
|
||||
/**
|
||||
* @brief Gets a list of all card nodes in the deck.
|
||||
*/
|
||||
|
||||
@@ -89,11 +89,11 @@ public:
|
||||
{
|
||||
return playerId;
|
||||
}
|
||||
bool getSpectator() const
|
||||
bool isSpectator() const
|
||||
{
|
||||
return spectator;
|
||||
}
|
||||
bool getJudge() const
|
||||
bool isJudge() const
|
||||
{
|
||||
return judge;
|
||||
}
|
||||
|
||||
@@ -1516,7 +1516,7 @@ Server_AbstractPlayer::cmdRevealCards(const Command_RevealCards &cmd, ResponseCo
|
||||
zone->addWritePermission(cmd.player_id());
|
||||
}
|
||||
|
||||
if (getJudge()) {
|
||||
if (isJudge()) {
|
||||
ges.setOverwriteOwnership(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ void Server_Game::pingClockTimeout()
|
||||
if (participant == nullptr)
|
||||
continue;
|
||||
|
||||
if (!participant->getSpectator()) {
|
||||
if (!participant->isSpectator()) {
|
||||
++playerCount;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ void Server_Game::pingClockTimeout()
|
||||
}
|
||||
|
||||
if ((participant->getPingTime() != -1) &&
|
||||
(!participant->getSpectator() || participant->getPlayerId() == hostId)) {
|
||||
(!participant->isSpectator() || participant->getPlayerId() == hostId)) {
|
||||
allPlayersInactive = false;
|
||||
}
|
||||
}
|
||||
@@ -222,7 +222,7 @@ QMap<int, Server_AbstractPlayer *> Server_Game::getPlayers() const // copies poi
|
||||
QMutexLocker locker(&gameMutex);
|
||||
for (int id : participants.keys()) {
|
||||
auto *participant = participants[id];
|
||||
if (!participant->getSpectator()) {
|
||||
if (!participant->isSpectator()) {
|
||||
players[id] = static_cast<Server_AbstractPlayer *>(participant);
|
||||
}
|
||||
}
|
||||
@@ -232,7 +232,7 @@ QMap<int, Server_AbstractPlayer *> Server_Game::getPlayers() const // copies poi
|
||||
Server_AbstractPlayer *Server_Game::getPlayer(int id) const
|
||||
{
|
||||
auto *participant = participants.value(id);
|
||||
if (!participant->getSpectator()) {
|
||||
if (participant && !participant->isSpectator()) {
|
||||
return static_cast<Server_AbstractPlayer *>(participant);
|
||||
} else {
|
||||
return nullptr;
|
||||
@@ -250,7 +250,7 @@ int Server_Game::getSpectatorCount() const
|
||||
|
||||
int result = 0;
|
||||
for (Server_AbstractParticipant *participant : participants.values()) {
|
||||
if (participant->getSpectator())
|
||||
if (participant->isSpectator())
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
@@ -295,8 +295,8 @@ void Server_Game::sendGameStateToPlayers()
|
||||
// send game state info to clients according to their role in the game
|
||||
for (auto *participant : participants.values()) {
|
||||
GameEventContainer *gec;
|
||||
if (participant->getSpectator()) {
|
||||
if (spectatorsSeeEverything || participant->getJudge()) {
|
||||
if (participant->isSpectator()) {
|
||||
if (spectatorsSeeEverything || participant->isJudge()) {
|
||||
gec = prepareGameEvent(omniscientEvent, -1);
|
||||
} else {
|
||||
gec = prepareGameEvent(spectatorNormalEvent, -1);
|
||||
@@ -527,7 +527,7 @@ void Server_Game::removeParticipant(Server_AbstractParticipant *participant, Eve
|
||||
gameId, participant->getPlayerId());
|
||||
participants.remove(participant->getPlayerId());
|
||||
|
||||
bool spectator = participant->getSpectator();
|
||||
bool spectator = participant->isSpectator();
|
||||
GameEventStorage ges;
|
||||
if (!spectator) {
|
||||
auto *player = static_cast<Server_AbstractPlayer *>(participant);
|
||||
@@ -728,8 +728,8 @@ void Server_Game::createGameJoinedEvent(Server_AbstractParticipant *joiningParti
|
||||
getInfo(*event1.mutable_game_info());
|
||||
event1.set_host_id(hostId);
|
||||
event1.set_player_id(joiningParticipant->getPlayerId());
|
||||
event1.set_spectator(joiningParticipant->getSpectator());
|
||||
event1.set_judge(joiningParticipant->getJudge());
|
||||
event1.set_spectator(joiningParticipant->isSpectator());
|
||||
event1.set_judge(joiningParticipant->isJudge());
|
||||
event1.set_resuming(resuming);
|
||||
if (resuming) {
|
||||
const QStringList &allGameTypes = room->getGameTypes();
|
||||
@@ -747,7 +747,7 @@ void Server_Game::createGameJoinedEvent(Server_AbstractParticipant *joiningParti
|
||||
event2.set_active_player_id(activePlayer);
|
||||
event2.set_active_phase(activePhase);
|
||||
|
||||
bool omniscient = joiningParticipant->getSpectator() && (spectatorsSeeEverything || joiningParticipant->getJudge());
|
||||
bool omniscient = joiningParticipant->isSpectator() && (spectatorsSeeEverything || joiningParticipant->isJudge());
|
||||
for (auto *participant : participants.values()) {
|
||||
participant->getInfo(event2.add_player_list(), joiningParticipant, omniscient, true);
|
||||
}
|
||||
@@ -763,9 +763,8 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont,
|
||||
|
||||
cont->set_game_id(gameId);
|
||||
for (auto *participant : participants.values()) {
|
||||
const bool playerPrivate =
|
||||
(participant->getPlayerId() == privatePlayerId) ||
|
||||
(participant->getSpectator() && (spectatorsSeeEverything || participant->getJudge()));
|
||||
const bool playerPrivate = (participant->getPlayerId() == privatePlayerId) ||
|
||||
(participant->isSpectator() && (spectatorsSeeEverything || participant->isJudge()));
|
||||
if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) ||
|
||||
(recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate))
|
||||
participant->sendGameEvent(*cont);
|
||||
|
||||
Reference in New Issue
Block a user