mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-12 15:49:28 -08:00
Compare commits
11 Commits
oracle-mem
...
tooomm_dox
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d803387b7 | ||
|
|
5905787d3e | ||
|
|
50ba36e2d5 | ||
|
|
fd67ee6d1b | ||
|
|
e41059fa1b | ||
|
|
5df911938b | ||
|
|
057c7f0d3f | ||
|
|
07339efa3c | ||
|
|
2012bfd04b | ||
|
|
27f177fe08 | ||
|
|
5d61cfb133 |
@@ -1,4 +1,4 @@
|
||||
FROM fedora:43
|
||||
FROM fedora:41
|
||||
|
||||
RUN dnf install -y \
|
||||
ccache \
|
||||
@@ -1,21 +0,0 @@
|
||||
FROM debian:11
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ccache \
|
||||
clang-format \
|
||||
cmake \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt5sql5-mysql \
|
||||
libqt5websockets5-dev \
|
||||
ninja-build \
|
||||
protobuf-compiler \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
106
.ci/compile.sh
106
.ci/compile.sh
@@ -11,8 +11,7 @@
|
||||
# --debug or --release sets the build type ie CMAKE_BUILD_TYPE
|
||||
# --ccache [<size>] uses ccache and shows stats, optionally provide size
|
||||
# --dir <dir> sets the name of the build dir, default is "build"
|
||||
# --target-macos-version <version> sets the min os version - only used for macOS builds
|
||||
# uses env: BUILDTYPE MAKE_INSTALL MAKE_PACKAGE PACKAGE_TYPE PACKAGE_SUFFIX MAKE_SERVER MAKE_NO_CLIENT MAKE_TEST USE_CCACHE CCACHE_SIZE BUILD_DIR CMAKE_GENERATOR TARGET_MACOS_VERSION
|
||||
# uses env: BUILDTYPE MAKE_INSTALL MAKE_PACKAGE PACKAGE_TYPE PACKAGE_SUFFIX MAKE_SERVER MAKE_TEST USE_CCACHE CCACHE_SIZE BUILD_DIR CMAKE_GENERATOR
|
||||
# (correspond to args: --debug/--release --install --package <package type> --suffix <suffix> --server --test --ccache <ccache_size> --dir <dir>)
|
||||
# exitcode: 1 for failure, 3 for invalid arguments
|
||||
|
||||
@@ -47,10 +46,6 @@ while [[ $# != 0 ]]; do
|
||||
MAKE_SERVER=1
|
||||
shift
|
||||
;;
|
||||
'--no-client')
|
||||
MAKE_NO_CLIENT=1
|
||||
shift
|
||||
;;
|
||||
'--test')
|
||||
MAKE_TEST=1
|
||||
shift
|
||||
@@ -71,10 +66,6 @@ while [[ $# != 0 ]]; do
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
'--vcpkg')
|
||||
USE_VCPKG=1
|
||||
shift
|
||||
;;
|
||||
'--dir')
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
@@ -84,15 +75,6 @@ while [[ $# != 0 ]]; do
|
||||
BUILD_DIR="$1"
|
||||
shift
|
||||
;;
|
||||
'--target-macos-version')
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--target-macos-version expects an argument"
|
||||
exit 3
|
||||
fi
|
||||
TARGET_MACOS_VERSION="$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "::error file=$0::unrecognized option: $1"
|
||||
exit 3
|
||||
@@ -121,9 +103,6 @@ flags=("-DCMAKE_BUILD_TYPE=$BUILDTYPE")
|
||||
if [[ $MAKE_SERVER ]]; then
|
||||
flags+=("-DWITH_SERVER=1")
|
||||
fi
|
||||
if [[ $MAKE_NO_CLIENT ]]; then
|
||||
flags+=("-DWITH_CLIENT=0" "-DWITH_ORACLE=0" "-DWITH_DBCONVERTER=0")
|
||||
fi
|
||||
if [[ $MAKE_TEST ]]; then
|
||||
flags+=("-DTEST=1")
|
||||
fi
|
||||
@@ -137,9 +116,6 @@ fi
|
||||
if [[ $PACKAGE_TYPE ]]; then
|
||||
flags+=("-DCPACK_GENERATOR=$PACKAGE_TYPE")
|
||||
fi
|
||||
if [[ $USE_VCPKG ]]; then
|
||||
flags+=("-DUSE_VCPKG=1")
|
||||
fi
|
||||
|
||||
# Add cmake --build flags
|
||||
buildflags=(--config "$BUILDTYPE")
|
||||
@@ -156,35 +132,9 @@ function ccachestatsverbose() {
|
||||
|
||||
# Compile
|
||||
if [[ $RUNNER_OS == macOS ]]; then
|
||||
|
||||
if [[ $TARGET_MACOS_VERSION ]]; then
|
||||
# CMAKE_OSX_DEPLOYMENT_TARGET is a vanilla cmake flag needed to compile to target macOS version
|
||||
flags+=("-DCMAKE_OSX_DEPLOYMENT_TARGET=$TARGET_MACOS_VERSION")
|
||||
|
||||
# vcpkg dependencies need a vcpkg triplet file to compile to the target macOS version
|
||||
# an easy way is to copy the x64-osx.cmake file and modify it
|
||||
triplets_dir="/tmp/cmake/triplets"
|
||||
triplet_version="custom-triplet"
|
||||
triplet_file="$triplets_dir/$triplet_version.cmake"
|
||||
arch=$(uname -m)
|
||||
if [[ $arch == x86_64 ]]; then
|
||||
arch="x64"
|
||||
fi
|
||||
mkdir -p "$triplets_dir"
|
||||
cp "../vcpkg/triplets/$arch-osx.cmake" "$triplet_file"
|
||||
echo "set(VCPKG_CMAKE_SYSTEM_VERSION $TARGET_MACOS_VERSION)" >>"$triplet_file"
|
||||
echo "set(VCPKG_OSX_DEPLOYMENT_TARGET $TARGET_MACOS_VERSION)" >>"$triplet_file"
|
||||
flags+=("-DVCPKG_OVERLAY_TRIPLETS=$triplets_dir")
|
||||
flags+=("-DVCPKG_HOST_TRIPLET=$triplet_version")
|
||||
flags+=("-DVCPKG_TARGET_TRIPLET=$triplet_version")
|
||||
echo "::group::Generated triplet $triplet_file"
|
||||
cat "$triplet_file"
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
echo "::group::Signing Certificate"
|
||||
if [[ -n "$MACOS_CERTIFICATE_NAME" ]]; then
|
||||
echo "$MACOS_CERTIFICATE" | base64 --decode >"certificate.p12"
|
||||
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
||||
security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
security set-keychain-settings -t 3600 -l build.keychain
|
||||
@@ -196,29 +146,6 @@ if [[ $RUNNER_OS == macOS ]]; then
|
||||
echo "No signing certificate configured. Skipping set up of keychain in macOS environment."
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ $MAKE_PACKAGE ]]; then
|
||||
# Workaround https://github.com/actions/runner-images/issues/7522
|
||||
# have hdiutil repeat the command 10 times in hope of success
|
||||
hdiutil_script="/tmp/hdiutil.sh"
|
||||
# shellcheck disable=SC2016
|
||||
echo '#!/bin/bash
|
||||
i=0
|
||||
while ! hdiutil "$@"; do
|
||||
if (( ++i >= 10 )); then
|
||||
echo "Error: hdiutil failed $i times!" >&2
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done' >"$hdiutil_script"
|
||||
chmod +x "$hdiutil_script"
|
||||
flags+=(-DCPACK_COMMAND_HDIUTIL="$hdiutil_script")
|
||||
fi
|
||||
|
||||
elif [[ $RUNNER_OS == Windows ]]; then
|
||||
# Enable MTT, see https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||
# and https://devblogs.microsoft.com/cppblog/cpp-build-throughput-investigation-and-tune-up/#multitooltask-mtt
|
||||
buildflags+=(-- -p:UseMultiToolTask=true -p:EnableClServerMode=true)
|
||||
fi
|
||||
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
@@ -229,13 +156,17 @@ fi
|
||||
|
||||
echo "::group::Configure cmake"
|
||||
cmake --version
|
||||
echo "Running cmake with flags: ${flags[*]}"
|
||||
cmake .. "${flags[@]}"
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build project"
|
||||
echo "Running cmake --build with flags: ${buildflags[*]}"
|
||||
cmake --build . "${buildflags[@]}"
|
||||
if [[ $RUNNER_OS == Windows ]]; then
|
||||
# Enable MTT, see https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||
# and https://devblogs.microsoft.com/cppblog/cpp-build-throughput-investigation-and-tune-up/#multitooltask-mtt
|
||||
cmake --build . "${buildflags[@]}" -- -p:UseMultiToolTask=true -p:EnableClServerMode=true
|
||||
else
|
||||
cmake --build . "${buildflags[@]}"
|
||||
fi
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
@@ -244,19 +175,6 @@ if [[ $USE_CCACHE ]]; then
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $RUNNER_OS == macOS ]]; then
|
||||
echo "::group::Inspect Mach-O binaries"
|
||||
for app in cockatrice oracle servatrice dbconverter; do
|
||||
binary="$GITHUB_WORKSPACE/build/$app/$app.app/Contents/MacOS/$app"
|
||||
echo "Inspecting $app..."
|
||||
vtool -show-build "$binary"
|
||||
file "$binary"
|
||||
lipo -info "$binary"
|
||||
echo ""
|
||||
done
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $MAKE_TEST ]]; then
|
||||
echo "::group::Run tests"
|
||||
ctest -C "$BUILDTYPE" --output-on-failure
|
||||
@@ -271,6 +189,12 @@ fi
|
||||
|
||||
if [[ $MAKE_PACKAGE ]]; then
|
||||
echo "::group::Create package"
|
||||
|
||||
if [[ $RUNNER_OS == macOS ]]; then
|
||||
# Workaround https://github.com/actions/runner-images/issues/7522
|
||||
echo "killing XProtectBehaviorService"; sudo pkill -9 XProtect >/dev/null || true;
|
||||
echo "waiting for XProtectBehaviorService kill"; while pgrep "XProtect"; do sleep 3; done;
|
||||
fi
|
||||
cmake --build . --target package --config "$BUILDTYPE"
|
||||
echo "::endgroup::"
|
||||
|
||||
|
||||
@@ -137,11 +137,10 @@ if [[ $SAVE ]]; then
|
||||
fi
|
||||
|
||||
# Set compile function, runs the compile script on the image, passes arguments to the script
|
||||
# shellcheck disable=2120
|
||||
function RUN ()
|
||||
{
|
||||
echo "running image:"
|
||||
if [[ $(docker images) =~ $IMAGE_NAME ]]; then
|
||||
if [[ $(docker images) =~ "$IMAGE_NAME" ]]; then
|
||||
local args=(--mount "type=bind,source=$PWD,target=/src")
|
||||
args+=(--workdir "/src")
|
||||
args+=(--user "$(id -u):$(id -g)")
|
||||
@@ -152,7 +151,6 @@ function RUN ()
|
||||
if [[ -n "$CMAKE_GENERATOR" ]]; then
|
||||
args+=(--env "CMAKE_GENERATOR=$CMAKE_GENERATOR")
|
||||
fi
|
||||
# shellcheck disable=2086
|
||||
docker run "${args[@]}" $RUN_ARGS "$IMAGE_NAME" bash "$BUILD_SCRIPT" $RUN_OPTS "$@"
|
||||
return $?
|
||||
else
|
||||
@@ -166,6 +164,5 @@ function RUN ()
|
||||
if [[ $INTERACTIVE ]]; then
|
||||
export BUILD_SCRIPT="-i"
|
||||
export RUN_ARGS="$RUN_ARGS -it"
|
||||
# shellcheck disable=2119
|
||||
RUN
|
||||
fi
|
||||
|
||||
@@ -11,19 +11,11 @@ if ! git merge-base origin/master HEAD; then
|
||||
fi
|
||||
|
||||
# Check formatting using format.sh
|
||||
echo "Checking your code using format.sh..."
|
||||
echo "Checking your code using clang-format/cmake-format..."
|
||||
|
||||
diff="$(./format.sh --diff --cmake --shell --print-version --branch origin/master)"
|
||||
diff="$(./format.sh --diff --cmake --cf-version --branch origin/master)"
|
||||
err=$?
|
||||
|
||||
sep="
|
||||
----------
|
||||
"
|
||||
used_version="${diff%%"$sep"*}"
|
||||
diff="${diff#*"$sep"}"
|
||||
changes_to_make="${diff%%"$sep"*}"
|
||||
files_to_edit="${diff#*"$sep"}"
|
||||
|
||||
case $err in
|
||||
1)
|
||||
cat <<EOM
|
||||
@@ -41,13 +33,14 @@ case $err in
|
||||
***********************************************************
|
||||
|
||||
Used version:
|
||||
$used_version
|
||||
|
||||
Affected files:
|
||||
$files_to_edit
|
||||
${diff%%
|
||||
----------
|
||||
*}
|
||||
|
||||
The following changes should be made:
|
||||
$changes_to_make
|
||||
${diff#*
|
||||
----------
|
||||
}
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
@@ -65,9 +58,6 @@ EOM
|
||||
*** ***
|
||||
***********************************************************
|
||||
|
||||
Used version:
|
||||
$used_version
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
exit 0
|
||||
|
||||
@@ -23,8 +23,8 @@ Available pre-compiled binaries for installation:
|
||||
• <kbd>Debian 13</kbd> <sub><i>Trixie</i></sub>
|
||||
• <kbd>Debian 12</kbd> <sub><i>Bookworm</i></sub>
|
||||
• <kbd>Debian 11</kbd> <sub><i>Bullseye</i></sub>
|
||||
• <kbd>Fedora 43</kbd>
|
||||
• <kbd>Fedora 42</kbd>
|
||||
• <kbd>Fedora 41</kbd>
|
||||
|
||||
<sub>We are also packaged in <kbd>Arch Linux</kbd>'s <a href="https://archlinux.org/packages/extra/x86_64/cockatrice">official extra repository</a>, courtesy of @FFY00.</sub>
|
||||
<sub>General Linux support is available via a <kbd>flatpak</kbd> package at <a href="https://flathub.org/apps/io.github.Cockatrice.cockatrice">Flathub</a>!</sub>
|
||||
|
||||
@@ -25,9 +25,6 @@ IndentCaseLabels: true
|
||||
PointerAlignment: Right
|
||||
SortIncludes: true
|
||||
IncludeBlocks: Regroup
|
||||
StatementAttributeLikeMacros: [emit]
|
||||
# requires clang-format 16
|
||||
# RemoveSemicolon: true
|
||||
---
|
||||
Language: Proto
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
|
||||
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@@ -1,4 +1,4 @@
|
||||
<!--! @page contributing Contributing -->
|
||||
@page contributing Contributing
|
||||
|
||||
[Introduction](#contributing-to-cockatrice) | [Code Style Guide](
|
||||
#code-style-guide) | [Translations](#translations) | [Release Management](
|
||||
|
||||
315
.github/workflows/desktop-build.yml
vendored
315
.github/workflows/desktop-build.yml
vendored
@@ -4,39 +4,25 @@ permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
actions: write # needed for ccache action to be able to delete gha caches
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '*/**' # matches all files not in root
|
||||
- '!**.md'
|
||||
- '!.github/**'
|
||||
- '!.husky/**'
|
||||
- '!.tx/**'
|
||||
- '!doc/**'
|
||||
- '!webclient/**'
|
||||
- '.github/workflows/desktop-build.yml'
|
||||
- 'CMakeLists.txt'
|
||||
- 'vcpkg.json'
|
||||
- 'vcpkg'
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
- '.github/workflows/docker-release.yml'
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*/**' # matches all files not in root
|
||||
- '!**.md'
|
||||
- '!.github/**'
|
||||
- '!.husky/**'
|
||||
- '!.tx/**'
|
||||
- '!doc/**'
|
||||
- '!webclient/**'
|
||||
- '.github/workflows/desktop-build.yml'
|
||||
- 'CMakeLists.txt'
|
||||
- 'vcpkg.json'
|
||||
- 'vcpkg'
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
|
||||
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on master)
|
||||
concurrency:
|
||||
@@ -70,7 +56,7 @@ jobs:
|
||||
|
||||
- name: Checkout
|
||||
if: steps.configure.outputs.tag != null
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -114,12 +100,7 @@ jobs:
|
||||
- distro: Debian
|
||||
version: 11
|
||||
package: DEB
|
||||
|
||||
- distro: Servatrice_Debian
|
||||
version: 11
|
||||
package: DEB
|
||||
test: skip
|
||||
server_only: yes
|
||||
test: skip # Running tests on all distros is superfluous
|
||||
|
||||
- distro: Debian
|
||||
version: 12
|
||||
@@ -131,12 +112,12 @@ jobs:
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora
|
||||
version: 42
|
||||
version: 41
|
||||
package: RPM
|
||||
test: skip # Running tests on all distros is superfluous
|
||||
|
||||
- distro: Fedora
|
||||
version: 43
|
||||
version: 42
|
||||
package: RPM
|
||||
|
||||
- distro: Ubuntu
|
||||
@@ -162,7 +143,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Restore compiler cache (ccache)
|
||||
id: ccache_restore
|
||||
@@ -196,11 +177,10 @@ jobs:
|
||||
SUFFIX: '-${{matrix.distro}}${{matrix.version}}'
|
||||
package: '${{matrix.package}}'
|
||||
CMAKE_GENERATOR: '${{env.CMAKE_GENERATOR}}'
|
||||
NO_CLIENT: ${{matrix.server_only == 'yes' && '--no-client' || '' }}
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --release --package "$package" --dir "$BUILD_DIR" \
|
||||
--ccache "$CCACHE_SIZE" $NO_CLIENT
|
||||
--ccache "$CCACHE_SIZE"
|
||||
.ci/name_build.sh
|
||||
|
||||
- name: Save compiler cache (ccache)
|
||||
@@ -213,7 +193,7 @@ jobs:
|
||||
- name: Upload artifact
|
||||
id: upload_artifact
|
||||
if: matrix.package != 'skip'
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{matrix.distro}}${{matrix.version}}-package
|
||||
path: ${{steps.build.outputs.path}}
|
||||
@@ -245,135 +225,78 @@ jobs:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
run: gh attestation verify ${{steps.build.outputs.path}} -R Cockatrice/Cockatrice
|
||||
|
||||
build-vcpkg:
|
||||
build-macos:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: macOS
|
||||
target: 13
|
||||
runner: macos-15-intel
|
||||
- target: 13
|
||||
soc: Intel
|
||||
xcode: "16.4"
|
||||
os: macos-13
|
||||
xcode: "14.3.1"
|
||||
type: Release
|
||||
override_target: 13
|
||||
make_package: 1
|
||||
package_suffix: "-macOS13_Intel"
|
||||
artifact_name: macOS13_Intel-package
|
||||
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
|
||||
|
||||
- os: macOS
|
||||
target: 14
|
||||
runner: macos-14
|
||||
- target: 14
|
||||
soc: Apple
|
||||
os: macos-14
|
||||
xcode: "15.4"
|
||||
type: Release
|
||||
make_package: 1
|
||||
package_suffix: "-macOS14"
|
||||
artifact_name: macOS14-package
|
||||
qt_version: 6.6.*
|
||||
qt_arch: clang_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: false
|
||||
cmake_generator: Ninja
|
||||
use_ccache: 1
|
||||
|
||||
- os: macOS
|
||||
target: 15
|
||||
runner: macos-15
|
||||
- target: 15
|
||||
soc: Apple
|
||||
xcode: "16.4"
|
||||
os: macos-15
|
||||
xcode: "16.2"
|
||||
type: Release
|
||||
make_package: 1
|
||||
package_suffix: "-macOS15"
|
||||
artifact_name: macOS15-package
|
||||
qt_version: 6.6.*
|
||||
qt_arch: clang_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: false
|
||||
cmake_generator: Ninja
|
||||
use_ccache: 1
|
||||
|
||||
- os: macOS
|
||||
target: 15
|
||||
runner: macos-15
|
||||
- target: 15
|
||||
soc: Apple
|
||||
xcode: "16.4"
|
||||
os: macos-15
|
||||
xcode: "16.2"
|
||||
type: Debug
|
||||
qt_version: 6.6.*
|
||||
qt_arch: clang_64
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
cache_qt: false
|
||||
cmake_generator: Ninja
|
||||
use_ccache: 1
|
||||
|
||||
- os: Windows
|
||||
target: 7
|
||||
runner: windows-2022
|
||||
type: Release
|
||||
make_package: 1
|
||||
package_suffix: "-Win7"
|
||||
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
|
||||
|
||||
- os: Windows
|
||||
target: 10
|
||||
runner: windows-2022
|
||||
type: Release
|
||||
make_package: 1
|
||||
package_suffix: "-Win10"
|
||||
artifact_name: Windows10-installer
|
||||
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
|
||||
|
||||
name: ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }}
|
||||
name: macOS ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }}
|
||||
needs: configure
|
||||
runs-on: ${{matrix.runner}}
|
||||
runs-on: ${{matrix.os}}
|
||||
continue-on-error: ${{matrix.allow-failure == 'yes'}}
|
||||
env:
|
||||
# Common parameters for all macOS builds
|
||||
QT_VERSION: 6.6.*
|
||||
QT_ARCH: clang_64
|
||||
QT_MODULES: "qtimageformats qtmultimedia qtwebsockets"
|
||||
# Build-specific environment variables
|
||||
CCACHE_DIR: ${{github.workspace}}/.ccache/${{matrix.os}}-${{matrix.type}}
|
||||
CCACHE_SIZE: 500M
|
||||
DEVELOPER_DIR:
|
||||
/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer
|
||||
CMAKE_GENERATOR: 'Ninja'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Add msbuild to PATH
|
||||
if: matrix.os == 'Windows'
|
||||
id: add-msbuild
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
|
||||
# Using jianmingyong/ccache-action to setup ccache without using brew
|
||||
# It tries to download a binary of ccache from GitHub Release and falls back to building from source if it fails
|
||||
- name: Setup ccache
|
||||
if: matrix.use_ccache == 1
|
||||
uses: jianmingyong/ccache-action@v1
|
||||
with:
|
||||
install-type: "binary"
|
||||
ccache-key-prefix: ccache-${{matrix.runner}}-${{matrix.soc}}-${{matrix.type}}
|
||||
max-size: 500M
|
||||
ccache-key-prefix: ccache-${{matrix.os}}-${{matrix.soc}}-${{matrix.type}}
|
||||
gh-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Install Qt ${{matrix.qt_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 Qt ${{env.QT_VERSION}}
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: ${{matrix.qt_version}}
|
||||
arch: ${{matrix.qt_arch}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
cache: ${{matrix.cache_qt}}
|
||||
cache: false # qt caches take too much space for macOS (1.1Gi)
|
||||
version: ${{env.QT_VERSION}}
|
||||
arch: ${{env.QT_ARCH}}
|
||||
modules: ${{env.QT_MODULES}}
|
||||
|
||||
- name: Setup vcpkg cache
|
||||
id: vcpkg-cache
|
||||
@@ -381,30 +304,24 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# uses environment variables, see compile.sh for more details
|
||||
- name: Build Cockatrice
|
||||
id: build
|
||||
- name: Build on Xcode ${{matrix.xcode}}
|
||||
shell: bash
|
||||
id: build
|
||||
env:
|
||||
BUILDTYPE: '${{matrix.type}}'
|
||||
MAKE_PACKAGE: '${{matrix.make_package}}'
|
||||
PACKAGE_SUFFIX: '${{matrix.package_suffix}}'
|
||||
CMAKE_GENERATOR: ${{matrix.cmake_generator}}
|
||||
CMAKE_GENERATOR_PLATFORM: ${{matrix.cmake_generator_platform}}
|
||||
USE_CCACHE: ${{matrix.use_ccache}}
|
||||
VCPKG_DISABLE_METRICS: 1
|
||||
VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite'
|
||||
# macOS-specific environment variables, will be ignored on Windows
|
||||
PACKAGE_SUFFIX: '-macOS${{matrix.target}}_${{matrix.soc}}'
|
||||
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
|
||||
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
|
||||
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
||||
DEVELOPER_DIR: '/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer'
|
||||
TARGET_MACOS_VERSION: ${{ matrix.override_target }}
|
||||
run: .ci/compile.sh --server --test --vcpkg
|
||||
CMAKE_GENERATOR: '${{env.CMAKE_GENERATOR}}'
|
||||
VCPKG_DISABLE_METRICS: 1
|
||||
VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite'
|
||||
run: .ci/compile.sh --server --test --ccache "$CCACHE_SIZE"
|
||||
|
||||
- name: Sign app bundle
|
||||
if: matrix.os == 'macOS' && matrix.make_package && (github.ref == 'refs/heads/master' || needs.configure.outputs.tag != null)
|
||||
if: matrix.make_package && (github.ref == 'refs/heads/master' || needs.configure.outputs.tag != null)
|
||||
env:
|
||||
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
|
||||
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
||||
@@ -416,7 +333,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Notarize app bundle
|
||||
if: matrix.os == 'macOS' && matrix.make_package && (github.ref == 'refs/heads/master' || needs.configure.outputs.tag != null)
|
||||
if: matrix.make_package && (github.ref == 'refs/heads/master' || needs.configure.outputs.tag != null)
|
||||
env:
|
||||
MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
|
||||
MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
|
||||
@@ -427,20 +344,20 @@ jobs:
|
||||
# Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI
|
||||
echo "Create keychain profile"
|
||||
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$MACOS_NOTARIZATION_APPLE_ID" --team-id "$MACOS_NOTARIZATION_TEAM_ID" --password "$MACOS_NOTARIZATION_PWD"
|
||||
|
||||
|
||||
# We can't notarize an app bundle directly, but we need to compress it as an archive.
|
||||
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
|
||||
# notarization service
|
||||
echo "Creating temp notarization archive"
|
||||
ditto -c -k --keepParent ${{steps.build.outputs.path}} "notarization.zip"
|
||||
|
||||
|
||||
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
|
||||
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
|
||||
# characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
|
||||
# you're curious
|
||||
echo "Notarize app"
|
||||
xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
|
||||
|
||||
|
||||
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
|
||||
# validated by macOS even when an internet connection is not available.
|
||||
echo "Attach staple"
|
||||
@@ -450,15 +367,109 @@ jobs:
|
||||
- name: Upload artifact
|
||||
id: upload_artifact
|
||||
if: matrix.make_package
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{matrix.artifact_name}}
|
||||
name: macOS${{matrix.target}}${{ matrix.soc == 'Intel' && '_Intel' || '' }}${{ matrix.type == 'Debug' && '_Debug' || '' }}-package
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
id: upload_release
|
||||
if: matrix.make_package && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{needs.configure.outputs.tag}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
|
||||
- name: Attest binary provenance
|
||||
id: attestation
|
||||
if: steps.upload_release.outcome == 'success'
|
||||
uses: actions/attest-build-provenance@v3
|
||||
with:
|
||||
subject-name: ${{steps.build.outputs.name}}
|
||||
subject-digest: sha256:${{ steps.upload_artifact.outputs.artifact-digest }}
|
||||
|
||||
- name: Verify binary attestation
|
||||
if: steps.attestation.outcome == 'success'
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
run: gh attestation verify ${{steps.build.outputs.path}} -R Cockatrice/Cockatrice
|
||||
|
||||
build-windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: 7
|
||||
qt_version: 5.15.*
|
||||
qt_arch: msvc2019_64
|
||||
|
||||
- target: 10
|
||||
qt_version: 6.6.*
|
||||
qt_arch: msvc2019_64
|
||||
qt_modules: "qtimageformats qtmultimedia qtwebsockets"
|
||||
|
||||
name: Windows ${{matrix.target}}
|
||||
needs: configure
|
||||
runs-on: windows-2022
|
||||
env:
|
||||
CMAKE_GENERATOR: 'Visual Studio 17 2022'
|
||||
|
||||
steps:
|
||||
- name: Add msbuild to PATH
|
||||
id: add-msbuild
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt ${{matrix.qt_version}}
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
cache: true
|
||||
setup-python: true
|
||||
version: ${{matrix.qt_version}}
|
||||
arch: win64_${{matrix.qt_arch}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
|
||||
- name: Setup vcpkg cache
|
||||
id: vcpkg-cache
|
||||
uses: TAServers/vcpkg-cache@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Cockatrice
|
||||
id: build
|
||||
shell: bash
|
||||
env:
|
||||
PACKAGE_SUFFIX: '-Win${{matrix.target}}'
|
||||
CMAKE_GENERATOR: '${{env.CMAKE_GENERATOR}}'
|
||||
CMAKE_GENERATOR_PLATFORM: 'x64'
|
||||
QTDIR: '${{github.workspace}}\Qt\${{matrix.qt_version}}\win64_${{matrix.qt_arch}}'
|
||||
VCPKG_DISABLE_METRICS: 1
|
||||
VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite'
|
||||
# No need for --parallel flag, MTT is added in the compile script to let cmake/msbuild manage core count,
|
||||
# project and process parallelism: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||
run: .ci/compile.sh --server --release --test --package
|
||||
|
||||
- name: Upload artifact
|
||||
id: upload_artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Windows${{matrix.target}}-installer
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload pdb database
|
||||
if: matrix.os == 'Windows'
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Windows${{matrix.target}}-debug-pdbs
|
||||
path: |
|
||||
|
||||
25
.github/workflows/desktop-lint.yml
vendored
25
.github/workflows/desktop-lint.yml
vendored
@@ -1,22 +1,13 @@
|
||||
name: Code Style (C++)
|
||||
|
||||
on:
|
||||
# push trigger not needed for linting, we do not allow direct pushes to master
|
||||
pull_request:
|
||||
paths:
|
||||
- '*/**' # matches all files not in root
|
||||
- '!**.md'
|
||||
- '!.ci/**'
|
||||
- '!.github/**'
|
||||
- '!.husky/**'
|
||||
- '!.tx/**'
|
||||
- '!doc/**'
|
||||
- '!webclient/**'
|
||||
- '.ci/lint_cpp.sh'
|
||||
- '.github/workflows/desktop-lint.yml'
|
||||
- '.clang-format'
|
||||
- '.cmake-format.json'
|
||||
- 'format.sh'
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
- '.github/workflows/docker-release.yml'
|
||||
|
||||
jobs:
|
||||
format:
|
||||
@@ -24,7 +15,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 20 # should be enough to find merge base
|
||||
|
||||
@@ -32,7 +23,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends clang-format cmake-format shellcheck
|
||||
sudo apt-get install -y --no-install-recommends clang-format cmake-format
|
||||
|
||||
- name: Check code formatting
|
||||
shell: bash
|
||||
|
||||
3
.github/workflows/docker-release.yml
vendored
3
.github/workflows/docker-release.yml
vendored
@@ -11,7 +11,6 @@ on:
|
||||
- master
|
||||
paths:
|
||||
- '.github/workflows/docker-release.yml'
|
||||
- 'Dockerfile'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
@@ -23,7 +22,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Docker metadata
|
||||
id: metadata
|
||||
|
||||
52
.github/workflows/documentation-build.yml
vendored
52
.github/workflows/documentation-build.yml
vendored
@@ -6,7 +6,8 @@ on:
|
||||
- '*' # Only re-generate docs when a new tagged version is pushed
|
||||
pull_request:
|
||||
paths:
|
||||
- 'doc/doxygen/**'
|
||||
- '**.h'
|
||||
- '/doc/doxygen/**'
|
||||
- '.github/workflows/documentation-build.yml'
|
||||
- 'Doxyfile'
|
||||
workflow_dispatch:
|
||||
@@ -20,42 +21,35 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Graphviz
|
||||
run: |
|
||||
sudo apt-get install -y graphviz
|
||||
dot -V
|
||||
|
||||
- name: Install Doxygen
|
||||
uses: ssciwr/doxygen-install@v1
|
||||
with:
|
||||
version: "1.14.0"
|
||||
|
||||
- name: Update Doxygen Configuration
|
||||
run: |
|
||||
git diff Doxyfile
|
||||
doxygen -u Doxyfile
|
||||
if git diff --quiet Doxyfile; then
|
||||
echo "::notice::No config changes in Doxyfile detected."
|
||||
else
|
||||
echo "::error::Config changes in Doxyfile detected! Please update the file by running 'doxygen -u Doxyfile'."
|
||||
echo ""
|
||||
git diff --color=always Doxyfile
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Doxygen and Graphviz
|
||||
shell: bash
|
||||
run: sudo apt-get install -y doxygen graphviz
|
||||
|
||||
- name: Generate Documentation
|
||||
if: always()
|
||||
shell: bash
|
||||
run: doxygen Doxyfile
|
||||
|
||||
- name: Deploy to cockatrice.github.io
|
||||
- name: Upload Documentation
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Cockatrice_Docs
|
||||
path: ./docs/html # Main output folder + subfolder defined in Doxygen config
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Deploy to cockatrice.github.io/docs
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }}
|
||||
external_repository: Cockatrice/cockatrice.github.io
|
||||
publish_branch: master
|
||||
publish_dir: ./docs/html
|
||||
destination_dir: docs # Docs will live under https://cockatrice.github.io/docs/
|
||||
publish_dir: ./docs/html # Main output folder + subfolder defined in Doxygen config
|
||||
destination_dir: docs # Subfolder of the GitHub Pages URL where the docs live
|
||||
|
||||
- name: Link to Documentation Page
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
run: echo "::notice title=New documentation published ::Shortly available at https://cockatrice.github.io/docs/"
|
||||
|
||||
3
.github/workflows/translations-pull.yml
vendored
3
.github/workflows/translations-pull.yml
vendored
@@ -7,7 +7,6 @@ on:
|
||||
- cron: '0 0 15 1,4,7,10 *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.tx/**'
|
||||
- '.github/workflows/translations-pull.yml'
|
||||
|
||||
jobs:
|
||||
@@ -20,7 +19,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Pull translated strings from Transifex
|
||||
uses: transifex/cli-action@v2
|
||||
|
||||
11
.github/workflows/translations-push.yml
vendored
11
.github/workflows/translations-push.yml
vendored
@@ -7,7 +7,6 @@ on:
|
||||
- cron: '0 0 1 1,4,7,10 *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.ci/update_translation_source_strings.sh'
|
||||
- '.github/workflows/translations-push.yml'
|
||||
|
||||
jobs:
|
||||
@@ -20,7 +19,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install lupdate
|
||||
shell: bash
|
||||
@@ -31,10 +30,10 @@ jobs:
|
||||
- name: Update Cockatrice translation source
|
||||
id: cockatrice
|
||||
shell: bash
|
||||
run: |
|
||||
FILE="cockatrice/cockatrice_en@source.ts"
|
||||
export DIRS="cockatrice/src $(find . -maxdepth 1 -type d -name 'libcockatrice_*')"
|
||||
FILE="$FILE" DIRS="$DIRS" .ci/update_translation_source_strings.sh
|
||||
env:
|
||||
FILE: 'cockatrice/cockatrice_en@source.ts'
|
||||
DIRS: 'cockatrice/src common'
|
||||
run: .ci/update_translation_source_strings.sh
|
||||
|
||||
- name: Update Oracle translation source
|
||||
id: oracle
|
||||
|
||||
10
.github/workflows/web-build.yml
vendored
10
.github/workflows/web-build.yml
vendored
@@ -5,16 +5,14 @@ on:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.husky/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
- '!**.md'
|
||||
- '.github/workflows/web-build.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.husky/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
- '!**.md'
|
||||
- '.github/workflows/web-build.yml'
|
||||
|
||||
jobs:
|
||||
build-web:
|
||||
@@ -35,10 +33,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: ${{matrix.node_version}}
|
||||
cache: 'npm'
|
||||
|
||||
7
.github/workflows/web-lint.yml
vendored
7
.github/workflows/web-lint.yml
vendored
@@ -1,12 +1,11 @@
|
||||
name: Code Style (TypeScript)
|
||||
|
||||
on:
|
||||
# push trigger not needed for linting, we do not allow direct pushes to master
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
- '!**.md'
|
||||
- '.github/workflows/web-lint.yml'
|
||||
|
||||
jobs:
|
||||
ESLint:
|
||||
@@ -18,10 +17,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'webclient/package-lock.json'
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,4 +14,3 @@ compile_commands.json
|
||||
.cache
|
||||
.gdb_history
|
||||
cockatrice/resources/config/qtlogging.ini
|
||||
docs/
|
||||
|
||||
@@ -24,8 +24,6 @@ option(WITH_ORACLE "build oracle" ON)
|
||||
option(WITH_DBCONVERTER "build dbconverter" ON)
|
||||
# Compile tests
|
||||
option(TEST "build tests" OFF)
|
||||
# Use vcpkg regardless of OS
|
||||
option(USE_VCPKG "Use vcpkg regardless of OS" OFF)
|
||||
|
||||
# Default to "Release" build type
|
||||
# User-provided value for CMAKE_BUILD_TYPE must be checked before the PROJECT() call
|
||||
@@ -50,8 +48,8 @@ if(USE_CCACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32 OR USE_VCPKG)
|
||||
# Use vcpkg toolchain on Windows (and on macOS in CI)
|
||||
if(WIN32 OR APPLE)
|
||||
# Use vcpkg toolchain on Windows and macOS
|
||||
set(CMAKE_TOOLCHAIN_FILE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
CACHE STRING "Vcpkg toolchain file"
|
||||
@@ -328,19 +326,7 @@ endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_interfaces ${CMAKE_BINARY_DIR}/libcockatrice_interfaces)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_protocol ${CMAKE_BINARY_DIR}/libcockatrice_protocol)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_network ${CMAKE_BINARY_DIR}/libcockatrice_network)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_deck_list ${CMAKE_BINARY_DIR}/libcockatrice_deck_list)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_rng ${CMAKE_BINARY_DIR}/libcockatrice_rng)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_card ${CMAKE_BINARY_DIR}/libcockatrice_card)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_utility ${CMAKE_BINARY_DIR}/libcockatrice_utility)
|
||||
if(WITH_ORACLE OR WITH_CLIENT)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_settings ${CMAKE_BINARY_DIR}/libcockatrice_settings)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_models ${CMAKE_BINARY_DIR}/libcockatrice_models)
|
||||
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_filters ${CMAKE_BINARY_DIR}/libcockatrice_filters)
|
||||
endif()
|
||||
|
||||
add_subdirectory(common)
|
||||
if(WITH_SERVER)
|
||||
add_subdirectory(servatrice)
|
||||
set(CPACK_INSTALL_CMAKE_PROJECTS "Servatrice;Servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
|
||||
33
Dockerfile
33
Dockerfile
@@ -1,9 +1,8 @@
|
||||
# -------- Build Stage --------
|
||||
FROM ubuntu:24.04 AS build
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
RUN apt-get update && apt-get install -y\
|
||||
build-essential \
|
||||
cmake \
|
||||
file \
|
||||
@@ -17,28 +16,20 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
RUN mkdir build && cd build && \
|
||||
cmake .. -DWITH_SERVER=1 -DWITH_CLIENT=0 -DWITH_ORACLE=0 -DWITH_DBCONVERTER=0 && \
|
||||
make -j$(nproc) && \
|
||||
make install
|
||||
COPY ./CMakeLists.txt ./LICENSE ./README.md /home/servatrice/code/
|
||||
COPY ./cmake /home/servatrice/code/cmake
|
||||
COPY ./common /home/servatrice/code/common
|
||||
COPY ./servatrice /home/servatrice/code/servatrice
|
||||
|
||||
WORKDIR /home/servatrice/code
|
||||
|
||||
# -------- Runtime Stage (clean) --------
|
||||
FROM ubuntu:24.04
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libprotobuf32t64 \
|
||||
libqt6sql6-mysql \
|
||||
libqt6websockets6 \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Only copy installed binaries, not source
|
||||
COPY --from=build /usr/local /usr/local
|
||||
WORKDIR build
|
||||
RUN cmake .. -DWITH_SERVER=1 -DWITH_CLIENT=0 -DWITH_ORACLE=0 -DWITH_DBCONVERTER=0 &&\
|
||||
make &&\
|
||||
make install
|
||||
|
||||
WORKDIR /home/servatrice
|
||||
|
||||
EXPOSE 4748
|
||||
|
||||
ENTRYPOINT [ "servatrice", "--log-to-console" ]
|
||||
|
||||
97
Doxyfile
97
Doxyfile
@@ -1,4 +1,5 @@
|
||||
# Doxyfile 1.14.0
|
||||
# Docs: https://www.doxygen.nl/manual
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# Doxygen (www.doxygen.org) for a project.
|
||||
@@ -42,7 +43,7 @@ DOXYFILE_ENCODING = UTF-8
|
||||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = Cockatrice
|
||||
PROJECT_NAME = "Cockatrice"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
@@ -54,7 +55,7 @@ PROJECT_NUMBER = $(COCKATRICE_REF)
|
||||
# for a project that appears at the top of each page and should give viewers a
|
||||
# quick idea about the purpose of the project. Keep the description short.
|
||||
|
||||
PROJECT_BRIEF = "A cross-platform virtual tabletop for multiplayer card games"
|
||||
PROJECT_BRIEF = A cross-platform virtual tabletop for multiplayer card games
|
||||
|
||||
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
|
||||
# in the documentation. The maximum height of the logo should not exceed 55
|
||||
@@ -379,7 +380,7 @@ TOC_INCLUDE_HEADINGS = 6
|
||||
# The default value is: DOXYGEN.
|
||||
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
||||
|
||||
MARKDOWN_ID_STYLE = GITHUB
|
||||
MARKDOWN_ID_STYLE = DOXYGEN
|
||||
|
||||
# When enabled Doxygen tries to link words that correspond to documented
|
||||
# classes, or namespaces to their corresponding documentation. Such a link can
|
||||
@@ -991,7 +992,7 @@ WARN_LOGFILE =
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = .
|
||||
INPUT = cockatrice common doc/doxygen/extra-pages doc/doxygen/groups .github/CONTRIBUTING.md
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that Doxygen parses. Internally Doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@@ -1031,7 +1032,8 @@ INPUT_FILE_ENCODING =
|
||||
# provided as Doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
|
||||
# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
|
||||
|
||||
FILE_PATTERNS = *.cc \
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
*.cxx \
|
||||
*.cxxm \
|
||||
*.cpp \
|
||||
@@ -1039,19 +1041,47 @@ FILE_PATTERNS = *.cc \
|
||||
*.ccm \
|
||||
*.c++ \
|
||||
*.c++m \
|
||||
*.java \
|
||||
*.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
*.inl \
|
||||
*.idl \
|
||||
*.ddl \
|
||||
*.odl \
|
||||
*.h \
|
||||
*.hh \
|
||||
*.hxx \
|
||||
*.hpp \
|
||||
*.h++ \
|
||||
*.l \
|
||||
*.cs \
|
||||
*.d \
|
||||
*.php \
|
||||
*.php4 \
|
||||
*.php5 \
|
||||
*.phtml \
|
||||
*.inc \
|
||||
*.m \
|
||||
*.markdown \
|
||||
*.md \
|
||||
*.dox
|
||||
*.mm \
|
||||
*.dox \
|
||||
*.py \
|
||||
*.pyw \
|
||||
*.f90 \
|
||||
*.f95 \
|
||||
*.f03 \
|
||||
*.f08 \
|
||||
*.f18 \
|
||||
*.f \
|
||||
*.for \
|
||||
*.vhd \
|
||||
*.vhdl \
|
||||
*.ucf \
|
||||
*.qsf \
|
||||
*.ice
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
# be searched for input files as well.
|
||||
@@ -1066,11 +1096,7 @@ RECURSIVE = YES
|
||||
# Note that relative paths are relative to the directory from which Doxygen is
|
||||
# run.
|
||||
|
||||
EXCLUDE = build/ \
|
||||
cmake/ \
|
||||
dbconverter/ \
|
||||
vcpkg/ \
|
||||
webclient/
|
||||
EXCLUDE = common/lib
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||
@@ -1086,8 +1112,7 @@ EXCLUDE_SYMLINKS = NO
|
||||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories for example use the pattern */test/*
|
||||
|
||||
EXCLUDE_PATTERNS = .* \
|
||||
.*/
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
@@ -1121,7 +1146,7 @@ EXAMPLE_RECURSIVE = NO
|
||||
# that contain images that are to be included in the documentation (see the
|
||||
# \image command).
|
||||
|
||||
IMAGE_PATH = doc/doxygen/images
|
||||
IMAGE_PATH =
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that Doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
@@ -1289,46 +1314,6 @@ USE_HTAGS = NO
|
||||
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the CLANG_ASSISTED_PARSING tag is set to YES then Doxygen will use the
|
||||
# clang parser (see:
|
||||
# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
|
||||
# performance. This can be particularly helpful with template rich C++ code for
|
||||
# which Doxygen's built-in parser lacks the necessary type information.
|
||||
# Note: The availability of this option depends on whether or not Doxygen was
|
||||
# generated with the -Duse_libclang=ON option for CMake.
|
||||
# The default value is: NO.
|
||||
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
|
||||
# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS
|
||||
# tag is set to YES then Doxygen will add the directory of each input to the
|
||||
# include path.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||
|
||||
CLANG_ADD_INC_PATHS = YES
|
||||
|
||||
# If clang assisted parsing is enabled you can provide the compiler with command
|
||||
# line options that you would normally use when invoking the compiler. Note that
|
||||
# the include paths will already be set by Doxygen for the files and directories
|
||||
# specified with INPUT and INCLUDE_PATH.
|
||||
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||
|
||||
CLANG_OPTIONS =
|
||||
|
||||
# If clang assisted parsing is enabled you can provide the clang parser with the
|
||||
# path to the directory containing a file called compile_commands.json. This
|
||||
# file is the compilation database (see:
|
||||
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
|
||||
# options used when the source files were built. This is equivalent to
|
||||
# specifying the -p option to a clang tool, such as clang-check. These options
|
||||
# will then be passed to the parser. Any options specified with CLANG_OPTIONS
|
||||
# will be added as well.
|
||||
# Note: The availability of this option depends on whether or not Doxygen was
|
||||
# generated with the -Duse_libclang=ON option for CMake.
|
||||
|
||||
CLANG_DATABASE_PATH =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2623,7 +2608,7 @@ DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
|
||||
# The default value is: labelfontname=Helvetica,labelfontsize=10.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10,arrowhead=open, arrowtail=open, arrowsize=0.5"
|
||||
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10,arrowhead=open, arrowtail=open, arrowsize=0.5"
|
||||
|
||||
# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes
|
||||
# around nodes set 'shape=plain' or 'shape=plaintext' <a
|
||||
@@ -2631,7 +2616,7 @@ DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10,arrowhead=ope
|
||||
# The default value is: shape=box,height=0.2,width=0.4.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
|
||||
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
|
||||
|
||||
# You can set the path where dot can find font specified with fontname in
|
||||
# DOT_COMMON_ATTR and others dot attributes.
|
||||
|
||||
@@ -115,7 +115,4 @@ string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" ORACLE_QT_MO
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" DB_CONVERTER_QT_MODULES "${_DBCONVERTER_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" TEST_QT_MODULES "${_TEST_NEEDED}")
|
||||
|
||||
# Core-only export (useful for headless libs)
|
||||
set(QT_CORE_MODULE "${COCKATRICE_QT_VERSION_NAME}::Core")
|
||||
|
||||
message(STATUS "Found Qt ${${COCKATRICE_QT_VERSION_NAME}_VERSION} at: ${${COCKATRICE_QT_VERSION_NAME}_DIR}")
|
||||
|
||||
@@ -7,52 +7,78 @@ project(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${
|
||||
set(cockatrice_SOURCES
|
||||
${VERSION_STRING_CPP}
|
||||
# sort by alphabetical order, so that there is no debate about where to add new sources to the list
|
||||
src/client/network/update/client/update_downloader.cpp
|
||||
src/client/network/interfaces/deck_stats_interface.cpp
|
||||
src/client/network/interfaces/tapped_out_interface.cpp
|
||||
src/card/card_info.cpp
|
||||
src/card/card_relation.cpp
|
||||
src/card/card_set.cpp
|
||||
src/card/card_set_list.cpp
|
||||
src/card/exact_card.cpp
|
||||
src/card/printing_info.cpp
|
||||
src/client/deck_editor_menu.cpp
|
||||
src/client/get_text_with_max.cpp
|
||||
src/client/network/client_update_checker.cpp
|
||||
src/client/network/parsers/deck_link_to_api_transformer.cpp
|
||||
src/client/network/update/client/client_update_checker.cpp
|
||||
src/client/network/update/client/release_channel.cpp
|
||||
src/client/network/update/card_spoiler/spoiler_background_updater.cpp
|
||||
src/client/network/release_channel.cpp
|
||||
src/client/network/replay_timeline_widget.cpp
|
||||
src/client/network/sets_model.cpp
|
||||
src/client/network/spoiler_background_updater.cpp
|
||||
src/client/replay_manager.cpp
|
||||
src/client/sound_engine.cpp
|
||||
src/client/settings/cache_settings.cpp
|
||||
src/client/settings/card_counter_settings.cpp
|
||||
src/client/settings/shortcut_treeview.cpp
|
||||
src/client/settings/shortcuts_settings.cpp
|
||||
src/interface/deck_loader/deck_loader.cpp
|
||||
src/interface/widgets/dialogs/dlg_connect.cpp
|
||||
src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.cpp
|
||||
src/interface/widgets/dialogs/dlg_create_game.cpp
|
||||
src/interface/widgets/dialogs/dlg_default_tags_editor.cpp
|
||||
src/interface/widgets/dialogs/dlg_edit_avatar.cpp
|
||||
src/interface/widgets/dialogs/dlg_edit_password.cpp
|
||||
src/interface/widgets/dialogs/dlg_edit_tokens.cpp
|
||||
src/interface/widgets/dialogs/dlg_edit_user.cpp
|
||||
src/interface/widgets/dialogs/dlg_filter_games.cpp
|
||||
src/interface/widgets/dialogs/dlg_forgot_password_challenge.cpp
|
||||
src/interface/widgets/dialogs/dlg_forgot_password_request.cpp
|
||||
src/interface/widgets/dialogs/dlg_forgot_password_reset.cpp
|
||||
src/interface/widgets/dialogs/dlg_load_deck.cpp
|
||||
src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp
|
||||
src/interface/widgets/dialogs/dlg_load_deck_from_website.cpp
|
||||
src/interface/widgets/dialogs/dlg_load_remote_deck.cpp
|
||||
src/interface/widgets/dialogs/dlg_manage_sets.cpp
|
||||
src/interface/widgets/dialogs/dlg_register.cpp
|
||||
src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp
|
||||
src/interface/widgets/dialogs/dlg_settings.cpp
|
||||
src/interface/widgets/dialogs/dlg_startup_card_check.cpp
|
||||
src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp
|
||||
src/interface/widgets/dialogs/dlg_update.cpp
|
||||
src/interface/widgets/dialogs/dlg_view_log.cpp
|
||||
src/interface/widgets/dialogs/tip_of_the_day.cpp
|
||||
src/client/tapped_out_interface.cpp
|
||||
src/client/update_downloader.cpp
|
||||
src/database/card_database.cpp
|
||||
src/database/card_database_loader.cpp
|
||||
src/database/card_database_manager.cpp
|
||||
src/database/card_database_querier.cpp
|
||||
src/database/model/card_database_model.cpp
|
||||
src/database/model/card_database_display_model.cpp
|
||||
src/database/model/card/card_completer_proxy_model.cpp
|
||||
src/database/model/card/card_search_model.cpp
|
||||
src/database/model/token/token_display_model.cpp
|
||||
src/database/model/token/token_edit_model.cpp
|
||||
src/database/parser/card_database_parser.cpp
|
||||
src/database/parser/cockatrice_xml_3.cpp
|
||||
src/database/parser/cockatrice_xml_4.cpp
|
||||
src/deck/custom_line_edit.cpp
|
||||
src/deck/deck_list_model.cpp
|
||||
src/deck/deck_loader.cpp
|
||||
src/deck/deck_stats_interface.cpp
|
||||
src/dialogs/dlg_connect.cpp
|
||||
src/dialogs/dlg_convert_deck_to_cod_format.cpp
|
||||
src/dialogs/dlg_create_game.cpp
|
||||
src/dialogs/dlg_default_tags_editor.cpp
|
||||
src/dialogs/dlg_edit_avatar.cpp
|
||||
src/dialogs/dlg_edit_password.cpp
|
||||
src/dialogs/dlg_edit_tokens.cpp
|
||||
src/dialogs/dlg_edit_user.cpp
|
||||
src/dialogs/dlg_filter_games.cpp
|
||||
src/dialogs/dlg_forgot_password_challenge.cpp
|
||||
src/dialogs/dlg_forgot_password_request.cpp
|
||||
src/dialogs/dlg_forgot_password_reset.cpp
|
||||
src/dialogs/dlg_load_deck.cpp
|
||||
src/dialogs/dlg_load_deck_from_clipboard.cpp
|
||||
src/dialogs/dlg_load_deck_from_website.cpp
|
||||
src/dialogs/dlg_load_remote_deck.cpp
|
||||
src/dialogs/dlg_manage_sets.cpp
|
||||
src/dialogs/dlg_register.cpp
|
||||
src/dialogs/dlg_select_set_for_cards.cpp
|
||||
src/dialogs/dlg_settings.cpp
|
||||
src/dialogs/dlg_startup_card_check.cpp
|
||||
src/dialogs/dlg_tip_of_the_day.cpp
|
||||
src/dialogs/dlg_update.cpp
|
||||
src/dialogs/dlg_view_log.cpp
|
||||
src/dialogs/tip_of_the_day.cpp
|
||||
src/filters/deck_filter_string.cpp
|
||||
src/filters/filter_builder.cpp
|
||||
src/filters/filter_card.cpp
|
||||
src/filters/filter_string.cpp
|
||||
src/filters/filter_tree.cpp
|
||||
src/filters/filter_tree_model.cpp
|
||||
src/filters/syntax_help.cpp
|
||||
src/game/abstract_game.cpp
|
||||
src/game/board/abstract_card_drag_item.cpp
|
||||
src/game/board/abstract_card_item.cpp
|
||||
src/game/board/abstract_counter.cpp
|
||||
src/game/board/abstract_graphics_item.cpp
|
||||
src/game/board/arrow_item.cpp
|
||||
src/game/board/arrow_target.cpp
|
||||
src/game/board/card_drag_item.cpp
|
||||
@@ -112,17 +138,9 @@ set(cockatrice_SOURCES
|
||||
src/game/zones/table_zone.cpp
|
||||
src/game/zones/view_zone.cpp
|
||||
src/game/zones/view_zone_widget.cpp
|
||||
src/game_graphics/board/abstract_graphics_item.cpp
|
||||
src/interface/card_picture_loader/card_picture_loader.cpp
|
||||
src/interface/card_picture_loader/card_picture_loader_local.cpp
|
||||
src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.cpp
|
||||
src/interface/card_picture_loader/card_picture_loader_status_bar.cpp
|
||||
src/interface/card_picture_loader/card_picture_loader_worker.cpp
|
||||
src/interface/card_picture_loader/card_picture_loader_worker_work.cpp
|
||||
src/interface/card_picture_loader/card_picture_to_load.cpp
|
||||
src/interface/layouts/flow_layout.cpp
|
||||
src/interface/layouts/overlap_layout.cpp
|
||||
src/interface/widgets/utility/line_edit_completer.cpp
|
||||
src/interface/line_edit_completer.cpp
|
||||
src/interface/pixel_map_generator.cpp
|
||||
src/interface/theme_manager.cpp
|
||||
src/interface/widgets/cards/additional_info/color_identity_widget.cpp
|
||||
@@ -142,22 +160,17 @@ set(cockatrice_SOURCES
|
||||
src/interface/widgets/cards/deck_card_zone_display_widget.cpp
|
||||
src/interface/widgets/cards/deck_preview_card_picture_widget.cpp
|
||||
src/interface/widgets/deck_analytics/deck_analytics_widget.cpp
|
||||
src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.cpp
|
||||
src/interface/widgets/deck_analytics/mana_base_widget.cpp
|
||||
src/interface/widgets/deck_analytics/mana_curve_widget.cpp
|
||||
src/interface/widgets/deck_analytics/mana_devotion_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_list_history_manager_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
|
||||
src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp
|
||||
src/interface/widgets/deck_editor/deck_list_style_proxy.cpp
|
||||
src/interface/widgets/general/background_sources.cpp
|
||||
src/interface/widgets/general/display/background_plate_widget.cpp
|
||||
src/interface/widgets/general/display/banner_widget.cpp
|
||||
src/interface/widgets/general/display/bar_widget.cpp
|
||||
src/interface/widgets/general/display/color_bar.cpp
|
||||
src/interface/widgets/general/display/dynamic_font_size_label.cpp
|
||||
src/interface/widgets/general/display/dynamic_font_size_push_button.cpp
|
||||
src/interface/widgets/general/display/labeled_input.cpp
|
||||
@@ -168,7 +181,6 @@ set(cockatrice_SOURCES
|
||||
src/interface/widgets/general/layout_containers/flow_widget.cpp
|
||||
src/interface/widgets/general/layout_containers/overlap_control_widget.cpp
|
||||
src/interface/widgets/general/layout_containers/overlap_widget.cpp
|
||||
src/interface/widgets/menus/deck_editor_menu.cpp
|
||||
src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp
|
||||
src/interface/widgets/printing_selector/card_amount_widget.cpp
|
||||
src/interface/widgets/printing_selector/printing_selector.cpp
|
||||
@@ -180,23 +192,6 @@ set(cockatrice_SOURCES
|
||||
src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp
|
||||
src/interface/widgets/quick_settings/settings_button_widget.cpp
|
||||
src/interface/widgets/quick_settings/settings_popup_widget.cpp
|
||||
src/interface/widgets/replay/replay_manager.cpp
|
||||
src/interface/widgets/replay/replay_timeline_widget.cpp
|
||||
src/interface/widgets/server/chat_view/chat_view.cpp
|
||||
src/interface/widgets/server/game_selector.cpp
|
||||
src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp
|
||||
src/interface/widgets/server/games_model.cpp
|
||||
src/interface/widgets/server/handle_public_servers.cpp
|
||||
src/interface/widgets/server/remote/remote_decklist_tree_widget.cpp
|
||||
src/interface/widgets/server/remote/remote_replay_list_tree_widget.cpp
|
||||
src/interface/widgets/server/user/user_context_menu.cpp
|
||||
src/interface/widgets/server/user/user_info_box.cpp
|
||||
src/interface/widgets/server/user/user_info_connection.cpp
|
||||
src/interface/widgets/server/user/user_list_manager.cpp
|
||||
src/interface/widgets/server/user/user_list_widget.cpp
|
||||
src/interface/widgets/utility/custom_line_edit.cpp
|
||||
src/interface/widgets/utility/get_text_with_max.cpp
|
||||
src/interface/widgets/utility/sequence_edit.cpp
|
||||
src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp
|
||||
src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp
|
||||
src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.cpp
|
||||
@@ -205,7 +200,6 @@ set(cockatrice_SOURCES
|
||||
src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp
|
||||
src/interface/widgets/visual_database_display/visual_database_display_widget.cpp
|
||||
src/interface/widgets/visual_database_display/visual_database_filter_display_widget.cpp
|
||||
src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.cpp
|
||||
src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp
|
||||
src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp
|
||||
src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.cpp
|
||||
@@ -223,65 +217,94 @@ set(cockatrice_SOURCES
|
||||
src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
|
||||
src/interface/window_main.cpp
|
||||
src/main.cpp
|
||||
src/interface/widgets/tabs/abstract_tab_deck_editor.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_average_deck_api_response.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/card_prices/edhrec_api_response_card_prices.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_details.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response_average_deck_statistics.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/tab_edhrec.cpp
|
||||
src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.cpp
|
||||
src/interface/widgets/tabs/tab.cpp
|
||||
src/interface/widgets/tabs/tab_account.cpp
|
||||
src/interface/widgets/tabs/tab_admin.cpp
|
||||
src/interface/widgets/tabs/tab_deck_editor.cpp
|
||||
src/interface/widgets/tabs/tab_deck_storage.cpp
|
||||
src/interface/widgets/tabs/tab_game.cpp
|
||||
src/interface/widgets/tabs/tab_home.cpp
|
||||
src/interface/widgets/tabs/tab_logs.cpp
|
||||
src/interface/widgets/tabs/tab_message.cpp
|
||||
src/interface/widgets/tabs/tab_replays.cpp
|
||||
src/interface/widgets/tabs/tab_room.cpp
|
||||
src/interface/widgets/tabs/tab_server.cpp
|
||||
src/interface/widgets/tabs/tab_supervisor.cpp
|
||||
src/interface/widgets/tabs/tab_visual_database_display.cpp
|
||||
src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp
|
||||
src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.cpp
|
||||
src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.cpp
|
||||
src/interface/key_signals.cpp
|
||||
src/interface/logger.cpp
|
||||
src/picture_loader/picture_loader.cpp
|
||||
src/picture_loader/picture_loader_local.cpp
|
||||
src/picture_loader/picture_loader_request_status_display_widget.cpp
|
||||
src/picture_loader/picture_loader_status_bar.cpp
|
||||
src/picture_loader/picture_loader_worker.cpp
|
||||
src/picture_loader/picture_loader_worker_work.cpp
|
||||
src/picture_loader/picture_to_load.cpp
|
||||
src/server/abstract_client.cpp
|
||||
src/server/chat_view/chat_view.cpp
|
||||
src/server/game_selector.cpp
|
||||
src/server/games_model.cpp
|
||||
src/server/handle_public_servers.cpp
|
||||
src/server/local_client.cpp
|
||||
src/server/local_server.cpp
|
||||
src/server/local_server_interface.cpp
|
||||
src/server/pending_command.cpp
|
||||
src/server/remote/remote_client.cpp
|
||||
src/server/remote/remote_decklist_tree_widget.cpp
|
||||
src/server/remote/remote_replay_list_tree_widget.cpp
|
||||
src/server/user/user_context_menu.cpp
|
||||
src/server/user/user_info_box.cpp
|
||||
src/server/user/user_info_connection.cpp
|
||||
src/server/user/user_list_manager.cpp
|
||||
src/server/user/user_list_widget.cpp
|
||||
src/settings/cache_settings.cpp
|
||||
src/settings/card_counter_settings.cpp
|
||||
src/settings/card_database_settings.cpp
|
||||
src/settings/card_override_settings.cpp
|
||||
src/settings/debug_settings.cpp
|
||||
src/settings/download_settings.cpp
|
||||
src/settings/game_filters_settings.cpp
|
||||
src/settings/layouts_settings.cpp
|
||||
src/settings/message_settings.cpp
|
||||
src/settings/recents_settings.cpp
|
||||
src/settings/servers_settings.cpp
|
||||
src/settings/settings_manager.cpp
|
||||
src/settings/shortcut_treeview.cpp
|
||||
src/settings/shortcuts_settings.cpp
|
||||
src/tabs/abstract_tab_deck_editor.cpp
|
||||
src/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.cpp
|
||||
src/tabs/api/edhrec/api_response/average_deck/edhrec_average_deck_api_response.cpp
|
||||
src/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp
|
||||
src/tabs/api/edhrec/api_response/card_prices/edhrec_api_response_card_prices.cpp
|
||||
src/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.cpp
|
||||
src/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_details.cpp
|
||||
src/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.cpp
|
||||
src/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.cpp
|
||||
src/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response.cpp
|
||||
src/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response_average_deck_statistics.cpp
|
||||
src/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.cpp
|
||||
src/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.cpp
|
||||
src/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.cpp
|
||||
src/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp
|
||||
src/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp
|
||||
src/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.cpp
|
||||
src/tabs/api/edhrec/tab_edhrec.cpp
|
||||
src/tabs/api/edhrec/tab_edhrec_main.cpp
|
||||
src/tabs/tab.cpp
|
||||
src/tabs/tab_account.cpp
|
||||
src/tabs/tab_admin.cpp
|
||||
src/tabs/tab_deck_editor.cpp
|
||||
src/tabs/tab_deck_storage.cpp
|
||||
src/tabs/tab_game.cpp
|
||||
src/tabs/tab_home.cpp
|
||||
src/tabs/tab_logs.cpp
|
||||
src/tabs/tab_message.cpp
|
||||
src/tabs/tab_replays.cpp
|
||||
src/tabs/tab_room.cpp
|
||||
src/tabs/tab_server.cpp
|
||||
src/tabs/tab_supervisor.cpp
|
||||
src/tabs/tab_visual_database_display.cpp
|
||||
src/tabs/visual_deck_editor/tab_deck_editor_visual.cpp
|
||||
src/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.cpp
|
||||
src/tabs/visual_deck_storage/tab_deck_storage_visual.cpp
|
||||
src/utility/card_info_comparator.cpp
|
||||
src/utility/deck_list_sort_filter_proxy_model.cpp
|
||||
src/utility/key_signals.cpp
|
||||
src/utility/levenshtein.cpp
|
||||
src/utility/logger.cpp
|
||||
src/utility/sequence_edit.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(sounds)
|
||||
@@ -293,23 +316,15 @@ configure_file(
|
||||
set(cockatrice_RESOURCES cockatrice.qrc)
|
||||
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
# Cockatrice main sources
|
||||
file(GLOB_RECURSE translate_cockatrice_SRCS ${CMAKE_SOURCE_DIR}/cockatrice/src/*.cpp
|
||||
${CMAKE_SOURCE_DIR}/cockatrice/src/*.h
|
||||
)
|
||||
|
||||
# All libcockatrice_* libraries (recursively)
|
||||
file(GLOB_RECURSE translate_lib_SRCS ${CMAKE_SOURCE_DIR}/libcockatrice_*/**/*.cpp
|
||||
${CMAKE_SOURCE_DIR}/libcockatrice_*/**/*.h
|
||||
)
|
||||
|
||||
# Combine all sources for translation
|
||||
set(translate_SRCS ${translate_cockatrice_SRCS} ${translate_lib_SRCS})
|
||||
|
||||
file(GLOB_RECURSE translate_common_SRCS ${CMAKE_SOURCE_DIR}/common/*.cpp ${CMAKE_SOURCE_DIR}/common/*.h)
|
||||
set(translate_SRCS ${translate_cockatrice_SRCS} ${translate_common_SRCS})
|
||||
set(cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice_en@source.ts")
|
||||
else()
|
||||
file(GLOB cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts")
|
||||
endif()
|
||||
endif(UPDATE_TRANSLATIONS)
|
||||
|
||||
if(WIN32)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} cockatrice.rc)
|
||||
@@ -339,6 +354,12 @@ set(DESKTOPDIR
|
||||
CACHE STRING "desktop file destination"
|
||||
)
|
||||
|
||||
# Include directories
|
||||
include_directories(../common)
|
||||
include_directories(${PROTOBUF_INCLUDE_DIR})
|
||||
include_directories(${CMAKE_BINARY_DIR}/common)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(COCKATRICE_MAC_QM_INSTALL_DIR "cockatrice.app/Contents/Resources/translations")
|
||||
set(COCKATRICE_UNIX_QM_INSTALL_DIR "share/cockatrice/translations")
|
||||
set(COCKATRICE_WIN32_QM_INSTALL_DIR "translations")
|
||||
@@ -378,31 +399,9 @@ elseif(Qt5_FOUND)
|
||||
endif()
|
||||
|
||||
if(Qt5_FOUND)
|
||||
target_link_libraries(
|
||||
cockatrice
|
||||
libcockatrice_card
|
||||
libcockatrice_deck_list
|
||||
libcockatrice_filters
|
||||
libcockatrice_utility
|
||||
libcockatrice_network
|
||||
libcockatrice_models
|
||||
libcockatrice_rng
|
||||
libcockatrice_settings
|
||||
${COCKATRICE_QT_MODULES}
|
||||
)
|
||||
target_link_libraries(cockatrice cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
else()
|
||||
target_link_libraries(
|
||||
cockatrice
|
||||
PUBLIC libcockatrice_card
|
||||
libcockatrice_deck_list
|
||||
libcockatrice_filters
|
||||
libcockatrice_utility
|
||||
libcockatrice_network
|
||||
libcockatrice_models
|
||||
libcockatrice_rng
|
||||
libcockatrice_settings
|
||||
${COCKATRICE_QT_MODULES}
|
||||
)
|
||||
target_link_libraries(cockatrice PUBLIC cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
|
||||
@@ -7,14 +7,11 @@
|
||||
|
||||
<file>resources/icons/arrow_bottom_green.svg</file>
|
||||
<file>resources/icons/arrow_down_green.svg</file>
|
||||
<file>resources/icons/arrow_history.svg</file>
|
||||
<file>resources/icons/arrow_left_green.svg</file>
|
||||
<file>resources/icons/arrow_redo.svg</file>
|
||||
<file>resources/icons/arrow_right_blue.svg</file>
|
||||
<file>resources/icons/arrow_right_green.svg</file>
|
||||
<file>resources/icons/arrow_top_green.svg</file>
|
||||
<file>resources/icons/arrow_up_green.svg</file>
|
||||
<file>resources/icons/arrow_undo.svg</file>
|
||||
<file>resources/icons/clearsearch.svg</file>
|
||||
<file>resources/icons/cogwheel.svg</file>
|
||||
<file>resources/icons/conceded.svg</file>
|
||||
@@ -28,7 +25,6 @@
|
||||
<file>resources/icons/lock.svg</file>
|
||||
<file>resources/icons/not_ready_start.svg</file>
|
||||
<file>resources/icons/pencil.svg</file>
|
||||
<file>resources/icons/pin.svg</file>
|
||||
<file>resources/icons/player.svg</file>
|
||||
<file>resources/icons/ready_start.svg</file>
|
||||
<file>resources/icons/reload.svg</file>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,14 +37,12 @@
|
||||
#card_zone = true
|
||||
#view_zone = true
|
||||
|
||||
#game_event_handler = true
|
||||
|
||||
#user_info_connection = true
|
||||
|
||||
#card_picture_loader = true
|
||||
#card_picture_loader.worker = true
|
||||
#card_picture_loader.card_back_cache_fail = true
|
||||
#card_picture_loader.picture_to_load = true
|
||||
#picture_loader = true
|
||||
#picture_loader.worker = true
|
||||
#picture_loader.card_back_cache_fail = true
|
||||
#picture_loader.picture_to_load = true
|
||||
#deck_loader = true
|
||||
#card_database = true
|
||||
#card_database.loading = true
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
|
||||
<title>
|
||||
history
|
||||
</title>
|
||||
<path d="M9 6v5h.06l2.48 2.47 1.41-1.41L11 10.11V6H9z"/>
|
||||
<path d="M10 1a9 9 0 0 0-7.85 13.35L.5 16H6v-5.5l-2.38 2.38A7 7 0 1 1 10 17v2a9 9 0 0 0 0-18z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 332 B |
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px"
|
||||
y="0px" width="485.212px" height="485.212px" viewBox="0 0 485.212 485.212"
|
||||
style="enable-background:new 0 0 485.212 485.212;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M242.607,424.559c-75.252,0-136.468-61.209-136.468-136.465c0-75.252,61.216-136.466,136.468-136.466v90.978 l151.629-121.302L242.607,0v90.978c-108.687,0-197.117,88.432-197.117,197.117c0,108.691,88.43,197.118,197.117,197.118 c108.687,0,197.114-88.427,197.114-197.118h-60.645C379.077,363.35,317.859,424.559,242.607,424.559z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1018 B |
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px"
|
||||
y="0px" width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;"
|
||||
xml:space="preserve">
|
||||
<g>
|
||||
<path d="M256,448c79.406,0,144-64.594,144-144s-64.594-144-144-144v96L96,128L256,0v96c114.688,0,208,93.313,208,208 c0,114.688-93.312,208-208,208c-114.687,0-208-93.312-208-208h64C112,383.406,176.594,448,256,448z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 874 B |
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="64" height="64">
|
||||
<g transform="matrix(0 1 -1 0 99.465813 0)" opacity="0.7">
|
||||
<path fill="#000000" fill-rule="evenodd" clip-rule="evenodd"
|
||||
stroke="#ffffff"
|
||||
stroke-width="4"
|
||||
stroke-linejoin="round"
|
||||
stroke-linecap="round"
|
||||
d="M65.5 62
|
||||
L78 49
|
||||
C73.5 44.5 69.5 42 63 44
|
||||
L45 31 C47 25 46 22 41.5 18
|
||||
L19 41.5
|
||||
C23 45.5 25 46.5 31 45
|
||||
L44 62.5
|
||||
C42.3 69 45 73.5 49 78
|
||||
L61.5 65.5
|
||||
L84 87
|
||||
L87 87
|
||||
L87.5 86.5
|
||||
L87.5 83.5 Z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 736 B |
@@ -363,6 +363,6 @@
|
||||
d="m 38.011063,984.77381 -10.143601,-5.23583 -10.063711,5.38779 1.845023,-11.2651 -8.233948,-7.90624 11.283888,-1.72639 4.974851,-10.27411 5.128803,10.19813 11.308575,1.55649 -8.114112,8.02918 z"
|
||||
inkscape:transform-center-x="0.094945927"
|
||||
inkscape:transform-center-y="-3.9764964"
|
||||
transform="matrix(-2.3768784,0,0,2.4799382,115.920285,-1400.1716)" />
|
||||
transform="matrix(2.3768784,0,0,2.4799382,-15.920285,-1400.1716)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -1,9 +1,10 @@
|
||||
#include "card_info.h"
|
||||
|
||||
#include "../picture_loader/picture_loader.h"
|
||||
#include "../settings/cache_settings.h"
|
||||
#include "card_relation.h"
|
||||
#include "game_specific_terms.h"
|
||||
#include "printing/printing_info.h"
|
||||
#include "relation/card_relation.h"
|
||||
#include "set/card_set.h"
|
||||
#include "printing_info.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QRegularExpression>
|
||||
@@ -26,18 +27,23 @@ CardInfo::CardInfo(const QString &_name,
|
||||
const QList<CardRelation *> &_relatedCards,
|
||||
const QList<CardRelation *> &_reverseRelatedCards,
|
||||
SetToPrintingsMap _sets,
|
||||
const UiAttributes _uiAttributes)
|
||||
bool _cipt,
|
||||
bool _landscapeOrientation,
|
||||
int _tableRow,
|
||||
bool _upsideDownArt)
|
||||
: name(_name), text(_text), isToken(_isToken), properties(std::move(_properties)), relatedCards(_relatedCards),
|
||||
reverseRelatedCards(_reverseRelatedCards), setsToPrintings(std::move(_sets)), uiAttributes(_uiAttributes)
|
||||
reverseRelatedCards(_reverseRelatedCards), setsToPrintings(std::move(_sets)), cipt(_cipt),
|
||||
landscapeOrientation(_landscapeOrientation), tableRow(_tableRow), upsideDownArt(_upsideDownArt)
|
||||
{
|
||||
simpleName = CardInfo::simplifyName(name);
|
||||
|
||||
refreshCachedSets();
|
||||
refreshCachedSetNames();
|
||||
}
|
||||
|
||||
CardInfoPtr CardInfo::newInstance(const QString &_name)
|
||||
{
|
||||
return newInstance(_name, "", false, {}, {}, {}, {}, {});
|
||||
return newInstance(_name, QString(), false, QVariantHash(), QList<CardRelation *>(), QList<CardRelation *>(),
|
||||
SetToPrintingsMap(), false, false, 0, false);
|
||||
}
|
||||
|
||||
CardInfoPtr CardInfo::newInstance(const QString &_name,
|
||||
@@ -47,10 +53,13 @@ CardInfoPtr CardInfo::newInstance(const QString &_name,
|
||||
const QList<CardRelation *> &_relatedCards,
|
||||
const QList<CardRelation *> &_reverseRelatedCards,
|
||||
SetToPrintingsMap _sets,
|
||||
const UiAttributes _uiAttributes)
|
||||
bool _cipt,
|
||||
bool _landscapeOrientation,
|
||||
int _tableRow,
|
||||
bool _upsideDownArt)
|
||||
{
|
||||
CardInfoPtr ptr(new CardInfo(_name, _text, _isToken, std::move(_properties), _relatedCards, _reverseRelatedCards,
|
||||
_sets, _uiAttributes));
|
||||
_sets, _cipt, _landscapeOrientation, _tableRow, _upsideDownArt));
|
||||
ptr->setSmartPointer(ptr);
|
||||
|
||||
for (const auto &printings : _sets) {
|
||||
@@ -84,7 +93,7 @@ void CardInfo::addToSet(const CardSetPtr &_set, const PrintingInfo _info)
|
||||
setsToPrintings[_set->getShortName()].append(_info);
|
||||
}
|
||||
|
||||
refreshCachedSets();
|
||||
refreshCachedSetNames();
|
||||
}
|
||||
|
||||
void CardInfo::combineLegalities(const QVariantHash &props)
|
||||
@@ -98,12 +107,6 @@ void CardInfo::combineLegalities(const QVariantHash &props)
|
||||
}
|
||||
}
|
||||
|
||||
void CardInfo::refreshCachedSets()
|
||||
{
|
||||
refreshCachedSetNames();
|
||||
refreshCachedAltNames();
|
||||
}
|
||||
|
||||
void CardInfo::refreshCachedSetNames()
|
||||
{
|
||||
QStringList setList;
|
||||
@@ -119,21 +122,6 @@ void CardInfo::refreshCachedSetNames()
|
||||
setsNames = setList.join(", ");
|
||||
}
|
||||
|
||||
void CardInfo::refreshCachedAltNames()
|
||||
{
|
||||
altNames.clear();
|
||||
|
||||
// update the altNames with the flavorNames
|
||||
for (const auto &printings : setsToPrintings) {
|
||||
for (const auto &printing : printings) {
|
||||
QString flavorName = printing.getFlavorName();
|
||||
if (!flavorName.isEmpty()) {
|
||||
altNames.insert(flavorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString CardInfo::simplifyName(const QString &name)
|
||||
{
|
||||
static const QRegularExpression spaceOrSplit("(\\s+|\\/\\/.*)");
|
||||
@@ -1,7 +1,13 @@
|
||||
/**
|
||||
* @file card_info.h
|
||||
* @ingroup Cards
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef CARD_INFO_H
|
||||
#define CARD_INFO_H
|
||||
|
||||
#include "printing/printing_info.h"
|
||||
#include "printing_info.h"
|
||||
|
||||
#include <QDate>
|
||||
#include <QHash>
|
||||
@@ -10,6 +16,7 @@
|
||||
#include <QMap>
|
||||
#include <QMetaType>
|
||||
#include <QSharedPointer>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
#include <utility>
|
||||
|
||||
@@ -46,26 +53,7 @@ class CardInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @class CardInfo::UiAttributes
|
||||
* @ingroup Cards
|
||||
*
|
||||
* @brief Attributes of the card that affect display and game logic.
|
||||
*/
|
||||
struct UiAttributes
|
||||
{
|
||||
bool cipt = false; ///< Positioning flag used by UI.
|
||||
bool landscapeOrientation = false; ///< Orientation flag for rendering.
|
||||
int tableRow = 0; ///< Row index in a table or visual representation.
|
||||
bool upsideDownArt = false; ///< Whether artwork is flipped for visual purposes.
|
||||
};
|
||||
|
||||
private:
|
||||
/** @name Private Card Properties
|
||||
* @anchor PrivateCardProperties
|
||||
*/
|
||||
///@{
|
||||
CardInfoPtr smartThis; ///< Smart pointer to self for safe cross-references.
|
||||
QString name; ///< Full name of the card.
|
||||
QString simpleName; ///< Simplified name for fuzzy matching.
|
||||
@@ -76,10 +64,11 @@ private:
|
||||
QList<CardRelation *> reverseRelatedCards; ///< Cards that refer back to this card.
|
||||
QList<CardRelation *> reverseRelatedCardsToMe; ///< Cards that consider this card as related.
|
||||
SetToPrintingsMap setsToPrintings; ///< Mapping from set names to printing variations.
|
||||
UiAttributes uiAttributes; ///< Attributes that affect display and game logic
|
||||
QString setsNames; ///< Cached, human-readable list of set names.
|
||||
QSet<QString> altNames; ///< Cached set of alternate names, used when searching
|
||||
///@}
|
||||
bool cipt; ///< Positioning flag used by UI.
|
||||
bool landscapeOrientation; ///< Orientation flag for rendering.
|
||||
int tableRow; ///< Row index in a table or visual representation.
|
||||
bool upsideDownArt; ///< Whether artwork is flipped for visual purposes.
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -92,7 +81,10 @@ public:
|
||||
* @param _relatedCards Forward references to related cards.
|
||||
* @param _reverseRelatedCards Backward references to related cards.
|
||||
* @param _sets Map of set names to printing information.
|
||||
* @param _uiAttributes Attributes that affect display and game logic
|
||||
* @param _cipt UI positioning flag.
|
||||
* @param _landscapeOrientation UI rendering orientation.
|
||||
* @param _tableRow Row index for table placement.
|
||||
* @param _upsideDownArt Whether the artwork should be displayed upside down.
|
||||
*/
|
||||
explicit CardInfo(const QString &_name,
|
||||
const QString &_text,
|
||||
@@ -101,7 +93,10 @@ public:
|
||||
const QList<CardRelation *> &_relatedCards,
|
||||
const QList<CardRelation *> &_reverseRelatedCards,
|
||||
SetToPrintingsMap _sets,
|
||||
UiAttributes _uiAttributes);
|
||||
bool _cipt,
|
||||
bool _landscapeOrientation,
|
||||
int _tableRow,
|
||||
bool _upsideDownArt);
|
||||
|
||||
/**
|
||||
* @brief Copy constructor for CardInfo.
|
||||
@@ -114,8 +109,8 @@ public:
|
||||
: QObject(other.parent()), name(other.name), simpleName(other.simpleName), text(other.text),
|
||||
isToken(other.isToken), properties(other.properties), relatedCards(other.relatedCards),
|
||||
reverseRelatedCards(other.reverseRelatedCards), reverseRelatedCardsToMe(other.reverseRelatedCardsToMe),
|
||||
setsToPrintings(other.setsToPrintings), uiAttributes(other.uiAttributes), setsNames(other.setsNames),
|
||||
altNames(other.altNames)
|
||||
setsToPrintings(other.setsToPrintings), setsNames(other.setsNames), cipt(other.cipt),
|
||||
landscapeOrientation(other.landscapeOrientation), tableRow(other.tableRow), upsideDownArt(other.upsideDownArt)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -139,7 +134,10 @@ public:
|
||||
* @param _relatedCards Forward relationships.
|
||||
* @param _reverseRelatedCards Reverse relationships.
|
||||
* @param _sets Printing information per set.
|
||||
* @param _uiAttributes Attributes that affect display and game logic
|
||||
* @param _cipt UI positioning flag.
|
||||
* @param _landscapeOrientation UI rendering orientation.
|
||||
* @param _tableRow Row index for table placement.
|
||||
* @param _upsideDownArt Artwork orientation flag.
|
||||
* @return Shared pointer to the new CardInfo instance.
|
||||
*/
|
||||
static CardInfoPtr newInstance(const QString &_name,
|
||||
@@ -149,7 +147,10 @@ public:
|
||||
const QList<CardRelation *> &_relatedCards,
|
||||
const QList<CardRelation *> &_reverseRelatedCards,
|
||||
SetToPrintingsMap _sets,
|
||||
UiAttributes _uiAttributes);
|
||||
bool _cipt,
|
||||
bool _landscapeOrientation,
|
||||
int _tableRow,
|
||||
bool _upsideDownArt);
|
||||
|
||||
/**
|
||||
* @brief Clones the current CardInfo instance.
|
||||
@@ -158,9 +159,9 @@ public:
|
||||
*
|
||||
* @return Shared pointer to the cloned CardInfo.
|
||||
*/
|
||||
[[nodiscard]] CardInfoPtr clone() const
|
||||
CardInfoPtr clone() const
|
||||
{
|
||||
auto newCardInfo = CardInfoPtr(new CardInfo(*this));
|
||||
CardInfoPtr newCardInfo = CardInfoPtr(new CardInfo(*this));
|
||||
newCardInfo->setSmartPointer(newCardInfo); // Set the smart pointer for the new instance
|
||||
return newCardInfo;
|
||||
}
|
||||
@@ -178,19 +179,15 @@ public:
|
||||
}
|
||||
|
||||
/** @name Basic Properties Accessors */ //@{
|
||||
[[nodiscard]] inline const QString &getName() const
|
||||
inline const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
[[nodiscard]] const QString &getSimpleName() const
|
||||
const QString &getSimpleName() const
|
||||
{
|
||||
return simpleName;
|
||||
}
|
||||
const QSet<QString> &getAltNames()
|
||||
{
|
||||
return altNames;
|
||||
}
|
||||
[[nodiscard]] const QString &getText() const
|
||||
const QString &getText() const
|
||||
{
|
||||
return text;
|
||||
}
|
||||
@@ -199,15 +196,15 @@ public:
|
||||
text = _text;
|
||||
emit cardInfoChanged(smartThis);
|
||||
}
|
||||
[[nodiscard]] bool getIsToken() const
|
||||
bool getIsToken() const
|
||||
{
|
||||
return isToken;
|
||||
}
|
||||
[[nodiscard]] QStringList getProperties() const
|
||||
QStringList getProperties() const
|
||||
{
|
||||
return properties.keys();
|
||||
}
|
||||
[[nodiscard]] QString getProperty(const QString &propertyName) const
|
||||
QString getProperty(const QString &propertyName) const
|
||||
{
|
||||
return properties.value(propertyName).toString();
|
||||
}
|
||||
@@ -216,34 +213,34 @@ public:
|
||||
properties.insert(_name, _value);
|
||||
emit cardInfoChanged(smartThis);
|
||||
}
|
||||
[[nodiscard]] bool hasProperty(const QString &propertyName) const
|
||||
bool hasProperty(const QString &propertyName) const
|
||||
{
|
||||
return properties.contains(propertyName);
|
||||
}
|
||||
[[nodiscard]] const SetToPrintingsMap &getSets() const
|
||||
const SetToPrintingsMap &getSets() const
|
||||
{
|
||||
return setsToPrintings;
|
||||
}
|
||||
[[nodiscard]] const QString &getSetsNames() const
|
||||
const QString &getSetsNames() const
|
||||
{
|
||||
return setsNames;
|
||||
}
|
||||
//@}
|
||||
|
||||
/** @name Related Cards Accessors */ //@{
|
||||
[[nodiscard]] const QList<CardRelation *> &getRelatedCards() const
|
||||
const QList<CardRelation *> &getRelatedCards() const
|
||||
{
|
||||
return relatedCards;
|
||||
}
|
||||
[[nodiscard]] const QList<CardRelation *> &getReverseRelatedCards() const
|
||||
const QList<CardRelation *> &getReverseRelatedCards() const
|
||||
{
|
||||
return reverseRelatedCards;
|
||||
}
|
||||
[[nodiscard]] const QList<CardRelation *> &getReverseRelatedCards2Me() const
|
||||
const QList<CardRelation *> &getReverseRelatedCards2Me() const
|
||||
{
|
||||
return reverseRelatedCardsToMe;
|
||||
}
|
||||
[[nodiscard]] QList<CardRelation *> getAllRelatedCards() const
|
||||
QList<CardRelation *> getAllRelatedCards() const
|
||||
{
|
||||
QList<CardRelation *> result;
|
||||
result.append(getRelatedCards());
|
||||
@@ -258,24 +255,39 @@ public:
|
||||
//@}
|
||||
|
||||
/** @name UI Positioning */ //@{
|
||||
[[nodiscard]] const UiAttributes &getUiAttributes() const
|
||||
bool getCipt() const
|
||||
{
|
||||
return uiAttributes;
|
||||
return cipt;
|
||||
}
|
||||
bool getLandscapeOrientation() const
|
||||
{
|
||||
return landscapeOrientation;
|
||||
}
|
||||
int getTableRow() const
|
||||
{
|
||||
return tableRow;
|
||||
}
|
||||
void setTableRow(int _tableRow)
|
||||
{
|
||||
tableRow = _tableRow;
|
||||
}
|
||||
bool getUpsideDownArt() const
|
||||
{
|
||||
return upsideDownArt;
|
||||
}
|
||||
const QChar getColorChar() const;
|
||||
//@}
|
||||
|
||||
[[nodiscard]] const QChar getColorChar() const;
|
||||
|
||||
/** @name Legacy/Convenience Property Accessors */ //@{
|
||||
[[nodiscard]] const QString getCardType() const;
|
||||
const QString getCardType() const;
|
||||
void setCardType(const QString &value);
|
||||
[[nodiscard]] const QString getCmc() const;
|
||||
[[nodiscard]] const QString getColors() const;
|
||||
const QString getCmc() const;
|
||||
const QString getColors() const;
|
||||
void setColors(const QString &value);
|
||||
[[nodiscard]] const QString getLoyalty() const;
|
||||
[[nodiscard]] const QString getMainCardType() const;
|
||||
[[nodiscard]] const QString getManaCost() const;
|
||||
[[nodiscard]] const QString getPowTough() const;
|
||||
const QString getLoyalty() const;
|
||||
const QString getMainCardType() const;
|
||||
const QString getManaCost() const;
|
||||
const QString getPowTough() const;
|
||||
void setPowTough(const QString &value);
|
||||
//@}
|
||||
|
||||
@@ -286,7 +298,7 @@ public:
|
||||
*
|
||||
* @return Corrected card name as a QString.
|
||||
*/
|
||||
[[nodiscard]] QString getCorrectedName() const;
|
||||
QString getCorrectedName() const;
|
||||
|
||||
/**
|
||||
* @brief Adds a printing to a specific set.
|
||||
@@ -308,11 +320,11 @@ public:
|
||||
void combineLegalities(const QVariantHash &props);
|
||||
|
||||
/**
|
||||
* @brief Refreshes all cached fields that are calculated from the contained sets and printings.
|
||||
* @brief Refreshes the cached, human-readable list of set names.
|
||||
*
|
||||
* Typically called after adding or modifying set memberships or printings.
|
||||
* Typically called after adding or modifying set memberships.
|
||||
*/
|
||||
void refreshCachedSets();
|
||||
void refreshCachedSetNames();
|
||||
|
||||
/**
|
||||
* @brief Simplifies a name for fuzzy matching.
|
||||
@@ -324,21 +336,6 @@ public:
|
||||
*/
|
||||
static QString simplifyName(const QString &name);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Refreshes the cached, human-readable list of set names.
|
||||
*
|
||||
* Typically called after adding or modifying set memberships.
|
||||
*/
|
||||
void refreshCachedSetNames();
|
||||
|
||||
/**
|
||||
* @brief Refreshes the cached list of alt names for the card.
|
||||
*
|
||||
* Typically called after adding or modifying the contained printings.
|
||||
*/
|
||||
void refreshCachedAltNames();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Emitted when a pixmap for this card has been updated or finished loading.
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "card_relation.h"
|
||||
|
||||
#include "card_relation_type.h"
|
||||
|
||||
CardRelation::CardRelation(const QString &_name,
|
||||
CardRelationType _attachType,
|
||||
bool _isCreateAllExclusion,
|
||||
73
cockatrice/src/card/card_relation.h
Normal file
73
cockatrice/src/card/card_relation.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef COCKATRICE_CARD_RELATION_H
|
||||
#define COCKATRICE_CARD_RELATION_H
|
||||
|
||||
#include "card_relation_type.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class CardRelation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QString name;
|
||||
CardRelationType attachType;
|
||||
bool isCreateAllExclusion;
|
||||
bool isVariableCount;
|
||||
int defaultCount;
|
||||
bool isPersistent;
|
||||
|
||||
public:
|
||||
explicit CardRelation(const QString &_name = QString(),
|
||||
CardRelationType _attachType = CardRelationType::DoesNotAttach,
|
||||
bool _isCreateAllExclusion = false,
|
||||
bool _isVariableCount = false,
|
||||
int _defaultCount = 1,
|
||||
bool _isPersistent = false);
|
||||
|
||||
const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
CardRelationType getAttachType() const
|
||||
{
|
||||
return attachType;
|
||||
}
|
||||
bool getDoesAttach() const
|
||||
{
|
||||
return attachType != CardRelationType::DoesNotAttach;
|
||||
}
|
||||
bool getDoesTransform() const
|
||||
{
|
||||
return attachType == CardRelationType::TransformInto;
|
||||
}
|
||||
|
||||
QString getAttachTypeAsString() const
|
||||
{
|
||||
return cardAttachTypeToString(attachType);
|
||||
}
|
||||
|
||||
bool getCanCreateAnother() const
|
||||
{
|
||||
return !getDoesAttach();
|
||||
}
|
||||
bool getIsCreateAllExclusion() const
|
||||
{
|
||||
return isCreateAllExclusion;
|
||||
}
|
||||
bool getIsVariable() const
|
||||
{
|
||||
return isVariableCount;
|
||||
}
|
||||
int getDefaultCount() const
|
||||
{
|
||||
return defaultCount;
|
||||
}
|
||||
bool getIsPersistent() const
|
||||
{
|
||||
return isPersistent;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_CARD_RELATION_H
|
||||
@@ -4,13 +4,7 @@
|
||||
#include <QString>
|
||||
|
||||
/**
|
||||
* @enum CardRelationType
|
||||
* @ingroup Cards
|
||||
* @brief Types of attachments between cards.
|
||||
*
|
||||
* DoesNotAttach: No attachment is present.
|
||||
* AttachTo: This card attaches to another card.
|
||||
* TransformInto: This card transforms into another card.
|
||||
* Represents how a card relates to another (attach, transform, etc.).
|
||||
*/
|
||||
enum class CardRelationType
|
||||
{
|
||||
@@ -19,7 +13,7 @@ enum class CardRelationType
|
||||
TransformInto = 2,
|
||||
};
|
||||
|
||||
// Helper function to transform the enum values into human-readable strings
|
||||
// Optional helper
|
||||
inline QString cardAttachTypeToString(CardRelationType type)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -1,30 +1,26 @@
|
||||
#include "card_set.h"
|
||||
|
||||
#include <QSet>
|
||||
#include <utility>
|
||||
#include "../settings/cache_settings.h"
|
||||
|
||||
const char *CardSet::TOKENS_SETNAME = "TK";
|
||||
|
||||
CardSet::CardSet(ICardSetPriorityController *_priorityController,
|
||||
const QString &_shortName,
|
||||
CardSet::CardSet(const QString &_shortName,
|
||||
const QString &_longName,
|
||||
const QString &_setType,
|
||||
const QDate &_releaseDate,
|
||||
const CardSet::Priority _priority)
|
||||
: priorityController(std::move(_priorityController)), shortName(_shortName), longName(_longName),
|
||||
releaseDate(_releaseDate), setType(_setType), priority(_priority)
|
||||
: shortName(_shortName), longName(_longName), releaseDate(_releaseDate), setType(_setType), priority(_priority)
|
||||
{
|
||||
loadSetOptions();
|
||||
}
|
||||
|
||||
CardSetPtr CardSet::newInstance(ICardSetPriorityController *_priorityController,
|
||||
const QString &_shortName,
|
||||
CardSetPtr CardSet::newInstance(const QString &_shortName,
|
||||
const QString &_longName,
|
||||
const QString &_setType,
|
||||
const QDate &_releaseDate,
|
||||
const Priority _priority)
|
||||
{
|
||||
CardSetPtr ptr(new CardSet(_priorityController, _shortName, _longName, _setType, _releaseDate, _priority));
|
||||
CardSetPtr ptr(new CardSet(_shortName, _longName, _setType, _releaseDate, _priority));
|
||||
// ptr->setSmartPointer(ptr);
|
||||
return ptr;
|
||||
}
|
||||
@@ -61,25 +57,25 @@ QString CardSet::getCorrectedShortName() const
|
||||
|
||||
void CardSet::loadSetOptions()
|
||||
{
|
||||
sortKey = priorityController->getSortKey(shortName);
|
||||
enabled = priorityController->isEnabled(shortName);
|
||||
isknown = priorityController->isKnown(shortName);
|
||||
sortKey = SettingsCache::instance().cardDatabase().getSortKey(shortName);
|
||||
enabled = SettingsCache::instance().cardDatabase().isEnabled(shortName);
|
||||
isknown = SettingsCache::instance().cardDatabase().isKnown(shortName);
|
||||
}
|
||||
|
||||
void CardSet::setSortKey(unsigned int _sortKey)
|
||||
{
|
||||
sortKey = _sortKey;
|
||||
priorityController->setSortKey(shortName, _sortKey);
|
||||
SettingsCache::instance().cardDatabase().setSortKey(shortName, _sortKey);
|
||||
}
|
||||
|
||||
void CardSet::setEnabled(bool _enabled)
|
||||
{
|
||||
enabled = _enabled;
|
||||
priorityController->setEnabled(shortName, _enabled);
|
||||
SettingsCache::instance().cardDatabase().setEnabled(shortName, _enabled);
|
||||
}
|
||||
|
||||
void CardSet::setIsKnown(bool _isknown)
|
||||
{
|
||||
isknown = _isknown;
|
||||
priorityController->setIsKnown(shortName, _isknown);
|
||||
SettingsCache::instance().cardDatabase().setIsKnown(shortName, _isknown);
|
||||
}
|
||||
116
cockatrice/src/card/card_set.h
Normal file
116
cockatrice/src/card/card_set.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef COCKATRICE_CARD_SET_H
|
||||
#define COCKATRICE_CARD_SET_H
|
||||
|
||||
#include <QDate>
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class CardInfo;
|
||||
using CardInfoPtr = QSharedPointer<CardInfo>;
|
||||
|
||||
class CardSet;
|
||||
using CardSetPtr = QSharedPointer<CardSet>;
|
||||
|
||||
class CardSet : public QList<CardInfoPtr>
|
||||
{
|
||||
public:
|
||||
enum Priority
|
||||
{
|
||||
PriorityFallback = 0,
|
||||
PriorityPrimary = 10,
|
||||
PrioritySecondary = 20,
|
||||
PriorityReprint = 30,
|
||||
PriorityOther = 40,
|
||||
PriorityLowest = 100,
|
||||
};
|
||||
|
||||
static const char *TOKENS_SETNAME;
|
||||
|
||||
private:
|
||||
QString shortName, longName;
|
||||
unsigned int sortKey;
|
||||
QDate releaseDate;
|
||||
QString setType;
|
||||
Priority priority;
|
||||
bool enabled, isknown;
|
||||
|
||||
public:
|
||||
explicit CardSet(const QString &_shortName = QString(),
|
||||
const QString &_longName = QString(),
|
||||
const QString &_setType = QString(),
|
||||
const QDate &_releaseDate = QDate(),
|
||||
const Priority _priority = PriorityFallback);
|
||||
|
||||
static CardSetPtr newInstance(const QString &_shortName = QString(),
|
||||
const QString &_longName = QString(),
|
||||
const QString &_setType = QString(),
|
||||
const QDate &_releaseDate = QDate(),
|
||||
const Priority _priority = PriorityFallback);
|
||||
|
||||
QString getCorrectedShortName() const;
|
||||
|
||||
QString getShortName() const
|
||||
{
|
||||
return shortName;
|
||||
}
|
||||
QString getLongName() const
|
||||
{
|
||||
return longName;
|
||||
}
|
||||
QString getSetType() const
|
||||
{
|
||||
return setType;
|
||||
}
|
||||
QDate getReleaseDate() const
|
||||
{
|
||||
return releaseDate;
|
||||
}
|
||||
Priority getPriority() const
|
||||
{
|
||||
return priority;
|
||||
}
|
||||
|
||||
void setLongName(const QString &_longName)
|
||||
{
|
||||
longName = _longName;
|
||||
}
|
||||
void setSetType(const QString &_setType)
|
||||
{
|
||||
setType = _setType;
|
||||
}
|
||||
void setReleaseDate(const QDate &_releaseDate)
|
||||
{
|
||||
releaseDate = _releaseDate;
|
||||
}
|
||||
void setPriority(const Priority _priority)
|
||||
{
|
||||
priority = _priority;
|
||||
}
|
||||
|
||||
void loadSetOptions();
|
||||
int getSortKey() const
|
||||
{
|
||||
return sortKey;
|
||||
}
|
||||
void setSortKey(unsigned int _sortKey);
|
||||
|
||||
bool getEnabled() const
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
void setEnabled(bool _enabled);
|
||||
|
||||
bool getIsKnown() const
|
||||
{
|
||||
return isknown;
|
||||
}
|
||||
void setIsKnown(bool _isknown);
|
||||
|
||||
bool getIsKnownIgnored() const
|
||||
{
|
||||
return longName.length() + setType.length() + releaseDate.toString().length() == 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_CARD_SET_H
|
||||
26
cockatrice/src/card/card_set_list.h
Normal file
26
cockatrice/src/card/card_set_list.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef COCKATRICE_CARD_SET_LIST_H
|
||||
#define COCKATRICE_CARD_SET_LIST_H
|
||||
|
||||
#include "card_set.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
|
||||
class CardSetList : public QList<CardSetPtr>
|
||||
{
|
||||
private:
|
||||
class KeyCompareFunctor;
|
||||
|
||||
public:
|
||||
void sortByKey();
|
||||
void guessSortKeys();
|
||||
void enableAllUnknown();
|
||||
void enableAll();
|
||||
void markAllAsKnown();
|
||||
int getEnabledSetsNum();
|
||||
int getUnknownSetsNum();
|
||||
QStringList getUnknownSetsNames();
|
||||
void defaultSort();
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_CARD_SET_LIST_H
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "exact_card.h"
|
||||
|
||||
#include "../card_info.h"
|
||||
#include "printing_info.h"
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* This will set the CardInfoPtr to null.
|
||||
48
cockatrice/src/card/exact_card.h
Normal file
48
cockatrice/src/card/exact_card.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef EXACT_CARD_H
|
||||
#define EXACT_CARD_H
|
||||
|
||||
#include "card_info.h"
|
||||
|
||||
/**
|
||||
* @class ExactCard
|
||||
* @ingroup Cards
|
||||
* @brief Identifies the card by its CardInfoPtr along with its exact printing by its PrintingInfo.
|
||||
*/
|
||||
class ExactCard
|
||||
{
|
||||
CardInfoPtr card;
|
||||
PrintingInfo printing;
|
||||
|
||||
public:
|
||||
ExactCard();
|
||||
explicit ExactCard(const CardInfoPtr &_card, const PrintingInfo &_printing = PrintingInfo());
|
||||
|
||||
/**
|
||||
* Gets the CardInfoPtr. Can be null.
|
||||
*/
|
||||
CardInfoPtr getCardPtr() const
|
||||
{
|
||||
return card;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PrintingInfo. Can be empty.
|
||||
*/
|
||||
PrintingInfo getPrinting() const
|
||||
{
|
||||
return printing;
|
||||
}
|
||||
|
||||
bool operator==(const ExactCard &other) const;
|
||||
|
||||
QString getName() const;
|
||||
const CardInfo &getInfo() const;
|
||||
QString getPixmapCacheKey() const;
|
||||
|
||||
bool isEmpty() const;
|
||||
explicit operator bool() const;
|
||||
|
||||
void emitPixmapUpdated() const;
|
||||
};
|
||||
|
||||
#endif // EXACT_CARD_H
|
||||
@@ -53,6 +53,6 @@ inline static const QString getNicePropertyName(QString key)
|
||||
return QCoreApplication::translate("Mtg", "Color Identity");
|
||||
return key;
|
||||
}
|
||||
} // namespace Mtg
|
||||
}; // namespace Mtg
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "printing_info.h"
|
||||
|
||||
#include "../set/card_set.h"
|
||||
|
||||
PrintingInfo::PrintingInfo(const CardSetPtr &_set) : set(_set)
|
||||
{
|
||||
}
|
||||
@@ -12,9 +10,4 @@ PrintingInfo::PrintingInfo(const CardSetPtr &_set) : set(_set)
|
||||
QString PrintingInfo::getUuid() const
|
||||
{
|
||||
return properties.value("uuid").toString();
|
||||
}
|
||||
|
||||
QString PrintingInfo::getFlavorName() const
|
||||
{
|
||||
return properties.value("flavorName").toString();
|
||||
}
|
||||
56
cockatrice/src/card/printing_info.h
Normal file
56
cockatrice/src/card/printing_info.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef COCKATRICE_PRINTING_INFO_H
|
||||
#define COCKATRICE_PRINTING_INFO_H
|
||||
|
||||
#include "card_set.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
class PrintingInfo;
|
||||
|
||||
using SetToPrintingsMap = QMap<QString, QList<PrintingInfo>>;
|
||||
|
||||
/**
|
||||
* Info relating to a specific printing for a card.
|
||||
*/
|
||||
class PrintingInfo
|
||||
{
|
||||
public:
|
||||
explicit PrintingInfo(const CardSetPtr &_set = nullptr);
|
||||
~PrintingInfo() = default;
|
||||
|
||||
bool operator==(const PrintingInfo &other) const
|
||||
{
|
||||
return this->set == other.set && this->properties == other.properties;
|
||||
}
|
||||
|
||||
private:
|
||||
CardSetPtr set;
|
||||
// per-printing card properties;
|
||||
QVariantHash properties;
|
||||
|
||||
public:
|
||||
CardSetPtr getSet() const
|
||||
{
|
||||
return set;
|
||||
}
|
||||
|
||||
QStringList getProperties() const
|
||||
{
|
||||
return properties.keys();
|
||||
}
|
||||
QString getProperty(const QString &propertyName) const
|
||||
{
|
||||
return properties.value(propertyName).toString();
|
||||
}
|
||||
void setProperty(const QString &_name, const QString &_value)
|
||||
{
|
||||
properties.insert(_name, _value);
|
||||
}
|
||||
|
||||
QString getUuid() const;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_PRINTING_INFO_H
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "../../../interface/widgets/menus/deck_editor_menu.h"
|
||||
#include "deck_editor_menu.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../settings/cache_settings.h"
|
||||
#include "../settings/shortcuts_settings.h"
|
||||
|
||||
DeckEditorMenu::DeckEditorMenu(AbstractTabDeckEditor *parent) : QMenu(parent), deckEditor(parent)
|
||||
{
|
||||
@@ -7,6 +7,8 @@
|
||||
#ifndef DECK_EDITOR_MENU_H
|
||||
#define DECK_EDITOR_MENU_H
|
||||
|
||||
#include "../tabs/abstract_tab_deck_editor.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
class AbstractTabDeckEditor;
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "get_text_with_max.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
|
||||
QString getTextWithMax(QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &label,
|
||||
@@ -7,9 +7,9 @@
|
||||
#ifndef GETTEXTWITHMAX_H
|
||||
#define GETTEXTWITHMAX_H
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
#include "trice_limits.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
|
||||
QString getTextWithMax(QWidget *parent,
|
||||
const QString &title,
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "client_update_checker.h"
|
||||
|
||||
#include "../../../settings/cache_settings.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "release_channel.h"
|
||||
|
||||
ClientUpdateChecker::ClientUpdateChecker(QObject *parent) : QObject(parent)
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#ifndef INTERFACE_JSON_DECK_PARSER_H
|
||||
#define INTERFACE_JSON_DECK_PARSER_H
|
||||
#include "../../../interface/deck_loader/deck_loader.h"
|
||||
#include "../../../deck/deck_loader.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
@@ -24,13 +24,13 @@ class ArchidektJsonParser : public IJsonDeckParser
|
||||
public:
|
||||
DeckLoader *parse(const QJsonObject &obj) override
|
||||
{
|
||||
DeckLoader *loader = new DeckLoader(nullptr);
|
||||
DeckLoader *list = new DeckLoader();
|
||||
|
||||
QString deckName = obj.value("name").toString();
|
||||
QString deckDescription = obj.value("description").toString();
|
||||
|
||||
loader->getDeckList()->setName(deckName);
|
||||
loader->getDeckList()->setComments(deckDescription);
|
||||
list->setName(deckName);
|
||||
list->setComments(deckDescription);
|
||||
|
||||
QString outputText;
|
||||
QTextStream outStream(&outputText);
|
||||
@@ -47,10 +47,10 @@ public:
|
||||
outStream << quantity << ' ' << cardName << " (" << setName << ") " << collectorNumber << '\n';
|
||||
}
|
||||
|
||||
loader->getDeckList()->loadFromStream_Plain(outStream, false);
|
||||
DeckLoader::resolveSetNameAndNumberToProviderID(loader->getDeckList());
|
||||
list->loadFromStream_Plain(outStream, false);
|
||||
list->resolveSetNameAndNumberToProviderID();
|
||||
|
||||
return loader;
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -59,13 +59,13 @@ class MoxfieldJsonParser : public IJsonDeckParser
|
||||
public:
|
||||
DeckLoader *parse(const QJsonObject &obj) override
|
||||
{
|
||||
DeckLoader *loader = new DeckLoader(nullptr);
|
||||
DeckLoader *list = new DeckLoader();
|
||||
|
||||
QString deckName = obj.value("name").toString();
|
||||
QString deckDescription = obj.value("description").toString();
|
||||
|
||||
loader->getDeckList()->setName(deckName);
|
||||
loader->getDeckList()->setComments(deckDescription);
|
||||
list->setName(deckName);
|
||||
list->setComments(deckDescription);
|
||||
|
||||
QString outputText;
|
||||
QTextStream outStream(&outputText);
|
||||
@@ -94,8 +94,8 @@ public:
|
||||
outStream << quantity << ' ' << cardName << " (" << setName << ") " << collectorNumber << '\n';
|
||||
}
|
||||
|
||||
loader->getDeckList()->loadFromStream_Plain(outStream, false);
|
||||
DeckLoader::resolveSetNameAndNumberToProviderID(loader->getDeckList());
|
||||
list->loadFromStream_Plain(outStream, false);
|
||||
list->resolveSetNameAndNumberToProviderID();
|
||||
|
||||
QJsonObject commandersObj = obj.value("commanders").toObject();
|
||||
if (!commandersObj.isEmpty()) {
|
||||
@@ -106,12 +106,12 @@ public:
|
||||
QString collectorNumber = cardData.value("cn").toString();
|
||||
QString providerId = cardData.value("scryfall_id").toString();
|
||||
|
||||
loader->getDeckList()->setBannerCard({commanderName, providerId});
|
||||
loader->getDeckList()->addCard(commanderName, DECK_ZONE_MAIN, -1, setName, collectorNumber, providerId);
|
||||
list->setBannerCard({commanderName, providerId});
|
||||
list->addCard(commanderName, DECK_ZONE_MAIN, -1, setName, collectorNumber, providerId);
|
||||
}
|
||||
}
|
||||
|
||||
return loader;
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -57,27 +57,27 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
[[nodiscard]] QString getName() const
|
||||
QString getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
[[nodiscard]] QString getDescriptionUrl() const
|
||||
QString getDescriptionUrl() const
|
||||
{
|
||||
return descriptionUrl;
|
||||
}
|
||||
[[nodiscard]] QString getDownloadUrl() const
|
||||
QString getDownloadUrl() const
|
||||
{
|
||||
return downloadUrl;
|
||||
}
|
||||
[[nodiscard]] QString getCommitHash() const
|
||||
QString getCommitHash() const
|
||||
{
|
||||
return commitHash;
|
||||
}
|
||||
[[nodiscard]] QDate getPublishDate() const
|
||||
QDate getPublishDate() const
|
||||
{
|
||||
return publishDate;
|
||||
}
|
||||
[[nodiscard]] bool isCompatibleVersionFound() const
|
||||
bool isCompatibleVersionFound() const
|
||||
{
|
||||
return compatibleVersionFound;
|
||||
}
|
||||
@@ -97,15 +97,15 @@ protected:
|
||||
|
||||
protected:
|
||||
static bool downloadMatchesCurrentOS(const QString &fileName);
|
||||
[[nodiscard]] virtual QString getReleaseChannelUrl() const = 0;
|
||||
virtual QString getReleaseChannelUrl() const = 0;
|
||||
|
||||
public:
|
||||
Release *getLastRelease()
|
||||
{
|
||||
return lastRelease;
|
||||
}
|
||||
[[nodiscard]] virtual QString getManualDownloadUrl() const = 0;
|
||||
[[nodiscard]] virtual QString getName() const = 0;
|
||||
virtual QString getManualDownloadUrl() const = 0;
|
||||
virtual QString getName() const = 0;
|
||||
void checkForUpdates();
|
||||
signals:
|
||||
void finishedCheck(bool needToUpdate, bool isCompatible, Release *release);
|
||||
@@ -122,12 +122,12 @@ public:
|
||||
explicit StableReleaseChannel() = default;
|
||||
~StableReleaseChannel() override = default;
|
||||
|
||||
[[nodiscard]] QString getManualDownloadUrl() const override;
|
||||
QString getManualDownloadUrl() const override;
|
||||
|
||||
[[nodiscard]] QString getName() const override;
|
||||
QString getName() const override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] QString getReleaseChannelUrl() const override;
|
||||
QString getReleaseChannelUrl() const override;
|
||||
protected slots:
|
||||
|
||||
void releaseListFinished() override;
|
||||
@@ -143,12 +143,12 @@ public:
|
||||
BetaReleaseChannel() = default;
|
||||
~BetaReleaseChannel() override = default;
|
||||
|
||||
[[nodiscard]] QString getManualDownloadUrl() const override;
|
||||
QString getManualDownloadUrl() const override;
|
||||
|
||||
[[nodiscard]] QString getName() const override;
|
||||
QString getName() const override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] QString getReleaseChannelUrl() const override;
|
||||
QString getReleaseChannelUrl() const override;
|
||||
protected slots:
|
||||
|
||||
void releaseListFinished() override;
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "replay_timeline_widget.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QPalette>
|
||||
#include <QTimer>
|
||||
|
||||
ReplayTimelineWidget::ReplayTimelineWidget(QWidget *parent)
|
||||
@@ -7,8 +7,9 @@
|
||||
#ifndef REPLAY_TIMELINE_WIDGET
|
||||
#define REPLAY_TIMELINE_WIDGET
|
||||
|
||||
#include "../../../game/player/event_processing_options.h"
|
||||
#include "../../game/player/event_processing_options.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMouseEvent>
|
||||
#include <QWidget>
|
||||
|
||||
@@ -59,10 +60,10 @@ public:
|
||||
|
||||
explicit ReplayTimelineWidget(QWidget *parent = nullptr);
|
||||
void setTimeline(const QList<int> &_replayTimeline);
|
||||
[[nodiscard]] QSize sizeHint() const override;
|
||||
[[nodiscard]] QSize minimumSizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
void setTimeScaleFactor(qreal _timeScaleFactor);
|
||||
[[nodiscard]] int getCurrentEvent() const
|
||||
int getCurrentEvent() const
|
||||
{
|
||||
return currentEvent;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "card_sets_model.h"
|
||||
#include "sets_model.h"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
#ifndef SETSMODEL_H
|
||||
#define SETSMODEL_H
|
||||
|
||||
#include "../../database/card_database.h"
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QMimeData>
|
||||
#include <QSet>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
|
||||
class SetsProxyModel;
|
||||
|
||||
@@ -25,11 +26,11 @@ public:
|
||||
SetsMimeData(int _oldRow) : oldRow(_oldRow)
|
||||
{
|
||||
}
|
||||
[[nodiscard]] int getOldRow() const
|
||||
int getOldRow() const
|
||||
{
|
||||
return oldRow;
|
||||
}
|
||||
[[nodiscard]] QStringList formats() const
|
||||
QStringList formats() const
|
||||
{
|
||||
return QStringList() << "application/x-cockatricecardset";
|
||||
}
|
||||
@@ -64,23 +65,22 @@ public:
|
||||
|
||||
explicit SetsModel(CardDatabase *_db, QObject *parent = nullptr);
|
||||
~SetsModel() override;
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
[[nodiscard]] int columnCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return NUM_COLS;
|
||||
}
|
||||
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
[[nodiscard]] QVariant
|
||||
headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
[[nodiscard]] Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
[[nodiscard]] Qt::DropActions supportedDropActions() const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
|
||||
[[nodiscard]] QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
bool
|
||||
dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
[[nodiscard]] QStringList mimeTypes() const override;
|
||||
QStringList mimeTypes() const override;
|
||||
void swapRows(int oldRow, int newRow);
|
||||
void toggleRow(int row, bool enable);
|
||||
void toggleRow(int row);
|
||||
@@ -98,8 +98,8 @@ public:
|
||||
explicit SetsDisplayModel(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
[[nodiscard]] bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
[[nodiscard]] bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
void fetchMore(const QModelIndex &index) override;
|
||||
};
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
#include "spoiler_background_updater.h"
|
||||
|
||||
#include "../../../../interface/window_main.h"
|
||||
#include "../../../../main.h"
|
||||
#include "../../../settings/cache_settings.h"
|
||||
#include "../../database/card_database.h"
|
||||
#include "../../database/card_database_manager.h"
|
||||
#include "../../interface/window_main.h"
|
||||
#include "../../main.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QUrl>
|
||||
#include <QtConcurrent>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
|
||||
#define SPOILERS_STATUS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Spoiler/files/SpoilerSeasonEnabled"
|
||||
#define SPOILERS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Spoiler/files/spoiler.xml"
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
inline QString getCardUpdaterBinaryName()
|
||||
{
|
||||
return "oracle";
|
||||
}
|
||||
};
|
||||
QByteArray getHash(const QString fileName);
|
||||
QByteArray getHash(QByteArray data);
|
||||
static bool deleteSpoilerFile();
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "replay_manager.h"
|
||||
|
||||
#include "../interface/widgets/tabs/tab_game.h"
|
||||
#include "../tabs/tab_game.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QToolButton>
|
||||
@@ -8,11 +8,11 @@
|
||||
#ifndef REPLAY_MANAGER_H
|
||||
#define REPLAY_MANAGER_H
|
||||
|
||||
#include "replay_timeline_widget.h"
|
||||
#include "network/replay_timeline_widget.h"
|
||||
#include "pb/game_replay.pb.h"
|
||||
|
||||
#include <QToolButton>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/protocol/pb/game_replay.pb.h>
|
||||
|
||||
class TabGame;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "sound_engine.h"
|
||||
|
||||
#include "settings/cache_settings.h"
|
||||
#include "../settings/cache_settings.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QMediaPlayer>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#include "tapped_out_interface.h"
|
||||
|
||||
#include "deck_list.h"
|
||||
#include "deck_list_card_node.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QRegularExpression>
|
||||
#include <QUrlQuery>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/tree/deck_list_card_node.h>
|
||||
|
||||
TappedOutInterface::TappedOutInterface(CardDatabase &_cardDatabase, QObject *parent)
|
||||
: QObject(parent), cardDatabase(_cardDatabase)
|
||||
@@ -7,8 +7,11 @@
|
||||
#ifndef TAPPEDOUT_INTERFACE_H
|
||||
#define TAPPEDOUT_INTERFACE_H
|
||||
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include "../database/card_database.h"
|
||||
#include "deck_list.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QObject>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(TappedOutInterfaceLog, "tapped_out_interface");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "update_downloader.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
|
||||
UpdateDownloader::UpdateDownloader(QObject *parent) : QObject(parent), response(nullptr)
|
||||
@@ -7,7 +7,9 @@
|
||||
#ifndef COCKATRICE_UPDATEDOWNLOADER_H
|
||||
#define COCKATRICE_UPDATEDOWNLOADER_H
|
||||
|
||||
#include <QDate>
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QtNetwork>
|
||||
|
||||
class UpdateDownloader : public QObject
|
||||
@@ -1,34 +1,35 @@
|
||||
#include "card_database.h"
|
||||
|
||||
#include "../relation/card_relation.h"
|
||||
#include "../card/card_relation.h"
|
||||
#include "../picture_loader/picture_loader.h"
|
||||
#include "../settings/cache_settings.h"
|
||||
#include "parser/cockatrice_xml_3.h"
|
||||
#include "parser/cockatrice_xml_4.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
CardDatabase::CardDatabase(QObject *parent,
|
||||
ICardPreferenceProvider *prefs,
|
||||
ICardDatabasePathProvider *pathProvider,
|
||||
ICardSetPriorityController *_setPriorityController)
|
||||
: QObject(parent), setPriorityController(_setPriorityController), loadStatus(NotLoaded)
|
||||
CardDatabase::CardDatabase(QObject *parent) : QObject(parent), loadStatus(NotLoaded)
|
||||
{
|
||||
qRegisterMetaType<CardInfoPtr>("CardInfoPtr");
|
||||
qRegisterMetaType<CardInfoPtr>("CardSetPtr");
|
||||
|
||||
// create loader and wire it up
|
||||
loader = new CardDatabaseLoader(this, this, pathProvider, prefs);
|
||||
loader = new CardDatabaseLoader(this, this);
|
||||
// re-emit loader signals (so other code doesn't need to know about internals)
|
||||
connect(loader, &CardDatabaseLoader::loadingFinished, this, &CardDatabase::cardDatabaseLoadingFinished);
|
||||
connect(loader, &CardDatabaseLoader::loadingFailed, this, &CardDatabase::cardDatabaseLoadingFailed);
|
||||
connect(loader, &CardDatabaseLoader::newSetsFound, this, &CardDatabase::cardDatabaseNewSetsFound);
|
||||
connect(loader, &CardDatabaseLoader::allNewSetsEnabled, this, &CardDatabase::cardDatabaseAllNewSetsEnabled);
|
||||
|
||||
querier = new CardDatabaseQuerier(this, this, prefs);
|
||||
querier = new CardDatabaseQuerier(this, this);
|
||||
}
|
||||
|
||||
CardDatabase::~CardDatabase()
|
||||
@@ -138,7 +139,7 @@ CardSetPtr CardDatabase::getSet(const QString &setName)
|
||||
if (sets.contains(setName)) {
|
||||
return sets.value(setName);
|
||||
} else {
|
||||
CardSetPtr newSet = CardSet::newInstance(setPriorityController, setName);
|
||||
CardSetPtr newSet = CardSet::newInstance(setName);
|
||||
sets.insert(setName, newSet);
|
||||
return newSet;
|
||||
}
|
||||
@@ -192,9 +193,8 @@ void CardDatabase::markAllSetsAsKnown()
|
||||
void CardDatabase::notifyEnabledSetsChanged()
|
||||
{
|
||||
// refresh the list of cached set names
|
||||
for (const CardInfoPtr &card : cards) {
|
||||
card->refreshCachedSets();
|
||||
}
|
||||
for (const CardInfoPtr &card : cards)
|
||||
card->refreshCachedSetNames();
|
||||
|
||||
// inform the carddatabasemodels that they need to re-check their list of cards
|
||||
emit cardDatabaseEnabledSetsChanged();
|
||||
103
cockatrice/src/database/card_database.h
Normal file
103
cockatrice/src/database/card_database.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @file card_database.h
|
||||
* @ingroup CardDatabase
|
||||
* @brief The CardDatabase is responsible for holding the card and set maps.
|
||||
*/
|
||||
|
||||
#ifndef CARDDATABASE_H
|
||||
#define CARDDATABASE_H
|
||||
|
||||
#include "../card/card_set_list.h"
|
||||
#include "../card/exact_card.h"
|
||||
#include "../common/card_ref.h"
|
||||
#include "card_database_loader.h"
|
||||
#include "card_database_querier.h"
|
||||
|
||||
#include <QBasicMutex>
|
||||
#include <QDate>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QLoggingCategory>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
#include <utility>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CardDatabaseLog, "card_database");
|
||||
|
||||
class CardDatabase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
/*
|
||||
* The cards, indexed by name.
|
||||
*/
|
||||
CardNameMap cards;
|
||||
|
||||
/**
|
||||
* The cards, indexed by their simple name.
|
||||
*/
|
||||
CardNameMap simpleNameCards;
|
||||
|
||||
/*
|
||||
* The sets, indexed by short name.
|
||||
*/
|
||||
SetNameMap sets;
|
||||
|
||||
// loader responsible for file discovery & parsing
|
||||
CardDatabaseLoader *loader;
|
||||
|
||||
LoadStatus loadStatus;
|
||||
|
||||
CardDatabaseQuerier *querier;
|
||||
|
||||
private:
|
||||
void checkUnknownSets();
|
||||
void refreshCachedReverseRelatedCards();
|
||||
|
||||
QBasicMutex *clearDatabaseMutex = new QBasicMutex(), *addCardMutex = new QBasicMutex(),
|
||||
*removeCardMutex = new QBasicMutex();
|
||||
|
||||
public:
|
||||
explicit CardDatabase(QObject *parent = nullptr);
|
||||
~CardDatabase() override;
|
||||
|
||||
void removeCard(CardInfoPtr card);
|
||||
void clear();
|
||||
|
||||
const CardNameMap &getCardList() const
|
||||
{
|
||||
return cards;
|
||||
}
|
||||
CardSetPtr getSet(const QString &setName);
|
||||
CardSetList getSetList() const;
|
||||
LoadStatus getLoadStatus() const
|
||||
{
|
||||
return loadStatus;
|
||||
}
|
||||
CardDatabaseQuerier *query() const
|
||||
{
|
||||
return querier;
|
||||
}
|
||||
void enableAllUnknownSets();
|
||||
void markAllSetsAsKnown();
|
||||
void notifyEnabledSetsChanged();
|
||||
|
||||
public slots:
|
||||
void addCard(CardInfoPtr card);
|
||||
void addSet(CardSetPtr set);
|
||||
void loadCardDatabases();
|
||||
bool saveCustomTokensToFile();
|
||||
signals:
|
||||
void cardDatabaseLoadingFinished();
|
||||
void cardDatabaseLoadingFailed();
|
||||
void cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknownSetsNames);
|
||||
void cardDatabaseAllNewSetsEnabled();
|
||||
void cardDatabaseEnabledSetsChanged();
|
||||
void cardAdded(CardInfoPtr card);
|
||||
void cardRemoved(CardInfoPtr card);
|
||||
|
||||
friend class CardDatabaseLoader;
|
||||
friend class CardDatabaseQuerier;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "card_database_loader.h"
|
||||
|
||||
#include "../settings/cache_settings.h"
|
||||
#include "card_database.h"
|
||||
#include "parser/cockatrice_xml_3.h"
|
||||
#include "parser/cockatrice_xml_4.h"
|
||||
@@ -9,14 +10,10 @@
|
||||
#include <QFile>
|
||||
#include <QTime>
|
||||
|
||||
CardDatabaseLoader::CardDatabaseLoader(QObject *parent,
|
||||
CardDatabase *db,
|
||||
ICardDatabasePathProvider *_pathProvider,
|
||||
ICardPreferenceProvider *_preferenceProvider)
|
||||
: QObject(parent), database(db), pathProvider(_pathProvider)
|
||||
CardDatabaseLoader::CardDatabaseLoader(QObject *parent, CardDatabase *db) : QObject(parent), database(db)
|
||||
{
|
||||
// instantiate available parsers here and connect them to the database
|
||||
availableParsers << new CockatriceXml4Parser(_preferenceProvider);
|
||||
availableParsers << new CockatriceXml4Parser;
|
||||
availableParsers << new CockatriceXml3Parser;
|
||||
|
||||
for (auto *p : availableParsers) {
|
||||
@@ -26,7 +23,7 @@ CardDatabaseLoader::CardDatabaseLoader(QObject *parent,
|
||||
}
|
||||
|
||||
// when SettingsCache's path changes, trigger reloads
|
||||
connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this,
|
||||
connect(&SettingsCache::instance(), &SettingsCache::cardDatabasePathChanged, this,
|
||||
&CardDatabaseLoader::loadCardDatabases);
|
||||
}
|
||||
|
||||
@@ -39,7 +36,8 @@ CardDatabaseLoader::~CardDatabaseLoader()
|
||||
LoadStatus CardDatabaseLoader::loadFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
file.open(QIODevice::ReadOnly);
|
||||
if (!file.isOpen()) {
|
||||
return FileError;
|
||||
}
|
||||
|
||||
@@ -86,9 +84,10 @@ LoadStatus CardDatabaseLoader::loadCardDatabases()
|
||||
|
||||
database->clear(); // remove old db
|
||||
|
||||
LoadStatus loadStatus = loadCardDatabase(pathProvider->getCardDatabasePath()); // load main card database
|
||||
loadCardDatabase(pathProvider->getTokenDatabasePath()); // load tokens database
|
||||
loadCardDatabase(pathProvider->getSpoilerCardDatabasePath()); // load spoilers database
|
||||
LoadStatus loadStatus =
|
||||
loadCardDatabase(SettingsCache::instance().getCardDatabasePath()); // load main card database
|
||||
loadCardDatabase(SettingsCache::instance().getTokenDatabasePath()); // load tokens database
|
||||
loadCardDatabase(SettingsCache::instance().getSpoilerCardDatabasePath()); // load spoilers database
|
||||
|
||||
// find all custom card databases, recursively & following symlinks
|
||||
// then load them alphabetically
|
||||
@@ -119,7 +118,7 @@ LoadStatus CardDatabaseLoader::loadCardDatabases()
|
||||
|
||||
QStringList CardDatabaseLoader::collectCustomDatabasePaths() const
|
||||
{
|
||||
QDirIterator it(pathProvider->getCustomCardDatabasePath(), {"*.xml"}, QDir::Files,
|
||||
QDirIterator it(SettingsCache::instance().getCustomCardDatabasePath(), {"*.xml"}, QDir::Files,
|
||||
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
||||
|
||||
QStringList paths;
|
||||
@@ -136,7 +135,7 @@ bool CardDatabaseLoader::saveCustomTokensToFile()
|
||||
return false;
|
||||
}
|
||||
|
||||
QString fileName = pathProvider->getCustomCardDatabasePath() + "/" + CardSet::TOKENS_SETNAME + ".xml";
|
||||
QString fileName = SettingsCache::instance().getCustomCardDatabasePath() + "/" + CardSet::TOKENS_SETNAME + ".xml";
|
||||
|
||||
SetNameMap tmpSets;
|
||||
CardSetPtr customTokensSet = database->getSet(CardSet::TOKENS_SETNAME);
|
||||
@@ -151,4 +150,4 @@ bool CardDatabaseLoader::saveCustomTokensToFile()
|
||||
|
||||
availableParsers.first()->saveToFile(tmpSets, tmpCards, fileName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
63
cockatrice/src/database/card_database_loader.h
Normal file
63
cockatrice/src/database/card_database_loader.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file card_database_loader.h
|
||||
* @ingroup CardDatabase
|
||||
* @brief The CardDatabaseLoader is responsible for populating the card database from files on disk.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_CARD_DATABASE_LOADER_H
|
||||
#define COCKATRICE_CARD_DATABASE_LOADER_H
|
||||
|
||||
#include <QBasicMutex>
|
||||
#include <QList>
|
||||
#include <QLoggingCategory>
|
||||
#include <QObject>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingLog, "card_database.loading");
|
||||
inline Q_LOGGING_CATEGORY(CardDatabaseLoadingSuccessOrFailureLog, "card_database.loading.success_or_failure");
|
||||
|
||||
class CardDatabase;
|
||||
class ICardDatabaseParser;
|
||||
|
||||
enum LoadStatus
|
||||
{
|
||||
Ok,
|
||||
VersionTooOld,
|
||||
Invalid,
|
||||
NotLoaded,
|
||||
FileError,
|
||||
NoCards
|
||||
};
|
||||
|
||||
class CardDatabaseLoader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CardDatabaseLoader(QObject *parent, CardDatabase *db);
|
||||
~CardDatabaseLoader() override;
|
||||
|
||||
public slots:
|
||||
LoadStatus loadCardDatabases(); // discover & load the configured databases
|
||||
LoadStatus loadCardDatabase(const QString &path); // load a single file
|
||||
bool saveCustomTokensToFile(); // write tokens to custom DB path
|
||||
|
||||
signals:
|
||||
void loadingStarted();
|
||||
void loadingFinished();
|
||||
void loadingFailed();
|
||||
void newSetsFound(int numSets, const QStringList &setNames);
|
||||
void allNewSetsEnabled();
|
||||
|
||||
private:
|
||||
LoadStatus loadFromFile(const QString &fileName); // internal helper
|
||||
QStringList collectCustomDatabasePaths() const;
|
||||
|
||||
CardDatabase *database; // non-owning pointer to the container
|
||||
|
||||
// parsers
|
||||
QList<ICardDatabaseParser *> availableParsers;
|
||||
|
||||
QBasicMutex *loadFromFileMutex = new QBasicMutex();
|
||||
QBasicMutex *reloadDatabaseMutex = new QBasicMutex();
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_CARD_DATABASE_LOADER_H
|
||||
12
cockatrice/src/database/card_database_manager.cpp
Normal file
12
cockatrice/src/database/card_database_manager.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "card_database_manager.h"
|
||||
|
||||
CardDatabase *CardDatabaseManager::getInstance()
|
||||
{
|
||||
static CardDatabase instance; // Created only once, on first access
|
||||
return &instance;
|
||||
}
|
||||
|
||||
CardDatabaseQuerier *CardDatabaseManager::query()
|
||||
{
|
||||
return getInstance()->query();
|
||||
}
|
||||
29
cockatrice/src/database/card_database_manager.h
Normal file
29
cockatrice/src/database/card_database_manager.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file card_database_manager.h
|
||||
* @ingroup CardDatabase
|
||||
* @brief The CardDatabaseManager is responsible for managing the global database singleton.
|
||||
*/
|
||||
|
||||
#ifndef CARD_DATABASE_ACCESSOR_H
|
||||
#define CARD_DATABASE_ACCESSOR_H
|
||||
|
||||
#pragma once
|
||||
#include "card_database.h"
|
||||
|
||||
class CardDatabaseManager
|
||||
{
|
||||
public:
|
||||
// Delete copy constructor and assignment operator to enforce singleton
|
||||
CardDatabaseManager(const CardDatabaseManager &) = delete;
|
||||
CardDatabaseManager &operator=(const CardDatabaseManager &) = delete;
|
||||
|
||||
// Static method to access the singleton instance
|
||||
static CardDatabase *getInstance();
|
||||
static CardDatabaseQuerier *query();
|
||||
|
||||
private:
|
||||
CardDatabaseManager() = default; // Private constructor
|
||||
~CardDatabaseManager() = default;
|
||||
};
|
||||
|
||||
#endif // CARD_DATABASE_ACCESSOR_H
|
||||
@@ -1,16 +1,11 @@
|
||||
#include "card_database_querier.h"
|
||||
|
||||
#include "../card_info.h"
|
||||
#include "../printing/exact_card.h"
|
||||
#include "../set/card_set_comparator.h"
|
||||
#include "../utility/card_set_comparator.h"
|
||||
#include "card_database.h"
|
||||
|
||||
#include <qrandom.h>
|
||||
|
||||
CardDatabaseQuerier::CardDatabaseQuerier(QObject *_parent,
|
||||
const CardDatabase *_db,
|
||||
const ICardPreferenceProvider *prefs)
|
||||
: QObject(_parent), db(_db), prefs(prefs)
|
||||
CardDatabaseQuerier::CardDatabaseQuerier(QObject *_parent, const CardDatabase *_db) : QObject(_parent), db(_db)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -207,17 +202,6 @@ PrintingInfo CardDatabaseQuerier::getSpecificPrinting(const QString &cardName,
|
||||
return PrintingInfo(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the card representing the preferred printing of the cardInfo
|
||||
*
|
||||
* @param cardName The cardName to find the preferred card and printing for
|
||||
* @return A specific printing of a card
|
||||
*/
|
||||
ExactCard CardDatabaseQuerier::getPreferredCard(const QString &cardName) const
|
||||
{
|
||||
return getPreferredCard(getCardInfo(cardName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the card representing the preferred printing of the cardInfo
|
||||
*
|
||||
@@ -250,12 +234,6 @@ PrintingInfo CardDatabaseQuerier::getPreferredPrinting(const CardInfoPtr &cardIn
|
||||
return PrintingInfo(nullptr);
|
||||
}
|
||||
|
||||
const auto &pinnedPrintingProviderId = prefs->getCardPreferenceOverride(cardInfo->getName());
|
||||
|
||||
if (!pinnedPrintingProviderId.isEmpty()) {
|
||||
return getSpecificPrinting({cardInfo->getName(), pinnedPrintingProviderId});
|
||||
}
|
||||
|
||||
SetToPrintingsMap setMap = cardInfo->getSets();
|
||||
if (setMap.empty()) {
|
||||
return PrintingInfo(nullptr);
|
||||
60
cockatrice/src/database/card_database_querier.h
Normal file
60
cockatrice/src/database/card_database_querier.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file card_database_querier.h
|
||||
* @ingroup CardDatabase
|
||||
* @brief The CardDatabaseQuerier is responsible for querying the database and returning data.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_CARD_DATABASE_QUERIER_H
|
||||
#define COCKATRICE_CARD_DATABASE_QUERIER_H
|
||||
|
||||
#include "../card/exact_card.h"
|
||||
#include "../common/card_ref.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class CardDatabase;
|
||||
class CardDatabaseQuerier : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CardDatabaseQuerier(QObject *parent, const CardDatabase *db);
|
||||
|
||||
[[nodiscard]] CardInfoPtr getCardInfo(const QString &cardName) const;
|
||||
[[nodiscard]] QList<CardInfoPtr> getCardInfos(const QStringList &cardNames) const;
|
||||
|
||||
/*
|
||||
* Get a card by its simple name. The name will be simplified in this
|
||||
* function, so you don't need to simplify it beforehand.
|
||||
*/
|
||||
[[nodiscard]] CardInfoPtr getCardBySimpleName(const QString &cardName) const;
|
||||
|
||||
[[nodiscard]] ExactCard guessCard(const CardRef &cardRef) const;
|
||||
[[nodiscard]] ExactCard getCard(const CardRef &cardRef) const;
|
||||
[[nodiscard]] QList<ExactCard> getCards(const QList<CardRef> &cardRefs) const;
|
||||
|
||||
[[nodiscard]] ExactCard getRandomCard() const;
|
||||
[[nodiscard]] ExactCard getCardFromSameSet(const QString &cardName, const PrintingInfo &otherPrinting) const;
|
||||
|
||||
[[nodiscard]] ExactCard getPreferredCard(const CardInfoPtr &card) const;
|
||||
[[nodiscard]] bool isPreferredPrinting(const CardRef &cardRef) const;
|
||||
[[nodiscard]] PrintingInfo getPreferredPrinting(const CardInfoPtr &card) const;
|
||||
[[nodiscard]] PrintingInfo getPreferredPrinting(const QString &cardName) const;
|
||||
[[nodiscard]] QString getPreferredPrintingProviderId(const QString &cardName) const;
|
||||
|
||||
[[nodiscard]] PrintingInfo getSpecificPrinting(const CardRef &cardRef) const;
|
||||
[[nodiscard]] PrintingInfo
|
||||
getSpecificPrinting(const QString &cardName, const QString &setCode, const QString &collectorNumber) const;
|
||||
[[nodiscard]] PrintingInfo findPrintingWithId(const CardInfoPtr &card, const QString &providerId) const;
|
||||
|
||||
[[nodiscard]] QStringList getAllMainCardTypes() const;
|
||||
[[nodiscard]] QMap<QString, int> getAllMainCardTypesWithCount() const;
|
||||
[[nodiscard]] QMap<QString, int> getAllSubCardTypesWithCount() const;
|
||||
|
||||
private:
|
||||
const CardDatabase *db;
|
||||
|
||||
CardInfoPtr lookupCardByName(const QString &name) const;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_CARD_DATABASE_QUERIER_H
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef COCKATRICE_SETTINGS_CARD_PREFERENCE_PROVIDER_H
|
||||
#define COCKATRICE_SETTINGS_CARD_PREFERENCE_PROVIDER_H
|
||||
#include "../../client/settings/cache_settings.h"
|
||||
|
||||
#include <libcockatrice/interfaces/interface_card_preference_provider.h>
|
||||
|
||||
class SettingsCardPreferenceProvider : public ICardPreferenceProvider
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] QString getCardPreferenceOverride(const QString &cardName) const override
|
||||
{
|
||||
return SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardName);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool getIncludeRebalancedCards() const override
|
||||
{
|
||||
return SettingsCache::instance().getIncludeRebalancedCards();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_SETTINGS_CARD_PREFERENCE_PROVIDER_H
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
explicit CardCompleterProxyModel(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
[[nodiscard]] bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
};
|
||||
|
||||
#endif // CARD_COMPLETER_PROXY_MODEL_H
|
||||
@@ -1,10 +1,9 @@
|
||||
#include "card_search_model.h"
|
||||
|
||||
#include "../card_database_display_model.h"
|
||||
#include "../../../utility/levenshtein.h"
|
||||
#include "../card_database_model.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <libcockatrice/utility/levenshtein.h>
|
||||
|
||||
CardSearchModel::CardSearchModel(CardDatabaseDisplayModel *sourceModel, QObject *parent)
|
||||
: QAbstractListModel(parent), sourceModel(sourceModel)
|
||||
@@ -17,8 +17,8 @@ class CardSearchModel : public QAbstractListModel
|
||||
public:
|
||||
explicit CardSearchModel(CardDatabaseDisplayModel *sourceModel, QObject *parent = nullptr);
|
||||
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
void updateSearchResults(const QString &query); // Update results based on input
|
||||
|
||||
@@ -184,20 +184,13 @@ bool CardDatabaseDisplayModel::rowMatchesCardName(CardInfoPtr info) const
|
||||
|
||||
void CardDatabaseDisplayModel::clearFilterAll()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 9, 0))
|
||||
beginFilterChange();
|
||||
#endif
|
||||
cardName.clear();
|
||||
cardText.clear();
|
||||
cardTypes.clear();
|
||||
cardColors.clear();
|
||||
if (filterTree != nullptr)
|
||||
filterTree->clear();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 10, 0))
|
||||
endFilterChange(QSortFilterProxyModel::Direction::Rows);
|
||||
#else
|
||||
invalidateFilter();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CardDatabaseDisplayModel::setFilterTree(FilterTree *_filterTree)
|
||||
@@ -224,4 +217,4 @@ const QString CardDatabaseDisplayModel::sanitizeCardName(const QString &dirtyNam
|
||||
}
|
||||
}
|
||||
return QString::fromStdWString(toReturn);
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,12 @@
|
||||
#ifndef COCKATRICE_CARD_DATABASE_DISPLAY_MODEL_H
|
||||
#define COCKATRICE_CARD_DATABASE_DISPLAY_MODEL_H
|
||||
|
||||
#include "../../filters/filter_string.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QTimer>
|
||||
#include <libcockatrice/filters/filter_string.h>
|
||||
|
||||
class FilterTree;
|
||||
class CardDatabaseDisplayModel : public QSortFilterProxyModel
|
||||
@@ -75,17 +78,17 @@ public:
|
||||
dirtyTimer.start(20);
|
||||
}
|
||||
void clearFilterAll();
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
[[nodiscard]] bool canFetchMore(const QModelIndex &parent) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
bool canFetchMore(const QModelIndex &parent) const override;
|
||||
void fetchMore(const QModelIndex &parent) override;
|
||||
signals:
|
||||
void modelDirty();
|
||||
|
||||
protected:
|
||||
[[nodiscard]] bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
static int lessThanNumerically(const QString &left, const QString &right);
|
||||
[[nodiscard]] bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
[[nodiscard]] bool rowMatchesCardName(CardInfoPtr info) const;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool rowMatchesCardName(CardInfoPtr info) const;
|
||||
|
||||
private slots:
|
||||
void filterTreeChanged();
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "card_database_model.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
|
||||
#define CARDDBMODEL_COLUMNS 6
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
#ifndef CARDDATABASEMODEL_H
|
||||
#define CARDDATABASEMODEL_H
|
||||
|
||||
#include "../card_database.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
|
||||
class CardDatabaseModel : public QAbstractListModel
|
||||
{
|
||||
@@ -31,16 +32,15 @@ public:
|
||||
};
|
||||
CardDatabaseModel(CardDatabase *_db, bool _showOnlyCardsFromEnabledSets, QObject *parent = nullptr);
|
||||
~CardDatabaseModel() override;
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
[[nodiscard]] int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
|
||||
[[nodiscard]] QVariant
|
||||
headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
[[nodiscard]] CardDatabase *getDatabase() const
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
CardDatabase *getDatabase() const
|
||||
{
|
||||
return db;
|
||||
}
|
||||
[[nodiscard]] CardInfoPtr getCard(int index) const
|
||||
CardInfoPtr getCard(int index) const
|
||||
{
|
||||
return cardList[index];
|
||||
}
|
||||
@@ -14,10 +14,10 @@ class TokenDisplayModel : public CardDatabaseDisplayModel
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TokenDisplayModel(QObject *parent = nullptr);
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_TOKEN_DISPLAY_MODEL_H
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "token_edit_model.h"
|
||||
|
||||
#include "../card_database_display_model.h"
|
||||
#include "../card_database_model.h"
|
||||
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
|
||||
TokenEditModel::TokenEditModel(QObject *parent) : CardDatabaseDisplayModel(parent)
|
||||
{
|
||||
}
|
||||
@@ -14,10 +14,10 @@ class TokenEditModel : public CardDatabaseDisplayModel
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TokenEditModel(QObject *parent = nullptr);
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_TOKEN_EDIT_MODEL_H
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "card_database_parser.h"
|
||||
|
||||
#include <libcockatrice/interfaces/noop_card_set_priority_controller.h>
|
||||
|
||||
SetNameMap ICardDatabaseParser::sets;
|
||||
|
||||
void ICardDatabaseParser::clearSetlist()
|
||||
@@ -19,7 +17,7 @@ CardSetPtr ICardDatabaseParser::internalAddSet(const QString &setName,
|
||||
return sets.value(setName);
|
||||
}
|
||||
|
||||
CardSetPtr newSet = CardSet::newInstance(new NoopCardSetPriorityController(), setName);
|
||||
CardSetPtr newSet = CardSet::newInstance(setName);
|
||||
newSet->setLongName(longName);
|
||||
newSet->setSetType(setType);
|
||||
newSet->setReleaseDate(releaseDate);
|
||||
51
cockatrice/src/database/parser/card_database_parser.h
Normal file
51
cockatrice/src/database/parser/card_database_parser.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file card_database_parser.h
|
||||
* @ingroup CardDatabaseParsers
|
||||
* @brief The ICardDatabaseParser defines the base interface for parser sub-classes.
|
||||
*/
|
||||
|
||||
#ifndef CARDDATABASE_PARSER_H
|
||||
#define CARDDATABASE_PARSER_H
|
||||
|
||||
#include "../../card/card_info.h"
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QString>
|
||||
|
||||
#define COCKATRICE_XML_XSI_NAMESPACE "http://www.w3.org/2001/XMLSchema-instance"
|
||||
|
||||
class ICardDatabaseParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~ICardDatabaseParser() override = default;
|
||||
|
||||
virtual bool getCanParseFile(const QString &name, QIODevice &device) = 0;
|
||||
virtual void parseFile(QIODevice &device) = 0;
|
||||
virtual bool saveToFile(SetNameMap sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl = "unknown",
|
||||
const QString &sourceVersion = "unknown") = 0;
|
||||
static void clearSetlist();
|
||||
|
||||
protected:
|
||||
/*
|
||||
* A cached list of the available sets, needed to cross-reference sets from cards.
|
||||
* Shared between all parsers
|
||||
*/
|
||||
static SetNameMap sets;
|
||||
|
||||
CardSetPtr internalAddSet(const QString &setName,
|
||||
const QString &longName = "",
|
||||
const QString &setType = "",
|
||||
const QDate &releaseDate = QDate(),
|
||||
const CardSet::Priority priority = CardSet::PriorityFallback);
|
||||
signals:
|
||||
void addCard(CardInfoPtr card);
|
||||
void addSet(CardSetPtr set);
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(ICardDatabaseParser, "ICardDatabaseParser")
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "cockatrice_xml_3.h"
|
||||
|
||||
#include "../../relation/card_relation.h"
|
||||
#include "../../relation/card_relation_type.h"
|
||||
#include "../../card/card_relation.h"
|
||||
#include "../../card/card_relation_type.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
@@ -282,13 +282,9 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
properties.insert("colors", colors);
|
||||
|
||||
CardInfo::UiAttributes attributes = {.cipt = cipt,
|
||||
.landscapeOrientation = landscapeOrientation,
|
||||
.tableRow = tableRow,
|
||||
.upsideDownArt = upsideDown};
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, _sets, attributes);
|
||||
CardInfoPtr newCard =
|
||||
CardInfo::newInstance(name, text, isToken, properties, relatedCards, reverseRelatedCards, _sets, cipt,
|
||||
landscapeOrientation, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
@@ -421,15 +417,14 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
}
|
||||
|
||||
// positioning
|
||||
const CardInfo::UiAttributes &attributes = info->getUiAttributes();
|
||||
xml.writeTextElement("tablerow", QString::number(attributes.tableRow));
|
||||
if (attributes.cipt) {
|
||||
xml.writeTextElement("tablerow", QString::number(info->getTableRow()));
|
||||
if (info->getCipt()) {
|
||||
xml.writeTextElement("cipt", "1");
|
||||
}
|
||||
if (attributes.landscapeOrientation) {
|
||||
if (info->getLandscapeOrientation()) {
|
||||
xml.writeTextElement("landscapeOrientation", "1");
|
||||
}
|
||||
if (attributes.upsideDownArt) {
|
||||
if (info->getUpsideDownArt()) {
|
||||
xml.writeTextElement("upsidedown", "1");
|
||||
}
|
||||
|
||||
38
cockatrice/src/database/parser/cockatrice_xml_3.h
Normal file
38
cockatrice/src/database/parser/cockatrice_xml_3.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file cockatrice_xml_3.h
|
||||
* @ingroup CardDatabaseParsers
|
||||
* @brief The CockatriceXml3Parser is capable of parsing version 3 of the Cockatrice XML Schema.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_XML3_H
|
||||
#define COCKATRICE_XML3_H
|
||||
|
||||
#include "card_database_parser.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CockatriceXml3Log, "cockatrice_xml.xml_3_parser");
|
||||
|
||||
class CockatriceXml3Parser : public ICardDatabaseParser
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(ICardDatabaseParser)
|
||||
public:
|
||||
CockatriceXml3Parser() = default;
|
||||
~CockatriceXml3Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap _sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl = "unknown",
|
||||
const QString &sourceVersion = "unknown") override;
|
||||
|
||||
private:
|
||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||
void loadSetsFromXml(QXmlStreamReader &xml);
|
||||
QString getMainCardType(QString &type);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "cockatrice_xml_4.h"
|
||||
|
||||
#include "../../relation/card_relation.h"
|
||||
#include "../../card/card_relation.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
@@ -13,11 +14,6 @@
|
||||
#define COCKATRICE_XML4_SCHEMALOCATION \
|
||||
"https://raw.githubusercontent.com/Cockatrice/Cockatrice/master/doc/carddatabase_v4/cards.xsd"
|
||||
|
||||
CockatriceXml4Parser::CockatriceXml4Parser(ICardPreferenceProvider *_cardPreferenceProvider)
|
||||
: cardPreferenceProvider(_cardPreferenceProvider)
|
||||
{
|
||||
}
|
||||
|
||||
bool CockatriceXml4Parser::getCanParseFile(const QString &fileName, QIODevice &device)
|
||||
{
|
||||
qCInfo(CockatriceXml4Log) << "Trying to parse: " << fileName;
|
||||
@@ -136,7 +132,7 @@ QVariantHash CockatriceXml4Parser::loadCardPropertiesFromXml(QXmlStreamReader &x
|
||||
|
||||
void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
{
|
||||
bool includeRebalancedCards = cardPreferenceProvider->getIncludeRebalancedCards();
|
||||
bool includeRebalancedCards = SettingsCache::instance().getIncludeRebalancedCards();
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
@@ -262,12 +258,9 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
continue;
|
||||
}
|
||||
|
||||
CardInfo::UiAttributes attributes = {.cipt = cipt,
|
||||
.landscapeOrientation = landscapeOrientation,
|
||||
.tableRow = tableRow,
|
||||
.upsideDownArt = upsideDown};
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, _sets, attributes);
|
||||
CardInfoPtr newCard =
|
||||
CardInfo::newInstance(name, text, isToken, properties, relatedCards, reverseRelatedCards, _sets, cipt,
|
||||
landscapeOrientation, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
@@ -382,15 +375,14 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
}
|
||||
|
||||
// positioning
|
||||
const CardInfo::UiAttributes &attributes = info->getUiAttributes();
|
||||
xml.writeTextElement("tablerow", QString::number(attributes.tableRow));
|
||||
if (attributes.cipt) {
|
||||
xml.writeTextElement("tablerow", QString::number(info->getTableRow()));
|
||||
if (info->getCipt()) {
|
||||
xml.writeTextElement("cipt", "1");
|
||||
}
|
||||
if (attributes.landscapeOrientation) {
|
||||
if (info->getLandscapeOrientation()) {
|
||||
xml.writeTextElement("landscapeOrientation", "1");
|
||||
}
|
||||
if (attributes.upsideDownArt) {
|
||||
if (info->getUpsideDownArt()) {
|
||||
xml.writeTextElement("upsidedown", "1");
|
||||
}
|
||||
|
||||
38
cockatrice/src/database/parser/cockatrice_xml_4.h
Normal file
38
cockatrice/src/database/parser/cockatrice_xml_4.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file cockatrice_xml_4.h
|
||||
* @ingroup CardDatabaseParsers
|
||||
* @brief The CockatriceXml4Parser is capable of parsing version 4 of the Cockatrice XML Schema.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_XML4_H
|
||||
#define COCKATRICE_XML4_H
|
||||
|
||||
#include "card_database_parser.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CockatriceXml4Log, "cockatrice_xml.xml_4_parser");
|
||||
|
||||
class CockatriceXml4Parser : public ICardDatabaseParser
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(ICardDatabaseParser)
|
||||
public:
|
||||
CockatriceXml4Parser() = default;
|
||||
~CockatriceXml4Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap _sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl = "unknown",
|
||||
const QString &sourceVersion = "unknown") override;
|
||||
|
||||
private:
|
||||
QVariantHash loadCardPropertiesFromXml(QXmlStreamReader &xml);
|
||||
void loadCardsFromXml(QXmlStreamReader &xml);
|
||||
void loadSetsFromXml(QXmlStreamReader &xml);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "custom_line_edit.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../../client/settings/shortcuts_settings.h"
|
||||
#include "../settings/cache_settings.h"
|
||||
#include "../settings/shortcuts_settings.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QLineEdit>
|
||||
@@ -1,15 +1,26 @@
|
||||
#include "deck_list_model.h"
|
||||
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include "../database/card_database_manager.h"
|
||||
#include "../main.h"
|
||||
#include "../settings/cache_settings.h"
|
||||
#include "deck_loader.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QFont>
|
||||
#include <QPrinter>
|
||||
#include <QProgressDialog>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocument>
|
||||
#include <QTextStream>
|
||||
#include <QTextTable>
|
||||
|
||||
DeckListModel::DeckListModel(QObject *parent)
|
||||
: 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 DeckLoader;
|
||||
deckList->setParent(this);
|
||||
connect(deckList, &DeckLoader::deckLoaded, this, &DeckListModel::rebuildTree);
|
||||
connect(deckList, &DeckLoader::deckHashChanged, this, &DeckListModel::deckHashChanged);
|
||||
root = new InnerDecklistNode;
|
||||
}
|
||||
|
||||
@@ -98,95 +109,82 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const
|
||||
return {};
|
||||
}
|
||||
|
||||
auto *node = static_cast<AbstractDecklistNode *>(index.internalPointer());
|
||||
auto *card = dynamic_cast<DecklistModelCardNode *>(node);
|
||||
|
||||
// Group node
|
||||
if (!card) {
|
||||
const auto *group = dynamic_cast<InnerDecklistNode *>(node);
|
||||
|
||||
auto *temp = static_cast<AbstractDecklistNode *>(index.internalPointer());
|
||||
auto *card = dynamic_cast<DecklistModelCardNode *>(temp);
|
||||
if (card == nullptr) {
|
||||
const auto *node = dynamic_cast<InnerDecklistNode *>(temp);
|
||||
switch (role) {
|
||||
case Qt::FontRole: {
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
return f;
|
||||
}
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole: {
|
||||
switch (index.column()) {
|
||||
case DeckListModelColumns::CARD_AMOUNT:
|
||||
return group->recursiveCount(true);
|
||||
case DeckListModelColumns::CARD_NAME:
|
||||
if (role == Qt::DisplayRole) {
|
||||
return group->getVisibleName();
|
||||
}
|
||||
return group->getName();
|
||||
case DeckListModelColumns::CARD_SET:
|
||||
return group->getCardSetShortName();
|
||||
case DeckListModelColumns::CARD_COLLECTOR_NUMBER:
|
||||
return group->getCardCollectorNumber();
|
||||
case DeckListModelColumns::CARD_PROVIDER_ID:
|
||||
return group->getCardProviderId();
|
||||
case 0:
|
||||
return node->recursiveCount(true);
|
||||
case 1: {
|
||||
if (role == Qt::DisplayRole)
|
||||
return node->getVisibleName();
|
||||
return node->getName();
|
||||
}
|
||||
case 2: {
|
||||
return node->getCardSetShortName();
|
||||
}
|
||||
case 3: {
|
||||
return node->getCardCollectorNumber();
|
||||
}
|
||||
case 4: {
|
||||
return node->getCardProviderId();
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
case DeckRoles::IsCardRole:
|
||||
case Qt::UserRole + 1:
|
||||
return false;
|
||||
|
||||
case DeckRoles::DepthRole:
|
||||
return group->depth();
|
||||
|
||||
// legality does not apply to group nodes
|
||||
case DeckRoles::IsLegalRole:
|
||||
return true;
|
||||
|
||||
case Qt::BackgroundRole: {
|
||||
int color = 90 + 60 * node->depth();
|
||||
return QBrush(QColor(color, 255, color));
|
||||
}
|
||||
case Qt::ForegroundRole: {
|
||||
return QBrush(QColor(0, 0, 0));
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
// Card node
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
switch (index.column()) {
|
||||
case DeckListModelColumns::CARD_AMOUNT:
|
||||
return card->getNumber();
|
||||
case DeckListModelColumns::CARD_NAME:
|
||||
return card->getName();
|
||||
case DeckListModelColumns::CARD_SET:
|
||||
return card->getCardSetShortName();
|
||||
case DeckListModelColumns::CARD_COLLECTOR_NUMBER:
|
||||
return card->getCardCollectorNumber();
|
||||
case DeckListModelColumns::CARD_PROVIDER_ID:
|
||||
return card->getCardProviderId();
|
||||
default:
|
||||
return {};
|
||||
} else {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole: {
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
return card->getNumber();
|
||||
case 1:
|
||||
return card->getName();
|
||||
case 2:
|
||||
return card->getCardSetShortName();
|
||||
case 3:
|
||||
return card->getCardCollectorNumber();
|
||||
case 4:
|
||||
return card->getCardProviderId();
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
case DeckRoles::IsCardRole: {
|
||||
return true;
|
||||
case Qt::UserRole + 1:
|
||||
return true;
|
||||
case Qt::BackgroundRole: {
|
||||
int color = 255 - (index.row() % 2) * 30;
|
||||
return QBrush(QColor(color, color, color));
|
||||
}
|
||||
case Qt::ForegroundRole: {
|
||||
return QBrush(QColor(0, 0, 0));
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
case DeckRoles::DepthRole: {
|
||||
return card->depth();
|
||||
}
|
||||
|
||||
default: {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckListModel::emitBackgroundUpdates(const QModelIndex &parent)
|
||||
{
|
||||
int rows = rowCount(parent);
|
||||
if (rows == 0)
|
||||
return;
|
||||
|
||||
QModelIndex topLeft = index(0, 0, parent);
|
||||
QModelIndex bottomRight = index(rows - 1, columnCount() - 1, parent);
|
||||
emit dataChanged(topLeft, bottomRight, {Qt::BackgroundRole});
|
||||
|
||||
for (int r = 0; r < rows; ++r) {
|
||||
QModelIndex child = index(r, 0, parent);
|
||||
emitBackgroundUpdates(child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,15 +199,15 @@ QVariant DeckListModel::headerData(const int section, const Qt::Orientation orie
|
||||
}
|
||||
|
||||
switch (section) {
|
||||
case DeckListModelColumns::CARD_AMOUNT:
|
||||
case 0:
|
||||
return tr("Count");
|
||||
case DeckListModelColumns::CARD_NAME:
|
||||
case 1:
|
||||
return tr("Card");
|
||||
case DeckListModelColumns::CARD_SET:
|
||||
case 2:
|
||||
return tr("Set");
|
||||
case DeckListModelColumns::CARD_COLLECTOR_NUMBER:
|
||||
case 3:
|
||||
return tr("Number");
|
||||
case DeckListModelColumns::CARD_PROVIDER_ID:
|
||||
case 4:
|
||||
return tr("Provider ID");
|
||||
default:
|
||||
return {};
|
||||
@@ -266,19 +264,19 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, con
|
||||
}
|
||||
|
||||
switch (index.column()) {
|
||||
case DeckListModelColumns::CARD_AMOUNT:
|
||||
case 0:
|
||||
node->setNumber(value.toInt());
|
||||
break;
|
||||
case DeckListModelColumns::CARD_NAME:
|
||||
case 1:
|
||||
node->setName(value.toString());
|
||||
break;
|
||||
case DeckListModelColumns::CARD_SET:
|
||||
case 2:
|
||||
node->setCardSetShortName(value.toString());
|
||||
break;
|
||||
case DeckListModelColumns::CARD_COLLECTOR_NUMBER:
|
||||
case 3:
|
||||
node->setCardCollectorNumber(value.toString());
|
||||
break;
|
||||
case DeckListModelColumns::CARD_PROVIDER_ID:
|
||||
case 4:
|
||||
node->setCardProviderId(value.toString());
|
||||
break;
|
||||
default:
|
||||
@@ -287,7 +285,6 @@ bool DeckListModel::setData(const QModelIndex &index, const QVariant &value, con
|
||||
|
||||
emitRecursiveUpdates(index);
|
||||
deckList->refreshDeckHash();
|
||||
emit deckHashChanged();
|
||||
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
@@ -426,7 +423,6 @@ QModelIndex DeckListModel::addCard(const ExactCard &card, const QString &zoneNam
|
||||
cardNode->setCardCollectorNumber(printingInfo.getProperty("num"));
|
||||
cardNode->setCardProviderId(printingInfo.getProperty("uuid"));
|
||||
deckList->refreshDeckHash();
|
||||
emit deckHashChanged();
|
||||
}
|
||||
sort(lastKnownColumn, lastKnownOrder);
|
||||
emitRecursiveUpdates(parentIndex);
|
||||
@@ -526,7 +522,7 @@ void DeckListModel::sort(int column, Qt::SortOrder order)
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria::Type newCriteria)
|
||||
void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria newCriteria)
|
||||
{
|
||||
activeGroupCriteria = newCriteria;
|
||||
rebuildTree();
|
||||
@@ -534,17 +530,19 @@ void DeckListModel::setActiveGroupCriteria(DeckListModelGroupCriteria::Type newC
|
||||
|
||||
void DeckListModel::cleanList()
|
||||
{
|
||||
setDeckList(new DeckList);
|
||||
setDeckList(new DeckLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _deck The deck.
|
||||
* @param _deck The deck. Takes ownership of the object
|
||||
*/
|
||||
void DeckListModel::setDeckList(DeckList *_deck)
|
||||
void DeckListModel::setDeckList(DeckLoader *_deck)
|
||||
{
|
||||
if (deckList != _deck) {
|
||||
deckList = _deck;
|
||||
}
|
||||
deckList->deleteLater();
|
||||
deckList = _deck;
|
||||
deckList->setParent(this);
|
||||
connect(deckList, &DeckLoader::deckLoaded, this, &DeckListModel::rebuildTree);
|
||||
connect(deckList, &DeckLoader::deckHashChanged, this, &DeckListModel::deckHashChanged);
|
||||
rebuildTree();
|
||||
}
|
||||
|
||||
@@ -632,4 +630,98 @@ QList<QString> *DeckListModel::getZones() const
|
||||
zones->append(currentZone->getName());
|
||||
}
|
||||
return zones;
|
||||
}
|
||||
}
|
||||
|
||||
void DeckListModel::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node)
|
||||
{
|
||||
const int totalColumns = 2;
|
||||
|
||||
if (node->height() == 1) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(11);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(0);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QTextTable *table = cursor->insertTable(node->size() + 1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
auto *card = dynamic_cast<AbstractDecklistCardNode *>(node->at(i));
|
||||
|
||||
QTextCharFormat cellCharFormat;
|
||||
cellCharFormat.setFontPointSize(9);
|
||||
|
||||
QTextTableCell cell = table->cellAt(i, 0);
|
||||
cell.setFormat(cellCharFormat);
|
||||
QTextCursor cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(QString("%1 ").arg(card->getNumber()));
|
||||
|
||||
cell = table->cellAt(i, 1);
|
||||
cell.setFormat(cellCharFormat);
|
||||
cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(card->getName());
|
||||
}
|
||||
} else if (node->height() == 2) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(14);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(10);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QVector<QTextLength> constraints;
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
constraints << QTextLength(QTextLength::PercentageLength, 100.0 / totalColumns);
|
||||
}
|
||||
tableFormat.setColumnWidthConstraints(constraints);
|
||||
|
||||
QTextTable *table = cursor->insertTable(1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
QTextCursor cellCursor = table->cellAt(0, (i * totalColumns) / node->size()).lastCursorPosition();
|
||||
printDeckListNode(&cellCursor, dynamic_cast<InnerDecklistNode *>(node->at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
cursor->movePosition(QTextCursor::End);
|
||||
}
|
||||
|
||||
void DeckListModel::printDeckList(QPrinter *printer)
|
||||
{
|
||||
QTextDocument doc;
|
||||
|
||||
QFont font("Serif");
|
||||
font.setStyleHint(QFont::Serif);
|
||||
doc.setDefaultFont(font);
|
||||
|
||||
QTextCursor cursor(&doc);
|
||||
|
||||
QTextBlockFormat headerBlockFormat;
|
||||
QTextCharFormat headerCharFormat;
|
||||
headerCharFormat.setFontPointSize(16);
|
||||
headerCharFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(deckList->getName());
|
||||
|
||||
headerCharFormat.setFontPointSize(12);
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(deckList->getComments());
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
for (int i = 0; i < root->size(); i++) {
|
||||
cursor.insertHtml("<br><img src=theme:hr.jpg>");
|
||||
// cursor.insertHtml("<hr>");
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
printDeckListNode(&cursor, dynamic_cast<InnerDecklistNode *>(root->at(i)));
|
||||
}
|
||||
|
||||
doc.print(printer);
|
||||
}
|
||||
@@ -1,103 +1,28 @@
|
||||
#ifndef DECKLISTMODEL_H
|
||||
#define DECKLISTMODEL_H
|
||||
|
||||
#include <../../../../libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.h>
|
||||
#include <../../../../libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.h>
|
||||
#include "../card/exact_card.h"
|
||||
#include "abstract_deck_list_card_node.h"
|
||||
#include "deck_list.h"
|
||||
#include "deck_list_card_node.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QList>
|
||||
#include <libcockatrice/card/printing/exact_card.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
|
||||
class DeckLoader;
|
||||
class CardDatabase;
|
||||
class QPrinter;
|
||||
class QTextCursor;
|
||||
|
||||
/**
|
||||
* @namespace DeckRoles
|
||||
* @brief Custom model roles used by the DeckListModel for data retrieval.
|
||||
*
|
||||
* These roles extend Qt's item data roles starting at Qt::UserRole.
|
||||
* @brief Specifies the criteria used to group cards in the DeckListModel.
|
||||
*/
|
||||
namespace DeckRoles
|
||||
{
|
||||
/**
|
||||
* @enum DeckRoles
|
||||
* @brief Custom data roles for deck-related model items.
|
||||
*
|
||||
* These roles are used to retrieve specialized data from the DeckListModel.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
IsCardRole = Qt::UserRole + 1, /**< Indicates whether the item represents a card. */
|
||||
DepthRole, /**< Depth level within the deck's grouping hierarchy. */
|
||||
IsLegalRole /**< Whether the card is legal in the current deck format. */
|
||||
};
|
||||
} // namespace DeckRoles
|
||||
|
||||
/**
|
||||
* @namespace DeckListModelColumns
|
||||
* @brief Column indices for the DeckListModel.
|
||||
*
|
||||
* These values map to the columns in the deck list table representation.
|
||||
*/
|
||||
namespace DeckListModelColumns
|
||||
{
|
||||
/**
|
||||
* @enum DeckListModelColumns
|
||||
* @brief Column identifiers for displaying card information in the deck list.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
CARD_AMOUNT = 0, /**< The number of copies of the card. */
|
||||
CARD_NAME = 1, /**< The card's name. */
|
||||
CARD_SET = 2, /**< The set or expansion the card belongs to. */
|
||||
CARD_COLLECTOR_NUMBER = 3, /**< Collector number of the card within the set. */
|
||||
CARD_PROVIDER_ID = 4 /**< ID used by the external data provider (e.g., Scryfall). */
|
||||
};
|
||||
} // namespace DeckListModelColumns
|
||||
|
||||
/**
|
||||
* @namespace DeckListModelGroupCriteria
|
||||
* @brief Specifies criteria used to group cards in the DeckListModel.
|
||||
*
|
||||
* These values determine how cards are grouped in UI views such as the deck editor.
|
||||
*/
|
||||
namespace DeckListModelGroupCriteria
|
||||
{
|
||||
/**
|
||||
* @enum DeckListModelGroupCriteria
|
||||
* @brief Available grouping strategies for deck visualization.
|
||||
*/
|
||||
enum Type
|
||||
enum DeckListModelGroupCriteria
|
||||
{
|
||||
MAIN_TYPE, /**< Group cards by their main type (e.g., creature, instant). */
|
||||
MANA_COST, /**< Group cards by their total mana cost. */
|
||||
MANA_COST, /**< Group cards by their mana cost. */
|
||||
COLOR /**< Group cards by their color identity. */
|
||||
};
|
||||
static inline QString toString(Type t)
|
||||
{
|
||||
switch (t) {
|
||||
case MAIN_TYPE:
|
||||
return "Main Type";
|
||||
case MANA_COST:
|
||||
return "Mana Cost";
|
||||
case COLOR:
|
||||
return "Colors";
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static inline Type fromString(const QString &s)
|
||||
{
|
||||
if (s == "Main Type")
|
||||
return MAIN_TYPE;
|
||||
if (s == "Mana Cost")
|
||||
return MANA_COST;
|
||||
if (s == "Colors")
|
||||
return COLOR;
|
||||
return MAIN_TYPE; // default
|
||||
}
|
||||
} // namespace DeckListModelGroupCriteria
|
||||
|
||||
/**
|
||||
* @class DecklistModelCardNode
|
||||
@@ -124,7 +49,7 @@ public:
|
||||
: AbstractDecklistCardNode(_parent, position), dataNode(_dataNode)
|
||||
{
|
||||
}
|
||||
[[nodiscard]] int getNumber() const override
|
||||
int getNumber() const override
|
||||
{
|
||||
return dataNode->getNumber();
|
||||
}
|
||||
@@ -132,7 +57,7 @@ public:
|
||||
{
|
||||
dataNode->setNumber(_number);
|
||||
}
|
||||
[[nodiscard]] QString getName() const override
|
||||
QString getName() const override
|
||||
{
|
||||
return dataNode->getName();
|
||||
}
|
||||
@@ -140,7 +65,7 @@ public:
|
||||
{
|
||||
dataNode->setName(_name);
|
||||
}
|
||||
[[nodiscard]] QString getCardProviderId() const override
|
||||
QString getCardProviderId() const override
|
||||
{
|
||||
return dataNode->getCardProviderId();
|
||||
}
|
||||
@@ -148,7 +73,7 @@ public:
|
||||
{
|
||||
dataNode->setCardProviderId(_cardProviderId);
|
||||
}
|
||||
[[nodiscard]] QString getCardSetShortName() const override
|
||||
QString getCardSetShortName() const override
|
||||
{
|
||||
return dataNode->getCardSetShortName();
|
||||
}
|
||||
@@ -156,7 +81,7 @@ public:
|
||||
{
|
||||
dataNode->setCardSetShortName(_cardSetShortName);
|
||||
}
|
||||
[[nodiscard]] QString getCardCollectorNumber() const override
|
||||
QString getCardCollectorNumber() const override
|
||||
{
|
||||
return dataNode->getCardCollectorNumber();
|
||||
}
|
||||
@@ -169,7 +94,7 @@ public:
|
||||
* @brief Returns the underlying data node.
|
||||
* @return Pointer to the DecklistCardNode wrapped by this node.
|
||||
*/
|
||||
[[nodiscard]] DecklistCardNode *getDataNode() const
|
||||
DecklistCardNode *getDataNode() const
|
||||
{
|
||||
return dataNode;
|
||||
}
|
||||
@@ -195,12 +120,12 @@ public:
|
||||
*
|
||||
* Slots:
|
||||
* - rebuildTree(): rebuilds the model structure from the underlying DeckLoader.
|
||||
* - printDeckList(): renders the decklist to a QPrinter.
|
||||
*/
|
||||
class DeckListModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
private slots:
|
||||
/**
|
||||
* @brief Rebuilds the model tree from the underlying DeckLoader.
|
||||
*
|
||||
@@ -209,6 +134,13 @@ public slots:
|
||||
*/
|
||||
void rebuildTree();
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Prints the decklist to the provided QPrinter.
|
||||
* @param printer The printer to render the decklist to.
|
||||
*/
|
||||
void printDeckList(QPrinter *printer);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Emitted whenever the deck hash changes due to modifications in the model.
|
||||
@@ -223,27 +155,26 @@ public:
|
||||
* @brief Returns the root index of the model.
|
||||
* @return QModelIndex representing the root node.
|
||||
*/
|
||||
[[nodiscard]] QModelIndex getRoot() const
|
||||
QModelIndex getRoot() const
|
||||
{
|
||||
return nodeToIndex(root);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns the value of the grouping category for a card based on the current criteria.
|
||||
* @param info Pointer to card information.
|
||||
* @return String representing the value of the current grouping criteria for the card.
|
||||
*/
|
||||
[[nodiscard]] QString getGroupCriteriaForCard(CardInfoPtr info) const;
|
||||
QString getGroupCriteriaForCard(CardInfoPtr info) const;
|
||||
|
||||
// Qt model overrides
|
||||
[[nodiscard]] int rowCount(const QModelIndex &parent) const override;
|
||||
[[nodiscard]] int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override;
|
||||
[[nodiscard]] QVariant data(const QModelIndex &index, int role) const override;
|
||||
void emitBackgroundUpdates(const QModelIndex &parent);
|
||||
[[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
[[nodiscard]] QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
[[nodiscard]] QModelIndex parent(const QModelIndex &index) const override;
|
||||
[[nodiscard]] Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent) override;
|
||||
|
||||
@@ -255,10 +186,10 @@ public:
|
||||
* @param cardNumber Optional collector number.
|
||||
* @return QModelIndex of the card, or invalid index if not found.
|
||||
*/
|
||||
[[nodiscard]] QModelIndex findCard(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId = "",
|
||||
const QString &cardNumber = "") const;
|
||||
QModelIndex findCard(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId = "",
|
||||
const QString &cardNumber = "") const;
|
||||
|
||||
/**
|
||||
* @brief Adds a card using the preferred printing if available.
|
||||
@@ -292,38 +223,40 @@ public:
|
||||
* @brief Removes all cards and resets the model.
|
||||
*/
|
||||
void cleanList();
|
||||
[[nodiscard]] DeckList *getDeckList() const
|
||||
DeckLoader *getDeckList() const
|
||||
{
|
||||
return deckList;
|
||||
}
|
||||
void setDeckList(DeckList *_deck);
|
||||
void setDeckList(DeckLoader *_deck);
|
||||
|
||||
[[nodiscard]] QList<ExactCard> getCards() const;
|
||||
[[nodiscard]] QList<ExactCard> getCardsForZone(const QString &zoneName) const;
|
||||
[[nodiscard]] QList<QString> *getZones() const;
|
||||
QList<ExactCard> getCards() const;
|
||||
QList<ExactCard> getCardsForZone(const QString &zoneName) const;
|
||||
QList<QString> *getZones() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the criteria used to group cards in the model.
|
||||
* @param newCriteria The new grouping criteria.
|
||||
*/
|
||||
void setActiveGroupCriteria(DeckListModelGroupCriteria::Type newCriteria);
|
||||
void setActiveGroupCriteria(DeckListModelGroupCriteria newCriteria);
|
||||
|
||||
private:
|
||||
DeckList *deckList; /**< Pointer to the deck loader providing the underlying data. */
|
||||
DeckLoader *deckList; /**< Pointer to the deck loader providing the underlying data. */
|
||||
InnerDecklistNode *root; /**< Root node of the model tree. */
|
||||
DeckListModelGroupCriteria::Type activeGroupCriteria = DeckListModelGroupCriteria::MAIN_TYPE;
|
||||
DeckListModelGroupCriteria activeGroupCriteria = DeckListModelGroupCriteria::MAIN_TYPE;
|
||||
int lastKnownColumn; /**< Last column used for sorting. */
|
||||
Qt::SortOrder lastKnownOrder; /**< Last known sort order. */
|
||||
|
||||
InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent);
|
||||
QModelIndex nodeToIndex(AbstractDecklistNode *node) const;
|
||||
[[nodiscard]] DecklistModelCardNode *findCardNode(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId = "",
|
||||
const QString &cardNumber = "") const;
|
||||
DecklistModelCardNode *findCardNode(const QString &cardName,
|
||||
const QString &zoneName,
|
||||
const QString &providerId = "",
|
||||
const QString &cardNumber = "") const;
|
||||
void emitRecursiveUpdates(const QModelIndex &index);
|
||||
void sortHelper(InnerDecklistNode *node, Qt::SortOrder order);
|
||||
|
||||
void printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node);
|
||||
|
||||
template <typename T> T getNode(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
@@ -1,5 +1,11 @@
|
||||
#include "deck_loader.h"
|
||||
|
||||
#include "../database/card_database.h"
|
||||
#include "../database/card_database_manager.h"
|
||||
#include "../main.h"
|
||||
#include "deck_list.h"
|
||||
#include "deck_list_card_node.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
@@ -7,29 +13,32 @@
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFutureWatcher>
|
||||
#include <QPrinter>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocument>
|
||||
#include <QTextStream>
|
||||
#include <QTextTable>
|
||||
#include <QtConcurrentRun>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/tree/deck_list_card_node.h>
|
||||
|
||||
const QStringList DeckLoader::ACCEPTED_FILE_EXTENSIONS = {"*.cod", "*.dec", "*.dek", "*.txt", "*.mwDeck"};
|
||||
|
||||
const QStringList DeckLoader::FILE_NAME_FILTERS = {
|
||||
tr("Common deck formats (%1)").arg(ACCEPTED_FILE_EXTENSIONS.join(" ")), tr("All files (*.*)")};
|
||||
|
||||
DeckLoader::DeckLoader(QObject *parent) : QObject(parent), deckList(new DeckList())
|
||||
DeckLoader::DeckLoader() : DeckList(), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(QObject *parent, DeckList *_deckList) : QObject(parent), deckList(_deckList)
|
||||
DeckLoader::DeckLoader(const QString &nativeString)
|
||||
: DeckList(nativeString), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const DeckList &other)
|
||||
: DeckList(other), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const DeckLoader &other)
|
||||
: DeckList(other), lastFileName(other.lastFileName), lastFileFormat(other.lastFileFormat),
|
||||
lastRemoteDeckId(other.lastRemoteDeckId)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -43,15 +52,15 @@ bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool user
|
||||
bool result = false;
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = deckList->loadFromFile_Plain(&file);
|
||||
result = loadFromFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat: {
|
||||
result = deckList->loadFromFile_Native(&file);
|
||||
result = loadFromFile_Native(&file);
|
||||
qCInfo(DeckLoaderLog) << "Loaded from" << fileName << "-" << result;
|
||||
if (!result) {
|
||||
qCInfo(DeckLoaderLog) << "Retrying as plain format";
|
||||
file.seek(0);
|
||||
result = deckList->loadFromFile_Plain(&file);
|
||||
result = loadFromFile_Plain(&file);
|
||||
fmt = PlainTextFormat;
|
||||
}
|
||||
break;
|
||||
@@ -62,10 +71,8 @@ bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool user
|
||||
}
|
||||
|
||||
if (result) {
|
||||
lastLoadInfo = {
|
||||
.fileName = fileName,
|
||||
.fileFormat = fmt,
|
||||
};
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
if (userRequest) {
|
||||
updateLastLoadedTimestamp(fileName, fmt);
|
||||
}
|
||||
@@ -86,10 +93,8 @@ bool DeckLoader::loadFromFileAsync(const QString &fileName, FileFormat fmt, bool
|
||||
watcher->deleteLater();
|
||||
|
||||
if (result) {
|
||||
lastLoadInfo = {
|
||||
.fileName = fileName,
|
||||
.fileFormat = fmt,
|
||||
};
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
if (userRequest) {
|
||||
updateLastLoadedTimestamp(fileName, fmt);
|
||||
}
|
||||
@@ -107,13 +112,13 @@ bool DeckLoader::loadFromFileAsync(const QString &fileName, FileFormat fmt, bool
|
||||
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
return deckList->loadFromFile_Plain(&file);
|
||||
return loadFromFile_Plain(&file);
|
||||
case CockatriceFormat: {
|
||||
bool result = false;
|
||||
result = deckList->loadFromFile_Native(&file);
|
||||
result = loadFromFile_Native(&file);
|
||||
if (!result) {
|
||||
file.seek(0);
|
||||
return deckList->loadFromFile_Plain(&file);
|
||||
return loadFromFile_Plain(&file);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -129,11 +134,11 @@ bool DeckLoader::loadFromFileAsync(const QString &fileName, FileFormat fmt, bool
|
||||
|
||||
bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId)
|
||||
{
|
||||
bool result = deckList->loadFromString_Native(nativeString);
|
||||
bool result = loadFromString_Native(nativeString);
|
||||
if (result) {
|
||||
lastLoadInfo = {
|
||||
.remoteDeckId = remoteDeckId,
|
||||
};
|
||||
lastFileName = QString();
|
||||
lastFileFormat = CockatriceFormat;
|
||||
lastRemoteDeckId = remoteDeckId;
|
||||
|
||||
emit deckLoaded();
|
||||
}
|
||||
@@ -150,20 +155,16 @@ bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
|
||||
bool result = false;
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = deckList->saveToFile_Plain(&file);
|
||||
result = saveToFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
result = deckList->saveToFile_Native(&file);
|
||||
qCInfo(DeckLoaderLog) << "Saving to " << fileName << "-" << result;
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
lastLoadInfo = {
|
||||
.fileName = fileName,
|
||||
.fileFormat = fmt,
|
||||
};
|
||||
qCInfo(DeckLoaderLog) << "Deck was saved -" << result;
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
}
|
||||
|
||||
file.flush();
|
||||
@@ -194,21 +195,19 @@ bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, FileFormat f
|
||||
// Perform file modifications
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = deckList->saveToFile_Plain(&file);
|
||||
result = saveToFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
deckList->setLastLoadedTimestamp(QDateTime::currentDateTime().toString());
|
||||
result = deckList->saveToFile_Native(&file);
|
||||
setLastLoadedTimestamp(QDateTime::currentDateTime().toString());
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
}
|
||||
|
||||
file.close(); // Close the file to ensure changes are flushed
|
||||
|
||||
if (result) {
|
||||
lastLoadInfo = {
|
||||
.fileName = fileName,
|
||||
.fileFormat = fmt,
|
||||
};
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
|
||||
// Re-open the file and set the original timestamp
|
||||
if (!file.open(QIODevice::ReadWrite)) {
|
||||
@@ -271,11 +270,9 @@ static QString toDecklistExportString(const DecklistCardNode *card)
|
||||
|
||||
/**
|
||||
* Export deck to decklist function, called to format the deck in a way to be sent to a server
|
||||
*
|
||||
* @param deckList The decklist to export
|
||||
* @param website The website we're sending the deck to
|
||||
*/
|
||||
QString DeckLoader::exportDeckToDecklist(const DeckList *deckList, DecklistWebsite website)
|
||||
QString DeckLoader::exportDeckToDecklist(DecklistWebsite website)
|
||||
{
|
||||
// Add the base url
|
||||
QString deckString = "https://" + getDomainForWebsite(website) + "/?";
|
||||
@@ -301,7 +298,7 @@ QString DeckLoader::exportDeckToDecklist(const DeckList *deckList, DecklistWebsi
|
||||
};
|
||||
|
||||
// call our struct function for each card in the deck
|
||||
deckList->forEachCard(formatDeckListForExport);
|
||||
forEachCard(formatDeckListForExport);
|
||||
// Remove the extra return at the end of the last cards
|
||||
mainBoardCards.chop(3);
|
||||
sideBoardCards.chop(3);
|
||||
@@ -342,24 +339,20 @@ struct SetProviderIdToPreferred
|
||||
/**
|
||||
* This function iterates through each card in the decklist and sets the providerId
|
||||
* on each card based on its set name and collector number.
|
||||
*
|
||||
* @param deckList The decklist to modify
|
||||
*/
|
||||
void DeckLoader::setProviderIdToPreferredPrinting(const DeckList *deckList)
|
||||
void DeckLoader::setProviderIdToPreferredPrinting()
|
||||
{
|
||||
// Set up the struct to call.
|
||||
SetProviderIdToPreferred setProviderIdToPreferred;
|
||||
|
||||
// Call the forEachCard method for each card in the deck
|
||||
deckList->forEachCard(setProviderIdToPreferred);
|
||||
forEachCard(setProviderIdToPreferred);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the providerId on each card in the decklist based on its set name and collector number.
|
||||
*
|
||||
* @param deckList The decklist to modify
|
||||
*/
|
||||
void DeckLoader::resolveSetNameAndNumberToProviderID(const DeckList *deckList)
|
||||
void DeckLoader::resolveSetNameAndNumberToProviderID()
|
||||
{
|
||||
auto setProviderId = [](const auto node, const auto card) {
|
||||
Q_UNUSED(node);
|
||||
@@ -374,7 +367,7 @@ void DeckLoader::resolveSetNameAndNumberToProviderID(const DeckList *deckList)
|
||||
card->setCardProviderId(providerId);
|
||||
};
|
||||
|
||||
deckList->forEachCard(setProviderId);
|
||||
forEachCard(setProviderId);
|
||||
}
|
||||
|
||||
// This struct is here to support the forEachCard function call, defined in decklist.
|
||||
@@ -398,10 +391,8 @@ struct ClearSetNameNumberAndProviderId
|
||||
|
||||
/**
|
||||
* Clears the set name and numbers on each card in the decklist.
|
||||
*
|
||||
* @param deckList The decklist to modify
|
||||
*/
|
||||
void DeckLoader::clearSetNamesAndNumbers(const DeckList *deckList)
|
||||
void DeckLoader::clearSetNamesAndNumbers()
|
||||
{
|
||||
auto clearSetNameAndNumber = [](const auto node, auto card) {
|
||||
Q_UNUSED(node)
|
||||
@@ -411,7 +402,7 @@ void DeckLoader::clearSetNamesAndNumbers(const DeckList *deckList)
|
||||
card->setCardProviderId(nullptr);
|
||||
};
|
||||
|
||||
deckList->forEachCard(clearSetNameAndNumber);
|
||||
forEachCard(clearSetNameAndNumber);
|
||||
}
|
||||
|
||||
DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName)
|
||||
@@ -422,27 +413,24 @@ DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName)
|
||||
return PlainTextFormat;
|
||||
}
|
||||
|
||||
void DeckLoader::saveToClipboard(const DeckList *deckList, bool addComments, bool addSetNameAndNumber)
|
||||
void DeckLoader::saveToClipboard(bool addComments, bool addSetNameAndNumber) const
|
||||
{
|
||||
QString buffer;
|
||||
QTextStream stream(&buffer);
|
||||
saveToStream_Plain(stream, deckList, addComments, addSetNameAndNumber);
|
||||
saveToStream_Plain(stream, addComments, addSetNameAndNumber);
|
||||
QApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||
QApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||
}
|
||||
|
||||
bool DeckLoader::saveToStream_Plain(QTextStream &out,
|
||||
const DeckList *deckList,
|
||||
bool addComments,
|
||||
bool addSetNameAndNumber)
|
||||
bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments, bool addSetNameAndNumber) const
|
||||
{
|
||||
if (addComments) {
|
||||
saveToStream_DeckHeader(out, deckList);
|
||||
saveToStream_DeckHeader(out);
|
||||
}
|
||||
|
||||
// loop zones
|
||||
for (int i = 0; i < deckList->getRoot()->size(); i++) {
|
||||
const auto *zoneNode = dynamic_cast<InnerDecklistNode *>(deckList->getRoot()->at(i));
|
||||
for (int i = 0; i < getRoot()->size(); i++) {
|
||||
const auto *zoneNode = dynamic_cast<InnerDecklistNode *>(getRoot()->at(i));
|
||||
|
||||
saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber);
|
||||
|
||||
@@ -453,14 +441,14 @@ bool DeckLoader::saveToStream_Plain(QTextStream &out,
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeckLoader::saveToStream_DeckHeader(QTextStream &out, const DeckList *deckList)
|
||||
void DeckLoader::saveToStream_DeckHeader(QTextStream &out) const
|
||||
{
|
||||
if (!deckList->getName().isEmpty()) {
|
||||
out << "// " << deckList->getName() << "\n\n";
|
||||
if (!getName().isEmpty()) {
|
||||
out << "// " << getName() << "\n\n";
|
||||
}
|
||||
|
||||
if (!deckList->getComments().isEmpty()) {
|
||||
QStringList commentRows = deckList->getComments().split(QRegularExpression("\n|\r\n|\r"));
|
||||
if (!getComments().isEmpty()) {
|
||||
QStringList commentRows = getComments().split(QRegularExpression("\n|\r\n|\r"));
|
||||
for (const QString &row : commentRows) {
|
||||
out << "// " << row << "\n";
|
||||
}
|
||||
@@ -471,7 +459,7 @@ void DeckLoader::saveToStream_DeckHeader(QTextStream &out, const DeckList *deckL
|
||||
void DeckLoader::saveToStream_DeckZone(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
bool addComments,
|
||||
bool addSetNameAndNumber)
|
||||
bool addSetNameAndNumber) const
|
||||
{
|
||||
// group cards by card type and count the subtotals
|
||||
QMultiMap<QString, DecklistCardNode *> cardsByType;
|
||||
@@ -519,7 +507,7 @@ void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments,
|
||||
bool addSetNameAndNumber)
|
||||
bool addSetNameAndNumber) const
|
||||
{
|
||||
// QMultiMap sorts values in reverse order
|
||||
for (int i = cards.size() - 1; i >= 0; --i) {
|
||||
@@ -567,7 +555,7 @@ bool DeckLoader::convertToCockatriceFormat(QString fileName)
|
||||
switch (getFormatFromName(fileName)) {
|
||||
case PlainTextFormat:
|
||||
// Save in Cockatrice's native format
|
||||
result = deckList->saveToFile_Native(&file);
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed.";
|
||||
@@ -588,16 +576,14 @@ bool DeckLoader::convertToCockatriceFormat(QString fileName)
|
||||
} else {
|
||||
qCInfo(DeckLoaderLog) << "Original file deleted successfully:" << fileName;
|
||||
}
|
||||
lastLoadInfo = {
|
||||
.fileName = newFileName,
|
||||
.fileFormat = CockatriceFormat,
|
||||
};
|
||||
lastFileName = newFileName;
|
||||
lastFileFormat = CockatriceFormat;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCardZoneFromName(const QString &cardName, QString currentZoneName)
|
||||
QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneName)
|
||||
{
|
||||
CardInfoPtr card = CardDatabaseManager::query()->getCardInfo(cardName);
|
||||
|
||||
@@ -608,7 +594,7 @@ QString DeckLoader::getCardZoneFromName(const QString &cardName, QString current
|
||||
return currentZoneName;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCompleteCardName(const QString &cardName)
|
||||
QString DeckLoader::getCompleteCardName(const QString &cardName) const
|
||||
{
|
||||
if (CardDatabaseManager::getInstance()) {
|
||||
ExactCard temp = CardDatabaseManager::query()->guessCard({cardName});
|
||||
@@ -619,97 +605,3 @@ QString DeckLoader::getCompleteCardName(const QString &cardName)
|
||||
|
||||
return cardName;
|
||||
}
|
||||
|
||||
void DeckLoader::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node)
|
||||
{
|
||||
const int totalColumns = 2;
|
||||
|
||||
if (node->height() == 1) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(11);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(0);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QTextTable *table = cursor->insertTable(node->size() + 1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
auto *card = dynamic_cast<AbstractDecklistCardNode *>(node->at(i));
|
||||
|
||||
QTextCharFormat cellCharFormat;
|
||||
cellCharFormat.setFontPointSize(9);
|
||||
|
||||
QTextTableCell cell = table->cellAt(i, 0);
|
||||
cell.setFormat(cellCharFormat);
|
||||
QTextCursor cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(QString("%1 ").arg(card->getNumber()));
|
||||
|
||||
cell = table->cellAt(i, 1);
|
||||
cell.setFormat(cellCharFormat);
|
||||
cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(card->getName());
|
||||
}
|
||||
} else if (node->height() == 2) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(14);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(10);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QVector<QTextLength> constraints;
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
constraints << QTextLength(QTextLength::PercentageLength, 100.0 / totalColumns);
|
||||
}
|
||||
tableFormat.setColumnWidthConstraints(constraints);
|
||||
|
||||
QTextTable *table = cursor->insertTable(1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
QTextCursor cellCursor = table->cellAt(0, (i * totalColumns) / node->size()).lastCursorPosition();
|
||||
printDeckListNode(&cellCursor, dynamic_cast<InnerDecklistNode *>(node->at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
cursor->movePosition(QTextCursor::End);
|
||||
}
|
||||
|
||||
void DeckLoader::printDeckList(QPrinter *printer, const DeckList *deckList)
|
||||
{
|
||||
QTextDocument doc;
|
||||
|
||||
QFont font("Serif");
|
||||
font.setStyleHint(QFont::Serif);
|
||||
doc.setDefaultFont(font);
|
||||
|
||||
QTextCursor cursor(&doc);
|
||||
|
||||
QTextBlockFormat headerBlockFormat;
|
||||
QTextCharFormat headerCharFormat;
|
||||
headerCharFormat.setFontPointSize(16);
|
||||
headerCharFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(deckList->getName());
|
||||
|
||||
headerCharFormat.setFontPointSize(12);
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(deckList->getComments());
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
for (int i = 0; i < deckList->getRoot()->size(); i++) {
|
||||
cursor.insertHtml("<br><img src=theme:hr.jpg>");
|
||||
// cursor.insertHtml("<hr>");
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
printDeckListNode(&cursor, dynamic_cast<InnerDecklistNode *>(deckList->getRoot()->at(i)));
|
||||
}
|
||||
|
||||
doc.print(printer);
|
||||
}
|
||||
112
cockatrice/src/deck/deck_loader.h
Normal file
112
cockatrice/src/deck/deck_loader.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* @file deck_loader.h
|
||||
* @ingroup ImportExport
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DECK_LOADER_H
|
||||
#define DECK_LOADER_H
|
||||
|
||||
#include "deck_list.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DeckLoaderLog, "deck_loader")
|
||||
|
||||
class DeckLoader : public DeckList
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void deckLoaded();
|
||||
void loadFinished(bool success);
|
||||
|
||||
public:
|
||||
enum FileFormat
|
||||
{
|
||||
PlainTextFormat,
|
||||
CockatriceFormat
|
||||
};
|
||||
|
||||
/**
|
||||
* Supported file extensions for decklist files
|
||||
*/
|
||||
static const QStringList ACCEPTED_FILE_EXTENSIONS;
|
||||
|
||||
/**
|
||||
* For use with `QFileDialog::setNameFilters`
|
||||
*/
|
||||
static const QStringList FILE_NAME_FILTERS;
|
||||
|
||||
enum DecklistWebsite
|
||||
{
|
||||
DecklistOrg,
|
||||
DecklistXyz
|
||||
};
|
||||
|
||||
private:
|
||||
QString lastFileName;
|
||||
FileFormat lastFileFormat;
|
||||
int lastRemoteDeckId;
|
||||
|
||||
public:
|
||||
DeckLoader();
|
||||
explicit DeckLoader(const QString &nativeString);
|
||||
explicit DeckLoader(const DeckList &other);
|
||||
DeckLoader(const DeckLoader &other);
|
||||
const QString &getLastFileName() const
|
||||
{
|
||||
return lastFileName;
|
||||
}
|
||||
void setLastFileName(const QString &_lastFileName)
|
||||
{
|
||||
lastFileName = _lastFileName;
|
||||
}
|
||||
FileFormat getLastFileFormat() const
|
||||
{
|
||||
return lastFileFormat;
|
||||
}
|
||||
int getLastRemoteDeckId() const
|
||||
{
|
||||
return lastRemoteDeckId;
|
||||
}
|
||||
|
||||
bool hasNotBeenLoaded() const
|
||||
{
|
||||
return getLastFileName().isEmpty() && getLastRemoteDeckId() == -1;
|
||||
}
|
||||
|
||||
void clearSetNamesAndNumbers();
|
||||
static FileFormat getFormatFromName(const QString &fileName);
|
||||
|
||||
bool loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest = false);
|
||||
bool loadFromFileAsync(const QString &fileName, FileFormat fmt, bool userRequest);
|
||||
bool loadFromRemote(const QString &nativeString, int remoteDeckId);
|
||||
bool saveToFile(const QString &fileName, FileFormat fmt);
|
||||
bool updateLastLoadedTimestamp(const QString &fileName, FileFormat fmt);
|
||||
QString exportDeckToDecklist(DecklistWebsite website);
|
||||
void setProviderIdToPreferredPrinting();
|
||||
|
||||
void resolveSetNameAndNumberToProviderID();
|
||||
|
||||
void saveToClipboard(bool addComments = true, bool addSetNameAndNumber = true) const;
|
||||
|
||||
// overload
|
||||
bool saveToStream_Plain(QTextStream &out, bool addComments = true, bool addSetNameAndNumber = true) const;
|
||||
bool convertToCockatriceFormat(QString fileName);
|
||||
|
||||
protected:
|
||||
void saveToStream_DeckHeader(QTextStream &out) const;
|
||||
void saveToStream_DeckZone(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
bool addComments = true,
|
||||
bool addSetNameAndNumber = true) const;
|
||||
void saveToStream_DeckZoneCards(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments = true,
|
||||
bool addSetNameAndNumber = true) const;
|
||||
[[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override;
|
||||
[[nodiscard]] QString getCompleteCardName(const QString &cardName) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,15 @@
|
||||
#include "deck_stats_interface.h"
|
||||
|
||||
#include "deck_list.h"
|
||||
#include "deck_list_card_node.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QRegularExpression>
|
||||
#include <QUrlQuery>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/tree/deck_list_card_node.h>
|
||||
|
||||
DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent)
|
||||
: QObject(parent), cardDatabase(_cardDatabase)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user