diff --git a/.ci/Debian12/Dockerfile b/.ci/Debian12/Dockerfile index fc756aac2..14c6f018c 100644 --- a/.ci/Debian12/Dockerfile +++ b/.ci/Debian12/Dockerfile @@ -4,7 +4,6 @@ RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ build-essential \ ccache \ - clang-format \ cmake \ file \ g++ \ diff --git a/.ci/Debian13/Dockerfile b/.ci/Debian13/Dockerfile index bdecb56df..b597307c5 100644 --- a/.ci/Debian13/Dockerfile +++ b/.ci/Debian13/Dockerfile @@ -5,7 +5,6 @@ RUN apt-get update && \ build-essential \ ca-certificates \ ccache \ - clang-format \ cmake \ file \ g++ \ diff --git a/.ci/Servatrice_Debian12/Dockerfile b/.ci/Servatrice_Debian12/Dockerfile index 321aa7c0f..f1a16843a 100644 --- a/.ci/Servatrice_Debian12/Dockerfile +++ b/.ci/Servatrice_Debian12/Dockerfile @@ -4,7 +4,6 @@ RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ build-essential \ ccache \ - clang-format \ cmake \ file \ g++ \ diff --git a/.ci/Ubuntu24.04/Dockerfile b/.ci/Ubuntu24.04/Dockerfile index 715997474..b9fb2b701 100644 --- a/.ci/Ubuntu24.04/Dockerfile +++ b/.ci/Ubuntu24.04/Dockerfile @@ -4,7 +4,6 @@ RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ build-essential \ ccache \ - clang-format \ cmake \ file \ g++ \ diff --git a/.ci/Ubuntu26.04/Dockerfile b/.ci/Ubuntu26.04/Dockerfile index 96dd10763..cc6528858 100644 --- a/.ci/Ubuntu26.04/Dockerfile +++ b/.ci/Ubuntu26.04/Dockerfile @@ -5,10 +5,10 @@ RUN apt-get update && \ build-essential \ ca-certificates \ ccache \ - clang-format \ cmake \ file \ g++ \ + gcovr \ git \ libgl-dev \ liblzma-dev \ diff --git a/.ci/compile.sh b/.ci/compile.sh index 72a017f33..a9386400f 100755 --- a/.ci/compile.sh +++ b/.ci/compile.sh @@ -8,14 +8,19 @@ # --suffix renames package with this suffix, requires arg # --server compiles servatrice # --test runs tests +# --sanitize builds with AddressSanitizer and UndefinedBehaviorSanitizer, gcc/clang only +# --coverage instruments the test run for line coverage and prints a gcovr summary, gcc only + # --debug or --release sets the build type ie CMAKE_BUILD_TYPE # --ccache [] uses ccache and shows stats, optionally provide size # --evict-ccache runs ccache eviction based on given age after build +# --sccache uses sccache instead, needs a generator that runs the compiler itself # --dir sets the name of the build dir, default is "build" # --cmake-generator sets CMAKE_GENERATOR as used by cmake # --target-macos-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 CCACHE_EVICTION_AGE BUILD_DIR CMAKE_GENERATOR TARGET_MACOS_VERSION -# (correspond to args: --debug/--release --install --package --suffix --server --test --ccache --dir ) +# --profile writes an MSBuild performance summary and binary log, Windows only +# uses env: BUILDTYPE MAKE_INSTALL MAKE_PACKAGE PACKAGE_TYPE PACKAGE_SUFFIX MAKE_SERVER MAKE_NO_CLIENT MAKE_TEST USE_CCACHE CCACHE_SIZE CCACHE_EVICTION_AGE BUILD_DIR CMAKE_GENERATOR TARGET_MACOS_VERSION MAKE_SANITIZE MAKE_COVERAGE VCPKG_TARGET_MACOS_VERSION BUILD_PARALLEL_LEVEL BUILD_PROFILE USE_SCCACHE +# (correspond to args: --debug/--release --install --package --suffix --server --test --sanitize --coverage --ccache --dir --profile --sccache) # exitcode: 1 for failure, 3 for invalid arguments # Read arguments @@ -57,6 +62,14 @@ while [[ $# != 0 ]]; do MAKE_TEST=1 shift ;; + '--sanitize') + MAKE_SANITIZE=1 + shift + ;; + '--coverage') + MAKE_COVERAGE=1 + shift + ;; '--debug') BUILDTYPE="Debug" shift @@ -82,6 +95,10 @@ while [[ $# != 0 ]]; do CCACHE_EVICTION_AGE=$1 shift ;; + '--sccache') + USE_SCCACHE=1 + shift + ;; '--vcpkg') USE_VCPKG=1 shift @@ -104,6 +121,10 @@ while [[ $# != 0 ]]; do export CMAKE_GENERATOR=$1 shift ;; + '--profile') + BUILD_PROFILE=1 + shift + ;; '--target-macos-version') shift if [[ $# == 0 ]]; then @@ -122,6 +143,12 @@ done set -e +# cmake reads the generator platform from the environment, so a leftover platform +# follows the generator around; Ninja has no platform to select. +if [[ $CMAKE_GENERATOR != "Visual Studio"* ]]; then + unset CMAKE_GENERATOR_PLATFORM +fi + # Setup ./servatrice/check_schema_version.sh if [[ ! $BUILDTYPE ]]; then @@ -131,6 +158,15 @@ if [[ ! $BUILD_DIR ]]; then BUILD_DIR="build" fi mkdir -p "$BUILD_DIR" + +if [[ $MAKE_COVERAGE ]]; then + # Resolved while the working directory is still the source root. $0 is relative to the + # directory the script was invoked from, so after the cd below it no longer resolves, and + # under `set -e` the failed subshell would abort the build rather than just yielding an empty + # variable. Only the coverage report needs this, so only coverage pays for it. + SRC_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +fi + cd "$BUILD_DIR" # Set minimum CMake Version @@ -138,6 +174,16 @@ export CMAKE_POLICY_VERSION_MINIMUM=3.10 # Add cmake flags flags=("-DCMAKE_BUILD_TYPE=$BUILDTYPE") +if [[ $USE_CCACHE && $USE_SCCACHE ]]; then + echo "::error file=$0::ccache and sccache at the same time is not a supported combination" + exit 1 +fi +if [[ $USE_SCCACHE && $CMAKE_GENERATOR != "Ninja"* ]]; then + # A compiler cache wraps the compiler, and only generators that run the compiler + # themselves are given a launcher to wrap: cmake does not pass one to MSBuild. + echo "::error file=$0::sccache needs a Ninja generator, not '$CMAKE_GENERATOR', which would ignore it" + exit 1 +fi if [[ $MAKE_SERVER ]]; then flags+=("-DWITH_SERVER=1") fi @@ -147,6 +193,17 @@ fi if [[ $MAKE_TEST ]]; then flags+=("-DTEST=1") fi +if [[ $MAKE_SANITIZE ]]; then + flags+=("-DENABLE_SANITIZERS=ON") +else + # The release-package step re-runs cmake in the same build dir, so an + # ENABLE_SANITIZERS=ON left over from the debug step would otherwise leak + # into the shipped binaries (libasan/libubsan Depends in the DEB). + flags+=("-DENABLE_SANITIZERS=OFF") +fi +if [[ $MAKE_COVERAGE ]]; then + flags+=("-DENABLE_COVERAGE=ON") +fi if [[ $USE_CCACHE ]]; then flags+=("-DUSE_CCACHE=1") # PCH-aware caching is required or ccache refuses to cache any TU that @@ -157,6 +214,10 @@ if [[ $USE_CCACHE ]]; then ccache --max-size "$CCACHE_SIZE" fi fi +if [[ $USE_SCCACHE ]]; then + flags+=("-DUSE_SCCACHE=1") + flags+=("-DCMAKE_C_COMPILER_LAUNCHER=sccache" "-DCMAKE_CXX_COMPILER_LAUNCHER=sccache") +fi if [[ $PACKAGE_TYPE ]]; then flags+=("-DCPACK_GENERATOR=$PACKAGE_TYPE") fi @@ -178,6 +239,22 @@ function ccachestatsverbose() { fi } +function cpuinfo() { + # The number of cores decides how much build parallelism is useful; the hosted + # runners are not all sized alike, so read it off the machine instead of assuming. + case "$RUNNER_OS" in + Windows) + echo "cores: ${NUMBER_OF_PROCESSORS:-unknown}" + ;; + macOS) + echo "cores: $(sysctl -n hw.ncpu)" + ;; + *) + echo "cores: $(nproc 2>/dev/null || echo unknown)" + ;; + esac +} + # Compile if [[ $RUNNER_OS == macOS ]]; then # QTDIR is needed for macOS since we actually only use the cached thin Qt binaries instead of the install-qt-action, @@ -212,8 +289,14 @@ if [[ $RUNNER_OS == macOS ]]; then triplet_source="../vcpkg/triplets/community/$arch-osx.cmake" fi cp "$triplet_source" "$triplet_file" - echo "set(VCPKG_CMAKE_SYSTEM_VERSION $TARGET_MACOS_VERSION)" >>"$triplet_file" - echo "set(VCPKG_OSX_DEPLOYMENT_TARGET $TARGET_MACOS_VERSION)" >>"$triplet_file" + # The triplet is what vcpkg hashes into the ABI hash of every port, so two legs that + # agree here reuse each other's binary cache. Targets 14, 15 and 26 on the same Xcode + # produce identical binaries when they share the lowest deployment target, so they all + # build against 14 to keep one vcpkg cache scope instead of three. + # Keep in sync with "vcpkg_scope" and "vcpkg_deployment_target" in desktop-build.yml. + vcpkg_target="${VCPKG_TARGET_MACOS_VERSION:-$TARGET_MACOS_VERSION}" + echo "set(VCPKG_CMAKE_SYSTEM_VERSION $vcpkg_target)" >>"$triplet_file" + echo "set(VCPKG_OSX_DEPLOYMENT_TARGET $vcpkg_target)" >>"$triplet_file" flags+=("-DVCPKG_OVERLAY_TRIPLETS=$triplets_dir") flags+=("-DVCPKG_HOST_TRIPLET=$triplet_version") flags+=("-DVCPKG_TARGET_TRIPLET=$triplet_version") @@ -256,9 +339,33 @@ if [[ $RUNNER_OS == macOS ]]; then 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) + if [[ $CMAKE_GENERATOR == "Visual Studio"* ]]; then + # cmake only hands MSBuild a job count when it is asked for, and without it + # MSBuild builds a single node: one project at a time, whatever MTT does inside + # it. Ask for a node per core. + if [[ ! $BUILD_PARALLEL_LEVEL ]]; then + BUILD_PARALLEL_LEVEL="${NUMBER_OF_PROCESSORS:-1}" + fi + buildflags+=(--parallel "$BUILD_PARALLEL_LEVEL") + + # 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 + # EnforceProcessCountAcrossBuilds makes the CL_MPCount ceiling apply across all + # the projects the nodes are building, instead of each node running its own + # cl.exe processes and /m and MTT multiplying into an oversubscribed machine. + buildflags+=(-- -p:UseMultiToolTask=true -p:EnableClServerMode=true -p:EnforceProcessCountAcrossBuilds=true -p:CL_MPCount="$BUILD_PARALLEL_LEVEL") + if [[ $BUILD_PROFILE ]]; then + # A performance summary says which projects and tasks cost what, the binary log + # keeps the full timeline; both are far too noisy to always produce. The files + # land next to the solution, i.e. in the build dir the workflow uploads. These + # join the MTT options above, which already carried the "--" separator. + buildflags+=("-flp:PerformanceSummary;v=q;LogFile=msbuild-perf.log" -bl:msbuild.binlog) + fi + else + # Ninja runs the compiler itself, so it neither needs the MSVC switches nor + # wants a job count: it sizes its own pool for the cores it finds. + echo "ninja $(ninja --version)" + fi fi if [[ $USE_CCACHE ]]; then @@ -274,10 +381,19 @@ cmake .. "${flags[@]}" echo "::endgroup::" echo "::group::Build project" +cpuinfo echo "Running cmake --build with flags: ${buildflags[*]}" cmake --build . "${buildflags[@]}" echo "::endgroup::" +if [[ $BUILD_PROFILE && $RUNNER_OS == Windows && -f msbuild-perf.log ]]; then + # Repeat the summary in the job log so the numbers are readable without + # downloading the binary log, which is hundreds of megabytes. + echo "::group::MSBuild performance summary" + cat msbuild-perf.log + echo "::endgroup::" +fi + if [[ $USE_CCACHE ]]; then if [[ $CCACHE_EVICTION_AGE ]]; then echo "::group::evict ccache files older than $CCACHE_EVICTION_AGE" @@ -287,6 +403,10 @@ if [[ $USE_CCACHE ]]; then echo "::group::Show ccache stats again" ccachestatsverbose echo "::endgroup::" +elif [[ $USE_SCCACHE ]]; then + echo "::group::Show sccache stats" + sccache --show-stats + echo "::endgroup::" elif [[ $CCACHE_EVICTION_AGE ]]; then echo "::error file=$0::ccache eviction is enabled while ccache is disabled!" fi @@ -306,7 +426,50 @@ fi if [[ $MAKE_TEST ]]; then echo "::group::Run tests" - ctest -C "$BUILDTYPE" --output-on-failure + if [[ $MAKE_SANITIZE ]]; then + # detect_leaks=0: Qt and the sanitizers' own runtimes both leak at exit by design, and + # LeakSanitizer's default is aggressive enough to bury our real findings under hundreds + # of process-teardown reports. Malloc/free misuse and use-after-free are what ASan is for + # and they stay fully on. + # abort_on_error=1: a bad access leaves the process in an unusable state, so continuing + # only produces a second, more confusing report from the wreckage. + # UBSAN halt_on_error=1: without it UBSan prints "runtime error: ..." but the + # process exits 0 (recover mode), so gtest/ctest report a pass and the job + # stays green. Combined with -fno-sanitize-recover=undefined at compile time, + # the first finding aborts the test process with a non-zero exit. + export ASAN_OPTIONS="detect_leaks=0:abort_on_error=1:print_stacktrace=1:symbolize=1" + export UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1:symbolize=1" + fi + # Every TEST() is its own CTest entry, so the suite is process-spawn bound rather than CPU + # bound and -j recovers nearly all of the per-process overhead. The test binaries are safe to + # run concurrently: the only one that claims a fixed resource is single_instance_manager_test, + # which already scopes its local socket name to its own pid so parallel copies cannot collide. + ctest -C "$BUILDTYPE" --output-on-failure -j "${CTEST_JOBS:-4}" + echo "::endgroup::" +fi + +if [[ $MAKE_COVERAGE ]]; then + # gcovr is not a build dependency and is not available everywhere, so a missing one is reported + # and skipped rather than failing an otherwise green build. + echo "::group::Coverage report" + GCOVR="$(command -v gcovr || true)" + if [[ -z $GCOVR ]]; then + echo "gcovr not found; install it to produce a coverage report" + else + "$GCOVR" --version + # This script configures with `cmake ..`, so the build dir it was started from is the object + # directory and the source root is one level up. Both are passed explicitly: gcovr otherwise + # walks the current directory and trips over in-tree build directories left by other tooling, + # whose stale .gcno files cannot be resolved. --config is named too, so the filters apply no + # matter what directory gcovr happens to start from. + GCOVR_ARGS=("." --root "$SRC_ROOT" --object-directory "." --config "$SRC_ROOT/gcovr.cfg") + "$GCOVR" "${GCOVR_ARGS[@]}" --txt --decisions + "$GCOVR" "${GCOVR_ARGS[@]}" --html-details coverage-details.html --html-title "Cockatrice line coverage" + "$GCOVR" "${GCOVR_ARGS[@]}" --lcov -o coverage.lcov + "$GCOVR" "${GCOVR_ARGS[@]}" --cobertura-pretty -o coverage.xml + "$GCOVR" "${GCOVR_ARGS[@]}" --json-summary-pretty -o coverage-summary.json + echo "Coverage artifacts written to coverage-details.html, coverage.lcov, coverage.xml and coverage-summary.json" + fi echo "::endgroup::" fi @@ -353,15 +516,21 @@ if [[ $MAKE_PACKAGE ]]; then fi echo "Installer content is clean" - # Fail the build if the installer is missing a Qt runtime the applications - # link against. The DLLs reach the package by globbing every *.dll out of - # the build output directories, so a module the client links statically - # (Qt6Multimedia.dll, Qt6QuickWidgets.dll) can be left out without anything - # else noticing, and the only symptom is a client that refuses to start - # after an update. required-qt-runtime.txt is written by the top level - # CMakeLists.txt from the same module list the targets are built against. - if [[ ! -f required-qt-runtime.txt ]]; then - echo "::error file=$0::required-qt-runtime.txt not found in the build dir, cannot verify the Qt runtime" + # Fail the build if the installer does not carry the runtime the + # applications link against - a file that must be there, or a DLL that must + # not be. The runtime DLLs reach the package by globbing every *.dll out of + # the build output directories, so anything that build produced can ride + # along and nothing else in the build objects to it: a Qt module the client + # links statically (Qt6Multimedia.dll, Qt6QuickWidgets.dll) can be left out, + # and the test framework's gtest.dll can be shipped. Either only surfaces on + # a user's machine after an update has already replaced their install, as + # "The code execution cannot proceed because Qt6Multimedia.dll was not + # found" or "abseil_dll.dll is either not designed to run on Windows or it + # contains an error". required-runtime.txt is written by the top level + # CMakeLists.txt from the same module lists the targets are built against + # plus the vcpkg bin directory the app-local copies come from. + if [[ ! -f required-runtime.txt ]]; then + echo "::error file=$0::required-runtime.txt not found in the build dir, cannot verify the runtime" exit 1 fi # 7-Zip writes CRLF on Windows, so the \r has to come off before any @@ -371,7 +540,7 @@ if [[ $MAKE_PACKAGE ]]; then # being a wildcard; -i because that is how the installed tree behaves - # the uninstaller clears both $INSTDIR\plugins and $INSTDIR\Plugins. # The archive side and the manifest side have to agree on line endings. - # CMake writes required-qt-runtime.txt with the platform's line ending and + # CMake writes required-runtime.txt with the platform's line ending and # 7-Zip writes CRLF on Windows, so a trailing \r survives on $entry and # defeats the whole-line match - every entry then reads as missing even # though the listing holds it verbatim. @@ -380,7 +549,7 @@ if [[ $MAKE_PACKAGE ]]; then installer_paths="$("$seven_zip" l -slt "$package" | tr -d '\r' | sed -n 's/^Path = //p' | sed -e 's|\\|/|g' -e 's|^[$]INSTDIR/||' -e 's|^[$]OUTDIR/||' -e 's|^[$]PLUGINSDIR/||' -e 's|^\./||' -e 's|^/||')" - manifest="$(tr -d '\r' sets the location to cache the image or for ccache # # requires: docker -# uses env: NAME CACHE BUILD GET SAVE INTERACTIVE +# uses env: NAME IMAGE_SUFFIX CACHE BUILD GET SAVE INTERACTIVE # (correspond to args: --set-cache --build --get --save --interactive) # sets env: RUN CCACHE_DIR IMAGE_NAME RUN_ARGS RUN_OPTS BUILD_SCRIPT # exitcode: 1 for failure, 2 for missing dockerfile, 3 for invalid arguments # +# IMAGE_SUFFIX is optional and only appended to the image name, never to NAME, so that a matrix +# leg can have its own image and image cache without needing its own directory under .ci. Two legs +# building and tagging the same image concurrently would race on `docker build --tag`. +# It is deliberately not called SUFFIX: compile.sh already uses SUFFIX for output file names, and +# a job-level SUFFIX would be silently overridden by those per-step env blocks. +# # exported RUN function will run the BUILD_SCRIPT inside of the docker container. # note that the docker container will not inherit any environment variables! # @@ -81,7 +87,7 @@ if ! [[ $NAME ]]; then return 3 fi -export IMAGE_NAME="${project_name,,}_${NAME,,}" # lower case +export IMAGE_NAME="${project_name,,}_${NAME,,}${IMAGE_SUFFIX:+_${IMAGE_SUFFIX,,}}" # lower case docker_dir=".ci/$NAME" if ! [[ -r $docker_dir/Dockerfile ]]; then diff --git a/.dockerignore b/.dockerignore index 2abeb2727..8e0b69332 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,3 @@ -.git/ build/ .github/ .tx/ diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index 17c42b07d..b12b0eabd 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -144,17 +144,36 @@ jobs: package: DEB - name: ${{ matrix.distro }} ${{ matrix.version }} + # The one leg that runs the suite under AddressSanitizer and + # UndefinedBehaviorSanitizer. Debian 13 and Fedora 44 keep covering the + # uninstrumented suite, so nothing is lost by instrumenting this one. + sanitize: yes + + - distro: Ubuntu + version: 26.04 + variant: cover # separate image and ccache, same distro + + # The one leg that runs instrumented for line coverage and publishes the report as + # a workflow artifact. It is a separate leg rather than a second flag on the + # sanitizer leg because the two instruments answer different questions: the + # sanitizer leg reports what the run did wrong, the coverage leg reports what the + # run never touched at all. Combining them would also slow both down. Packaging is + # skipped because the leg above already publishes the DEB for this distro. + coverage: yes + package: skip + + name: ${{ matrix.distro }} ${{ matrix.version }}${{ matrix.variant && format(' {0}', matrix.variant) || '' }} needs: configure runs-on: ubuntu-latest # https://github.com/actions/runner-images continue-on-error: ${{ matrix.allow-failure == 'yes' }} timeout-minutes: 70 env: - CACHE: ${{ github.workspace }}/.cache/${{ matrix.distro }}${{ matrix.version }} # directory for caching docker image and ccache + CACHE: ${{ github.workspace }}/.cache/${{ matrix.distro }}${{ matrix.version }}${{ matrix.variant }} # directory for caching docker image and ccache CCACHE_EVICTION_AGE: 7d CCACHE_SIZE: 600M # space of all repo is 10Gi: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy CMAKE_GENERATOR: 'Ninja' NAME: ${{ matrix.distro }}${{ matrix.version }} + IMAGE_SUFFIX: ${{ matrix.variant }} steps: - name: "Checkout" @@ -164,8 +183,8 @@ jobs: id: restore_ccache uses: actions/cache/restore@v6 with: - key: ccache-${{ matrix.distro }}${{ matrix.version }} - path: ${{ env.CACHE }} + key: ccache-${{ matrix.distro }}${{ matrix.version }}${{ matrix.variant }} + path: ${{ env.CACHE }}/.ccache - name: "Build ${{ matrix.distro }} ${{ matrix.version }} Docker image" shell: bash @@ -174,6 +193,9 @@ jobs: - name: "Build debug and test" if: matrix.test != 'skip' shell: bash + env: + sanitize: '${{ matrix.sanitize }}' + coverage: '${{ matrix.coverage }}' run: | source .ci/docker.sh args=() @@ -181,7 +203,33 @@ jobs: args+=(--ccache "$CCACHE_SIZE") args+=(--cmake-generator "$CMAKE_GENERATOR") - RUN --server --debug --test "${args[@]}" + extra=() + [[ $sanitize == yes ]] && extra+=(--sanitize) + [[ $coverage == yes ]] && extra+=(--coverage) + + RUN --server --debug --test "${extra[@]}" "${args[@]}" + + # RUN bind-mounts the workspace into the container, so the report the build wrote into + # build/ is already on the host and no second container is needed to collect it. + - name: "Collect coverage report" + if: matrix.coverage == 'yes' + shell: bash + run: | + mkdir -p coverage + # --html-details writes one page per source file plus a stylesheet and script, and the + # index links to all of them by relative name. Copying the index alone would publish a + # report where every link 404s, so the whole family has to travel together. + cp build/coverage-details* coverage/ + cp build/coverage.lcov build/coverage.xml build/coverage-summary.json coverage/ + ls -la coverage/ + + - name: "Upload coverage artifact" + if: matrix.coverage == 'yes' + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: coverage/ + if-no-files-found: warn - name: "Build release package" id: build @@ -219,7 +267,7 @@ jobs: uses: actions/cache/save@v6 with: key: ${{ steps.restore_ccache.outputs.cache-primary-key }} - path: ${{ env.CACHE }} + path: ${{ env.CACHE }}/.ccache - name: "Upload artifact" id: upload_artifact @@ -277,6 +325,8 @@ jobs: soc: Intel type: Release use_ccache: 1 + vcpkg_scope: 'vcpkg/macos13-x64-xcode26.3/' + vcpkg_upload: 1 # only one leg per vcpkg_scope hands its archives over xcode: "26.3" - os: macOS @@ -293,6 +343,9 @@ jobs: soc: Apple type: Release use_ccache: 1 + vcpkg_deployment_target: 14 + vcpkg_scope: 'vcpkg/macos14-arm64-xcode26.6/' + vcpkg_upload: 1 # only one leg per vcpkg_scope hands its archives over xcode: "26.6" - os: macOS @@ -309,6 +362,8 @@ jobs: soc: Apple type: Release use_ccache: 1 + vcpkg_deployment_target: 14 + vcpkg_scope: 'vcpkg/macos14-arm64-xcode26.6/' xcode: "26.6" - os: macOS @@ -322,12 +377,20 @@ jobs: soc: Apple type: Debug use_ccache: 1 + vcpkg_deployment_target: 14 + vcpkg_scope: 'vcpkg/macos14-arm64-xcode26.6/' xcode: "26.6" - os: Windows target: 10 runner: windows-2025 # https://github.com/actions/runner-images/blob/main/images/windows/Windows2025-VS2026-Readme.md + # Set build_profile: 1 to have the build write an MSBuild performance + # summary and a binary log; empty on every entry that runs by default. + # Enabled here on purpose: this pull request measures MSBuild + # parallelism, so its run is the one worth profiling. + build_profile: 1 + cmake_generator: "Visual Studio 18 2026" cmake_generator_platform: x64 make_package: 1 @@ -335,12 +398,40 @@ jobs: qt_version: 6.11.* qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets type: Release + vcpkg_scope: 'vcpkg/windows10-x64-vs2026/' + vcpkg_upload: 1 # only one leg per vcpkg_scope hands its archives over - name: ${{ matrix.os }} ${{ matrix.target }}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} + # A/B run: is Ninja faster than the Visual Studio generator on this runner? + # It is allowed to fail and is never published, see the steps that build + # a release below. Delete this entry once the answer is known. + - os: Windows + target: 10 + runner: windows-2025 + + cmake_generator: Ninja + experiment: yes + make_package: 1 + package_suffix: "-Win10-ninja" + qt_version: 6.11.* + qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets + type: Release + use_sccache: 1 + variant: ' (Ninja)' + # The same scope as the Visual Studio leg, so both halves of the A/B + # start from the same vcpkg cache and the comparison is about the + # generator alone. Without it this leg's prefix is empty, which makes + # the cache action restore the whole vcpkg/ namespace and write entries + # that no scope claims. vcpkg_upload is deliberately left unset, so only + # the Visual Studio leg hands its archives over. + vcpkg_scope: 'vcpkg/windows10-x64-vs2026/' + + name: ${{ matrix.os }} ${{ matrix.target }}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }}${{ matrix.variant }} needs: configure runs-on: ${{ matrix.runner }} + continue-on-error: ${{ matrix.experiment == 'yes' }} timeout-minutes: 100 env: + BUILD_PROFILE: '${{ matrix.build_profile }}' CCACHE_DIR: ${{ github.workspace }}/.cache/ CCACHE_SIZE: 600M # space of all repo is 10Gi: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy @@ -423,6 +514,28 @@ jobs: modules: ${{ matrix.qt_modules }} version: ${{ matrix.qt_version }} + # Ninja invokes cl.exe directly and needs the MSVC environment on PATH; the + # Visual Studio generator locates the compiler on its own and skips this. + - name: "[Windows/Ninja] Set up MSVC environment" + if: matrix.os == 'Windows' && matrix.cmake_generator == 'Ninja' + uses: TheMrMilchmann/setup-msvc-dev@v4.1.0 + with: + arch: x64 + + # sccache is only useful for the Ninja job: a compiler cache has to wrap the + # compiler, and MSBuild is driven by cmake instead of running it, so a + # launcher handed to MSBuild is ignored without a word. + - name: "[Windows/Ninja] Set up sccache" + if: matrix.os == 'Windows' && matrix.cmake_generator == 'Ninja' + uses: mozilla-actions/sccache-action@v0.0.11 + env: + SCCACHE_GHA_ENABLED: "true" + # A fork pull request can read the cache, but the token it runs with + # cannot write to the base branch's scope. + SCCACHE_GHA_RW_MODE: ${{ github.event.pull_request.head.repo.fork && 'READ_ONLY' || 'READ_WRITE' }} + # A cache that cannot be reached must not fail the build. + SCCACHE_IGNORE_SERVER_IO_ERROR: "1" + - name: "[Windows] Install NSIS" if: matrix.os == 'Windows' shell: bash @@ -432,8 +545,28 @@ jobs: id: vcpkg-cache uses: TAServers/vcpkg-cache@v3 with: + # Every entry is keyed by vcpkg ABI hash, and one hash set exists per platform, + # target and toolchain. The action restores every entry it finds under the + # prefix, not just the hashes vcpkg asks for, so with one shared vcpkg/ + # namespace every leg downloads all 66 archives of all 5 legs on every run. + # Each of those restores also refreshes the entry's last access date, which + # is why a dead ABI generation is never evicted by age. Naming the scope is + # what makes those generations identifiable, and prune-caches below able to + # delete them. + prefix: ${{ matrix.vcpkg_scope }} token: ${{ secrets.GITHUB_TOKEN }} + # The action only creates its directory when the prefix matched at least one + # entry, and it reads that directory unguarded when it saves at the end of the + # job. A scope nobody has written to yet therefore leaves the directory missing + # and fails the job, which is exactly the state every scope starts in. Make the + # directory up front so an empty scope is a cache miss instead of an error. + - name: "Create vcpkg cache directory" + shell: bash + env: + CACHE_DIR: '${{ steps.vcpkg-cache.outputs.path }}' + run: mkdir -p "$CACHE_DIR" + # Uses environment variables, see compile.sh for more details - name: "Build Cockatrice" id: build @@ -451,11 +584,22 @@ jobs: MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} MAKE_PACKAGE: '${{ matrix.make_package }}' PACKAGE_SUFFIX: '${{ matrix.package_suffix }}' - TARGET_MACOS_VERSION: ${{ matrix.override_target }} + TARGET_MACOS_VERSION: '${{ matrix.override_target }}' USE_CCACHE: ${{ matrix.use_ccache }} + USE_SCCACHE: ${{ matrix.use_sccache }} + # Only pushes to the default branch may write the shared binary cache: the + # archives a run compiles are only as trustworthy as the code they were + # built from, and only merged code may populate the scope that master and + # release builds restore and link. Pull requests (same-repository ones + # included) restore the shared cache but never write it; with the source + # left at read the collect step below finds nothing on PRs, so no + # pull-request-scoped entry is ever saved that no later run could restore. + # Forks pushing to their own default branch resolve github.ref against + # their own repository, so they keep a working cache of their own there. VCPKG_BINARY_SOURCES: "clear;files,${{ steps.vcpkg-cache.outputs.path }},${{ case(github.ref == 'refs/heads/master', 'readwrite', 'read') }}" VCPKG_DISABLE_METRICS: 1 VCPKG_FEATURE_FLAGS: dependencygraph + VCPKG_TARGET_MACOS_VERSION: ${{ matrix.vcpkg_deployment_target }} run: .ci/compile.sh --server --test --vcpkg # CPack reports a failed makensis run as "Problem running NSIS command" @@ -469,6 +613,63 @@ jobs: shell: bash run: find . -name NSISOutput.log -exec cat {} + + # A master run hands over the archives it had to build itself so that + # vcpkg-cache-import.yml, which runs in the default branch scope, can save them + # where later runs can restore them. Pull requests hand over nothing: their cache + # entries would be scoped to refs/pull//merge and stay unreadable for every + # other run, so writing them only burns the repository's quota. + # vcpkg_upload keeps this to one leg per scope: macOS 14, 15 and 26 share a scope + # by design, and all three rebuild the same archives, so uploading from each of them + # would publish three identical 269 MB artifacts under one artifact name and make + # the importer spawn a save job per copy. + - name: "Collect new vcpkg entries" + id: vcpkg_new + if: github.ref == 'refs/heads/master' && matrix.vcpkg_upload == 1 + shell: bash + env: + CACHE_DIR: '${{ steps.vcpkg-cache.outputs.path }}' + GH_TOKEN: ${{ github.token }} + VCPKG_SCOPE: '${{ matrix.vcpkg_scope }}' + run: | + # The archive name is the ABI hash, so a missing key is exactly what vcpkg had + # to compile from source in this job. + gh api --paginate \ + "repos/$GITHUB_REPOSITORY/actions/caches?ref=refs/heads/master&key=$VCPKG_SCOPE&per_page=100" \ + --jq '.actions_caches[].key' | sort -u >"$RUNNER_TEMP/master-keys.txt" + find "$CACHE_DIR" -type f -name '*.zip' -exec basename {} .zip \; | + sed "s|^|$VCPKG_SCOPE|" | sort -u >"$RUNNER_TEMP/local-keys.txt" + comm -23 "$RUNNER_TEMP/local-keys.txt" "$RUNNER_TEMP/master-keys.txt" >"$RUNNER_TEMP/new-keys.txt" + + mkdir -p "$RUNNER_TEMP/vcpkg-new" + : >"$RUNNER_TEMP/vcpkg-new/keys.txt" + while read -r key; do + hash="${key##*/}" + archive="$(find "$CACHE_DIR" -type f -name "$hash.zip" -print -quit)" + dir="$RUNNER_TEMP/vcpkg-new/${hash:0:2}" # vcpkg's own two character fanout + mkdir -p "$dir" + cp "$archive" "$dir/" + echo "$key ${hash:0:2}/$hash.zip" >>"$RUNNER_TEMP/vcpkg-new/keys.txt" + done <"$RUNNER_TEMP/new-keys.txt" + + count="$(wc -l <"$RUNNER_TEMP/new-keys.txt")" + echo "vcpkg scope $VCPKG_SCOPE: $count entries to import" + echo "count=$count" >>"$GITHUB_OUTPUT" + echo "slug=$(sed -e 's|^vcpkg/||' -e 's|/$||' -e 's|/|-|g' <<<"$VCPKG_SCOPE")" >>"$GITHUB_OUTPUT" + + # archive: false accepts a single file and nothing else, and a scope hands over one + # archive per ABI hash vcpkg had to rebuild, which is 23 files on a cold runner. + # Zipping the directory keeps the fanout at the artifact root, which is where + # vcpkg-cache-import.yml looks for keys.txt once download-artifact unpacks it. + - name: "Upload new vcpkg entries" + # An empty count means the step above did not run at all, on master and on forks + if: steps.vcpkg_new.outputs.count != '' && steps.vcpkg_new.outputs.count != '0' + uses: actions/upload-artifact@v7 + with: + if-no-files-found: error # a count above zero with nothing staged is a bug + name: vcpkg-new-${{ steps.vcpkg_new.outputs.slug }} + path: ${{ runner.temp }}/vcpkg-new + retention-days: 1 + # Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342 - name: "[macOS] Delete remote compiler cache (ccache)" if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master' && steps.restore_ccache.outputs.cache-hit @@ -544,8 +745,11 @@ jobs: if-no-files-found: error path: ${{ steps.build.outputs.path }} + # Ninja writes its PDBs next to the binaries instead of into a Release + # subdirectory, and the experimental job is not a source of release debug + # symbols, so it keeps out of both. - name: "[Windows] Upload PDBs (Program Databases)" - if: matrix.os == 'Windows' && github.ref_type != 'tag' + if: matrix.os == 'Windows' && matrix.experiment != 'yes' && github.ref_type != 'tag' uses: actions/upload-artifact@v7 with: if-no-files-found: error @@ -555,8 +759,19 @@ jobs: build/oracle/Release/*.pdb build/servatrice/Release/*.pdb + # Written only when the matrix entry sets build_profile, so the artifact + # exists exactly on the runs that were asked to produce one. + - name: "[Windows] Upload MSBuild binary log" + if: always() && matrix.os == 'Windows' && env.BUILD_PROFILE == '1' + uses: actions/upload-artifact@v7 + with: + if-no-files-found: error + name: ${{ steps.build.outputs.name }}-msbuild + path: build/msbuild.binlog + retention-days: 7 + - name: "Upload to release" - if: needs.configure.outputs.tag != null && matrix.make_package == '1' + if: needs.configure.outputs.tag != null && matrix.make_package == '1' && matrix.experiment != 'yes' id: upload_release shell: bash env: @@ -581,3 +796,67 @@ jobs: BUILD_PATH: ${{ steps.build.outputs.path }} GH_TOKEN: ${{ github.token }} run: gh attestation verify "$BUILD_PATH" --repo Cockatrice/Cockatrice + + prune-caches: + name: Prune caches + # Only master writes caches at all, so only master may clean them up too + if: github.ref == 'refs/heads/master' + runs-on: ubuntu-slim # https://github.com/actions/runner-images/blob/main/images/ubuntu-slim/ubuntu-slim-Readme.md + continue-on-error: true # freeing space must never fail a build + + steps: + # The repository holds 10Gi of cache against entries that want more, and GitHub + # evicts the least recently used entry whenever that is exceeded. The vcpkg + # entries are the reason that never happens: the restore above touches every + # entry under the prefix on every run, so a dead ABI generation keeps its access + # date fresh forever and age based eviction can never reach it. Deleting by age + # alone cannot fix that, only knowing which scope an entry belongs to can. + - name: "Delete unusable cache entries" + shell: bash + env: + GH_TOKEN: ${{ github.token }} + # Must list every vcpkg_scope of the build-vcpkg matrix above, or the entries of + # a scope that is still in use get deleted on the next run. + LIVE_VCPKG_SCOPES: 'vcpkg/macos13-x64-xcode26.3/ vcpkg/macos14-arm64-xcode26.6/ vcpkg/windows10-x64-vs2026/' + run: | + gh api --paginate "repos/$GITHUB_REPOSITORY/actions/caches?per_page=100" \ + --jq '.actions_caches[] | [.id, .ref, .key, .last_accessed_at] | @tsv' >"$RUNNER_TEMP/caches.tsv" + + cutoff="$(( $(date -u +%s) - 7 * 24 * 3600 ))" + live=" ${LIVE_VCPKG_SCOPES} " + deleted=0 + while IFS=$'\t' read -r id ref key accessed; do + [[ -n $id ]] || continue + # Only ever touch the key shapes this workflow creates, so that an entry of + # some other workflow can never be deleted by accident + case "$key" in + vcpkg/* | ccache-* | Qt*) ;; + *) continue ;; + esac + + reason="" + if [[ $ref != refs/heads/master ]]; then + reason="scoped to $ref" + elif [[ $key == vcpkg/* ]]; then + # "/", cut the hash off the end to get the scope + scope="vcpkg/${key#vcpkg/}" + scope="${scope%/*}/" + if [[ $live != *" $scope "* ]]; then + reason="no matrix leg uses $scope" + fi + fi + if [[ -z $reason ]]; then + stamp="$(date -u -d "$accessed" +%s 2>/dev/null || echo 0)" + if [[ $stamp -ne 0 && $stamp -lt $cutoff ]]; then + reason="unused since $accessed" + fi + fi + + if [[ -n $reason ]]; then + echo "::notice::deleting $key, $reason" + gh api -X DELETE "repos/$GITHUB_REPOSITORY/actions/caches/$id" + deleted=$((deleted + 1)) + fi + done <"$RUNNER_TEMP/caches.tsv" + + echo "::notice::deleted $deleted of $(wc -l <"$RUNNER_TEMP/caches.tsv") cache entries" diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index 967d94c58..937386940 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -20,11 +20,22 @@ on: release: types: - released # publishing of stable releases + workflow_dispatch: # (re)publish the image for an existing stable release + inputs: + tag: + description: 'Existing release tag to build and publish (e.g. 2026-10-03-Release-3.1.0)' + required: true + type: string + latest: + description: 'Also update the "latest" tag' + required: true + type: boolean + default: true -# Cancel earlier, unfinished runs of this workflow on the same branch (unless on release) +# Cancel earlier, unfinished runs of this workflow on the same branch (unless publishing) concurrency: - group: "${{ github.workflow }} @ ${{ github.ref_name }}" - cancel-in-progress: ${{ github.event_name != 'release' }} + group: "${{ github.workflow }} @ ${{ inputs.tag || github.ref_name }}" + cancel-in-progress: ${{ github.event_name != 'release' && github.event_name != 'workflow_dispatch' }} env: GHCR_IMAGE: ghcr.io/cockatrice/servatrice @@ -57,12 +68,14 @@ jobs: steps: - name: "Checkout" uses: actions/checkout@v7 + with: + ref: ${{ case(github.event_name == 'workflow_dispatch', format('refs/tags/{0}', inputs.tag), '') }} - name: "Set up Docker buildx" uses: docker/setup-buildx-action@v4 - name: "Login to GitHub Container Registry (GHCR)" - if: github.event_name == 'release' && github.event.release.prerelease == false + if: (github.event_name == 'release' && github.event.release.prerelease == false) || github.event_name == 'workflow_dispatch' id: login uses: docker/login-action@v4 with: @@ -70,7 +83,7 @@ jobs: username: ${{ github.actor }} password: ${{ github.token }} - # Don't push for non-release triggers + # Don't push for non-publishing triggers - name: "Build image" if: steps.login.outcome != 'success' uses: docker/build-push-action@v7 @@ -111,7 +124,6 @@ jobs: if: steps.login.outcome == 'success' uses: actions/upload-artifact@v7 with: - archive: false if-no-files-found: error name: digest-${{ matrix.label }} path: ${{ runner.temp }}/digests/* @@ -121,7 +133,7 @@ jobs: # Create an OCI image index from the platform-specific image manifests index: name: "Publish multi-platform Servatrice image" - if: github.repository_owner == 'Cockatrice' && github.event_name == 'release' && github.event.release.prerelease == false + if: github.repository_owner == 'Cockatrice' && ((github.event_name == 'release' && github.event.release.prerelease == false) || github.event_name == 'workflow_dispatch') needs: build runs-on: ubuntu-slim # https://github.com/actions/runner-images/blob/main/images/ubuntu-slim/ubuntu-slim-Readme.md @@ -147,8 +159,11 @@ jobs: images: ${{ env.GHCR_IMAGE }} flavor: | latest=auto + # if semver, also: type=semver,pattern={{version}} / {{major}}.{{minor}} tags: | - type=ref,event=tag # if semver, also: type=semver,pattern={{version}} / {{major}}.{{minor}} + type=ref,event=tag + type=raw,value=${{ inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' }} + type=raw,value=latest,enable=${{ github.event_name == 'workflow_dispatch' && inputs.latest }} # Add OCI annotations to image index and publish tags - name: "Create image index" @@ -176,7 +191,7 @@ jobs: - name: "Inspect images" env: - GITHUB_TAG: ${{ github.ref_name }} + GITHUB_TAG: ${{ inputs.tag || github.ref_name }} run: | docker buildx imagetools inspect "$GHCR_IMAGE:latest" docker buildx imagetools inspect "$GHCR_IMAGE:$GITHUB_TAG" diff --git a/.github/workflows/documentation-build.yml b/.github/workflows/documentation-build.yml index f13b964cd..91ee14e3e 100644 --- a/.github/workflows/documentation-build.yml +++ b/.github/workflows/documentation-build.yml @@ -28,12 +28,13 @@ jobs: runs-on: ubuntu-latest steps: - - name: "Checkout code" + - name: "Checkout" uses: actions/checkout@v7 with: submodules: recursive - name: "Install Graphviz" + shell: bash run: | sudo apt-get install -y graphviz dot -V @@ -44,6 +45,7 @@ jobs: version: "1.18.0" - name: "Update Doxygen Configuration" + shell: bash run: | git diff Doxyfile doxygen -u Doxyfile @@ -58,9 +60,10 @@ jobs: - name: "Generate Documentation" if: always() + shell: bash run: doxygen Doxyfile - - name: "Deploy to cockatrice.github.io" + - name: "Deploy to cockatrice.github.io/docs" if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' uses: peaceiris/actions-gh-pages@v4 with: @@ -69,3 +72,8 @@ jobs: external_repository: Cockatrice/cockatrice.github.io publish_branch: master publish_dir: ./docs/html + + - name: Link to Documentation Page + if: github.event_name == 'release' || github.event_name == 'workflow_dispatch' + shell: bash + run: echo "::notice title=New documentation published::Shortly available at https://cockatrice.github.io/docs/" diff --git a/.github/workflows/translations-pull.yml b/.github/workflows/translations-pull.yml index 71b0b4c22..da3df1714 100644 --- a/.github/workflows/translations-pull.yml +++ b/.github/workflows/translations-pull.yml @@ -1,7 +1,7 @@ name: Update Translations permissions: - contents: read + contents: write pull-requests: write on: diff --git a/.github/workflows/translations-push.yml b/.github/workflows/translations-push.yml index 41a7aef40..17645cab2 100644 --- a/.github/workflows/translations-push.yml +++ b/.github/workflows/translations-push.yml @@ -1,7 +1,7 @@ name: Update Translation Source permissions: - contents: read + contents: write pull-requests: write on: diff --git a/.github/workflows/vcpkg-cache-import.yml b/.github/workflows/vcpkg-cache-import.yml new file mode 100644 index 000000000..3cc7b2203 --- /dev/null +++ b/.github/workflows/vcpkg-cache-import.yml @@ -0,0 +1,121 @@ +name: Import vcpkg cache + +# After a runner image update changes every port's ABI hash, the first master run +# rebuilds protobuf, openssl and abseil from source and saves them into the shared +# cache, where every later run can restore them. +# +# Only master pushes are imported here: the collect step, keys.txt and the zip +# contents all come from the workflow run being imported, so importing from an +# unmerged pull request would let anyone who can push a branch — or a bot actor +# such as Dependabot, whose PRs are same-repo — promote arbitrary binaries into +# the scope that master and tag builds restore and link into signed releases. +# Forks build untrusted code and must never reach that scope either. +# +# repository_dispatch is not used on purpose: it would also resolve to the default branch, +# but it counts as a low-trust trigger and may only write there when it declares a +# write-capable cache-mode, which puts it in the same position as workflow_run. + +permissions: + actions: write # needed to save entries into the default branch's cache scope + contents: read + +on: + workflow_run: + workflows: ["Build Desktop"] + types: [completed] + +# Every import writes the same scopes, so let them queue instead of racing each other +concurrency: + group: vcpkg-cache-import + cancel-in-progress: false + +jobs: + list: + name: List new vcpkg entries + # Only a successful push to the default branch has archives worth importing. + # Only code that landed on master may populate the scope master runs restore. + # Bot actors are excluded on top: their runs must never promote binaries into + # the shared scope even if they somehow target the default branch. + if: >- + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event == 'push' && + github.event.workflow_run.head_branch == 'master' && + github.event.workflow_run.head_repository.full_name == github.repository && + !endsWith(github.event.workflow_run.actor.login, '[bot]') && + !endsWith(github.event.workflow_run.triggering_actor.login, '[bot]') + runs-on: ubuntu-slim # https://github.com/actions/runner-images/blob/main/images/ubuntu-slim/ubuntu-slim-Readme.md + # workflow_run is a low-trust trigger, so cache access is read-only by default even + # though this run resolves to the default branch. Assert below that this took effect, + # because a save under read-only access only warns and would import nothing silently. + cache-mode: write + outputs: + entries: ${{ steps.scan.outputs.entries }} + + steps: + - name: "Download new vcpkg entries" + uses: actions/download-artifact@v8 + with: + pattern: vcpkg-new-* + path: incoming + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: "Assert write access" + shell: bash + run: | + if [[ $ACTIONS_CACHE_MODE != *write* ]]; then + echo "::error::expected a write-capable cache, got '$ACTIONS_CACHE_MODE'" + exit 1 + fi + + - name: "List cache entries" + id: scan + shell: bash + working-directory: incoming + run: | + entries="$(find . -name keys.txt -type f -exec sh -c ' + for manifest; do + artifact="$(basename "$(dirname "$manifest")")" + while read -r key path; do + printf "{\"artifact\": \"%s\", \"key\": \"%s\", \"path\": \"%s\"}\n" \ + "$artifact" "$key" "$path" + done <"$manifest" + done + ' _ {} +)" + [[ -n $entries ]] || exit 0 + # Compact, because a multi line value cannot be written to GITHUB_OUTPUT + entries="$(jq -cs '.' <<<"$entries")" + echo "entries=$entries" >>"$GITHUB_OUTPUT" + echo "::notice::importing $(jq length <<<"$entries") vcpkg entries" + + save: + name: "Save ${{ matrix.entry.key }}" + needs: list + if: needs.list.outputs.entries + runs-on: ubuntu-slim + cache-mode: write + strategy: + # One job per archive, they run in parallel and each only uploads a single file + fail-fast: false + max-parallel: 20 + matrix: + entry: ${{ fromJSON(needs.list.outputs.entries) }} + + steps: + - name: "Download new vcpkg entries" + uses: actions/download-artifact@v8 + with: + pattern: ${{ matrix.entry.artifact }} + path: incoming + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: "Save vcpkg entry" + uses: actions/cache/save@v6 + with: + # The payload is a Windows or macOS archive while the upload runs on Linux, and + # without this the entry would be stamped as a Linux cache that neither of them + # is allowed to restore. + enableCrossOsArchive: true + key: ${{ matrix.entry.key }} + path: incoming/${{ matrix.entry.path }} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ea17b664..2ae7b94a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,19 @@ # 3.16 required for Qt6 and target_precompile_headers() cmake_minimum_required(VERSION 3.16) +# Let CMake pick the MSVC debug information format through +# CMAKE_MSVC_DEBUG_INFORMATION_FORMAT instead of writing it into the +# CMAKE__FLAGS_ defaults. The policy has to be settled before the +# first project() enables a language, and it does not exist before CMake 3.25, +# where the old defaults are the only thing available. +if(POLICY CMP0141) + cmake_policy(SET CMP0141 NEW) +endif() + # Use compiler cache (ccache) option(USE_CCACHE "Cache the build results with ccache" ON) +# Use compiler cache (sccache), for generators that invoke the compiler themselves +option(USE_SCCACHE "Cache the build results with sccache" OFF) # Treat warnings as errors (Debug builds only) option(WARNING_AS_ERROR "Treat warnings as errors in debug builds" ON) # Check for translation updates @@ -22,6 +33,10 @@ option(WITH_ORACLE "Build Cockatrice card database tool (Oracle)" ON) option(WITH_SERVER "Build Cockatrice server (Servatrice)" OFF) # Compile tests option(TEST "Build tests" OFF) +# Build with AddressSanitizer and UndefinedBehaviorSanitizer +option(ENABLE_SANITIZERS "Build with AddressSanitizer and UndefinedBehaviorSanitizer" OFF) +# Build instrumented for GCC line coverage, reported with gcovr +option(ENABLE_COVERAGE "Build instrumented for GCC line coverage" OFF) # Use vcpkg regardless of OS option(USE_VCPKG "Use vcpkg regardless of OS" OFF) @@ -86,11 +101,11 @@ endif() # A project name is needed for CPack # Version can be overriden by git tags, see cmake/getversion.cmake -project("Cockatrice" VERSION 3.1.0) +project("Cockatrice" VERSION 3.1.2) # Set release name if not provided via env/cmake var if(NOT DEFINED GIT_TAG_RELEASENAME) - set(GIT_TAG_RELEASENAME "Graduation Day") + set(GIT_TAG_RELEASENAME "Reality Check") endif() # Use c++20 for all targets @@ -152,8 +167,17 @@ endif() # Define proper compilation flags if(MSVC) - # Disable Warning C4251, C++20 compatibility, Multi-threaded Builds, Warn Detection, Unwind Semantics, Debug Symbols - set(CMAKE_CXX_FLAGS "/wd4251 /Zc:__cplusplus /std:c++20 /permissive- /W4 /MP /EHsc /Zi") + # Debug information: a cache can only store and restore objects that carry it + # inside, so a cached build asks for /Z7 (Embedded); otherwise /Zi (ProgramDatabase). + # Either way the linker is told to write the PDB, in every configuration. + if(USE_SCCACHE) + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded) + else() + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT ProgramDatabase) + endif() + + # Disable Warning C4251, C++20 compatibility, Multi-threaded Builds, Warn Detection, Unwind Semantics + set(CMAKE_CXX_FLAGS "/wd4251 /Zc:__cplusplus /std:c++20 /permissive- /W4 /MP /EHsc") # Visual Studio: Maximum Optimization, Multi-threaded DLL set(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD") # Visual Studio: No Optimization, Multi-threaded Debug DLL @@ -211,6 +235,12 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe") endif() +# Always included, because they define cockatrice_disable_sanitizers_for() and +# cockatrice_disable_coverage_for() for the vendored trees. They only touch the global flags +# when ENABLE_SANITIZERS or ENABLE_COVERAGE is on. +include(Sanitizers) +include(Coverage) + # GNU systems need to define the Mersenne exponent for the RNG to compile w/o warning if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") add_definitions("-DSFMT_MEXP=19937") @@ -326,38 +356,54 @@ elseif(WIN32) # Configure file with custom definitions for NSIS. configure_file("${COCKATRICE_CMAKE_PATH}/NSIS.definitions.nsh.in" "${PROJECT_BINARY_DIR}/NSIS.definitions.nsh") - # Every Qt module the client links against, as the DLL names a Windows install - # has to contain, plus the platform plugin without which the client cannot - # start. .ci/compile.sh reads this and fails the build when the packaged - # installer is missing one of them. + # Every runtime DLL a Windows install has to contain, as paths relative to the + # install root. .ci/compile.sh reads this and fails the build when the packaged + # installer is missing one of them, or carries a runtime it does not know about. # - # Only the client is packaged on Windows, so this is the client's module list - # rather than the union across server, client and Oracle: demanding Oracle's or - # Servatrice's modules of the client installer checks nothing about the client. + # All three applications are packaged into the same directory on Windows, so + # this is the union of their Qt module lists, not just the client's: Servatrice + # contributes Qt6Sql.dll and Oracle contributes nothing the client lacks, and a + # client-only manifest leaves Qt6Sql.dll unasserted even though servatrice.exe + # is installed next to cockatrice.exe and cannot start without it. # # A statically linked Qt module ships no runtime DLL, so requiring one would # fail the package check on a static build for no reason. cockatrice/CMakeLists.txt # installs the runtime of every module listed here, and skips static ones the # same way, so the two can never disagree. # - # A DLL missing from the package only surfaces on a user's machine, after an - # update has already replaced their install, as "The code execution cannot - # proceed because Qt6Multimedia.dll was not found" or as a missing procedure - # entry point in a Qt6QuickWidgets.dll left over from the previous version. - # Assert it while the installer is still being built instead. - set(_required_qt_runtime "") - foreach(_qt_module IN LISTS COCKATRICE_QT_MODULES) + # Only the Qt modules, and that is deliberate. protobuf, Abseil, liblzma, zlib + # and OpenSSL also ride in on the "*.dll" glob, and a client whose runtime is + # absent, stale or of the wrong architecture fails to start with "abseil_dll.dll + # is either not designed to run on Windows or it contains an error", so they + # are exactly the files worth asserting. + # + # Their names cannot be derived from the vcpkg bin directory, which is what a + # first attempt did and what a Windows build immediately refuted: bin holds + # everything vcpkg installed, not everything the applications import. It also + # contains gmock.dll, libprotobuf-lite.dll, libprotoc.dll, legacy.dll and three + # pthreadVC*.dll FindThreads probes, none of which any shipped executable + # links, so requiring them failed a build over a package that was correct. + # + # Deriving them from the executables' own import tables is the real answer, + # and fixup_bundle already walks it to decide what to copy. Until that result + # is available to CMake, requiring the vcpkg half would mean guessing names + # again, which is what produced this bug report in the first place. So assert + # what is derived from the build's own link lists and leave the rest to the + # purge in cmake/NSIS.template.in, which removes every DLL regardless of name. + set(_required_runtime "") + foreach(_qt_module IN LISTS COCKATRICE_QT_MODULES SERVATRICE_QT_MODULES ORACLE_QT_MODULES) get_target_property(_qt_module_type ${_qt_module} TYPE) if(_qt_module_type STREQUAL "SHARED_LIBRARY") string(REGEX REPLACE "^Qt6::" "" _qt_component "${_qt_module}") - list(APPEND _required_qt_runtime "Qt6${_qt_component}.dll") + list(APPEND _required_runtime "Qt6${_qt_component}.dll") endif() endforeach() - list(APPEND _required_qt_runtime "Plugins/platforms/qwindows.dll") - list(REMOVE_DUPLICATES _required_qt_runtime) - list(SORT _required_qt_runtime) - string(REPLACE ";" "\n" _required_qt_runtime "${_required_qt_runtime}") - file(WRITE "${PROJECT_BINARY_DIR}/required-qt-runtime.txt" "${_required_qt_runtime}\n") + list(APPEND _required_runtime "Plugins/platforms/qwindows.dll") + + list(REMOVE_DUPLICATES _required_runtime) + list(SORT _required_runtime) + string(REPLACE ";" "\n" _required_runtime "${_required_runtime}") + file(WRITE "${PROJECT_BINARY_DIR}/required-runtime.txt" "${_required_runtime}\n") # include vcredist into the package; NSIS will take care of running it if(VCREDISTRUNTIME_FOUND) diff --git a/Doxyfile b/Doxyfile index d6f0af2d2..c12ff4a8a 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1066,25 +1066,11 @@ 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 \ - *.cxx \ - *.cxxm \ - *.cpp \ +FILE_PATTERNS = *.cpp \ *.cppm \ - *.ccm \ - *.c++ \ - *.c++m \ - *.ii \ - *.ixx \ *.ipp \ - *.i++ \ *.inl \ *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.markdown \ *.md \ *.dox \ *.proto @@ -2667,7 +2653,7 @@ DOT_NUM_THREADS = 0 # Minimum value: 1, maximum value: 1000, default value: 50. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_BATCH_SIZE = 500 +DOT_BATCH_SIZE = 50 # DOT_COMMON_ATTR is common attributes for nodes, edges and labels of # subgraphs. When you want a differently looking font in the dot files that diff --git a/README.md b/README.md index 5935bb540..f2a170868 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ There are various places where useful information for different needs are mainta - [Official Wiki](https://github.com/Cockatrice/Cockatrice/wiki) `Community supported` - [Official Webpage](https://cockatrice.github.io/) - [Official README](https://github.com/Cockatrice/Cockatrice/blob/master/README.md) `This file` +- [Official CONTRIBUTING](https://github.com/Cockatrice/Cockatrice/blob/master/.github/CONTRIBUTING.md) Cockatrice tries to use the [Google Developer Documentation Style Guide](https://developers.google.com/style/) to ensure consistent documentation. We encourage you to improve the documentation by suggesting edits based on this guide. @@ -159,6 +160,12 @@ The following flags (with their non-default values) can be passed to `cmake`: | `-DUPDATE_TRANSLATIONS=1` | Configure `make` to update the translation .ts files for new strings in the source code
**Note:** `make clean` will remove the .ts files | | `-DTEST=1` | Enable regression tests
**Note:** `make test` to run tests, *googletest* will be downloaded if not available | +> [!TIP] +> Build code documentation ([Doxygen](https://www.doxygen.nl)) according to our [configuration](https://github.com/Cockatrice/Cockatrice/blob/master/Doxyfile) into `/docs`: +> ```bash +> doxygen Doxyfile +> ``` + # Run diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake new file mode 100644 index 000000000..0345a2d36 --- /dev/null +++ b/cmake/Coverage.cmake @@ -0,0 +1,75 @@ +# Line-coverage instrumentation opt-in, plus per-source opt-out +# Input: ENABLE_COVERAGE +# Defines: cockatrice_disable_coverage_for +# +# Included once from the root CMakeLists.txt, immediately after the per-compiler flag +# block, so add_compile_options() reaches every library and executable defined below. +# +# Note the name deliberately shadows CMake's own built-in Modules/Coverage.cmake. It resolves +# to this file only because the root CMakeLists.txt puts cmake/ at the front of +# CMAKE_MODULE_PATH; if that ever moves, include(Coverage) would silently pick up the built-in +# module, which only defines a `COVERAGE` custom target and touches no global flags, so +# instrumentation would quietly stop happening rather than erroring. + +include(CheckCXXSourceCompiles) + +# Opt a set of vendored sources out of instrumentation. +# +# cockatrice_disable_coverage_for( ...) +# +# Third-party code drags the total down with lines no test can ever reach, and a total that +# cannot move is not a useful signal. This is the same carve-out the sanitizer build uses. +# +# The sources must be named relative to the directory that compiles them. CMake resolves a +# source-file property against the directory scope the target was declared in, so calling +# this from the root with absolute paths silently does nothing. That is why the call sites +# live next to the add_library/add_executable that pull the vendored code in. +# +# SKIP_PRECOMPILE_HEADERS mirrors the sanitizer helper. The precompiled header carries the +# instrumentation flags, and mixing an instrumented PCH with an uninstrumented translation +# unit makes GCC reject it. +function(cockatrice_disable_coverage_for) + if(NOT ENABLE_COVERAGE) + return() + endif() + # There is no -fno-coverage: --coverage is shorthand for -fprofile-arcs -ftest-coverage, so both + # halves have to be negated. CC rejects "-fno-coverage" outright, which is how the vendored C + # files below hit it first. + set_source_files_properties( + ${ARGN} PROPERTIES COMPILE_OPTIONS "-fno-profile-arcs;-fno-test-coverage" SKIP_PRECOMPILE_HEADERS ON + ) +endfunction() + +if(ENABLE_COVERAGE) + # Line coverage needs the compiler's own toolchain, so only GCC is supported. Clang's + # equivalent is llvm-cov, which reads a different intermediate format and would need a + # separate report path; rejecting it is better than emitting .gcno files that gcovr cannot + # read. + if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + message(FATAL_ERROR "ENABLE_COVERAGE requires GCC, but the compiler is ${CMAKE_CXX_COMPILER_ID}. " + "Clang coverage needs llvm-cov and is not wired up." + ) + endif() + + # Probe the way the flag will actually be used: compile AND link. A .gcno file comes from the + # compile step, but the runtime that writes .gcda files comes from the link step, so probing + # only the compile step would pass on a toolchain that cannot actually produce coverage. + set(_cockatrice_saved_required_flags "${CMAKE_REQUIRED_FLAGS}") + set(_cockatrice_saved_required_link_options "${CMAKE_REQUIRED_LINK_OPTIONS}") + set(CMAKE_REQUIRED_FLAGS "-O0 -g") + set(CMAKE_REQUIRED_LINK_OPTIONS -fprofile-arcs -ftest-coverage) + check_cxx_source_compiles("int main() { return 0; }" COCKATRICE_HAVE_COVERAGE_FLAGS) + set(CMAKE_REQUIRED_FLAGS "${_cockatrice_saved_required_flags}") + set(CMAKE_REQUIRED_LINK_OPTIONS "${_cockatrice_saved_required_link_options}") + + if(NOT COCKATRICE_HAVE_COVERAGE_FLAGS) + message(FATAL_ERROR "ENABLE_COVERAGE is on, but this toolchain rejected the coverage flags.") + endif() + + # -O0 keeps the line mapping honest: at higher optimisation levels the compiler merges and + # relocates lines, and the report describes code that no longer exists in that form. + add_compile_options(--coverage -O0 -g) + add_link_options(--coverage) + + message(STATUS "Coverage instrumentation enabled (--coverage). Report with gcovr over the build dir.") +endif() diff --git a/cmake/FindQtRuntime.cmake b/cmake/FindQtRuntime.cmake index 971c9094d..2d74aca4d 100644 --- a/cmake/FindQtRuntime.cmake +++ b/cmake/FindQtRuntime.cmake @@ -7,6 +7,12 @@ # Output: ORACLE_QT_MODULES # Output: TEST_QT_MODULES +# Every Qt module an application links against, as the DLL names a Windows +# install has to contain. Core is listed explicitly rather than left to arrive +# transitively: it is the one module nothing can do without, and required-runtime.txt +# is built from these lists, so a module missing here is a runtime the package +# check never asserts. That is how Qt6Core.dll went unasserted while every other +# Qt module was checked. set(REQUIRED_QT_COMPONENTS Core) if(WITH_SERVER) set(_SERVATRICE_NEEDED Network Sql WebSockets) @@ -14,6 +20,7 @@ endif() if(WITH_CLIENT) set(_COCKATRICE_NEEDED Concurrent + Core Gui Multimedia Network @@ -33,7 +40,9 @@ endif() if(TEST) # Union of Qt modules required across all test targets (independent of application targets). # When adding a new test that needs additional Qt modules, add them here rather than in the test's CMakeLists.txt. - set(_TEST_NEEDED Concurrent Network Svg Widgets) + # Test is QtTest: it brings QAbstractItemModelTester and QSignalSpy, which are how the Qt model + # and signal contracts get verified without standing up a GUI. + set(_TEST_NEEDED Concurrent Network Svg Widgets Test) endif() set(REQUIRED_QT_COMPONENTS ${REQUIRED_QT_COMPONENTS} ${_SERVATRICE_NEEDED} ${_COCKATRICE_NEEDED} ${_ORACLE_NEEDED} diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index 597667e9d..b6125238f 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -21,6 +21,13 @@ Var IsUpgrade Var AbortReason Var WaitPid Var LauncherExited +Var InstallLogPath +Var LogHandle +Var LogMessage +Var LogFindHandle +Var LogFindName +Var LogMatchLabel +Var LogMatchPattern !include LogicLib.nsh !include FileFunc.nsh @@ -64,8 +71,67 @@ Page Custom PortableModePageCreate PortableModePageLeave !insertmacro MUI_LANGUAGE English +; Installer log +; Every run appends a step-by-step trace to a file so a failed upgrade on a +; user's machine can be diagnosed after the fact. Kept in $TEMP rather than in +; $INSTDIR because the previous version's uninstaller removes the whole install +; directory part-way through an upgrade. Read it back with: +; notepad %TEMP%\Cockatrice-installer.log +!macro CockLog text + Push "${text}" + Call CockLogWrite +!macroend + +Function CockLogWrite + Pop $LogMessage + FileOpen $LogHandle "$InstallLogPath" a + ${If} $LogHandle == "" + Return + ${EndIf} + ; FileOpen places the pointer at the start of the file in every mode, so + ; 'a' alone would overwrite the log from the beginning on each line. Seek + ; past the existing content first to actually append. + FileSeek $LogHandle 0 END + FileWrite $LogHandle "$LogMessage$\r$\n" + FileClose $LogHandle +FunctionEnd + +; Logs every file matching $INSTDIR\. Used to record the DLL inventory +; before and after the upgrade purge, which is what shows whether Qt6Gui.dll was +; on disk and what (if anything) survived the deletes. +!macro CockLogListing label mask + Push "${label}" + Push "$INSTDIR\${mask}" + Call CockLogListing +!macroend + +Function CockLogListing + Pop $LogMatchPattern + Pop $LogMatchLabel + !insertmacro CockLog "listing [$LogMatchLabel] pattern=$LogMatchPattern" + FindFirst $LogFindHandle $LogFindName "$LogMatchPattern" + ${If} $LogFindHandle == "" + !insertmacro CockLog "listing [$LogMatchLabel] (no matches)" + Return + ${EndIf} + log_listing_loop: + !insertmacro CockLog "listing [$LogMatchLabel] $LogFindName" + ClearErrors + FindNext $LogFindHandle $LogFindName + IfErrors 0 log_listing_loop + FindClose $LogFindHandle +FunctionEnd + Function .onInit +StrCpy $InstallLogPath "$TEMP\Cockatrice-installer.log" +; Start each run from a clean file so the log that gets sent back is the last +; run, not every past run glued together. +FileOpen $LogHandle "$InstallLogPath" w +FileClose $LogHandle +!insertmacro CockLog "==================================================================" +!insertmacro CockLog "installer start: @CPACK_PACKAGE_NAME@ @CPACK_PACKAGE_VERSION@" + ${If} ${NSIS_IS_64_BIT} == 1 #NSIS 64bit ${IfNot} ${RunningX64} MessageBox MB_OK|MB_ICONSTOP "This version of Cockatrice requires a 64-bit Windows system." @@ -158,6 +224,13 @@ ${EndIf} ; Now that $PortableMode reflects reality, commit InstDir into the correct slot Call SetModeDestinationFromInstdir +!insertmacro CockLog "options: InstDir=$InstDir PortableMode=$PortableMode ReinstallMode=$ReinstallMode WaitPid=$WaitPid" +${If} ${Silent} + !insertmacro CockLog "options: running silently" +${Else} + !insertmacro CockLog "options: interactive" +${EndIf} + ; Wait for the process that launched this installer to exit before anything is ; replaced or deleted. It goes first because it is the one check here that needs ; no powershell.exe: on a machine where the process lookup cannot run at all, the @@ -175,12 +248,14 @@ Call SetModeDestinationFromInstdir ; interactive installs the section re-checks after the directory page, when ; $INSTDIR is the directory the user actually picked. ${If} $ReinstallMode = 1 + !insertmacro CockLog "reinstall: waiting for launcher and other instances" Call WaitForLauncherToExit Call EnsureAppsNotRunning ${EndIf} ${If} $ReinstallMode = 1 ${AndIf} $PortableMode = 0 + !insertmacro CockLog "reinstall: auto-uninstalling previous version" Call AutoUninstallIfNeeded ${EndIf} @@ -226,13 +301,23 @@ Function AutoUninstallIfNeeded SetShellVarContext all +; _?=$INSTDIR keeps the old uninstaller running in place. An NSIS uninstaller +; normally copies itself to %TEMP% and runs from there so that it can delete its +; own directory, and the process we started exits at once. ExecWait then returns +; before the uninstall has run, and the temp copy keeps deleting files - from +; 3.1.0 and 3.1.1 on disk a blanket "RMDir /r $INSTDIR" - while the section +; below is still writing the new payload. _?= disables the copy and makes +; ExecWait block until the uninstall finishes. It must be the last argument +; and must not be quoted, even when the path contains spaces. +; ; --- 32-bit uninstall --- SetRegView 32 ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "QuietUninstallString" +!insertmacro CockLog "uninstall (32-bit): '$R0 _?=$INSTDIR'" StrCmp $R0 "" done32 DetailPrint "Removing previous version (32-bit)..." -ExecWait '$R0' +ExecWait '$R0 _?=$INSTDIR' done32: @@ -241,9 +326,10 @@ ${If} ${RunningX64} SetRegView 64 ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "QuietUninstallString" + !insertmacro CockLog "uninstall (64-bit): '$R0 _?=$INSTDIR'" StrCmp $R0 "" done64 DetailPrint "Removing previous version (64-bit)..." - ExecWait '$R0' + ExecWait '$R0 _?=$INSTDIR' done64: ${EndIf} @@ -360,6 +446,7 @@ Function WaitForAppToClose ; usage: set $R1 to the display name (e.g. "cockatrice.exe") and $R2 to the ; base image name (e.g. "cockatrice") Call IsAppRunning + !insertmacro CockLog "guard $R1: state=$R0 (dir=$GuardDir)" ; Only a definite "running" is worth waiting for. "Not running" is done, and ; "could not determine" must not keep the installer waiting on an answer it ; will never get - but it cannot simply be waved through either, see @@ -384,6 +471,7 @@ Function WaitForAppToClose Sleep 500 Call IsAppRunning ${If} $R0 = 0 + !insertmacro CockLog "guard $R1: closed gracefully" DetailPrint "$R1 closed." Return ${EndIf} @@ -402,6 +490,7 @@ Function WaitForAppToClose ; deck, and nothing has been replaced yet, so aborting just defers the ; update and preserves the user's data. ${If} $AllowForceClose = 0 + !insertmacro CockLog "guard $R1: still running after 60s, aborting (no force close)" DetailPrint "$R1 is still running after 60 s; aborting the update so that no data is lost." StrCpy $AbortReason \ "$R1 did not close within 60 seconds, so the installation was aborted to avoid losing unsaved data.$\r$\n$\r$\nPlease close $R1 and run the installer again." @@ -410,11 +499,13 @@ Function WaitForAppToClose ; Oracle and Servatrice are console applications: CloseMainWindow() ; returned false for them and waiting longer cannot help. They hold no ; unsaved user data, so stop them by PID. + !insertmacro CockLog "guard $R1: still running after 60s, force-stopping" DetailPrint "Force-stopping $R1 ..." Call ForceCloseApps Sleep 2000 Call IsAppRunning ${If} $R0 = 0 + !insertmacro CockLog "guard $R1: force-stopped" DetailPrint "$R1 closed." Return ${EndIf} @@ -422,6 +513,7 @@ Function WaitForAppToClose Call HandleUnknownAppState Return ${EndIf} + !insertmacro CockLog "guard $R1: could not be stopped, aborting" DetailPrint "$R1 is still running after 60 s; aborting the update." StrCpy $AbortReason \ "$R1 could not be stopped, so the installation was aborted.$\r$\n$\r$\nPlease close $R1 and run the installer again." @@ -486,8 +578,16 @@ FunctionEnd ; Only the first of those two gets a dialog; the second reports through the log ; and the exit code. Function AbortInstall - ${IfNot} ${Silent} - MessageBox MB_OK|MB_ICONEXCLAMATION "$AbortReason" + !insertmacro CockLog "ABORT: $AbortReason" + !insertmacro CockLog "full installer log: $InstallLogPath" + ; Show a dialog whenever someone is at the keyboard to see it: an interactive + ; install, or the in-app updater's /R upgrade. The /R upgrade is silent, but + ; the client that launched the installer has already quit, so the user is + ; still there. Only a /S install without /R is attended by a package manager + ; and must go straight to the exit code. + ${If} $ReinstallMode = 1 + ${OrIfNot} ${Silent} + MessageBox MB_OK|MB_ICONEXCLAMATION "$AbortReason$\r$\n$\r$\nA detailed installer log was written to:$\r$\n$InstallLogPath" ${EndIf} SetErrorLevel 1 Abort @@ -510,17 +610,33 @@ FunctionEnd ; falls back to the name based guard. Function WaitForLauncherToExit StrCpy $LauncherExited 0 + !insertmacro CockLog "wait-launcher: pid='$WaitPid'" ${If} $WaitPid == "" + !insertmacro CockLog "wait-launcher: no pid given, falling back to name check" Return ${EndIf} ; PROCESS_SYNCHRONIZE is the only access this needs - enough to wait on the ; handle, and the least likely to be refused for a reason that has nothing to ; do with the upgrade. + ; + ; System.dll maps its output registers so that .rN writes $N and .RN writes + ; $RN. The caller reads $R0/$R1, so the uppercase .RN form is required; the + ; original .r0/.r1 wrote $0/$1 and left $R1 empty, which made the "did not + ; exit" test below compare "" against "0" and abort on every /PID= upgrade. ClearErrors - System::Call 'kernel32::OpenProcess(i 0x00100000, i 0, i $WaitPid) p.r0' + System::Call 'kernel32::OpenProcess(i 0x00100000, i 0, i $WaitPid) p.R0' + ; OpenProcess returns a null handle for a process that is already gone. The + ; System plugin does not raise the NSIS error flag from a called function's + ; return value, so ${Errors} alone never saw that case and the null handle was + ; passed straight to WaitForSingleObject. Fold a plugin failure into the same + ; null-handle case instead of reading a handle that was never written. ${If} ${Errors} + StrCpy $R0 0 + ${EndIf} + ${If} $R0 == 0 ; The launcher is gone - OpenProcess cannot open a dead process - which is ; exactly the state the wait was for. + !insertmacro CockLog "wait-launcher: already exited" DetailPrint "The application that started this installer has already exited." StrCpy $LauncherExited 1 Return @@ -529,14 +645,16 @@ Function WaitForLauncherToExit ; Same 60 s grace period the name based check uses, so a client that is slow ; to flush its card database does not get less room than it used to. ; WAIT_OBJECT_0 is 0; WAIT_TIMEOUT is 258 and a failed wait reports 0xFFFFFFFF. - System::Call 'kernel32::WaitForSingleObject(p r0, i 60000) i.r1' - System::Call 'kernel32::CloseHandle(p r0)' + System::Call 'kernel32::WaitForSingleObject(p R0, i 60000) i.R1' + System::Call 'kernel32::CloseHandle(p R0)' ${If} $R1 != 0 + !insertmacro CockLog "wait-launcher: did not exit within 60s (wait=$R1)" DetailPrint "The application that started this installer did not exit within 60 s." StrCpy $AbortReason \ "The application that started this update has not exited yet, so the installation was cancelled rather than replace files it is still using.$\r$\n$\r$\nPlease close Cockatrice and run the installer again." Call AbortInstall ${EndIf} + !insertmacro CockLog "wait-launcher: launcher exited" DetailPrint "The application that started this installer has exited." StrCpy $LauncherExited 1 FunctionEnd @@ -562,9 +680,11 @@ FunctionEnd Function GuardAppsNotRunning ; usage: set $GuardDir to the directory to guard, then call this Call IsProcessLookupAvailable + !insertmacro CockLog "guard: powershell available=$R0 dir=$GuardDir launcherExited=$LauncherExited" ${If} $R0 = 0 ; Without PowerShell we cannot tell whether a running instance is ; holding locks on the files we are about to replace. + !insertmacro CockLog "guard: powershell unavailable, skipping instance check" DetailPrint "Could not start powershell.exe; skipping the running instance check. Close Cockatrice, Oracle and Servatrice manually if the installation reports a problem." ; On a silent upgrade that used to be a warning and nothing more, which ; left the very process that launched the installer free to go on @@ -587,7 +707,8 @@ Function GuardAppsNotRunning ${EndIf} ; The user has to be told to close the applications by hand, but a /S ; install without /R is unattended and would block on this forever. - ${IfNot} ${Silent} + ${If} $ReinstallMode = 1 + ${OrIfNot} ${Silent} MessageBox MB_OK|MB_ICONEXCLAMATION "This installer could not check whether Cockatrice is still running, because powershell.exe could not be started.$\r$\n$\r$\nPlease close Cockatrice, Oracle and Servatrice manually before continuing." ${EndIf} Return @@ -633,7 +754,11 @@ Function IsExistingCockatriceInstall ; there to prove that it is one. Every Qt module Cockatrice links is part of ; the payload, so match them all: probing only Qt6Core.dll would miss a ; directory where that one file happened to be deletable and the others - ; were not. + ; were not. Qt6*.dll rather than *.dll on purpose: this function decides + ; whether a directory is ours, and a folder that merely holds some DLLs of + ; its own must not be purged. Qt6*.dll is enough even when only the protobuf + ; runtime survived, because the whole Qt set is mapped by the same process + ; that maps abseil_dll.dll and so is locked or free with it. StrCpy $R3 "Qt6*.dll" Call CheckStaleRuntimeMask ${If} ${FileExists} "$INSTDIR\qt.conf" @@ -645,36 +770,23 @@ FunctionEnd ; the purge. NSIS silently skips whatever it cannot delete, so one surviving file ; is enough to prove that something still holds a lock on the install directory. ; -; The masks below have to cover the purge above one for one. A check that only -; probed named files could not see a locked Qt6Multimedia.dll or a Plugins -; directory the purge was unable to remove, so the exact files that broke the -; install were also the ones this check was blind to. +; Any DLL at all counts, not a list of expected ones. The purge removes every +; top-level DLL, so after it has run the only DLL that can still be there is one +; it failed to delete, whatever its name. A mask per library family (Qt, then +; OpenSSL, then zlib) is what let abseil_dll.dll through: it is in neither the +; purge nor this check, so it survived a 3.0.2 to 3.1 update untouched, the new +; executables were written next to it, and the client then failed to start with +; "abseil_dll.dll is either not designed to run on Windows or it contains an +; error". Probing *.dll has no list to fall out of date when the next +; transitive dependency appears. Function HasStaleRuntimeFiles StrCpy $R0 0 - StrCpy $R3 "Qt*.dll" + StrCpy $R3 "*.dll" Call CheckStaleRuntimeMask - StrCpy $R3 "libcrypto*.dll" - Call CheckStaleRuntimeMask - StrCpy $R3 "libssl*.dll" - Call CheckStaleRuntimeMask - StrCpy $R3 "zlib*.dll" - Call CheckStaleRuntimeMask - StrCpy $R3 "icu*.dll" - Call CheckStaleRuntimeMask - StrCpy $R3 "libeay32.dll" - Call CheckStaleRuntimeMask - StrCpy $R3 "ssleay32.dll" - Call CheckStaleRuntimeMask - ${If} $R0 = 1 - Return - ${EndIf} - ${If} ${FileExists} "$INSTDIR\libmysql.dll" - StrCpy $R0 1 - Return - ${EndIf} ; IfFileExists takes wildcards, so a Plugins directory the purge could not ; remove counts as a leftover too. ${If} ${FileExists} "$INSTDIR\Plugins\*.*" + !insertmacro CockLog "stale-runtime: Plugins directory survived the purge" StrCpy $R0 1 ${EndIf} FunctionEnd @@ -687,6 +799,7 @@ Function CheckStaleRuntimeMask ${EndIf} FindFirst $StaleFindHandle $StaleFindName "$INSTDIR\$R3" ${If} $StaleFindHandle != "" + !insertmacro CockLog "stale-runtime: '$StaleFindName' matched $R3 in $INSTDIR" StrCpy $R0 1 FindClose $StaleFindHandle ${EndIf} @@ -925,9 +1038,10 @@ ${If} $PortableMode = 0 ; directory before letting it delete anything. The uninstall string is ; stashed away first, the check works on $R0. StrCpy $OldUninstallString $R0 + !insertmacro CockLog "componentsPagePre: old 32-bit uninstall '$OldUninstallString _?=$INSTDIR'" Call EnsureOldInstallNotRunning ClearErrors - ExecWait "$OldUninstallString" + ExecWait "$OldUninstallString _?=$INSTDIR" done32: @@ -947,9 +1061,10 @@ ${If} $PortableMode = 0 uninst64: StrCpy $OldUninstallString $R0 + !insertmacro CockLog "componentsPagePre: old 64-bit uninstall '$OldUninstallString _?=$INSTDIR'" Call EnsureOldInstallNotRunning ClearErrors - ExecWait "$OldUninstallString" + ExecWait "$OldUninstallString _?=$INSTDIR" done64: ${EndIf} @@ -964,15 +1079,19 @@ Section "Application" SecApplication SetShellVarContext all SetOutPath "$INSTDIR" +!insertmacro CockLog "section: InstDir=$INSTDIR PortableMode=$PortableMode ReinstallMode=$ReinstallMode" + ; No application instance may be running while any file below is deleted or ; replaced: both upgrade blocks start by removing the old executables and ; runtime DLLs, and NSIS silently skips whatever is locked, which is how an -; install ends up with a mix of old and new Qt DLLs next to the new executable -; ("The procedure entry point X could not be located in the dynamic link -; library ...Qt6Network.dll"). So the check has to come before the first -; Delete/RMDir and not after it - an interactive install into an existing -; portable directory with cockatrice.exe still running would otherwise delete -; the old files under its feet. +; install ends up with a mix of old and new runtimes next to the new executable. +; The next start then fails with "The procedure entry point X could not be +; located in the dynamic link library ...Qt6Network.dll" for the Qt ones, or +; "abseil_dll.dll is either not designed to run on Windows or it contains an +; error" for the protobuf ones. So the check has to come before the first +; Delete/RMDir and not after it: an interactive install into an existing portable +; directory with cockatrice.exe still running would otherwise delete the old +; files under its feet. ; ; It is skipped on the /R path: .onInit already ran it before ; AutoUninstallIfNeeded removed the previous installation, so by the time this @@ -987,32 +1106,39 @@ ${EndIf} ${If} $PortableMode = 1 ${AndIf} ${FileExists} "$INSTDIR\portable.dat" ; upgrade portable mode + !insertmacro CockLog "section: portable upgrade purge" + !insertmacro CockLogListing "before-portable-purge" "*.dll" + ; plugins and translations are payload and are rewritten by the payload + ; below, so removing them here is safe. sounds and themes are payload + ; too - the default packs are rewritten below as well - but a portable + ; user's custom sounds and themes live in exactly those folders, so a + ; recursive purge here would delete user content along with the defaults. + ; Stale default files from an older release are overwritten or replaced + ; by the payload, never by a purge. RMDir /r "$INSTDIR\plugins" - RMDir /r "$INSTDIR\sounds" - RMDir /r "$INSTDIR\themes" RMDir /r "$INSTDIR\translations" Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\cockatrice.exe" Delete "$INSTDIR\oracle.exe" Delete "$INSTDIR\servatrice.exe" - Delete "$INSTDIR\Qt*.dll" - Delete "$INSTDIR\libmysql.dll" - Delete "$INSTDIR\icu*.dll" - Delete "$INSTDIR\libcrypto*.dll" - Delete "$INSTDIR\libssl*.dll" - Delete "$INSTDIR\libeay32.dll" - Delete "$INSTDIR\ssleay32.dll" + ; Every top-level DLL, not a list of expected ones. The payload is written + ; after this block, so a DLL the new build still needs is put straight back; + ; what this has to guarantee is that nothing from the previous build is left + ; to be loaded next to the new executables. Naming the families by hand is + ; what let abseil_dll.dll through; see HasStaleRuntimeFiles. + Delete "$INSTDIR\*.dll" Delete "$INSTDIR\qt.conf" Delete "$INSTDIR\qdebug.txt" Delete "$INSTDIR\servatrice.sql" Delete "$INSTDIR\servatrice.ini.example" - Delete "$INSTDIR\zlib*.dll" RMDir "$INSTDIR" + !insertmacro CockLogListing "after-portable-purge" "*.dll" ${EndIf} ; Remove any runtime DLLs left over from older versions, so a mismatched -; Qt/OpenSSL set cannot survive next to the new executables. +; Qt/OpenSSL/protobuf set cannot survive next to the new executables. Call IsExistingCockatriceInstall +!insertmacro CockLog "section: IsExistingCockatriceInstall=$R0" ; Remembered because the stale-runtime check below must only ever fire for a ; directory this installer recognised as a Cockatrice install. Scanning for ; leftovers in an unrelated directory (a first-time install into a folder that @@ -1021,48 +1147,48 @@ Call IsExistingCockatriceInstall StrCpy $IsUpgrade $R0 ${If} $PortableMode = 0 ${AndIf} $R0 = 1 + !insertmacro CockLog "section: non-portable upgrade purge" + !insertmacro CockLogListing "before-purge" "*.dll" RMDir /r "$INSTDIR\Plugins" - Delete "$INSTDIR\Qt*.dll" - Delete "$INSTDIR\libcrypto*.dll" - Delete "$INSTDIR\libssl*.dll" - Delete "$INSTDIR\zlib*.dll" - Delete "$INSTDIR\libmysql.dll" - Delete "$INSTDIR\icu*.dll" - Delete "$INSTDIR\libeay32.dll" - Delete "$INSTDIR\ssleay32.dll" + Delete "$INSTDIR\*.dll" + !insertmacro CockLogListing "after-purge" "*.dll" + !insertmacro CockLogListing "after-plugins" "Plugins\*.*" ${EndIf} -; Whatever was locked during the purge - by an instance that started while the +; Whatever was locked during the purge (by an instance that started while the ; installer was running, or because the running instance check could not be -; performed at all - is still on disk, and the new executables are about to be +; performed at all) is still on disk, and the new executables are about to be ; written next to it. That mix is exactly what makes the next start fail with ; "The procedure entry point X could not be located in the dynamic link library -; ...Qt6QuickWidgets.dll" or "The code execution cannot proceed because -; Qt6Multimedia.dll was not found", so stop here instead of compounding it. -; Nothing of the new payload has been written at this point, so the next run - -; with the applications closed - gets a clean install. +; ...Qt6QuickWidgets.dll", "The code execution cannot proceed because +; Qt6Multimedia.dll was not found", or "abseil_dll.dll is either not designed to +; run on Windows or it contains an error", so stop here instead of compounding +; it. Nothing of the new payload has been written at this point, so the next run, +; with the applications closed, gets a clean install. ${If} $IsUpgrade = 1 Call HasStaleRuntimeFiles + !insertmacro CockLog "section: HasStaleRuntimeFiles=$R0" ${Else} StrCpy $R0 0 ${EndIf} ${If} $R0 = 1 + !insertmacro CockLog "section: aborting, files of a previous version survived the purge" DetailPrint "Files of a previous version could not be removed; aborting the installation." ; The in-app updater runs this installer silent and detached and never looks ; at its exit code, so the user has to be told what happened. A /S install - ; without /R is unattended - a package manager, for instance - and a message + ; without /R is unattended (a package manager, for instance) and a message ; box there would block forever, so that case only reports through the log - ; and the exit code. - ${IfNot} ${Silent} - MessageBox MB_OK|MB_ICONEXCLAMATION \ - "The installation could not remove all files of a previous version of Cockatrice, most likely because it is still running or was started as administrator, and was cancelled rather than leave a mismatched install behind.$\r$\n$\r$\nPlease close Cockatrice, Oracle and Servatrice and run the installer again." - ${EndIf} - SetErrorLevel 1 - Abort + ; and the exit code. AbortInstall owns that decision. + StrCpy $AbortReason \ + "The installation could not remove all files of a previous version of Cockatrice, most likely because it is still running or was started as administrator, and was cancelled rather than leave a mismatched install behind.$\r$\n$\r$\nPlease close Cockatrice, Oracle and Servatrice and run the installer again." + Call AbortInstall ${EndIf} @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ +!insertmacro CockLog "section: writing payload to $INSTDIR" @CPACK_NSIS_FULL_INSTALL@ +!insertmacro CockLog "section: payload written" +!insertmacro CockLogListing "final" "Qt6*.dll" ${If} $PortableMode = 0 WriteUninstaller "$INSTDIR\uninstall.exe" @@ -1126,6 +1252,7 @@ ${If} $ReinstallMode = 1 Exec '"$INSTDIR\cockatrice.exe"' ${EndIf} +!insertmacro CockLog "section: application install complete" SectionEnd Section "Start menu item" SecStartMenu @@ -1142,16 +1269,32 @@ Section "un.Application" UnSecApplication SetShellVarContext all StrCpy $R1 0 - ; Record whether this was a portable install before the directory (and the - ; portable.dat marker inside it) is removed below. + ; Record whether this was a portable install before portable.dat is + ; removed below. IfFileExists "$INSTDIR\portable.dat" 0 +2 StrCpy $R1 1 - ; Remove the entire application directory so any file that is not part of - ; the installed payload (e.g. build-tree artifacts such as *.dir folders, - ; *_autogen and *.tlog files from a build) cannot survive between an - ; uninstall and a fresh reinstall. - RMDir /r "$INSTDIR" + ; Remove only what the installer wrote. The two lists below are generated + ; by CPack from the staged install tree: one Delete per installed file and + ; one non-recursive RMDir per installed directory, children first. + ; Anything the user put in $INSTDIR - decks, pictures, portable data + ; folders - is not on those lists and survives, and $INSTDIR itself is + ; only removed when nothing else is left in it. An earlier version of this + ; section ran a blanket "RMDir /r $INSTDIR" to keep build-tree artifacts + ; out of a fresh reinstall; that also deleted user decks whenever a user + ; had pointed their data folders into the install directory, so payload + ; purity may never be bought at that price again. +@CPACK_NSIS_DELETE_FILES@ +@CPACK_NSIS_DELETE_DIRECTORIES@ + + ; Written by the installer itself, so absent from the staged payload + ; above; qdebug.txt is app-generated log output next to the executables. + Delete "$INSTDIR\uninstall.exe" + Delete "$INSTDIR\portable.dat" + Delete "$INSTDIR\qdebug.txt" + + ; Succeeds only when no foreign files remain. + RMDir "$INSTDIR" RMDir /r "$SMPROGRAMS\Cockatrice" diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake new file mode 100644 index 000000000..2e5d794de --- /dev/null +++ b/cmake/Sanitizers.cmake @@ -0,0 +1,109 @@ +# AddressSanitizer + UndefinedBehaviorSanitizer opt-in, plus per-source opt-out +# Input: ENABLE_SANITIZERS +# Defines: cockatrice_disable_sanitizers_for +# +# Included once from the root CMakeLists.txt, immediately after the per-compiler flag +# block, so add_compile_options() reaches every library and executable defined below. + +include(CheckCXXSourceCompiles) + +# Opt a set of vendored sources out of instrumentation. +# +# cockatrice_disable_sanitizers_for( ...) +# +# Sanitizer findings inside vendored code are not actionable for us, and letting them +# through buries our own bugs in noise until everyone learns to skip the job. +# +# The sources must be named relative to the directory that compiles them. CMake resolves a +# source-file property against the directory scope the target was declared in, so calling +# this from the root with absolute paths silently does nothing. That is why the call sites +# live next to the add_library/add_executable that pull the vendored code in. +# +# SKIP_PRECOMPILE_HEADERS is not optional. The precompiled header is built with the +# sanitizer flags, so it defines __SANITIZE_ADDRESS__; a translation unit compiled with +# -fno-sanitize=all does not, and GCC then refuses the PCH with +# "not used because __SANITIZE_ADDRESS__ not defined", which is a fatal -Werror=invalid-pch +# in the servatrice and oracle builds. +function(cockatrice_disable_sanitizers_for) + if(NOT ENABLE_SANITIZERS) + return() + endif() + set_source_files_properties(${ARGN} PROPERTIES COMPILE_OPTIONS "-fno-sanitize=all" SKIP_PRECOMPILE_HEADERS ON) +endfunction() + +if(ENABLE_SANITIZERS) + # Probe a flag the way it will actually be used: on the compile step AND the link step. + # check_cxx_compiler_flag() only probes the compile step, which makes every sanitizer + # flag look unsupported because linking an ASan object without -fsanitize=address leaves + # __asan_init undefined. That is a silent misconfiguration rather than an error, so the + # probe has to link. + function(cockatrice_probe_flag FLAG VARNAME) + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + set(CMAKE_REQUIRED_LINK_OPTIONS "${FLAG}") + check_cxx_source_compiles("int main() { return 0; }" ${VARNAME}) + unset(CMAKE_REQUIRED_FLAGS) + unset(CMAKE_REQUIRED_LINK_OPTIONS) + endfunction() + + set(SANITIZER_FLAGS + -fsanitize=address,undefined + -fno-omit-frame-pointer + # UBSan defaults to recover mode: it prints "runtime error: ..." but the + # process exits 0, so gtest/ctest report a pass and CI stays green. + # -fno-sanitize-recover makes the first finding abort instead. This is + # probed like the other cosmetic flags, but CI also sets + # UBSAN_OPTIONS=halt_on_error=1 as the runtime-side guarantee. + -fno-sanitize-recover=undefined + # Qt builds QObject subclasses into raw storage and writes the vptr afterwards, which + # the vptr check reports on essentially every QObject instantiation. The check has no + # value for us because nothing outside moc-generated code inherits QObject, so it is + # off outright rather than suppressed piecemeal. + -fno-sanitize=vptr + ) + + # MSVC has no ASan/UBSan equivalent, and clang-cl would need /fsanitize=address plus a + # matching runtime link, which is a separate piece of work. + if(MSVC) + message(FATAL_ERROR "ENABLE_SANITIZERS is not supported with MSVC") + endif() + + # Probe rather than assume, so an older toolchain gets the sanitizers it can support + # instead of failing the build on a flag it does not recognize. + set(SANITIZER_SUPPORTED_FLAGS) + foreach(FLAG ${SANITIZER_FLAGS}) + string(MAKE_C_IDENTIFIER "COCKATRICE_HAS${FLAG}" _FLAG_VAR) + cockatrice_probe_flag("${FLAG}" ${_FLAG_VAR}) + if(${_FLAG_VAR}) + list(APPEND SANITIZER_SUPPORTED_FLAGS ${FLAG}) + else() + message(STATUS "Sanitizers: ${FLAG} unsupported by ${CMAKE_CXX_COMPILER_ID}, skipping") + endif() + endforeach() + + # The whole point of the option is the sanitizers, so an unsupported pair is fatal even + # though the cosmetic flags above are allowed to degrade. + if(NOT "-fsanitize=address,undefined" IN_LIST SANITIZER_SUPPORTED_FLAGS) + message(FATAL_ERROR "ENABLE_SANITIZERS requires -fsanitize=address,undefined, which " + "${CMAKE_CXX_COMPILER_ID} does not accept" + ) + endif() + + add_compile_options(${SANITIZER_SUPPORTED_FLAGS}) + add_link_options(-fsanitize=address,undefined) + + # Recorded so the test tree can label its entries and a plain `make` at the same time + # cannot quietly disagree with what CI ran. + set(COCKATRICE_SANITIZERS + ON + CACHE INTERNAL "AddressSanitizer and UBSan are enabled" + ) +else() + # ENABLE_SANITIZERS is OFF, but COCKATRICE_SANITIZERS is CACHE INTERNAL, so a + # reused build dir (e.g. CI's release-package step reconfiguring the same dir + # after the sanitized debug step) would otherwise keep skipping NO_SANITIZE + # tests and keep the 300s discovery timeout. Reset it explicitly. + set(COCKATRICE_SANITIZERS + OFF + CACHE INTERNAL "AddressSanitizer and UBSan are enabled" FORCE + ) +endif() diff --git a/cmake/pch/qtcore_pch.h b/cmake/pch/qtcore_pch.h index cc3dd12ee..176f2939c 100644 --- a/cmake/pch/qtcore_pch.h +++ b/cmake/pch/qtcore_pch.h @@ -3,22 +3,53 @@ * * Safe for every target that links Qt Core, including the headless * Servatrice binary. Keep this header free of any widget/gui types. + * + * Candidates are chosen from IWYU include statistics: a header earns a + * spot when it is not already reachable from the rest of this list and + * enough translation units re-parse it. Qt headers are stable across + * builds, so the precompiled header rarely invalidates. */ #include #include +#include +#include +#include #include #include +#include +#include #include +#include #include +#include +#include +#include +#include +#include #include #include #include +#include #include +#include +#include #include +#include +#include #include +#include +#include +#include +#include #include +#include #include #include +#include +#include #include +#include #include +#include +#include diff --git a/cmake/pch/qtwidgets_pch.h b/cmake/pch/qtwidgets_pch.h index 2c63f450e..030bec69c 100644 --- a/cmake/pch/qtwidgets_pch.h +++ b/cmake/pch/qtwidgets_pch.h @@ -4,27 +4,56 @@ * Includes the Qt Core precompiled header plus the heavy Gui, Widgets and * Network layers that virtually every client translation unit re-parses. * Do not use on Servatrice (headless, QT_DONT_USE_QTGUI). + * + * Candidates are chosen from IWYU include statistics: a header earns a + * spot when it is not already reachable from the rest of this list and + * enough translation units re-parse it. Qt headers are stable across + * builds, so the precompiled header rarely invalidates. */ #include "qtcore_pch.h" #include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include +#include +#include +#include +#include #include +#include +#include #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include +#include +#include #include +#include +#include #include +#include #include +#include #include diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 1760d86b8..63ce7d1af 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -59,6 +59,7 @@ set(cockatrice_SOURCES src/interface/widgets/dialogs/dlg_update.cpp src/interface/widgets/dialogs/dlg_view_log.cpp src/interface/widgets/dialogs/override_printing_warning.cpp + src/interface/widgets/dialogs/path_safety_warning.cpp src/interface/widgets/dialogs/tip_of_the_day.cpp src/interface/widgets/deck_share/deck_share_utils.cpp src/interface/widgets/deck_share/shared_deck_preview_widget.cpp @@ -140,6 +141,10 @@ set(cockatrice_SOURCES src/game_graphics/zones/view_zone.cpp src/game_graphics/zones/view_zone_widget.cpp src/game_graphics/board/abstract_graphics_item.cpp + src/interface/card_database_update/card_database_update_status_bar.cpp + src/interface/card_database_update/card_database_update_status_bar.h + src/interface/card_database_update/card_update_progress.cpp + src/interface/card_database_update/card_update_progress.h 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 @@ -687,7 +692,7 @@ if(WIN32) # import table, and the glob above only sees DLLs that were already copied next # to the executable. Qt6::Concurrent is linked but never imported - QtConcurrent::run # and QFutureWatcher are header-only in Qt 6 - so neither step ships - # Qt6Concurrent.dll, even though required-qt-runtime.txt lists it and the + # Qt6Concurrent.dll, even though required-runtime.txt lists it and the # Windows package check then fails on a package that is fine to run. # Qt6::ShaderTools is skipped for the same reason. # diff --git a/cockatrice/cockatrice.desktop b/cockatrice/cockatrice.desktop index 4b15fa9c1..70db9d472 100644 --- a/cockatrice/cockatrice.desktop +++ b/cockatrice/cockatrice.desktop @@ -6,5 +6,4 @@ Name=Cockatrice Exec=cockatrice %U Icon=cockatrice Categories=Game;CardGame; -MimeType=application/x-cockatrice; -X-Scheme-Handler/cockatrice=true +MimeType=application/x-cockatrice;x-scheme-handler/cockatrice; diff --git a/cockatrice/cockatrice_en@source.ts b/cockatrice/cockatrice_en@source.ts index e06972ddc..426822209 100644 --- a/cockatrice/cockatrice_en@source.ts +++ b/cockatrice/cockatrice_en@source.ts @@ -4,7 +4,7 @@ AbstractCounter - + &Set counter... @@ -12,12 +12,12 @@ AbstractCounterDialog - + Set counter - + New value for counter '%1': @@ -38,64 +38,113 @@ AbstractTabDeckEditor - + Open in new tab - + Are you sure? - + The decklist has been modified. Do you want to save the changes? - - - - - - + + + + + + Error - + Could not open deck at %1 - + Could not save remote deck - - + + The deck could not be saved. Please check that the directory is writable and try again. - + Save deck - + + + Share deck + + + + + You must be connected to the server to share a deck. + + + + + The deck is empty. Add cards before sharing it. + + + + The deck could not be saved. - + There are no cards in your deck to be exported + + AccountSetupPage + + + Join a Server + + + + + Optional — you can always do this later from the menu. + + + + + Playing online needs a server account. + + + + + Register a new account… + + + + + I already have one — Connect… + + + + + Just want to play locally? Skip this and connect whenever you're ready. + + + AddAnalyticsPanelDialog @@ -107,12 +156,12 @@ Please check that the directory is writable and try again. AdminNotesDialog - + Update Notes - + Admin Notes for %1 @@ -138,218 +187,304 @@ Please check that the directory is writable and try again. AppearanceSettingsPage - + seconds - + Error - + Could not create themes directory at '%1'. - + Theme settings - + Current theme: - + Open themes folder - + Home tab background source: - + Home tab background shuffle frequency: - + Disabled - + Menu settings - + Show keyboard shortcuts in right-click menus - + Show game filter toolbar above list in room tab - + Card rendering - + Display card names on cards having a picture - + Auto-Rotate cards with sideways layout - + Override all card art with personal set preference (Pre-ProviderID change behavior) - + Light - + Dark - + + System - + + Show all playmats + + + + + Show own playmat only + + + + + Don't use playmats + + + + + Override deck playmat + + + + + Fallback if deck has none + + + + + Deck only, ignore collection + + + + Active theme palette: - + + Active theme style: + + + + + Qt widget style saved to this theme ("System" lets the application decide) + + + + Edit theme palette - + Home tab settings - + Display card name of background in bottom right - + + Dim the home tab background + + + + + Draw a translucent overlay over the home tab background so buttons and text stand out + + + + + Home tab button color: + + + + + Use the theme's identity accent colors, or extract colors from the background image + + + + + Playmat settings + + + + + Playmat visibility: + + + + + Default collection behavior: + + + + + Default playmat collection: + + + + + Edit... + + + + Styling settings - + Style user list - + Card printings - + Bump sets that the deck contains cards from to the top in the printing selector - + Scale cards on mouse over - + Use rounded card corners - + Card layout - + Minimum overlap percentage of cards on the stack and in vertical hand - + Maximum initial height for card view window: - - + + rows - + Maximum expanded height for card view window: - + Card counters - + Counter %1 - + Hand layout - + Display hand horizontally (wastes space) - + Enable left justification - + Table grid layout - + Invert vertical coordinate - + Minimum player count for multi-column layout: - + Maximum font size for information displayed on cards: @@ -357,12 +492,12 @@ Please check that the directory is writable and try again. ArchidektApiResponseDeckDisplayWidget - + Back to results - + Open Deck in Deck Editor @@ -388,111 +523,111 @@ Please check that the directory is writable and try again. BanDialog - + ban &user name - + ban &IP address - + ban client I&D - + Ban type - + &permanent ban - + &temporary ban - + &Days: - + &Hours: - + &Minutes: - + Duration of the ban - + Please enter the reason for the ban. This is only saved for moderators and cannot be seen by the banned person. - + Please enter the reason for the ban that will be visible to the banned person. - + Redact all messages from this user in all rooms - + &OK - + &Cancel - + Ban user from server - - - - + + + + Error - + You have to select a name-based, IP-based, clientId based, or some combination of the three to place a ban. - + You must have a value in the name ban when selecting the name ban checkbox. - + You must have a value in the ip ban when selecting the ip ban checkbox. - + You must have a value in the clientid ban when selecting the clientid ban checkbox. @@ -500,22 +635,22 @@ This is only saved for moderators and cannot be seen by the banned person. BetaReleaseChannel - + Beta - + No reply received from the release update server. - + Invalid reply received from the release update server. - + No reply received from the file update server. @@ -523,7 +658,20 @@ This is only saved for moderators and cannot be seen by the banned person. CardArtPreviewWidget - + + Banner preview + + + + + + + + Zoom %1× + + + + No card selected @@ -531,22 +679,22 @@ This is only saved for moderators and cannot be seen by the banned person. CardArtRulesModel - + Card - + ProviderId - + Mode - + Reason @@ -554,65 +702,209 @@ This is only saved for moderators and cannot be seen by the banned person. CardDatabaseModel - + Name - + Sets - + Mana cost - + Card type - + P/T - + Color(s) + + CardDatabaseSetupPage + + + + Press Download to fetch the card database, or Skip to do it later. + + + + + Downloading the card database (%1%)… + + + + + Parsing the card database (%1%)… + + + + + Importing cards (%1%)… + + + + + Download + + + + + ▼ Advanced: custom download source + + + + + ▶ Advanced: custom download source + + + + + Invalid URL + + + + + That doesn't look like a valid URL. Double-check it and try again, or clear the field to use the default source. + + + + + Downloading the latest card database… + + + + + Card database ready ✓ + + + + + Couldn't download the card database automatically. Check your connection and retry, set it up manually, or skip this for now — you can do it later from the Card Database menu. + + + + + Card Database + + + + + Cockatrice needs card data to know what you're playing with. + + + + + Retry + + + + + Set up manually… + + + + + Leave blank to use the default source + + + + + Only change this if you know you need a mirror or a custom card data source. + + + + + Restore default + + + + + Apply && retry + + + + + Check for card database updates on startup + + + + + Don't check + + + + + Prompt for update + + + + + Always update in the background + + + + + Check for card database updates every + + + + + days + + + CardDatabaseView - + Add to Deck - + Add to Sideboard - + Select Printing - + + Add to Zone + + + + + Create &new zone... + + + + Show on EDHRec (Commander) - + Show on EDHRec (Card) - + Show Related cards @@ -722,22 +1014,22 @@ This is only saved for moderators and cannot be seen by the banned person. CardInfoFrameWidget - + Image - + Description - + Both - + View transformation @@ -745,22 +1037,22 @@ This is only saved for moderators and cannot be seen by the banned person. CardInfoPictureWidget - + View related cards - + Add card to deck - + Mainboard - + Sideboard @@ -768,27 +1060,27 @@ This is only saved for moderators and cannot be seen by the banned person. CardInfoTextWidget - + Name: - + Set: - + Collector Number: - + Related cards: - + Unknown card: @@ -796,129 +1088,129 @@ This is only saved for moderators and cannot be seen by the banned person. CardMenu - + Re&veal to... - + &All players - + View related cards - + Token: - + All tokens - + &Select All - + S&elect Row - + S&elect Column - + &Play - + &Hide - + Play &Face Down - + &Tap / Untap Turn sideways or back again - + Skip &untapping - + T&urn Over Turn face up/face down - + &Peek at card face - + &Clone - + Attac&h to card... - + Unattac&h - + &Draw arrow... - + &Set annotation... - + Reduce life by power - + Ca&rd counters - + &Add counter (%1) - + &Remove counter (%1) - + &Set counters (%1)... @@ -939,7 +1231,7 @@ This is only saved for moderators and cannot be seen by the banned person. CardSizeWidget - + Card Size @@ -1079,6 +1371,24 @@ This is only saved for moderators and cannot be seen by the banned person. + + ChatView + + + Join game "%1" (#%2) on %3 + + + + + Join game #%1 on %2 + + + + + Join game + + + CockatriceXml3Parser @@ -1108,63 +1418,155 @@ This is only saved for moderators and cannot be seen by the banned person. + + CommanderBracketNames + + + CommanderSpellbook + + + + + Official (approximate) + + + + + The bracket system combines both objective data, as well as subjective play experience to estimate a bracket for a deck. +CommanderSpellbook's estimation is algorithmical, which means that it can only operate on the objective data, not the subjective intent. +They have chosen to represent this by defining their own bracket system which matches their algorithm. +This custom bracket system maps loosely to the standard system. +You may choose to use these mapped standardized names if these are more familiar to you, however, you should keep in mind that these are just rough estimations. + +Always consider the subjective factors of the bracket system when determing a deck's final bracket! + + + + + CommanderBracketWidget + + + + Bracket: + + + + + CommanderSpellbook integration + + + + + CommanderSpellbook can analyze your deck and estimate its Commander bracket. + +This sends your deck list to an external service. + +CommanderSpellbook uses its own bracket naming system based on their own algorithm. These names can be mapped to the official Commander brackets, but the mapping is only an approximation. + + + + + CommanderSpellbook bracket names + + + + + Official Commander bracket names (approximate) + + + + + Bracket naming: + + + + + Enable + + + + + Automatic + + + + + Disable + + + + + Calculating… + + + + + Why this bracket? + + + + + Recalculate bracket + + + ConnectionController - - + + The server has reached its maximum user capacity, please check back later. - + There are too many concurrent connections from your address. - + Banned by moderator - + Expected end time: %1 - + This ban lasts indefinitely. - + Scheduled server shutdown. - - + + Invalid username. - + You have been logged out due to logging in at another location. - + Connection closed - + The server has terminated your connection. Reason: %1 - + The server is going to be restarted in %n minute(s). All running games will be lost. Reason for shutdown: %1 @@ -1174,217 +1576,227 @@ Reason for shutdown: %1 - + Scheduled server shutdown - + Failed Login - + Your client seems to be missing features this server requires for connection. - + To update your client, go to 'Help -> Check for Client Updates'. - - - - - - - - - - - + + + + + + + + + + - - + + + Error - + Incorrect username or password. Please check your authentication information and try again. - + There is already an active session using this user name. Please close that session first and re-login. - - + + You are banned until %1. - - + + You are banned indefinitely. - + This server requires user registration. Do you want to register now? - + This server requires client IDs. Your client is either failing to generate an ID or you are running a modified client. Please close and reopen your client to try again. - + An internal error has occurred, please close and reopen Cockatrice before trying again. If the error persists, ensure you are running the latest version of the software and if needed contact the software developers. - + Account activation - + Your account has not been activated yet. You need to provide the activation token received in the activation email. - + + Password Change Required + + + + + An administrator has reset your password. Please contact your server administrator to obtain your temporary password, then log in and change it via Account -> Change Password. + + + + Server Full - + Unknown login error: %1 - - + + This usually means that your client version is out of date, and the server sent a reply your client doesn't understand. - - - - + + + + Registration denied - + Registration is currently disabled on this server - + There is already an existing account with the same user name. - + It's mandatory to specify a valid email address when registering. - + It appears you are attempting to register a new account on this server yet you already have an account registered with the email provided. This server restricts the number of accounts a user can register per address. Please contact the server operator for further assistance or to obtain your credential information. - + Password too short. - + Registration failed for a technical problem on the server. - + The connection to the server has been lost. - + Unknown registration error: %1 - + Account activation failed - + Socket error: %1 - + Server timeout - + You are trying to connect to an obsolete server. Please downgrade your Cockatrice version or connect to a suitable server. Local version is %1, remote version is %2. - + Your Cockatrice client is obsolete. Please update your Cockatrice version. Local version is %1, remote version is %2. - - + + Success - + Registration accepted. Will now login. - + Account activation accepted. Will now login. - + Information - + This server supports additional features that your client doesn't have. This is most likely not a problem, but this message might mean there is a new version of Cockatrice available or this server is running a custom or pre-release version. @@ -1392,113 +1804,113 @@ To update your client, go to Help -> Check for Updates. - - - + + + Reset Password - + Your password has been reset successfully, you can now log in using the new credentials. - + Failed to reset user account password, please contact the server operator to reset your password. - + Activation request received, please check your email for an activation token. - + Connecting to %1... - + Registering to %1 as %2... - + Disconnected - + Connected, logging in at %1 - + Requesting forgotten password to %1 as %2... - + Your username must respect these rules: - + is %1 - %2 characters long - + can %1 contain lowercase characters - - - - + + + + NOT - + can %1 contain uppercase characters - + can %1 contain numeric characters - + can contain the following punctuation: %1 - + first character can %1 be a punctuation mark - + no unacceptable language as specified by these server rules: note that the following lines will not be translated - + can not contain any of the following words: %1 - + can not match any of the following expressions: %1 - + You may only use A-Z, a-z, 0-9, _, ., and - in your username. @@ -1548,7 +1960,7 @@ To update your client, go to Help -> Check for Updates. DeckEditorCardDatabaseDockWidget - + Card Database @@ -1564,17 +1976,17 @@ To update your client, go to Help -> Check for Updates. DeckEditorDatabaseDisplayWidget - + Search by card name (or search expressions) - + Add card to &maindeck - + Add card to &sideboard @@ -1582,97 +1994,158 @@ To update your client, go to Help -> Check for Updates. DeckEditorDeckDockWidget - + Loading Database... - + Banner Card - + Main Type - + Mana Cost - + Colors - + + Playmat + + + + + + Edit Playmat... + + + + + Edit Playmat (%1) + + + + + &Rename zone... + + + + + Change &board + + + + + &Delete zone + + + + + Move or remove all cards first. + + + + + Delete zone + + + + + Delete the zone "%1"? + + + + Select Printing - + + Move to &zone + + + + + Create new zone and move &here... + + + + + Create &new zone... + + + + Deck - + Deck &name: - + Banner Card/Tags Visibility Settings - + Show banner card selection menu - + Show tags selection menu - + &Comments: - + Group by: - + Format: - + Hash: - + &Increment number - + &Decrement number - + &Remove row - + Swap card to/from sideboard @@ -1680,17 +2153,17 @@ To update your client, go to Help -> Check for Updates. DeckEditorFilterDockWidget - + Filters - + &Clear all filters - + Delete selected @@ -1698,114 +2171,119 @@ To update your client, go to Help -> Check for Updates. DeckEditorMenu - + &Deck Editor - + &New deck - + &Load deck... - + Load recent deck... - + Clear - + &Save deck - + Save deck &as... - + + Share deck... + + + + Load deck from cl&ipboard... - + Edit deck in clipboard - - + + Annotated - - + + Not Annotated - + Save deck to clipboard - + Annotated (No set info) - + Not Annotated (No set info) - + &Print deck... - + Load deck from online service... - + &Send deck to online service - + Create decklist (decklist.org) - + Create decklist (decklist.xyz) - + Analyze deck (deckstats.net) - + Analyze deck (tappedout.net) - + &Close @@ -1813,7 +2291,7 @@ To update your client, go to Help -> Check for Updates. DeckEditorPrintingSelectorDockWidget - + Printing Selector @@ -1821,110 +2299,152 @@ To update your client, go to Help -> Check for Updates. DeckEditorSettingsPage - - + + Update Spoilers - + Success - + Download URLs have been reset. - + Add URL - - + + URL: - - + + Edit URL - + Add New URL - + Remove URL - + Updating... - + + %1 (unlimited) + + + + + %1 (%2/s) + + + + + + + Adjust Rate Limit + + + + + Select a URL in the list first. + + + + + The selected URL does not have a valid host. + + + + + Requests per second (0 = unlimited, fastest; up to %1): + + + + + Requests per second (developer maximum is %1): + + + + + Adjust Rate Limit for %1 + + + + Choose path - + URL Download Priority - + Spoilers - + Download Spoilers Automatically - + Spoiler Location: - + Last Change - + Spoilers download automatically on launch - + Press the button to manually update without relaunching - + Do not close settings until manual update is complete - + Download card pictures on the fly - + How to add a custom URL - + Reset Download URLs @@ -1932,32 +2452,32 @@ To update your client, go to Help -> Check for Updates. DeckListHistoryManagerWidget - + Undo - + Redo - + Undo/Redo history - + Click on an entry to revert to that point in the history. - + [redo] - + [undo] @@ -1965,27 +2485,27 @@ To update your client, go to Help -> Check for Updates. DeckListModel - + Count - + Set - + Number - + Provider ID - + Card @@ -2006,17 +2526,22 @@ To update your client, go to Help -> Check for Updates. DeckPreviewColorIdentityFilterWidget - + Mode: Exact Match - + Mode: Includes - + + Mode: Excludes + + + + Color identity filter mode (AND/OR/NOT conjunctions of filters) @@ -2024,7 +2549,7 @@ To update your client, go to Help -> Check for Updates. DeckPreviewDeckTagsDisplayWidget - + Edit tags ... @@ -2032,62 +2557,62 @@ To update your client, go to Help -> Check for Updates. DeckPreviewTagDialog - + Deck Tags Manager - + Manage your deck tags. Check or uncheck tags as needed, or add new ones: - + Add a new tag (e.g., Aggro️) - + Add Tag - + Filter tags... - + OK - + Edit default tags - + Cancel - + Invalid Input - + Tag name cannot be empty! - + Duplicate Tag - + This tag already exists. @@ -2095,94 +2620,109 @@ To update your client, go to Help -> Check for Updates. DeckPreviewWidget - + Banner Card - + Open in deck editor - + + Share deck... + + + + Edit Tags - + Rename Deck - + Save Deck to Clipboard - + Annotated - + Annotated (No set info) - + Not Annotated - + Not Annotated (No set info) - + Rename File - + Delete File - + Set Banner Card - - + + New name: - - + + Rename deck + + + + + Rename file + + + + + Error - + Rename failed - + Delete file - + Are you sure you want to delete the selected file? - + Delete failed @@ -2190,57 +2730,102 @@ To update your client, go to Help -> Check for Updates. DeckStateManager - + Rename deck to "%1" from "%2" - + Updated comments (was %1 chars, now %2 chars) - + Set banner card to %1 (%2) - + + Set playmat to %1 + + + + Tags changed - + Set format to %1 - + Added (%1): %2 (%3) %4 - + Moved to %1 1 × "%2" (%3) - + Removed "%1" (all copies) - + + Moved %1 × "%2" (%3) to %4 + + + + + Created zone "%1" in %2 + + + + + Renamed zone "%1" to "%2" + + + + + Moved zone "%1" to %2 + + + + + Deleted zone "%1" + + + + + Enter a zone name. + + + + + This name is reserved. + + + + + A zone with this name already exists. + + + + %1 1 × "%2" (%3) - + Added - + Removed @@ -2262,94 +2847,122 @@ To update your client, go to Help -> Check for Updates. DeckViewContainer - + Load deck... - + Load remote deck... - + Load from clipboard... - + Load from website... - + Unload deck - + Ready to start - + Force start - + Sideboard unlocked - + Sideboard locked - - + + Error - + The selected file could not be loaded. - + Deck is greater than maximum file size. - + Are you sure you want to force start? This will kick all non-ready players from the game. - + Cockatrice + + DeckZoneDialog + + + New zone + + + + + Rename zone + + + + + Zone &name: + + + + + &Parent zone: + + + + + Enter a zone name. + + + DialogConvertDeckToCodFormat - + Deck Format Conversion - + You tried to add a tag to a .txt format deck. Tags can only be added to .cod format decks. Do you want to convert the deck to the .cod format? - + Remember and automatically apply choice in the future @@ -2362,143 +2975,143 @@ This will kick all non-ready players from the game. - + Known Hosts - + Delete the currently selected saved server - + Refresh the server list with known public servers - + New Host - + Name: - + &Host: - + &Port: - + Player &name: - + P&assword: - + &Save password - + A&uto connect - + Automatically connect to the most recent login when Cockatrice opens - + If you have any trouble connecting or registering then contact the server staff for help! - - + + Webpage - + Reset Password - + Forgot password? - + &Connect - + Server - + Login - + Server Contact - + Connect to Server - + Server URL - + Communication Port - + Unique Server Name - + Connection Warning - + You need to name your new connection profile. - + Connect Warning - + The player name can't be empty. @@ -2506,122 +3119,122 @@ This will kick all non-ready players from the game. DlgCreateGame - + Re&member settings - + &Description: - + P&layers: - + General - + Game type - + &Password: - + Only &buddies can join - + Only &registered users can join - + Joining restrictions - + &Spectators can watch - + Spectators &need a password to watch - + Spectators can &chat - + Spectators can see &hands - + Create game as spectator - + Spectators - + Starting life total: - + Open decklists in lobby - + Create game as judge - + Game setup options - + &Clear - + Create game - + Game information - + Error - + Server error. @@ -2629,97 +3242,97 @@ This will kick all non-ready players from the game. DlgCreateToken - + &Name: - + Token - + C&olor: - + white - + blue - + black - + red - + green - + multicolor - + colorless - + &P/T: - + &Annotation: - + &Destroy token when it leaves the table - + Create face-down (Only hides name) - + Token data - + Show &all tokens - + Show tokens from this &deck - + Choose token from list - + Create token @@ -2727,53 +3340,53 @@ This will kick all non-ready players from the game. DlgDefaultTagsEditor - + Edit Tags - + Add - + Confirm - + Cancel - + Enter a tag and press Enter - - + + ✖ - + Invalid Input - + Tag name cannot be empty! - + Duplicate Tag - + This tag already exists. @@ -2782,7 +3395,7 @@ This will kick all non-ready players from the game. DlgEditAvatar - + No image chosen. @@ -2793,27 +3406,32 @@ To remove your current avatar, confirm without choosing a new image. - + + Images are automatically downscaled to at most %1x%1 pixels. + + + + Browse... - + Change avatar - + Open Image - + Image Files (*.png *.jpg *.bmp) - + Invalid image chosen. @@ -2839,38 +3457,38 @@ To remove your current avatar, confirm without choosing a new image. DlgEditPassword - + Old password: - + New password: - + Confirm new password: - + Change password - - + + Error - + Your password is too short. - + The new passwords don't match. @@ -2878,93 +3496,93 @@ To remove your current avatar, confirm without choosing a new image. DlgEditTokens - + &Name: - + C&olor: - + white - + blue - + black - + red - + green - + multicolor - + colorless - + &P/T: - + &Annotation: - + Token data - - + + Add token - + Remove token - + Edit custom tokens - + Please enter the name of the token: - + Error - + The chosen name conflicts with an existing card or token. Make sure to enable the 'Token' set in the "Manage sets" dialog to display them correctly. @@ -3042,7 +3660,8 @@ Make sure to enable the 'Token' set in the "Manage sets" dia - Hide games that have started + Hide started games + Hide games that have started @@ -3078,7 +3697,8 @@ Make sure to enable the 'Token' set in the "Manage sets" dia - &Creator name: + &Host name: + &Creator name: @@ -3145,52 +3765,52 @@ Make sure to enable the 'Token' set in the "Manage sets" dia DlgForgotPasswordChallenge - + Reset Password Challenge Warning - + A problem has occurred. Please try to request a new password again. - + Enter the information of the server and the account you'd like to request a new password for. - + &Host: - + &Port: - + Player &name: - + Email: - + Reset Password Challenge - + Reset Password Challenge Error - + The email address can't be empty. @@ -3198,37 +3818,37 @@ Make sure to enable the 'Token' set in the "Manage sets" dia DlgForgotPasswordRequest - + Enter the information of the server you'd like to request a new password for. - + &Host: - + &Port: - + Player &name: - + Reset Password Request - + Reset Password Error - + The player name can't be empty. @@ -3236,94 +3856,127 @@ Make sure to enable the 'Token' set in the "Manage sets" dia DlgForgotPasswordReset - + Reset Password Warning - + A problem has occurred. Please try to request a new password again. - + Enter the received token and the new password in order to set your new password. - + &Host: - + &Port: - + Player &name: - + Token: - - + + New Password: - + Reset Password - + The player name can't be empty. - - - - + + + + Reset Password Error - + The token can't be empty. - + The new password can't be empty. - + Error - + Your password is too short. - + The passwords do not match. + + DlgInviteToGame + + + Join my game (#%1): + + + + + Join my game "%1" (#%2): + + + + + Invite to Game + + + + + Search users... + + + + + Invite + + + + + Cancel + + + DlgLoadDeck - + Load Deck @@ -3407,165 +4060,566 @@ https://tappedout.net/mtg-decks/your-deck-name/ DlgLocalGameOptions - + Players: - + General - + Starting life total: - + Game setup options - + Remember settings - + Local game options + + DlgLoginPrompt + + + Sign in + + + + + This link requires you to be signed in. +Sign in to %1: + + + + + Username: + + + + + Password: + + + + + Save password for this server + + + DlgMoveTopCardsUntil - + Card name (or search expressions): - + Number of hits: - + Auto play hits - + Put top cards on stack until... - + No cards matching the search expression exists in the card database. Proceed anyways? - + Cockatrice - + Invalid filter + + DlgMyReports + + + My Reports + + + + + # + + + + + Time + + + + + Reported User + + + + + Category + + + + + Game ID + + + + + Status + + + + + Assigned To + + + + + Report Details + + + + + Chat Log Context + + + + + Comments: + + + + + Add a comment: + + + + + + Type your comment here... + + + + + Send + + + + + Close + + + + + Refresh + + + + + + + Loading... + + + + + Failed to load reports. + + + + + %1 report(s) + + + + + This report is closed. + + + + + Failed to load report details. + + + + + No comments yet. + + + + + [Moderator] + + + + + [You] + + + DlgRegister - + + Known Hosts + + + + + Delete the currently selected saved server + + + + + Refresh the server list with known public servers + + + + + New Host + + + + + Server + + + + Enter your information and the information of the server you'd like to register to. Your email will be used to verify your account. - + &Host: - + &Port: - + Player &name: - + P&assword: - + Password (again): - + Email: - + Email (again): - + Country: - + Undefined - + Real name: - + Register to server - - - - + + Server URL + + + + + Communication Port + + + + + + + Registration Warning - + Your password is too short. - + Your passwords do not match, please try again. - + Your email addresses do not match, please try again. - + The player name can't be empty. + + + Downloading... + + + + + DlgReportUser + + + Report User + + + + + Reports are reviewed by moderators. False reports may result in account penalties. + + + + + Report Details + + + + + Reported User: + + + + + Game ID: + + + + + (Optional) Enter game ID if available + + + + + If the report is related to a specific game, enter its ID. + + + + + Category + + + + + Category: + + + + + Description + + + + + Please describe what happened. Include dates, game details, or any evidence if available. + + + + + Chat Log Context + + + + + No chat context available (not triggered from chat). + + + + + This chat log is captured from your local chat window and may not reflect the full conversation. + + + + + + Submit Report + + + + + Missing description + + + + + Please describe what happened before submitting. + + + + + Confirm Report + + + + + Submit report against %1 for %2? + + + + + Submitting... + + + + + Report Submitted + + + + + Your report has been submitted and will be reviewed by a moderator. Thank you. + + + + + + + Submission Failed + + + + + You have reached the daily report limit. Please try again later. + + + + + The reported user could not be found. Guests (unregistered users) cannot be reported. + + + + + Failed to submit report. Please try again. + + + + + Cheating / Unsporting behavior + + + + + Bug Abuse + + + + + Harassment / Abuse + + + + + Verbal Abuse + + + + + Hate speech + + + + + Spam + + + + + Other + + + + + Using external tools, cheat programs, or exploiting game bugs + + + + + Exploiting a bug or glitch to gain an unfair advantage + + + + + Threatening, bullying, or persistent unwanted contact + + + + + Abusive or offensive language directed at another player + + + + + Discriminatory language targeting race, gender, religion, etc. + + + + + Repeated unwanted messages or advertisements + + + + + Any behavior not covered by the above categories + + DlgRollDice @@ -3631,34 +4685,12 @@ Your email will be used to verify your account. DlgSettings - + Unknown Error loading card database - - Your card database is invalid. - -Cockatrice may not function correctly with an invalid database - -You may need to rerun oracle to update your card database. - -Would you like to change your database location setting? - - - - - Your card database version is too old. - -This can cause problems loading card information or images - -Usually this can be fixed by rerunning oracle to to update your card database. - -Would you like to change your database location setting? - - - - + Your card database did not finish loading Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues with your cards.xml attached @@ -3667,21 +4699,21 @@ Would you like to change your database location setting? - + File Error loading your card database. Would you like to change your database location setting? - + Your card database was loaded but contains no cards. Would you like to change your database location setting? - + Unknown card database load status Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues @@ -3690,104 +4722,235 @@ Would you like to change your database location setting? - - - + + + Error - + The path to your deck directory is invalid. Would you like to go back and set the correct path? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? - + Settings - + + Search settings... + + + + + OK + + + + General - + Appearance - + User Interface - + Storage - + Card Sources - + + Your card database is invalid. + +Cockatrice may not function correctly with an invalid database + +You may need to rerun Oracle to update your card database. + +Would you like to change your database location setting? + + + + + Your card database version is too old. + +This can cause problems loading card information or images + +Usually this can be fixed by rerunning Oracle to to update your card database. + +Would you like to change your database location setting? + + + + Chat - + Sound - + Shortcuts + + DlgShareDeck + + + + + + Share deck + + + + + + Shared deck + + + + + Share name: + + + + + Create share link + + + + + Cancel + + + + + Failed to create the share link (server response code %1). + + + + + Share link created and copied to the clipboard: + +%1 + +The share expires on %2. + + + + + The server did not respond in time. Try again. + + + + + DlgSharedDecksPreview + + + Open shared decks + + + + + Share: %1 + + + + + Untitled + + + + + From %1 + + + + + This share link expires on %1 + + + + + Open selected + + + + + Open all + + + + + Cancel + + + + + Downloading deck %1 of %2: %3 + + + DlgStartupCardCheck - + Card Update Check - + It has been more than %2 days since you last checked your card database for updates. Choose how you would like to run the card database updater. You can always change this behavior in the 'General' settings tab. - + Run in foreground - + Run in background - + Run in background and always from now on - + Don't prompt again and don't run - + Don't run this time @@ -3795,17 +4958,17 @@ You can always change this behavior in the 'General' settings tab. DlgTipOfTheDay - + Next - + Previous - + Tip of the Day @@ -3813,164 +4976,174 @@ You can always change this behavior in the 'General' settings tab. DlgUpdate - + Current release channel - + Reinstall - + Cancel Download - + Open Download Page - + Check for Client Updates - - - - + + + + Error - + Cockatrice was not built with SSL support, therefore you cannot download updates automatically! Please visit the download page to update manually. - + Downloading update: %1 - + Checking for updates... - + Finished checking for updates - + No Update Available - + Cockatrice is up to date! - + You are already running the latest version available in the chosen release channel. - + Current version - + Selected release channel - - + + Update Available - - + + A new version of Cockatrice is available! - - + + New version - - + + Released - - + + Changelog - + Do you want to update now? - + Unfortunately, the automatic updater failed to find a compatible download. You may have to manually download the new version. - + Please check the <a href="%1">releases page</a> on our Github and download the build for your system. - - - + + Update + + + + + The update installer is already running and waits about a minute for Cockatrice to close. Cockatrice is still busy, so save your work and close it before then. Otherwise the installer gives up and the update is cancelled. + + + + + + Update Error - + An error occurred while checking for updates: - + An error occurred while downloading an update: - + Installing... - + Cockatrice is unable to open the installer. - + Try to update manually by closing Cockatrice and running the installer. - + Download location @@ -3978,17 +5151,17 @@ You may have to manually download the new version. DlgViewLog - + Clear log when closing - + Copy to clipboard - + Debug Log @@ -4226,7 +5399,7 @@ You may have to manually download the new version. EdhrecCommanderResponseCommanderDetailsDisplayWidget - + Salt: @@ -4234,7 +5407,7 @@ You may have to manually download the new version. FilterBuilder - + Type your filter here @@ -4242,45 +5415,88 @@ You may have to manually download the new version. FilterDisplayWidget - + Confirm Delete - + Are you sure you want to delete the filter '%1'? - + Delete Failed - + Failed to delete filter '%1'. + + FinishPage + + + You're All Set + + + + + That's everything for now. Jump into Settings any time to change your mind about any of this. + +Have fun! + + + + + FirstRunWizard + + + Finish + + + + + Next + + + + + Welcome to Cockatrice + + + + + Back + + + + + Skip + + + GameEventHandler - + kicked by game host or moderator - + player left the game - + player disconnected from server - + reason unknown @@ -4288,140 +5504,156 @@ You may have to manually download the new version. GameSelector - - - - - - - - - + + + + + + + + + Error - + Please join the appropriate room first. - + Wrong password. - + Spectators are not allowed in this game. - + The game is already full. - + The game does not exist any more. - + This game is only open to registered users. - + This game is only open to its creator's buddies. - + You are being ignored by the creator of this game. - + Join Game - + Spectate Game - + Game Information - + + Cop&y game link + + + + Join Game as Judge - + Spectate Game as Judge - + + Join game - - Password: + + The game is full. Join as a spectator instead? - + + Password for game #%1: + + + + + Password for "%1": + + + + Please join the respective room first. - + &Filter games - + C&lear filter - + C&reate - + &Join - + Join as judge - + J&oin as spectator - + Join as judge spectator - + Games shown: %1 / %2 - + Games @@ -4462,12 +5694,12 @@ You may have to manually download the new version. GamesModel - + >1 day - + %1%2 hr short age in hours @@ -4476,12 +5708,12 @@ You may have to manually download the new version. - + new - + %1%2 min short age in minutes @@ -4490,83 +5722,83 @@ You may have to manually download the new version. - + password - + buddies only - + reg. users only - + open decklists - - + + can chat - + see hands - + can see hands - + not allowed - + Room - + Age - + Description - - Creator + + Host - + Type - + Restrictions - + Players - + Spectators @@ -4574,158 +5806,275 @@ You may have to manually download the new version. GeneralSettingsPage - + Reset all paths - + All paths have been reset - - - - - - - + + + + English + + + + + + + + + + Choose path - + + <p>The card database only contains English card data. To see cards in <b>%1</b>, <b>Oracle</b> must run once with this language selected and re-import the card database.</p><p>The cached database and the downloaded card pictures have been cleared, so a re-import is picked up without stale entries.</p> + + + + + <p>The Scryfall URL that resolves card art by translated name was added to the top of your download list. You can remove or reorder it any time.</p> + + + + + <p>Run Oracle now?</p> + + + + + Card text & images language changed + + + + Language settings - + Language: - + + Card text & images language: + + + + + Foreign card names, text and art apply after you update the card database (Oracle). + + + + + Language used in card search: + + + + + Selected card language (untranslated cards still match in English) + + + + + English and selected card language + + + + Version settings - + Card database - + Startup settings - + + Startup tab: + + + + + Home + + + + + Visual Deck Storage + + + + + Deck Storage + + + + + Game Replays + + + + + Deck Editor + + + + + Visual Deck Editor + + + + + Server + + + + + Server Room + + + + + The tab shown when Cockatrice starts. If the chosen tab is not open yet, it is opened. + + + + + Server: + + + + + Room: + + + + + Room name + + + + Paths (editing disabled in portable mode) - + Paths - + How to help with translations - + Decks directory: - + Filters directory: - + Replays directory: - + Pictures directory: - + Card database: - + Custom database directory: - + Token database: - + Update channel - + Check for client updates on startup - + Check for card database updates on startup - + Don't check - + Prompt for update - + Always update in the background - + Check for card database updates every - + days - + Notify if a feature supported by the server is missing in my client - + Automatically run Oracle when running a new version of Cockatrice - + Show tips on startup - + Last update check on %1 (%2 days ago) @@ -4733,47 +6082,47 @@ You may have to manually download the new version. GraveyardMenu - + &Graveyard - + &View graveyard - + &Move graveyard to... - + &Top of library - + &Bottom of library - + &All players - + &Hand - + &Exile - + Reveal random card to... @@ -4867,59 +6216,359 @@ You may have to manually download the new version. + + HomeTabButtonColor + + + From theme colors + + + + + Extract from background + + + HomeWidget - + Create New Deck - + Browse Decks - + Browse Card Database - + Browse EDHRec - + Browse Archidekt - + View Replays - + Quit - + Connecting... - + Connect - + Play + + IntentConnectToServer + + + Timed out while connecting to %1:%2 + + + + + Failed to connect to %1:%2: %3 + + + + + IntentGetLoginCredentials + + + + No saved credentials for this server + + + + + IntentJoinServerGame + + + Game %1 not found in the room + + + + + IntentJoinServerRoom + + + No server tab available + + + + + Failed to join the server room %1 + + + + + Timed out while joining the server room %1 + + + + + IntentOpenLocalDeck + + + Unable to load deck file %1 + + + + + IntentOpenServerRoomByName + + + No server tab available + + + + + Timed out while looking for the server room %1 + + + + + Disconnected while looking for the server room %1 + + + + + Failed to join the server room %1: it doesn't exist on the server. + + + + + You do not have the required permission to join the server room %1. + + + + + Failed to join the server room %1 due to an unknown error. + + + + + IntentOpenSharedDeck + + + The shared deck could not be found or has expired + + + + + + The shared deck is empty + + + + + Failed to download the shared deck + + + + + The shared deck could not be loaded + + + + + + Unknown deck + + + + + Open shared decks + + + + + Could not download the deck "%1". + +%n deck(s) were already downloaded. Open them? + + + + + + + + Timed out while loading the shared deck + + + + + Timed out while downloading the shared deck + + + + + IntentUrlParser + + + Open game + + + + + Missing or empty hostname in the game link + + + + + Invalid or missing port in the game link + + + + + Invalid or missing room id in the game link + + + + + Invalid or missing game id in the game link + + + + + Join game + + + + + Join game #%1 in "%2" on %3? + + + + + Join game #%1 on %2? + + + + + Join game "%1" (#%2) in "%3" on %4? + + + + + Join game "%1" (#%2) on %3? + + + + + + + + Open shared deck + + + + + Missing or empty hostname in the share link + + + + + Invalid or missing port in the share link + + + + + Missing or empty share value in the share link + + + + + Opening this share link connects you to %1 instead of %2. + +Continue? + + + + + Opening this share link connects you to %1. + +Continue? + + + + + Opening this share link connects you to %1, a server you have never connected to before. + +Continue? + + + + + LatencyStatusWidget + + + Ping + + + + + Ping: %1 ms + + + + + Connection latency details + + + + + Connection quality over the last %n sample(s): + + + + + + + + Last: %1 ms + + + + + Median: %1 ms + + + + + 95th percentile: %1 ms + + + + + Maximum: %1 ms + + + LibraryMenu @@ -5137,300 +6786,321 @@ You may have to manually download the new version. MainWindow - - + + Player %1 - + Load replay - + About Cockatrice - + Version - + Cockatrice Webpage - + Project Manager: - + Past Project Managers: - + Developers: - + Our Developers - + Help Develop! - + Translators: - + Our Translators - + Help Translate! - + Support: - + Report an Issue - + Troubleshooting - + F.A.Q. - - + + Error - + &Connect... - + &Disconnect - + Start &local game... - + &Watch replay... - + &Full screen - + &Register to server... - + &Restore password... - + &Settings... - + &Exit - + A&ctions - + &Cockatrice - + C&ard Database - + &Manage sets... - + Edit custom &tokens... - + Open custom image folder - + Open custom sets folder - + Add custom sets/cards - + Reload card database - + Tabs - + &Help - + &About Cockatrice - + &Tip of the Day - + Check for Client Updates - + Check for Card Updates... - + Check for Card Updates (Automatic) - + Show Status Bar - + View &Debug Log - + Open Settings Folder - + + Re-run Onboarding Wizard... + + + + Show/Hide - + + Sign-in cancelled + + + + New Version - + Congratulations on updating to Cockatrice %1! Oracle will now launch to update your card database. - + Cockatrice installed - + Congratulations on installing Cockatrice %1! Oracle will now launch to install the initial card database. - + + Are you sure? + + + + + A card database update is still running. Quitting now will cancel it. +Are you sure you want to quit? + + + + Card database - + Cockatrice is unable to load the card database. Do you want to update your card database now? If unsure or first time user, choose "Yes" - - + + Yes - - + + No - + Open settings - + New sets found - + %n new set(s) found in the card database Set code(s): %1 Do you want to enable it/them? @@ -5440,110 +7110,110 @@ Do you want to enable it/them? - + Yes, always enable - + View sets - + Welcome - + Hi! It seems like you're running this version of Cockatrice for the first time. All the sets in the card database have been enabled. Read more about changing the set order or disabling specific sets and consequent effects in the "Manage Sets" dialog. - + Information - + A card database update is already running. - + Unable to run the card database updater: - + Card database update running. - + Failed to start. The file might be missing, or permissions might be incorrect. - + The process crashed some time after starting successfully. - + Timed out. The process took too long to respond. The last waitFor...() function timed out. - + An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel. - + An error occurred when attempting to read from the process. For example, the process may not be running. - + Unknown error occurred. - + The card database updater exited with an error: %1 - - - - - + + + + + Load sets/cards - + Selected file cannot be found. - + You can only import XML databases at this time. - + The new sets/cards have been added successfully. Cockatrice will now reload the card database. - + Sets/cards failed to import. @@ -5748,297 +7418,297 @@ Cockatrice will now reload the card database. MessageLogWidget - + from play - + from their graveyard - + from exile - + from their hand - + the top card of %1's library - + the top card of their library - + from the top of %1's library - + from the top of their library - + the bottom card of %1's library - + the bottom card of their library - + from the bottom of %1's library - + from the bottom of their library - + from %1's library - + from their library - + from sideboard - + from the stack - + from custom zone '%1' - + %1 is now keeping the top card %2 revealed. - + %1 is not revealing the top card %2 any longer. - + %1 can now look at top card %2 at any time. - + %1 no longer can look at top card %2 at any time. - + %1 attaches %2 to %3's %4. - + %1 has conceded the game. - + %1 has unconceded the game. - + %1 has restored connection to the game. - + %1 has lost connection to the game. - + %1 points from their %2 to themselves. - + %1 points from their %2 to %3. - + %1 points from %2's %3 to themselves. - + %1 points from %2's %3 to %4. - + %1 points from their %2 to their %3. - + %1 points from their %2 to %3's %4. - + %1 points from %2's %3 to their own %4. - + %1 points from %2's %3 to %4's %5. - + %1 creates a face down token. - + %1 creates token: %2%3. - + %1 has loaded a deck (%2). - + %1 has loaded a deck with %2 sideboard cards (%3). - + %1 destroys %2. - + a card - + %1 gives %2 control over %3. - + %1 puts %2 into play%3 face down. - + %1 puts %2 into play%3. - + %1 puts %2%3 into their graveyard face down. - + %1 puts %2%3 into their graveyard. - + %1 exiles %2%3 face down. - + %1 exiles %2%3. - + %1 moves %2%3 to their hand. - + %1 puts %2%3 into their library. - + %1 puts %2%3 onto the bottom of their library. - + %1 puts %2%3 on top of their library. - + %1 puts %2%3 into their library %4 cards from the top. - + %1 moves %2%3 to sideboard. - + %1 plays %2%3 face down. - + %1 plays %2%3. - + %1 moves %2%3 to custom zone '%4' face down. - + %1 moves %2%3 to custom zone '%4'. - + %1 tries to draw from an empty library - + %1 draws %2 card(s). @@ -6046,12 +7716,12 @@ Cockatrice will now reload the card database. - + %1 is looking at %2. - + %1 is looking at the %4 %3 card(s) %2. top card for singular, top %3 cards for plural @@ -6060,72 +7730,72 @@ Cockatrice will now reload the card database. - + bottom - + top - + %1 turns %2 face-down. - + %1 turns %2 face-up. - + The game has been closed. - + The game has started. - + You are flooding the game. Please wait a couple of seconds. - + %1 has joined the game. - + %1 is now watching the game. - + You have been kicked out of the game. - + %1 has left the game (%2). - + %1 is not watching the game any more (%2). - + %1 is not ready to start the game any more. - + %1 shuffles their deck and draws a new hand of %2 card(s). @@ -6133,28 +7803,28 @@ Cockatrice will now reload the card database. - + %1 shuffles their deck and draws a new hand. - + You are watching a replay of game #%1. - + %1 is ready to start the game. - + cards an unknown amount of cards - + %1 card(s) a card for singular, %1 cards for plural @@ -6163,107 +7833,107 @@ Cockatrice will now reload the card database. - + %1 lends %2 to %3. - + %1 reveals %2 to %3. - + %1 reveals %2. - + %1 randomly reveals %2%3 to %4. - + %1 randomly reveals %2%3. - + %1 peeks at face down card #%2. - + %1 peeks at face down card #%2: %3. - + %1 reveals %2%3 to %4. - + %1 reveals %2%3. - + %1 reversed turn order, now it's %2. - + reversed - + normal - + Heads - + Tails - + %1 flipped a coin. It landed as %2. - + %1 rolls a %2 with a %3-sided die. - + %1 flips %2 coins. There are %3 heads and %4 tails. - + %1 rolls a %2-sided dice %3 times: %4. - + %1's turn. - + %1 sets annotation of %2 to %3. - + %1 places %2 %3%4 counter(s) on %5 (now %6). @@ -6271,7 +7941,7 @@ Cockatrice will now reload the card database. - + %1 removes %2 %3%4 counter(s) from %5 (now %6). @@ -6279,102 +7949,102 @@ Cockatrice will now reload the card database. - + %1 failed to undo their last draw. - + %1 sets counter %2 to %3 (%4%5). - + %1 sets %2 to not untap normally. - + %1 sets %2 to untap normally. - + %1 removes the PT of %2. - + %1 changes the PT of %2 from nothing to %4. - + %1 changes the PT of %2 from %3 to %4. - + %1 has locked their sideboard. - + %1 has unlocked their sideboard. - + %1 taps their permanents. - + %1 untaps their permanents. - + %1 taps %2. - + %1 untaps %2. - + %1 shuffles %2. - + %1 shuffles the bottom %3 cards of %2. - + %1 shuffles the top %3 cards of %2. - + %1 shuffles cards %3 - %4 of %2. - + %1 unattaches %2. - + %1 undoes their last draw. - + %1 undoes their last draw (%2). @@ -6382,115 +8052,125 @@ Cockatrice will now reload the card database. MessagesSettingsPage - + Word1 Word2 Word3 - + Add New Message - + Edit Message - + Remove Message - + Add message - - + + Message: - + Edit message - + Chat settings - + Custom alert words - + Enable chat mentions - + Enable mention completer - + In-game message macros - + How to use in-game message macros - + Ignore chat room messages sent by unregistered users - + Ignore private messages sent by unregistered users - + Ignore private messages sent by non-buddy users - - + + Invert text color - + Enable desktop notifications for private messages - + Enable desktop notification for mentions - + Enable room message history on join - - + + Ignore all private messages + + + + + Use game time instead of local time in game logs + + + + + (Color is hexadecimal) - + Separate words with a space, alphanumeric characters only @@ -6498,42 +8178,42 @@ Cockatrice will now reload the card database. MoveMenu - + Move to - + &Top of library in random order - + X cards from the top of library... - + &Bottom of library in random order - + T&able - + &Hand - + &Graveyard - + &Exile @@ -6612,148 +8292,134 @@ Cockatrice will now reload the card database. PaletteEditorDialog - - + + Reset - - - Apply - - - - - - Save && Apply - - - - + ▼ Edit Palette - - + + ▶ Edit Palette - + Palette Editor — %1 - + <b>Palette Editor</b> &nbsp;·&nbsp; %1 - - This theme ships no default palette files - - - - - Replace current colours with the theme author's defaults - - - - - Switch between the light and dark palette files + + + Save - Editing: + Delete this scheme's custom palette and revert to the theme default (or the application palette) - Show or hide the per-role colour grid for manual tweaks + Switch between the light and dark palette files + Editing: + + + + + Show or hide the per-role colour grid for manual tweaks + + + + ↺ Revert to theme default - + Discard unsaved edits and restore the last saved palette - - Preview this palette without saving to disk + + Cannot save: this theme has no writable directory - + Write palette-%1.toml and reload the theme - - Cannot save: this theme has no directory on disk - - - - + + Save failed - + + Could not write %1 to: %2 - - - No default found - - - - - No default palette file found for the "%1" scheme. - - PaletteGridWidget - + Active - + Disabled - + Inactive - + Normal interactive state - + Widget is disabled / not interactive - + Window is in background / unfocused + + + App colors + + + + + Application-specific colors layered on top of the Qt palette + + Phase @@ -6876,30 +8542,21 @@ Cockatrice will now reload the card database. - - PictureLoader - - - en - code for scryfall's language property, not available for all languages - - - PlayerActions - - - - + + + + grave - - - - + + + + exile @@ -7018,16 +8675,272 @@ Cockatrice will now reload the card database. PlayerMenu - + Player "%1" - + &Counters + + PlaymatCollectionDialog + + + Default Playmats + + + + + Add... + + + + + Edit... + + + + + Remove + + + + + Move Up + + + + + Move Down + + + + + List mode: + + + + + Fixed (always the first entry) + + + + + Round-robin (cycle through entries) + + + + + Random (pick one per game) + + + + + PlaymatPreviewWidget + + + Playmat crop + + + + + + + + + Zoom %1× + + + + + No card selected + + + + + PlaymatSettingsDialog + + + Playmat Settings + + + + + Type a card name... + + + + + Card name: + + + + + Printing: + + + + + Show numerical editors + + + + + Left margin (%): + + + + + Right margin (%): + + + + + Vertical offset: + + + + + Zoom: + + + + + Card + + + + + Crop + + + + + Drag to pan, scroll to zoom, arrow keys nudge, plus and minus zoom, Backspace or Esc restores. Dimmed strips mark where a wider table crops further. + + + + + Remove Playmat + + + + + PreferencesSetupPage + + + A Few Preferences + + + + + Defaults are fine — tweak these now or from Settings anytime. + + + + + Gameplay + + + + + Double-click cards to play them + + + + + When disabled, a single click plays the selected card onto the table. + + + + + Display hand horizontally + + + + + Shows your hand as a row along the bottom of the table instead of a column beside it. + + + + + Play all nonlands onto the stack by default + + + + + Cards you play appear on the stack so other players can respond to them, as in a tabletop game. + + + + + Notifications && Sound + + + + + Show desktop notifications + + + + + Play sound effects + + + + + Startup + + + + + Startup tab: + + + + + Home + + + + + Visual Deck Storage + + + + + Deck Storage + + + + + Game Replays + + + + + Deck Editor + + + + + Visual Deck Editor + + + + + Server + + + + + Server Room + + + PrintingDisabledInfoWidget @@ -7048,12 +8961,12 @@ This setting means you'll only see the default printing for each card, inst PrintingSelector - + Display Navigation Buttons - + Printing Selector @@ -7061,25 +8974,65 @@ This setting means you'll only see the default printing for each card, inst PrintingSelectorCardOverlayWidget - + Preference - + Pin Printing - + Unpin Printing - + + Image Overrides + + + + + Load Custom Image... + + + + + Clear Custom Image + + + + + %1 %2 + + + + Show Related cards + + + Select Card Image + + + + + Images (*.png *.jpg *.jpeg *.webp) + + + + + Load Custom Image + + + + + The selected file could not be read as an image. + + PrintingSelectorCardSearchWidget @@ -7110,28 +9063,28 @@ This setting means you'll only see the default printing for each card, inst PrintingSelectorCardSortingWidget - + Alphabetical - + Preference - + Release Date - - + + Descending - + Ascending @@ -7147,95 +9100,103 @@ This setting means you'll only see the default printing for each card, inst PtMenu - + Power / toughness - + &Increase power - + &Decrease power - + I&ncrease toughness - + D&ecrease toughness - + In&crease power and toughness - + Dec&rease power and toughness - + Increase power and decrease toughness - + Decrease power and increase toughness - + Set &power and toughness... - + Reset p&ower and toughness + + PublicDeckPreviewWidget + + + Uploaded %1 + + + QMenuBar - + Services - + Hide %1 - + Hide Others - + Show All - + Preferences... - + Quit %1 - + About %1 @@ -7243,17 +9204,17 @@ This setting means you'll only see the default printing for each card, inst QObject - + Cockatrice card database (*.xml) - + All files (*.*) - + Cockatrice replays (*.cor) @@ -7273,17 +9234,22 @@ This setting means you'll only see the default printing for each card, inst - + + Maybeboard + + + + Overwrite Existing File? - + A .cod version of this deck already exists. Overwrite it? - + Enabling this feature will disable the use of the Printing Selector. You will not be able to manage printing preferences on a per-deck basis, or see printings other people have selected for their decks. @@ -7294,7 +9260,7 @@ Are you sure you would like to enable this feature? - + Disabling this feature will enable the Printing Selector. You can now choose printings on a per-deck basis in the Deck Editor and configure which printing gets added to a deck by default by pinning it in the Printing Selector. @@ -7305,100 +9271,110 @@ Are you sure you would like to disable this feature? - + Confirm Change + + + Art: %1 + + + + + Open deck + + QPlatformTheme - + OK - + Save - + Save All - + Open - + &Yes - + Yes to &All - + &No - + N&o to All - + Abort - + Retry - + Ignore - + Close - + Cancel - + Discard - + Help - + Apply - + Reset - + Restore Defaults @@ -7406,121 +9382,189 @@ Are you sure you would like to disable this feature? QuickSetupPanel - + %1% - + <b>Quick Setup</b> - + Generate all palette roles automatically from a single accent colour - + Accent: - + Primary hue. Used directly for highlights and links. At high intensity it also tints buttons and backgrounds. - + Intensity: - + Subtle - + Full colour - + 0–30 Subtle tint — only highlights and links change hue 30–70 Accented — buttons, tooltips, and borders join in 70–100 Full colour — backgrounds, everything - + 70% - - - Generate ↓ - - - - - Derive all palette roles from the accent colour above. -Fine-tune individual colours in the grid afterwards. - - RemoteDeckList_TreeModel - + + + Public + + + + + + Public (inherited) + + + + + + Private + + + + + This folder is visible to other users + + + + + This folder is private, but a parent folder is public (inherited). + + + + + This folder is only visible to you + + + + + This deck is visible to other users + + + + + This deck is private, but a parent folder is public (inherited). + + + + + This deck is only visible to you + + + + Name - + ID - + Upload time + + + Visibility + + + + + RemotePublicDecksModel + + + The server did not respond in time. Try again. + + + + + Failed to load the user's public decks (server response code %1). + + RemoteReplayList_TreeModel - + ID - + Name - + Players - + Keep - + Time started - + Duration (sec) + + ReplayQuickSettingsWidget + + + Fast forward speed: + + + + + Skip empty sections + + + RfgMenu @@ -7562,37 +9606,37 @@ Fine-tune individual colours in the grid afterwards. RoomSelector - + Rooms - + Joi&n - + Room - + Description - + Permissions - + Players - + Games @@ -7600,7 +9644,7 @@ Fine-tune individual colours in the grid afterwards. SayMenu - + S&ay @@ -7608,32 +9652,32 @@ Fine-tune individual colours in the grid afterwards. SequenceEdit - + Choose an action from the table - + Hit the key/combination of keys you want to set for this action - + Invalid key - + Shortcut already in use by: - + Clear - + Restore default @@ -7666,56 +9710,92 @@ Fine-tune individual colours in the grid afterwards. + + ShareBarWidget + + + Share name + + + + + Cancel + + + + + Create share link + + + + + SharedDeckPreviewWidget + + + Select this deck + + + + + (selected) + + + ShortcutSettingsPage - - + + Restore all default shortcuts - + Do you really want to restore all default shortcuts? - + Clear all default shortcuts - + Do you really want to clear all shortcuts? - + Section: - + Action: - + Shortcut: - + + Shortcut editor + + + + How to set custom shortcuts - + Clear all shortcuts - + Search by shortcut name @@ -7769,12 +9849,12 @@ Please check your shortcut settings! SideboardMenu - + &Sideboard - + &View sideboard @@ -7782,27 +9862,27 @@ Please check your shortcut settings! SoundSettingsPage - + Enable &sounds - + Current sounds theme: - + Test system sound engine - + Sound settings - + Master volume @@ -7810,48 +9890,48 @@ Please check your shortcut settings! SpoilerBackgroundUpdater - + Spoilers season has ended - + Deleting spoiler.xml. Please run Oracle - - + + Spoilers download failed - + No internet connection - + Error - + Spoilers already up to date - + No new spoilers added - + Spoilers have been updated! - + Last change: @@ -7859,157 +9939,170 @@ Please check your shortcut settings! StableReleaseChannel - + Default - + No reply received from the release update server. - + Invalid reply received from the release update server. - + No reply received from the tag update server. - + Invalid reply received from the tag update server. + + StatsTally + + + Total Power + + + + + Total Toughness + + + StorageSettingsPage - - - + + + Success - + Cached card pictures have been reset. - + Downloaded card pictures have been reset. - + Error - + One or more downloaded card pictures could not be cleared. - + In-memory (currently loaded) card pictures have been reset. - + Card Picture Loader Caching Method: - + The network cache is the preferred way of storing images. Downloaded images are stored here until the size of the cache exceeds the configured size. Cockatrice automatically monitors this cache and deletes the least recently seen card images to ensure the cache does not exceed the configured size. - + Writing card images directly to a folder on your hard drive is another way of storing images. This does not change how Cockatrice accesses or downloads images. Cockatrice will NOT automatically monitor and clear this folder, so if you enable this option, it is up to you to ensure sufficient available space. It should also be noted that if a provider outage causes you to download the wrong picture (i.e. wrong printing) you will be stuck with it until you manually delete the file, as opposed to using the network cache, which automatically rotates and thus correct errors after a while. - + This is the in-memory picture cache used by the application at runtime. It determines how much memory (RAM) Cockatrice can use before it has to fetch card images from the hard disk again. Increasing this will allow more card images to be displayed at once but shouldn't be necessary. Clearing this will make Cockatrice reload all images from the network cache or the disk. - + Delete Cached Images - + Delete Saved Images - + Clear In-Memory Images - + Card Picture Loader Cache Method - + Network Cache - + Filesystem - + In-Memory Picture Cache - + Network Cache Size: - + On-disk cache for downloaded pictures - + Redirect Cache TTL: - + How long cached redirects for urls are valid for. - + Picture Cache Size: - + In-memory cache for pictures not currently on screen - + Naming scheme: - + Day(s) @@ -8017,17 +10110,33 @@ Please check your shortcut settings! TabAccount - + + + My Reports + + + + Add to Buddy List - + Add to Ignore List - + + Buddies are marked with a star in chat, a sound plays when they join or leave the server, and they can be invited to buddy-only games. + + + + + Ignored users' chat messages are hidden from you, and they cannot send you private messages or join your games. + + + + Account @@ -8148,118 +10257,118 @@ Please check your shortcut settings! TabArchidekt - - - + + + Desc. - - + + AND - - + + Require ALL selected colors - - + + Deck name... - - + + Owner... - - + + Packages - - + + Advanced Filters - + Bracket: - - + + Any - - + + Contains card... - - + + Commander... - - + + Tag... - - + + Deck Size - + Cards: - - + + Asc. - + Sort by: - + Filter by: - + Display Settings - - + + Search - - + + Formats @@ -8272,42 +10381,42 @@ Please check your shortcut settings! TabCardArtRules - + Card: - + ProviderId: - + Mode: - + Reason: - + Type a card name... - + Add rule - + Remove rule - + Refresh @@ -8320,52 +10429,52 @@ Please check your shortcut settings! TabDeckEditor - + Card Info - + Deck - + Filters - + &View - + Card Database - + Printing - + Visible - + Floating - + Reset layout - + Deck: %1 @@ -8373,49 +10482,49 @@ Please check your shortcut settings! TabDeckEditorVisual - + Visual Deck: %1 - + &Visual Deck Editor - - + + Card Info - - + + Deck - + &View - + Printing - + Visible - + Floating - + Reset layout @@ -8423,22 +10532,22 @@ Please check your shortcut settings! TabDeckEditorVisualTabWidget - + Visual Deck View - + Visual Database Display - + Deck Analytics - + Sample Hand @@ -8446,138 +10555,245 @@ Please check your shortcut settings! TabDeckStorage - + Local file system - + Server deck storage - - + + Open in deck editor - + Rename deck or folder - + Upload deck - + Download deck - - - - + + + + New folder - - + + Delete - + + Share decks + + + + + Publish/unpublish deck + + + + Open decks folder - + Rename local folder - + Rename local file - + New name: - - - - + + + + + + + Error - + Rename failed - - + + + Invalid deck file - + Enter deck name - + This decklist does not have a name. Please enter a name: - + Unnamed deck - + Failed to upload deck to server - + Delete local file - + Are you sure you want to delete the selected files? - + Delete remote decks - + Are you sure you want to delete the selected decks? - - + + + Shared decks + + + + + + Only one folder can be shared at a time. + + + + + + Share either a folder or decks, not both. + + + + + Select folders or decks in the tree to share. + + + + + %n folder(s) + + + + + + + + %n deck(s) + + + + + + + + No decks selected + + + + + Selected: %1 + + + + + The root folder cannot be shared. + + + + + Select decks to share. + + + + + Failed to create the share link (server response code %1). + + + + + Share link copied to the clipboard. +Expires on %1. + + + + + Share link + + + + + The server did not respond in time. Try again. + + + + + Failed to change deck visibility on server (response code %1). + + + + + Failed to change the visibility of %n selected deck(s). + + + + + + + + Name of new folder: - + Deck Storage @@ -8585,20 +10801,277 @@ Please enter a name: TabDeckStorageVisual - + Visual Deck Storage - + Error - + Could not open deck at %1 + + + + Shared decks + + + + + Share deck + + + + + You must be connected to the server to share a deck. + + + + + %n deck(s) + + + + + + + + Click deck tiles to select the decks you want to share. + + + + + One deck selected. Create the link to share it with other players. + + + + + %n decks selected. Create the link to share them with other players. + + + + + + + + + Share decks + + + + + Select at least one deck to share. + + + + + Unable to load deck file %1 + + + + + Failed to create the share link (server response code %1). + + + + + Share link copied to the clipboard. +Expires on %1. + + + + + Share link + + + + + The server did not respond in time. Try again. + + + + + TabDeveloper + + + Auto-refresh + + + + + Automatically request fresh server statistics at a fixed interval. + + + + + s + + + + + Seconds between automatic refreshes. + + + + + Refresh server stats + + + + + Statistic;Value + + + + + Command;Count;Total ms;Avg ms + + + + + %1 GiB + + + + + %1 MiB + + + + + %1 KiB + + + + + %1 bytes + + + + + %1 s + + + + + %1 ms + + + + + No server statistics available yet. + + + + + Registered users online + + + + + Moderators online + + + + + Games running + + + + + Traffic sent (last tick) + + + + + Traffic received (last tick) + + + + + Server uptime + + + + + %1d %2h %3m + + + + + %1h %2m + + + + + Snapshot taken + + + + + Live Metrics + + + + + Cards in live games + + + + + Total commands processed + + + + + Avg command time + + + + + Active command types + + + + + Event loop stalls + + + + + Last stall overshoot + + + + + Worst stall overshoot + + + + + Game starts + + + + + Avg game start time + + + + + Updated %1 + + + + + Developer + + TabEdhRec @@ -8611,27 +11084,27 @@ Please enter a name: TabEdhRecMain - + &Cards - + Top Commanders - + Tags - + Search for a card ... - + Search @@ -8644,191 +11117,207 @@ Please enter a name: TabGame - - - + + + Replay - - + + Game - - + + Player List - - + + + Invite + + + + + Card Info - - + + Messages - - + + Replay Timeline - + &Phases - + &Game - + Next &phase - + Next phase with &action - + Next &turn - + Reverse turn order - + &Remove all local arrows - + Rotate View Cl&ockwise - + Rotate View Co&unterclockwise - + Game &information - + + Cop&y game link + + + + + Invite to Game... + + + + Un&concede - - - + + + &Concede - + &Leave game - + C&lose replay - + &Focus Chat - + &Say: - + Selected cards - + &View - + Visible - + Floating - + Reset layout - + Concede - + Are you sure you want to concede this game? - + Unconcede - + You have already conceded. Do you want to return to this game? - + Leave game - + Are you sure you want to leave this game? - + A player has joined game #%1 - + %1 has joined the game - + You have been kicked out of the game. @@ -8844,157 +11333,157 @@ Please enter a name: TabLog - + Logs - - - + + + Time;SenderName;SenderIP;Message;TargetID;TargetName - + Room Logs - + Game Logs - + Chat Logs - - + + Error - + You must select at least one filter. - + You have to select a valid number of days to locate. - + Username: - + IP Address: - + Game Name: - + GameID: - + Message: - + Main Room - + Game Room - + Private Chat - + Past X Days: - + Today - + Last Hour - + Maximum Results: - + At least one filter is required. The more information you put in, the more specific your results will be. - + Get User Logs - + Clear Filters - + Filters - + Log Locations - + Date Range - + Maximum Results - - + + Message History - + Failed to collect message history information. - + There are no messages for the selected filters. @@ -9002,218 +11491,558 @@ The more information you put in, the more specific your results will be. TabMessage - + Private &chat - + &Leave - + %1 - Private chat - + + You have ignored %1; your messages are not delivered. + + + + This user is ignoring you, they cannot see your messages in main chat and you cannot join their games. - + Private message from - + %1 has left the server. - + %1 has joined the server. + + + Message not sent — %1 is offline. + + + + + TabModeration + + + User name + + + + + Investigate + + + + + + Reset Password + + + + + + Remove Avatar + + + + + Refresh + + + + + User Info + + + + + Name: + + + + + Registered: + + + + + Last login: + + + + + Status: + + + + + Counts: + + + + + Admin notes: + + + + + Alts + + + + + Sessions + + + + + Staff Last Logins + + + + + + User + + + + + eMail + + + + + + Client ID + + + + + Registered + + + + + + Last login + + + + + Warns + + + + + Bans + + + + + + Active + + + + + IP + + + + + Start + + + + + End + + + + + Type + + + + + Level + + + + + Unknown + + + + + + Loading... + + + + + Error loading user info. + + + + + active + + + + + inactive + + + + + admin + + + + + Reports: %1 Bans: %2 Warnings: %3 + + + + + (none) + + + + + yes + + + + + no + + + + + Admin + + + + + Developer + + + + + Moderator + + + + + Judge + + + + + Reset the password of %1? A temporary password will be generated and shown to you. The user must change it on their first login. + + + + + + Error + + + + + Password reset failed. + + + + + Password reset + + + + + Temporary password for %1: + +%2 + +Pass it to the user through a secure channel. + + + + + Remove the avatar of %1? The user will have to upload a new one. + + + + + Could not remove the avatar. + + + + + Avatar removed + + + + + The avatar of %1 has been removed. + + + + + Moderation + + + + + TabPublicDecks + + + + + Public decks of %1 + + + + + + + This user has not published any decks. + + + + + + No decks match your filters. + + + + + + Refresh + + + + + Public Decks Settings + + + + + Loading public decks… + + + + + + Open public deck + + + + + Failed to open the public deck (server response code %1). + + + + + The public deck could not be parsed. + + TabReplays - + Local file system - + Server replay storage - - + + Watch replay - + Rename - - + + New folder - - + + Delete - + Open replays folder - + Download replay - + Toggle expiration lock - + Get replay share code - - + + Look up replay by share code - + Rename local folder - + Rename local file - + New name: - + Error - + Rename failed - + Name of new folder: - + Delete local file - + Are you sure you want to delete the selected files? - + Are you sure you want to delete the selected replays? - + Failed to get code - - + + Either this server does not support replay sharing, or does not permit replay sharing for you. - - - + + + Failed - + Could not get replay code - + Replay Share Code - + Others can use this code to add the replay to their list of remote replays: %1 - + Copy to clipboard - + Replay share code - + Replay code found - + Replay was added, or you already had access to it. - + Replay code not found - + Failed to submit code - + Unexpected error - + Delete remote replay @@ -9223,65 +12052,478 @@ The more information you put in, the more specific your results will be. + + TabReport + + + Search by username, category... + + + + + All Statuses + + + + + Open + + + + + Assigned + + + + + Resolved + + + + + Dismissed + + + + + Unresolved only + + + + + Refresh + + + + + # + + + + + Time + + + + + Reporter + + + + + Reported User + + + + + Category + + + + + Game ID + + + + + Status + + + + + Assigned To + + + + + Replay + + + + + Room + + + + + Description + + + + + Chat Log Context + + + + + Chat log attached by the reporter. It is captured from their client and may be incomplete or edited. + + + + + Comments / Thread + + + + + No description. + + + + + No chat log attached. + + + + + + No comments yet. + + + + + + Type a reply... + + + + + Send + + + + + Reported User Context + + + + + User: + + + + + Account Age: + + + + + Reports: + + + + + Bans: + + + + + Warns: + + + + + Admin Notes: + + + + + Recent Reports Against User: + + + + + Report Statistics + + + + + Assign to Me + + + + + Resolve + + + + + Resolve with note... + + + + + Dismiss... + + + + + View Replay + + + + + Join Game + + + + + + + + Loading... + + + + + Failed to load reports. + + + + + Yes + + + + + No + + + + + %1 report(s) + + + + + %1 open | %2 assigned | %3 resolved | %4 dismissed + + + + + This report is closed. + + + + + Failed to load report details. + + + + + [Moderator] + + + + + [Reporter] + + + + + Assigning... + + + + + Assigned. + + + + + Assignment failed. + + + + + Dismiss Report + + + + + Resolve Report + + + + + Optional note: + + + + + Resolution note (optional): + + + + + Dismissing... + + + + + Resolving... + + + + + Done. + + + + + Action failed. + + + + + Loading replay... + + + + + No replay available for this game. + + + + + Replay opened. + + + + + Failed to parse replay. + + + + + No room recorded for this report, use the replay instead. + + + + + Attempting to join game... + + + + + Failed to send comment. + + + + + Error loading user info. + + + + + %1 days (since %2) + + + + + (none) + + + + + No previous reports against this user. + + + + + Loading statistics... + + + + + Error loading statistics. + + + + + Total: %1 reports (%2 open, %3 assigned, %4 resolved/dismissed) + + + + + Last 24h: %1 | Last 7d: %2 | Last 30d: %3 | Avg resolution: %4h + + + + + This week: %1 vs last week: %2 (%3%) + + + + + By category: + + + + + === Top Categories === + + + + + === Most Reported Users === + + + + + === Top Reporters === + + + + + Report Queue + + + TabRoom - - Friends - - - - - Online - - - - - Ignored - - - - + &Say: - + Chat - + &Room - + &Leave room - + &Clear chat - + Chat Settings... - + mentioned you. - + Click to view - + You are flooding the chat. Please wait a couple of seconds. @@ -9289,35 +12531,35 @@ The more information you put in, the more specific your results will be. TabServer - + Server - - - - + + + + Error - + Failed to join the server room: it doesn't exist on the server. - + The server thinks you are in the server room but your client is unable to display it. Try restarting your client. - + You do not have the required permission to join this server room. - + Failed to join the server room due to an unknown error: %1. @@ -9325,97 +12567,176 @@ The more information you put in, the more specific your results will be. TabSupervisor - + Deck Editor - + Visual Deck Editor - + EDHRec - + Archidekt - + Home - + &Visual Deck Storage - + Visual Database Display - + Server - + Account - + Deck Storage - + Game Replays - + Administration - + Logs - + + Report Queue + + + + + Moderation + + + + + Card Art Rules + + + + + Developer + + + + Are you sure? - + There are still open games. Are you sure you want to quit? + + + Connection quality over the last %n sample(s): + + + + + - + + Last: %1 ms + + + + + Median: %1 ms + + + + + 95th percentile: %1 ms + + + + + Maximum: %1 ms + + + + + Game joins are only available on a remote server. + + + + + Could not join game %1. +%2 + + + + + Ignored user + + + + + You have ignored %1. Remove them from your ignore list to open a private chat. + + + + + Game #%1 + + + + + Game #%1 — %2 + + + + Click to view - + Your buddy %1 has signed on! - + Unknown Event - + The server has sent you a message that your client does not understand. This message might mean there is a new version of Cockatrice available or this server is running a custom or pre-release version. @@ -9423,38 +12744,38 @@ To update your client, go to Help -> Check for Updates. - + Idle Timeout - + You are about to be logged out due to inactivity. - + Promotion - + You have been promoted. Please log out and back in for changes to take effect. - + Warned - + You have received a warning due to %1. Please refrain from engaging in this activity or further actions may be taken against you. If you have any questions, please private message a moderator. - + You have received the following message from the server. (custom messages like these could be untranslated) @@ -9473,6 +12794,34 @@ Please refrain from engaging in this activity or further actions may be taken ag + + TallyMenu + + + Tally + + + + + None + + + + + Subtypes + + + + + Total Power + + + + + Total Toughness + + + TappedOutInterface @@ -9487,6 +12836,65 @@ Please refrain from engaging in this activity or further actions may be taken ag + + ThemeSetupPage + + + Light + + + + + Dark + + + + + Match system + + + + + Theme: + + + + + Appearance: + + + + + Home screen background: + + + + + Save failed + + + + + Could not write the theme palette to: +%1 + + + + + Pick a Look + + + + + You can fine-tune every colour later from Settings → Appearance. + + + + + Accent colour (optional) + + + TipsOfTheDay @@ -9556,57 +12964,52 @@ Please refrain from engaging in this activity or further actions may be taken ag UserCardArtSettingsDialog - + Card Art Settings - + Type a card name... - + Card name: - - Card ProviderId: + + Printing: - + + Card + + + + + Drag to pan, scroll to zoom, arrow keys nudge, plus and minus zoom, Backspace or Esc restores. + + + + + Banner + + + + Left margin (%): - + Right margin (%): - - Vertical offset: - - - - - Zoom: - - - - - Parameters - - - - - Preview - - - - + Remove Banner Card @@ -9614,216 +13017,266 @@ Please refrain from engaging in this activity or further actions may be taken ag UserContextMenu - + User &details - + Private &chat - + Show this user's &games - - - Add to &buddy list - - - - - Remove from &buddy list - - - - - Add to &ignore list - - - - - Remove from &ignore list - - - - - Kick from &game - - - - - Warn user - - - View user's war&n history + View this user's &public decks - Ban from &server + Add to &buddy list - View user's &ban history + Remove from &buddy list - &Promote user to moderator + Add to &ignore list - Dem&ote user from moderator + Remove from &ignore list - Promote user to &judge + Kick from &game - Demote user from judge + Report user + Warn user + + + + + View user's war&n history + + + + + Ban from &server + + + + + View user's &ban history + + + + + &Promote user to moderator + + + + + Dem&ote user from moderator + + + + + Promote user to &judge + + + + + Demote user from judge + + + + + Promote user to &developer + + + + + Demote user from de&veloper + + + + View admin notes - - + Investigate user + + + + + + Error - + This user does not exist. - + You are being ignored by %1 and can't see their games. - + Could not get %1's games. - + %1's games - - - + + + Ban History - + Ban Time;Moderator;Ban Length;Ban Reason;Visible Reason - + User has never been banned. - + Failed to collect ban information. - - - + + + Warning History - + Warning Time;Moderator;User Name;Reason - + User has never been warned. - + Failed to collect warning information. - + Failed to get admin notes. - - + + Success - + Successfully promoted user. - + Successfully demoted user. - + + &Invite to Game + + + + + Join my game (#%1): + + + + + Join my game "%1" (#%2): + + + + + Ignore list + + + + + %1 has been added to your ignore list. + + + + Kick Player - + Are you sure you want to kick this player from the game? - - - + + + Failed - + Failed to promote user. - + Failed to demote user. - + Copy hash to clipboard - + Remove this user's messages @@ -9861,61 +13314,61 @@ Please refrain from engaging in this activity or further actions may be taken ag - + Moderator - + Registered user - - + + Unregistered user - + Judge - + Unknown - + The entered password does not match your account. - - - - + + + + Information - + User information updated. - - - - - - + + + + + - - - + + + + Error @@ -9939,8 +13392,13 @@ Please refrain from engaging in this activity or further actions may be taken ag Edit Banner Card + + + Developer + + - + %n Year(s), amount of years (only shown if more than 0) @@ -9949,7 +13407,7 @@ Please refrain from engaging in this activity or further actions may be taken ag - + %10%n Day(s) %20 amount of years (if more than 0), amount of days, date in local short format @@ -9958,270 +13416,274 @@ Please refrain from engaging in this activity or further actions may be taken ag - + Enter Password - + Password verification is required in order to change your email address - - - + + + An error occurred while trying to update your user information. - + The selected card is blacklisted on this server or another error occurred. - + Banner card removed. - + Banner card updated. - + This server does not permit you to update your user informations. - - - Password changed. - - - This server does not permit you to change your password. + Password changed. - The new password is too short. + This server does not permit you to change your password. + The new password is too short. + + + + The old password is incorrect. - + Avatar updated. - + This server does not permit you to update your avatar. - + An error occured while trying to update your avatar. - - - This server does not permit you to update your user informations. - An error occured while trying to updater your avatar. - - UserInfoPopup - - + + Games - + Chat - + Open private chat - + Profile - + View user profile - + Show this user's games - + + Invite + + + + + Invite to your game + + + + − Buddy - + Remove from buddy list - + + Buddy - + Add to buddy list - + − Ignore - + Remove from ignore list - + + Ignore - + Add to ignore list - + Ban - + Ban from server - + Warn - + Warn user - + Ban log - + View ban history - + Warn log - + View warning history - + Notes - + View admin notes - + − Mod - + Demote from moderator - + + Mod - + Promote to moderator - + − Judge - + Demote from judge - + + Judge - + Promote to judge - + Join game - + Spectate - - + + Loading games… - + Could not load games. - + No active games. @@ -10229,223 +13691,344 @@ Please refrain from engaging in this activity or further actions may be taken ag UserInterfaceSettingsPage - + General interface settings - + &Double-click cards to play them (instead of single-click) - + &Clicking plays all selected cards (instead of just the clicked card) - + &Play all nonlands onto the stack (not the battlefield) by default - + Do not delete &arrows inside of subphases - + Close card view window when last card is removed - + Auto focus search bar when card view window is opened - + Annotate card text on tokens - + Show selection count during drag selection - + Show total selection count - - Show subtype breakdown in selection tally + + + Disabled - - Use tear-off menus, allowing right click menus to persist on screen + + + Enabled - - Keep game chat focused when clicking in game (Note: disables card view search bar) - - - - - Notifications settings - - - - - Enable notifications in taskbar - - - - - Notify in the taskbar for game events while you are spectating + + + Automatic - Notify in the taskbar when users in your buddy list connect - - - - - Animation settings + CommanderSpellbook bracket names + Official Commander bracket names (approximate) + + + + + Use tear-off menus, allowing right click menus to persist on screen + + + + + Keep game chat focused when clicking in game (Note: disables card view search bar) + + + + + Notifications settings + + + + + Enable notifications in taskbar + + + + + Notify in the taskbar for game events while you are spectating + + + + + Notify in the taskbar when users in your buddy list connect + + + + + Animation settings + + + + + &Enable all animations + + + + + &Disable all animations + + + + &Tap/untap animation - + + &Arrow draw animation + + + + + Life counter flash + + + + + Battlefield flash on damage + + + + Deck editor/storage settings - + Open deck in new tab by default - + + Show card counts in Visual Deck Editor + + + + Use visual deck storage in game lobby - + Use selection animation for Visual Deck Storage - + When adding a tag in the visual deck storage to a .txt deck: - - do nothing + + Do nothing - - ask to convert to .cod + + Ask to convert to .cod - - always convert to .cod + + Always convert to .cod - + Default deck editor type - + Classic Deck Editor - + Visual Deck Editor - + + Visual deck editor startup tab + + + + + Context + + + + + Deck display + + + + + Database display + + + + + Context mode: New decks open on the database display, existing decks open on the deck view. + + + + + CommanderSpellbook integration to estimate commander bracket + + + + + Bracket naming + + + + Replay settings - + Buffer time for backwards skip via shortcut: + + UserListPanelWidget + + + Search users... + + + UserListWidget - + Users connected to server: %1 - + Users in this room: %1 - + Buddies online: %1 / %2 - + Ignored users online: %1 / %2 + + + Buddies + + + + + Online + + + + + Ignored + + + + + %1 %2 (%3/%4) + + + + + %1 %2 (%3) + + UtilityMenu - + Increment all card counters - + &Untap all permanents - + R&oll die... - + Flip coin - + &Create token... - + C&reate another token - + Cr&eate predefined token @@ -10482,22 +14065,22 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDatabaseDisplayFilterSaveLoadWidget - + Search filter... - + Save Filter - + Save all currently applied filters to a file - + Enter filename... @@ -10505,72 +14088,72 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDatabaseDisplayFilterToolbarWidget - + Sort by - + Filter by - + Save and load filters - + Filter by exact card name - + Filter by card main-type - + Filter by card sub-type - + Filter by set - + Filter by format legality - + Save/Load - + Name - + Main Type - + Sub Type - + Sets - + Formats @@ -10672,7 +14255,7 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDatabaseDisplayRecentSetFilterSettingsWidget - + Filter to most recent sets @@ -10680,19 +14263,19 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDatabaseDisplaySetFilterWidget - + Search sets... - - + + Mode: Exact Match - - + + Mode: Includes @@ -10738,28 +14321,28 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDatabaseDisplayWidget - + Search by card name (or search expressions) - - + + Visual - + Loading database ... - + Clear all filters - + Table @@ -10767,43 +14350,43 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckDisplayOptionsWidget - + Group by: - + Change how cards are divided into categories/groups. - + Sort by: - + Click and drag to change the sort order within the groups - + Configure how cards are sorted within their groups - - + + Toggle Layout: Overlap - + Change how cards are displayed within zones (i.e. overlapped or fully visible.) - + Toggle Layout: Flat @@ -10819,12 +14402,12 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckEditorSampleHandWidget - + Draw a new sample hand - + Sample hand size @@ -10832,17 +14415,17 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckEditorWidget - + Type a card name here for suggestions from the database... - + Quick search and add card - + Search for closest match in the database (with auto-suggestions) and add preferred printing to the deck on pressing enter @@ -10850,7 +14433,7 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageFolderDisplayWidget - + Deck Storage @@ -10858,52 +14441,57 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageQuickSettingsWidget - + Show Folders - + Show Tag Filter - + Show Color Identity - + Show Tags On Deck Previews - + + Show Upload Time + + + + Show Banner Card Selection Option - + Draw unused Color Identities - + Unused Color Identities Opacity - + Deck tooltip: - + None - + Filepath @@ -10911,7 +14499,7 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageSearchWidget - + Search by filename (or search expression) @@ -10919,22 +14507,22 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageSortWidget - + Sort Alphabetically (Deck Name) - + Sort Alphabetically (Filename) - + Sort by Last Modified - + Sort by Last Loaded @@ -10942,17 +14530,22 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageWidget - + Loading database ... - + Refresh loaded files - + + Select decks to share + + + + Visual Deck Storage Settings @@ -10960,177 +14553,202 @@ Please refrain from engaging in this activity or further actions may be taken ag WarningDialog - + Which warning would you like to send? - + Redact all messages from this user in all rooms - + &OK - + &Cancel - + Warn user for misconduct - - + + Error - + User name to send a warning to can not be blank, please specify a user to warn. - + Warning to use can not be blank, please select a valid warning to send. + + + %1 (IL %2) + + + + + WelcomePage + + + Welcome! + + + + + Let's get you set up. This will only take a minute — we'll grab the card database, pick a look you like, and get you ready to connect to a server. + +You can change any of this later from Settings. + + + + + Language: + + WndSets - + Move selected set to the top - + Move selected set up - + Move selected set down - + Move selected set to the bottom - - Search by set name, code, or type - - - - + Default order - + Restore original art priority order - + Enable all sets - + Disable all sets - + Enable selected set(s) - + Disable selected set(s) - + Deck Editor - + Use CTRL+A to select all sets in the view. - + Only cards in enabled sets will appear in the card list of the deck editor. - + Image priority is decided in the following order: - + first the CUSTOM Folder (%1), then the Enabled Sets in this dialog (Top to Bottom) %1 is a link to the wiki - + Include cards rebalanced for Alchemy [requires restart] - + Card Art - - How to use custom card art + + Search by set name, code, type, or release date + How to use custom card art + + + + Hints - + Note - + Sorting by column allows you to find a set while not changing set priority. - + To enable ordering again, click the column header until this message disappears. - + Use the current sorting as the set priority instead - + Sorts the set priority using the same column - + Manage sets @@ -11138,93 +14756,85 @@ Please refrain from engaging in this activity or further actions may be taken ag ZoneViewWidget - + Search by card name (or search expressions) - + Ungrouped - + Group by Type - + Group by Mana Value - + Group by Color - + Unsorted - + Sort by Name - + Sort by Type - + Sort by Mana Cost - + Sort by Colors - + Sort by P/T - + Sort by Set - + shuffle when closing - + pile view - - i18n - - - English - - - main - + Connect on startup - + Debug to file @@ -12008,6 +15618,16 @@ Please refrain from engaging in this activity or further actions may be taken ag Graveyard + + + Report Queue + + + + + Moderation + + diff --git a/cockatrice/src/client/lag_monitor.cpp b/cockatrice/src/client/lag_monitor.cpp index 383d64644..6b72087ec 100644 --- a/cockatrice/src/client/lag_monitor.cpp +++ b/cockatrice/src/client/lag_monitor.cpp @@ -1,7 +1,10 @@ #include "lag_monitor.h" +#include #include +#include #include +#include #include LagMonitor::LagMonitor(QObject *parent) : QObject(parent) diff --git a/cockatrice/src/client/lag_monitor.h b/cockatrice/src/client/lag_monitor.h index 9fdf6b283..0bb98c25e 100644 --- a/cockatrice/src/client/lag_monitor.h +++ b/cockatrice/src/client/lag_monitor.h @@ -6,15 +6,15 @@ #ifndef LAG_MONITOR_H #define LAG_MONITOR_H -#include #include #include #include #include +#include +#include inline Q_LOGGING_CATEGORY(LagMonitorLog, "lag_monitor"); -class QEvent; class QTimer; /** diff --git a/cockatrice/src/client/latency_graph_widget.cpp b/cockatrice/src/client/latency_graph_widget.cpp index 46d6ccdd3..72df3ce6c 100644 --- a/cockatrice/src/client/latency_graph_widget.cpp +++ b/cockatrice/src/client/latency_graph_widget.cpp @@ -5,7 +5,11 @@ #include "latency_graph_widget.h" +#include #include +#include +#include +#include LatencyGraphWidget::LatencyGraphWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/client/latency_graph_widget.h b/cockatrice/src/client/latency_graph_widget.h index 4f6f38f8b..31a7022b2 100644 --- a/cockatrice/src/client/latency_graph_widget.h +++ b/cockatrice/src/client/latency_graph_widget.h @@ -8,6 +8,8 @@ #include #include +#include +#include /** * @brief Bar graph of recent network round-trip samples. diff --git a/cockatrice/src/client/latency_status_widget.cpp b/cockatrice/src/client/latency_status_widget.cpp index 779c726eb..940074581 100644 --- a/cockatrice/src/client/latency_status_widget.cpp +++ b/cockatrice/src/client/latency_status_widget.cpp @@ -6,11 +6,15 @@ #include "latency_status_widget.h" #include "latency_graph_widget.h" +#include "latency_tracker.h" #include #include #include +#include +#include #include +#include LatencyStatusWidget::LatencyStatusWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/client/latency_status_widget.h b/cockatrice/src/client/latency_status_widget.h index d9e1d130c..24d6fda4d 100644 --- a/cockatrice/src/client/latency_status_widget.h +++ b/cockatrice/src/client/latency_status_widget.h @@ -7,8 +7,10 @@ #define LATENCY_STATUS_WIDGET_H #include +#include #include #include +#include class QLabel; class LatencyGraphWidget; diff --git a/cockatrice/src/client/network/connection_controller/remote_connection_controller.cpp b/cockatrice/src/client/network/connection_controller/remote_connection_controller.cpp index c1598bd25..7480da27e 100644 --- a/cockatrice/src/client/network/connection_controller/remote_connection_controller.cpp +++ b/cockatrice/src/client/network/connection_controller/remote_connection_controller.cpp @@ -8,14 +8,25 @@ #include "../interface/widgets/dialogs/dlg_forgot_password_reset.h" #include "../interface/widgets/dialogs/dlg_register.h" #include "../interface/widgets/utility/get_text_with_max.h" +#include "libcockatrice/protocol/pb/event_connection_closed.pb.h" +#include "libcockatrice/protocol/pb/event_server_shutdown.pb.h" +#include #include +#include #include +#include #include +#include +#include +#include #include #include #include #include +#include + +class QWidget; ConnectionController::ConnectionController(QWidget *dialogParent, QObject *parent) : QObject(parent), dialogParent(dialogParent) diff --git a/cockatrice/src/client/network/connection_controller/remote_connection_controller.h b/cockatrice/src/client/network/connection_controller/remote_connection_controller.h index bae99a3e0..d4a832c75 100644 --- a/cockatrice/src/client/network/connection_controller/remote_connection_controller.h +++ b/cockatrice/src/client/network/connection_controller/remote_connection_controller.h @@ -2,17 +2,22 @@ #define COCKATRICE_REMOTE_CONNECTION_CONTROLLER_H #include "abstract_client.h" +#include "latency_tracker.h" #include #include #include -#include -#include -#include +#include +#include class RemoteClient; class ServerInfo_User; class DlgConnect; +class Event_ConnectionClosed; +class Event_ServerShutdown; +class QThread; +class QWidget; +template class QList; /** * Owns the RemoteClient and its worker thread. diff --git a/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp b/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp index 42292b2aa..d5cfdbbc9 100644 --- a/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp +++ b/cockatrice/src/client/network/interfaces/deck_stats_interface.cpp @@ -1,11 +1,22 @@ #include "deck_stats_interface.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" + +#include #include #include +#include #include #include #include +#include +#include +#include +#include #include +#include #include #include #include diff --git a/cockatrice/src/client/network/interfaces/deck_stats_interface.h b/cockatrice/src/client/network/interfaces/deck_stats_interface.h index 09bf998de..e7791075c 100644 --- a/cockatrice/src/client/network/interfaces/deck_stats_interface.h +++ b/cockatrice/src/client/network/interfaces/deck_stats_interface.h @@ -7,7 +7,8 @@ #ifndef DECKSTATS_INTERFACE_H #define DECKSTATS_INTERFACE_H -#include +#include +#include class QByteArray; class QNetworkAccessManager; diff --git a/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp b/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp index 627b7fe34..30044c2b6 100644 --- a/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp +++ b/cockatrice/src/client/network/interfaces/tapped_out_interface.cpp @@ -1,11 +1,28 @@ #include "tapped_out_interface.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" + +#include +#include #include +#include #include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include diff --git a/cockatrice/src/client/network/interfaces/tapped_out_interface.h b/cockatrice/src/client/network/interfaces/tapped_out_interface.h index 32f9369d5..615991b07 100644 --- a/cockatrice/src/client/network/interfaces/tapped_out_interface.h +++ b/cockatrice/src/client/network/interfaces/tapped_out_interface.h @@ -9,6 +9,7 @@ #include #include +#include inline Q_LOGGING_CATEGORY(TappedOutInterfaceLog, "tapped_out_interface"); diff --git a/cockatrice/src/client/network/parsers/deck_link_to_api_transformer.cpp b/cockatrice/src/client/network/parsers/deck_link_to_api_transformer.cpp index 010b63684..7127b0a29 100644 --- a/cockatrice/src/client/network/parsers/deck_link_to_api_transformer.cpp +++ b/cockatrice/src/client/network/parsers/deck_link_to_api_transformer.cpp @@ -1,6 +1,7 @@ #include "deck_link_to_api_transformer.h" #include +#include namespace DeckLinkToApiTransformer { diff --git a/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.cpp b/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.cpp index dae633717..192029b23 100644 --- a/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.cpp +++ b/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.cpp @@ -1,21 +1,36 @@ #include "spoiler_background_updater.h" -#include "../../../../interface/window_main.h" #include "../../../../main.h" #include "../../../settings/cache_settings.h" +#include #include #include #include +#include #include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include #include -#include +#include +#include +#include #include #include #include #include +#include +#include #include #define SPOILERS_STATUS_URL "https://raw.githubusercontent.com/Cockatrice/Magic-Spoiler/files/SpoilerSeasonEnabled" @@ -163,7 +178,15 @@ bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data) // Data written, so reload the card database qCInfo(SpoilerBackgroundUpdaterLog) << "Spoiler Service Data Written"; - const auto reloadOk = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); + // Spoilers can introduce sets the config has never seen; the loader never + // runs checkUnknownSets() itself, so run it once the finished snapshot has + // been swapped in. + auto *watcher = new QFutureWatcher(this); + connect(watcher, &QFutureWatcher::finished, this, [watcher] { + watcher->deleteLater(); + CardDatabaseManager::getInstance()->checkUnknownSets(); + }); + watcher->setFuture(QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); })); // If the user has notifications enabled, let them know // when the database was last updated diff --git a/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.h b/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.h index 03d4897a2..a6c4ed00f 100644 --- a/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.h +++ b/cockatrice/src/client/network/update/card_spoiler/spoiler_background_updater.h @@ -10,7 +10,11 @@ #include #include #include -#include +#include +#include + +class QProcess; +class QUrl; inline Q_LOGGING_CATEGORY(SpoilerBackgroundUpdaterLog, "spoiler_background_updater"); diff --git a/cockatrice/src/client/network/update/client/client_update_checker.h b/cockatrice/src/client/network/update/client/client_update_checker.h index 1a89de533..16cbd0369 100644 --- a/cockatrice/src/client/network/update/client/client_update_checker.h +++ b/cockatrice/src/client/network/update/client/client_update_checker.h @@ -6,9 +6,12 @@ #ifndef CLIENT_UPDATE_CHECKER_H #define CLIENT_UPDATE_CHECKER_H -#include +#include "release_channel.h" -class Release; +#include +#include +#include +#include /** * We use a singleton instance of UpdateChannel, which can cause interference and feedback loops when multiple objects diff --git a/cockatrice/src/client/network/update/client/release_channel.cpp b/cockatrice/src/client/network/update/client/release_channel.cpp index f401dfd00..45c503623 100644 --- a/cockatrice/src/client/network/update/client/release_channel.cpp +++ b/cockatrice/src/client/network/update/client/release_channel.cpp @@ -2,15 +2,27 @@ #include "version_string.h" +#include +#include #include #include #include -#include +#include +#include +#include +#include +#include #include +#include #include -#include +#include +#include +#include +#include #include #include +#include +#include #if defined(Q_OS_MACOS) #include diff --git a/cockatrice/src/client/network/update/client/release_channel.h b/cockatrice/src/client/network/update/client/release_channel.h index e038cb2f4..183a766ab 100644 --- a/cockatrice/src/client/network/update/client/release_channel.h +++ b/cockatrice/src/client/network/update/client/release_channel.h @@ -11,8 +11,9 @@ #include #include #include -#include +#include #include +#include #include inline Q_LOGGING_CATEGORY(ReleaseChannelLog, "release_channel"); diff --git a/cockatrice/src/client/network/update/client/update_downloader.cpp b/cockatrice/src/client/network/update/client/update_downloader.cpp index a71bcf8f8..c86972d60 100644 --- a/cockatrice/src/client/network/update/client/update_downloader.cpp +++ b/cockatrice/src/client/network/update/client/update_downloader.cpp @@ -1,6 +1,14 @@ #include "update_downloader.h" +#include +#include +#include +#include +#include +#include +#include #include +#include UpdateDownloader::UpdateDownloader(QObject *parent) : QObject(parent), response(nullptr) { diff --git a/cockatrice/src/client/network/update/client/update_downloader.h b/cockatrice/src/client/network/update/client/update_downloader.h index 9a0caccbc..8aeefb22a 100644 --- a/cockatrice/src/client/network/update/client/update_downloader.h +++ b/cockatrice/src/client/network/update/client/update_downloader.h @@ -7,8 +7,14 @@ #ifndef COCKATRICE_UPDATEDOWNLOADER_H #define COCKATRICE_UPDATEDOWNLOADER_H +#include #include -#include +#include +#include +#include +#include + +class QNetworkAccessManager; class UpdateDownloader : public QObject { diff --git a/cockatrice/src/client/settings/cache_settings.cpp b/cockatrice/src/client/settings/cache_settings.cpp index 0f8693f2d..08eccf1e4 100644 --- a/cockatrice/src/client/settings/cache_settings.cpp +++ b/cockatrice/src/client/settings/cache_settings.cpp @@ -2,15 +2,20 @@ #include "../network/update/client/release_channel.h" #include "card_counter_settings.h" +#include "libcockatrice/interfaces/interface_card_database_path_provider.h" #include "shortcuts_settings.h" -#include "version_string.h" +#include #include #include #include #include +#include #include +#include #include +#include +#include #include #include #include @@ -128,6 +133,10 @@ SettingsCache::SettingsCache() // Migrate settings from global.ini to per-class INI files (runs at most once) SettingsMigration::migrateSettingsFromGlobalIni(settingsPath); + // Repair gamefilters.ini keys renamed to camelCase by #7084 for profiles that migrated + // before that rename (idempotent, safe to run on every startup, portable builds included). + SettingsMigration::migrateGameFiltersToCamelCase(settingsPath); + shortcutsSettings = new ShortcutsSettings(settingsPath, this); cardDatabaseSettings = new CardDatabaseSettings(settingsPath, this); serversSettings = new ServersSettings(settingsPath, this); diff --git a/cockatrice/src/client/settings/cache_settings.h b/cockatrice/src/client/settings/cache_settings.h index 7a90d82f1..5f699247d 100644 --- a/cockatrice/src/client/settings/cache_settings.h +++ b/cockatrice/src/client/settings/cache_settings.h @@ -7,11 +7,13 @@ #ifndef SETTINGSCACHE_H #define SETTINGSCACHE_H +#include #include +#include #include #include #include -#include +#include inline Q_LOGGING_CATEGORY(SettingsCacheLog, "settings_cache"); diff --git a/cockatrice/src/client/settings/card_counter_settings.cpp b/cockatrice/src/client/settings/card_counter_settings.cpp index d4030c174..4bdd581b5 100644 --- a/cockatrice/src/client/settings/card_counter_settings.cpp +++ b/cockatrice/src/client/settings/card_counter_settings.cpp @@ -1,8 +1,15 @@ #include "card_counter_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include #include #include +#include #include +#include + +class QObject; CardCounterSettings::CardCounterSettings(const QString &settingsPath, QObject *parent) : SettingsManager(settingsPath + "card_counters.ini", "cards", "counters", parent) diff --git a/cockatrice/src/client/settings/card_counter_settings.h b/cockatrice/src/client/settings/card_counter_settings.h index 2ac658177..e5ca0a9bb 100644 --- a/cockatrice/src/client/settings/card_counter_settings.h +++ b/cockatrice/src/client/settings/card_counter_settings.h @@ -7,10 +7,12 @@ #ifndef CARD_COUNTER_SETTINGS_H #define CARD_COUNTER_SETTINGS_H +#include #include +#include -class QSettings; class QColor; +class QObject; class CardCounterSettings : public SettingsManager { diff --git a/cockatrice/src/client/settings/shortcut_treeview.cpp b/cockatrice/src/client/settings/shortcut_treeview.cpp index b909d47ac..4a5bafb01 100644 --- a/cockatrice/src/client/settings/shortcut_treeview.cpp +++ b/cockatrice/src/client/settings/shortcut_treeview.cpp @@ -3,7 +3,24 @@ #include "cache_settings.h" #include "shortcuts_settings.h" +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QObject; +class QWidget; ShortcutFilterProxyModel::ShortcutFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { diff --git a/cockatrice/src/client/settings/shortcut_treeview.h b/cockatrice/src/client/settings/shortcut_treeview.h index afaf7e7ed..53f3fa0ef 100644 --- a/cockatrice/src/client/settings/shortcut_treeview.h +++ b/cockatrice/src/client/settings/shortcut_treeview.h @@ -8,8 +8,13 @@ #define SHORTCUT_TREEVIEW_H #include -#include +#include #include +#include + +class QObject; +class QStandardItemModel; +class QWidget; /** * Custom implementation of QSortFilterProxyModel that appends the source and parent strings together when filtering diff --git a/cockatrice/src/client/settings/shortcuts_settings.cpp b/cockatrice/src/client/settings/shortcuts_settings.cpp index 2ff65ab6f..ffb4afcac 100644 --- a/cockatrice/src/client/settings/shortcuts_settings.cpp +++ b/cockatrice/src/client/settings/shortcuts_settings.cpp @@ -2,9 +2,13 @@ #include #include +#include #include +#include +#include +#include #include -#include +#include ShortcutKey::ShortcutKey(const QString &_name, QList _sequence, ShortcutGroup::Groups _group) : QList(_sequence), name(_name), group(_group) diff --git a/cockatrice/src/client/settings/shortcuts_settings.h b/cockatrice/src/client/settings/shortcuts_settings.h index f4ebc204e..24790a407 100644 --- a/cockatrice/src/client/settings/shortcuts_settings.h +++ b/cockatrice/src/client/settings/shortcuts_settings.h @@ -8,9 +8,18 @@ #define SHORTCUTSSETTINGS_H #include +#include +#include +#include #include +#include #include -#include +#include +#include +#include +#include +#include +#include inline Q_LOGGING_CATEGORY(ShortcutsSettingsLog, "shortcuts_settings"); diff --git a/cockatrice/src/client/sound_engine.cpp b/cockatrice/src/client/sound_engine.cpp index 96cafa3d3..4ac142cf4 100644 --- a/cockatrice/src/client/sound_engine.cpp +++ b/cockatrice/src/client/sound_engine.cpp @@ -4,8 +4,15 @@ #include #include +#include #include +#include +#include #include +#include +#include +#include +#include #include #define DEFAULT_THEME_NAME "Default" diff --git a/cockatrice/src/client/sound_engine.h b/cockatrice/src/client/sound_engine.h index 0c201523a..8167c71b5 100644 --- a/cockatrice/src/client/sound_engine.h +++ b/cockatrice/src/client/sound_engine.h @@ -7,17 +7,17 @@ #ifndef SOUNDENGINE_H #define SOUNDENGINE_H -#include #include #include -#include #include #include +#include + +class QAudioOutput; +class QMediaPlayer; inline Q_LOGGING_CATEGORY(SoundEngineLog, "sound_engine"); -class QBuffer; - typedef QMap QStringMap; class SoundEngine : public QObject diff --git a/cockatrice/src/database/interface/settings_card_preference_provider.h b/cockatrice/src/database/interface/settings_card_preference_provider.h index 64502e3a7..1feb2006b 100644 --- a/cockatrice/src/database/interface/settings_card_preference_provider.h +++ b/cockatrice/src/database/interface/settings_card_preference_provider.h @@ -13,11 +13,6 @@ public: { return SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardName); } - - [[nodiscard]] bool getIncludeRebalancedCards() const override - { - return SettingsCache::instance().cardsDisplay().getIncludeRebalancedCards(); - } }; #endif // COCKATRICE_SETTINGS_CARD_PREFERENCE_PROVIDER_H diff --git a/cockatrice/src/filters/deck_filter_string.cpp b/cockatrice/src/filters/deck_filter_string.cpp index a2b7519a8..616311750 100644 --- a/cockatrice/src/filters/deck_filter_string.cpp +++ b/cockatrice/src/filters/deck_filter_string.cpp @@ -1,9 +1,27 @@ #include "deck_filter_string.h" +#include "../interface/deck_loader/loaded_deck.h" +#include "libcockatrice/card/card_localization.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" + +#include +#include #include +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include static peg::parser search(R"( Start <- QueryPartList diff --git a/cockatrice/src/filters/deck_filter_string.h b/cockatrice/src/filters/deck_filter_string.h index 5b1419004..76b891b59 100644 --- a/cockatrice/src/filters/deck_filter_string.h +++ b/cockatrice/src/filters/deck_filter_string.h @@ -7,13 +7,14 @@ #ifndef DECK_FILTER_STRING_H #define DECK_FILTER_STRING_H -#include "../interface/deck_loader/loaded_deck.h" - #include #include #include #include +struct CardSearchLanguage; +struct LoadedDeck; + inline Q_LOGGING_CATEGORY(DeckFilterStringLog, "deck_filter_string"); /** diff --git a/cockatrice/src/filters/filter_builder.cpp b/cockatrice/src/filters/filter_builder.cpp index f109fbcd3..6cc893224 100644 --- a/cockatrice/src/filters/filter_builder.cpp +++ b/cockatrice/src/filters/filter_builder.cpp @@ -5,8 +5,15 @@ #include #include +#include #include +#include +#include +#include +#include +#include #include +#include FilterBuilder::FilterBuilder(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/filters/filter_builder.h b/cockatrice/src/filters/filter_builder.h index 98fe3fd02..2aa38c992 100644 --- a/cockatrice/src/filters/filter_builder.h +++ b/cockatrice/src/filters/filter_builder.h @@ -8,8 +8,8 @@ #define FILTERBUILDER_H #include +#include -class QCheckBox; class QComboBox; class LineEditUnfocusable; class CardFilter; diff --git a/cockatrice/src/filters/filter_tree_model.cpp b/cockatrice/src/filters/filter_tree_model.cpp index 33b54530e..b3bf307f1 100644 --- a/cockatrice/src/filters/filter_tree_model.cpp +++ b/cockatrice/src/filters/filter_tree_model.cpp @@ -1,8 +1,15 @@ #include "filter_tree_model.h" +#include #include +#include +#include +#include #include #include +#include + +class QObject; FilterTreeModel::FilterTreeModel(QObject *parent) : QAbstractItemModel(parent) { diff --git a/cockatrice/src/filters/filter_tree_model.h b/cockatrice/src/filters/filter_tree_model.h index 7452f7a61..826fcc941 100644 --- a/cockatrice/src/filters/filter_tree_model.h +++ b/cockatrice/src/filters/filter_tree_model.h @@ -8,11 +8,15 @@ #define FILTERTREEMODEL_H #include +#include +#include #include +#include +#include class FilterTree; -class CardFilter; class FilterTreeNode; +class QObject; class FilterTreeModel : public QAbstractItemModel { diff --git a/cockatrice/src/filters/syntax_help.cpp b/cockatrice/src/filters/syntax_help.cpp index fa5338a41..baf5764d0 100644 --- a/cockatrice/src/filters/syntax_help.cpp +++ b/cockatrice/src/filters/syntax_help.cpp @@ -1,8 +1,21 @@ #include "syntax_help.h" +#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include +#include /** * Creates the card search syntax help window diff --git a/cockatrice/src/filters/syntax_help.h b/cockatrice/src/filters/syntax_help.h index d06fe03e5..52c878691 100644 --- a/cockatrice/src/filters/syntax_help.h +++ b/cockatrice/src/filters/syntax_help.h @@ -8,9 +8,10 @@ #ifndef SEARCH_SYNTAX_HELP_H #define SEARCH_SYNTAX_HELP_H -#include #include -#include + +class QLineEdit; +class QTextBrowser; inline Q_LOGGING_CATEGORY(SyntaxHelpLog, "syntax_help"); diff --git a/cockatrice/src/game/abstract_game.cpp b/cockatrice/src/game/abstract_game.cpp index 6aa2ab28f..efc575eff 100644 --- a/cockatrice/src/game/abstract_game.cpp +++ b/cockatrice/src/game/abstract_game.cpp @@ -1,7 +1,18 @@ #include "abstract_game.h" -#include "../interface/widgets/tabs/tab_game.h" +#include "game_event_handler.h" +#include "game_meta_info.h" +#include "game_state.h" +#include "libcockatrice/protocol/pb/game_replay.pb.h" +#include "player/player_info.h" #include "player/player_logic.h" +#include "player/player_manager.h" +#include "zones/card_zone_logic.h" + +#include +#include + +class AbstractClient; AbstractGame::AbstractGame(QObject *_parent) : QObject(_parent) { diff --git a/cockatrice/src/game/abstract_game.h b/cockatrice/src/game/abstract_game.h index fcf764492..326af8ac9 100644 --- a/cockatrice/src/game/abstract_game.h +++ b/cockatrice/src/game/abstract_game.h @@ -7,15 +7,18 @@ #ifndef COCKATRICE_ABSTRACT_GAME_H #define COCKATRICE_ABSTRACT_GAME_H -#include "game_event_handler.h" -#include "game_meta_info.h" -#include "game_state.h" -#include "player/player_manager.h" - #include -#include +#include +#include class CardItem; +class AbstractClient; +class GameEventHandler; +class GameMetaInfo; +class GameReplay; +class GameState; +class PlayerManager; + class AbstractGame : public QObject { Q_OBJECT diff --git a/cockatrice/src/game/arrow_registry.cpp b/cockatrice/src/game/arrow_registry.cpp index 286764b3b..c05134a75 100644 --- a/cockatrice/src/game/arrow_registry.cpp +++ b/cockatrice/src/game/arrow_registry.cpp @@ -1,6 +1,9 @@ #include "arrow_registry.h" #include "../game_graphics/board/arrow_item.h" +#include "board/arrow_data.h" + +#include void ArrowRegistry::insert(QSharedPointer data, ArrowItem *arrow) { diff --git a/cockatrice/src/game/arrow_registry.h b/cockatrice/src/game/arrow_registry.h index ef98229a2..ca3b04090 100644 --- a/cockatrice/src/game/arrow_registry.h +++ b/cockatrice/src/game/arrow_registry.h @@ -1,13 +1,13 @@ #ifndef COCKATRICE_ARROW_REGISTRY_H #define COCKATRICE_ARROW_REGISTRY_H -#include "board/arrow_data.h" - +#include #include #include -#include class ArrowItem; +struct ArrowData; +template class QSharedPointer; struct ArrowKey { diff --git a/cockatrice/src/game/board/arrow_data.cpp b/cockatrice/src/game/board/arrow_data.cpp index 9e89deed0..d5accd16e 100644 --- a/cockatrice/src/game/board/arrow_data.cpp +++ b/cockatrice/src/game/board/arrow_data.cpp @@ -1,5 +1,8 @@ #include "arrow_data.h" +#include "libcockatrice/protocol/pb/serverinfo_arrow.pb.h" +#include "libcockatrice/utility/color.h" + ArrowData ArrowData::fromProto(const ServerInfo_Arrow &arrow, int creatorId, bool isLocalCreator) { ArrowData data; diff --git a/cockatrice/src/game/board/arrow_data.h b/cockatrice/src/game/board/arrow_data.h index 2752f97e3..00217512f 100644 --- a/cockatrice/src/game/board/arrow_data.h +++ b/cockatrice/src/game/board/arrow_data.h @@ -3,8 +3,8 @@ #include #include -#include -#include + +class ServerInfo_Arrow; struct ArrowData { diff --git a/cockatrice/src/game/board/card_list.cpp b/cockatrice/src/game/board/card_list.cpp index 0080b5ae6..94bae67cd 100644 --- a/cockatrice/src/game/board/card_list.cpp +++ b/cockatrice/src/game/board/card_list.cpp @@ -1,9 +1,14 @@ #include "card_list.h" #include "../../game_graphics/board/card_item.h" +#include "libcockatrice/card/printing/exact_card.h" +#include #include +#include +#include #include +#include #include CardList::CardList(bool _contentsKnown) : QList(), contentsKnown(_contentsKnown) diff --git a/cockatrice/src/game/board/card_list.h b/cockatrice/src/game/board/card_list.h index 85a6848b7..b5427df0d 100644 --- a/cockatrice/src/game/board/card_list.h +++ b/cockatrice/src/game/board/card_list.h @@ -9,6 +9,8 @@ #include #include +#include +#include inline Q_LOGGING_CATEGORY(CardListLog, "card_list"); diff --git a/cockatrice/src/game/board/card_state.cpp b/cockatrice/src/game/board/card_state.cpp index 4319400d7..3f879a849 100644 --- a/cockatrice/src/game/board/card_state.cpp +++ b/cockatrice/src/game/board/card_state.cpp @@ -1,5 +1,7 @@ #include "card_state.h" +#include + void CardState::resetState(bool keepAnnotations) { attacking = false; diff --git a/cockatrice/src/game/board/card_state.h b/cockatrice/src/game/board/card_state.h index 0498b1aa2..ca7aaf927 100644 --- a/cockatrice/src/game/board/card_state.h +++ b/cockatrice/src/game/board/card_state.h @@ -3,9 +3,12 @@ #include #include +#include +#include class CardZoneLogic; class CardItem; + class CardState : public QObject { Q_OBJECT diff --git a/cockatrice/src/game/board/counter_state.cpp b/cockatrice/src/game/board/counter_state.cpp index 0970e4272..5d8c73d5b 100644 --- a/cockatrice/src/game/board/counter_state.cpp +++ b/cockatrice/src/game/board/counter_state.cpp @@ -1,5 +1,7 @@ #include "counter_state.h" +#include "libcockatrice/protocol/pb/serverinfo_counter.pb.h" + #include CounterState::CounterState(int id, const QString &name, const QColor &color, int radius, int value, QObject *parent) diff --git a/cockatrice/src/game/board/counter_state.h b/cockatrice/src/game/board/counter_state.h index 4c7b34473..8badc6217 100644 --- a/cockatrice/src/game/board/counter_state.h +++ b/cockatrice/src/game/board/counter_state.h @@ -4,7 +4,9 @@ #include #include #include -#include +#include + +class ServerInfo_Counter; class CounterState : public QObject { diff --git a/cockatrice/src/game/game.cpp b/cockatrice/src/game/game.cpp index 4c8b109c2..7343d052a 100644 --- a/cockatrice/src/game/game.cpp +++ b/cockatrice/src/game/game.cpp @@ -1,9 +1,17 @@ #include "game.h" -#include "../interface/widgets/tabs/tab_game.h" +#include "game_meta_info.h" +#include "game_state.h" +#include "player/player_manager.h" +#include +#include +#include #include +class AbstractClient; +class QObject; + Game::Game(QObject *_parent, bool isLocalGame, QList &_clients, diff --git a/cockatrice/src/game/game.h b/cockatrice/src/game/game.h index 4f912664c..6a309cfb2 100644 --- a/cockatrice/src/game/game.h +++ b/cockatrice/src/game/game.h @@ -9,7 +9,14 @@ #include "abstract_game.h" -#include +#include + +class AbstractClient; +class Event_GameJoined; +class QObject; +class QString; +template class QMap; +template class QList; class Game : public AbstractGame { diff --git a/cockatrice/src/game/game_event_handler.cpp b/cockatrice/src/game/game_event_handler.cpp index f146cdbb4..7b08af47c 100644 --- a/cockatrice/src/game/game_event_handler.cpp +++ b/cockatrice/src/game/game_event_handler.cpp @@ -1,9 +1,30 @@ #include "game_event_handler.h" -#include "../game_graphics/log/message_log_widget.h" -#include "../interface/widgets/tabs/tab_game.h" #include "abstract_game.h" +#include "game_meta_info.h" +#include "game_state.h" +#include "libcockatrice/protocol/pb/commands.pb.h" +#include "libcockatrice/protocol/pb/game_commands.pb.h" +#include "libcockatrice/protocol/pb/game_event.pb.h" +#include "libcockatrice/protocol/pb/game_event_context.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_player.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "player/player_event_handler.h" +#include "player/player_info.h" +#include "player/player_logic.h" +#include "player/player_manager.h" +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -13,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +48,8 @@ #include #include #include +#include +#include GameEventHandler::GameEventHandler(AbstractGame *_game) : QObject(_game), game(_game) { @@ -255,8 +277,6 @@ void GameEventHandler::eventSpectatorLeave(const Event_Leave &event, emit spectatorLeft(eventPlayerId); game->getPlayerManager()->removeSpectator(eventPlayerId); - - emitUserEvent(); } void GameEventHandler::eventGameStateChanged(const Event_GameStateChanged &event, @@ -443,9 +463,9 @@ void GameEventHandler::eventJoin(const Event_Join &event, int /*eventPlayerId*/, PlayerLogic *newPlayer = game->getPlayerManager()->addPlayer(playerId, playerInfo.user_info()); emit logJoinPlayer(newPlayer); emit playerJoined(playerInfo); - } - emitUserEvent(); + emitUserEvent(); + } } QString GameEventHandler::getLeaveReason(Event_Leave::LeaveReason reason) diff --git a/cockatrice/src/game/game_event_handler.h b/cockatrice/src/game/game_event_handler.h index 99277abb7..30021d295 100644 --- a/cockatrice/src/game/game_event_handler.h +++ b/cockatrice/src/game/game_event_handler.h @@ -19,23 +19,29 @@ #include #include +#include +#include +#include #include +#include + +// IWYU pragma: keep +// GameEventContext, ServerInfo_Player and ServerInfo_User are passed by value +// to signals and slots, so the moc-generated code needs the complete types. +#include #include +#include class AbstractClient; class AbstractGame; -class CommandContainer; -class GameCommand; class GameEventContainer; class GameEventContext; class PendingCommand; class PlayerLogic; class Response; - class Event_GameStateChanged; class Event_PlayerPropertiesChanged; class Event_Join; -class Event_Leave; class Event_GameHostChanged; class Event_GameClosed; class Event_SetActivePlayer; @@ -44,6 +50,15 @@ class Event_GameSay; class Event_Kicked; class Event_ReverseTurn; class Event_Ping; +class ServerInfo_PlayerProperties; +namespace google +{ +namespace protobuf +{ +class Message; +} // namespace protobuf +} // namespace google +template class QList; inline Q_LOGGING_CATEGORY(GameEventHandlerLog, "game_event_handler"); diff --git a/cockatrice/src/game/game_meta_info.h b/cockatrice/src/game/game_meta_info.h index cdba1605f..ef8f0c08e 100644 --- a/cockatrice/src/game/game_meta_info.h +++ b/cockatrice/src/game/game_meta_info.h @@ -9,13 +9,16 @@ #include #include +#include #include +#include // Translation layer class to expose protobuf safely and hook it up to Qt Signals. // This class de-couples the domain object (i.e. the GameMetaInfo) from the network object. // If the network object changes, only this class needs to be adjusted. class AbstractGame; + class GameMetaInfo : public QObject { Q_OBJECT diff --git a/cockatrice/src/game/game_state.cpp b/cockatrice/src/game/game_state.cpp index dc9ba02a3..e3bbbec00 100644 --- a/cockatrice/src/game/game_state.cpp +++ b/cockatrice/src/game/game_state.cpp @@ -2,6 +2,11 @@ #include "abstract_game.h" +#include +#include + +class AbstractClient; + GameState::GameState(AbstractGame *parent, int _secondsElapsed, int _hostId, diff --git a/cockatrice/src/game/game_state.h b/cockatrice/src/game/game_state.h index 94bbb853c..55784fb91 100644 --- a/cockatrice/src/game/game_state.h +++ b/cockatrice/src/game/game_state.h @@ -7,12 +7,14 @@ #ifndef COCKATRICE_GAME_STATE_H #define COCKATRICE_GAME_STATE_H -#include -#include +#include +#include +#include +#include class AbstractGame; -class ServerInfo_PlayerProperties; -class ServerInfo_User; +class AbstractClient; +class QTimer; class GameState : public QObject { diff --git a/cockatrice/src/game/phase.cpp b/cockatrice/src/game/phase.cpp index 7fb1700a5..f56228279 100644 --- a/cockatrice/src/game/phase.cpp +++ b/cockatrice/src/game/phase.cpp @@ -1,5 +1,10 @@ #include "phase.h" +#include +#include +#include +#include + Phase::Phase(const QString &_name, const QString &_color, const QString &_soundFileName) : name(_name), color(_color), soundFileName(_soundFileName) { diff --git a/cockatrice/src/game/phase.h b/cockatrice/src/game/phase.h index a888ad43b..b4eaa6e46 100644 --- a/cockatrice/src/game/phase.h +++ b/cockatrice/src/game/phase.h @@ -7,8 +7,9 @@ #ifndef PHASE_H #define PHASE_H -#include +#include #include +#include class Phase { diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp index 67c3295d6..35682ede8 100644 --- a/cockatrice/src/game/player/player_actions.cpp +++ b/cockatrice/src/game/player/player_actions.cpp @@ -1,14 +1,54 @@ #include "player_actions.h" +#include "../../client/settings/cache_settings.h" +#include "../../game_graphics/board/card_item.h" +#include "../../game_graphics/dialogs/dlg_create_token.h" #include "../../game_graphics/dialogs/dlg_move_top_cards_until.h" -#include "../../game_graphics/dialogs/dlg_roll_dice.h" #include "../../game_graphics/player/card_menu_action_type.h" -#include "../../game_graphics/zones/hand_zone.h" #include "../../game_graphics/zones/table_zone.h" -#include "../../interface/widgets/tabs/tab_game.h" -#include "../../interface/widgets/utility/get_text_with_max.h" +#include "../../interface/deck_loader/loaded_deck.h" +#include "../abstract_game.h" +#include "../board/counter_state.h" +#include "../game_event_handler.h" +#include "../zones/card_zone_logic.h" +#include "../zones/hand_zone_logic.h" +#include "../zones/pile_zone_logic.h" +#include "../zones/table_zone_logic.h" #include "../zones/view_zone_logic.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/relation/card_relation_type.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/filters/filter_string.h" +#include "libcockatrice/protocol/pb/card_attributes.pb.h" +#include "libcockatrice/protocol/pb/game_commands.pb.h" +#include "libcockatrice/settings/cards_display_settings.h" +#include "player_info.h" +#include "player_logic.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -26,13 +66,16 @@ #include #include #include -#include #include #include #include #include #include #include +#include +#include +#include +#include // milliseconds in between triggers of the move top cards until action static constexpr int MOVE_TOP_CARD_UNTIL_INTERVAL = 100; diff --git a/cockatrice/src/game/player/player_actions.h b/cockatrice/src/game/player/player_actions.h index fa4d54110..8fff81635 100644 --- a/cockatrice/src/game/player/player_actions.h +++ b/cockatrice/src/game/player/player_actions.h @@ -8,17 +8,25 @@ #ifndef COCKATRICE_PLAYER_ACTIONS_H #define COCKATRICE_PLAYER_ACTIONS_H -#include "../../game_graphics/board/card_item.h" +#include "../../game_graphics/board/card_item.h" // IWYU pragma: keep - moc instantiates the metatype for QList, which Qt 6.4 needs complete #include "../../game_graphics/dialogs/dlg_create_token.h" #include "../../game_graphics/dialogs/dlg_move_top_cards_until.h" #include "../../game_graphics/player/card_menu_action_type.h" -#include "event_processing_options.h" -#include "player_logic.h" +#include "../board/card_list.h" +#include "libcockatrice/card/card_info.h" -#include #include +#include +#include #include #include +#include + +class CardItem; +class CardRelation; +class QAction; +class QTimer; +template class QList; namespace google { @@ -29,9 +37,9 @@ class Message; } // namespace google class Command_MoveCard; -class GameEventContext; class PendingCommand; class PlayerLogic; + class PlayerActions : public QObject { Q_OBJECT diff --git a/cockatrice/src/game/player/player_event_handler.cpp b/cockatrice/src/game/player/player_event_handler.cpp index 277b8b1d4..18f6573df 100644 --- a/cockatrice/src/game/player/player_event_handler.cpp +++ b/cockatrice/src/game/player/player_event_handler.cpp @@ -1,15 +1,32 @@ #include "player_event_handler.h" -#include "../../game_graphics/board/arrow_item.h" #include "../../game_graphics/board/card_item.h" #include "../../game_graphics/zones/view_zone.h" -#include "../../interface/widgets/tabs/tab_game.h" +#include "../abstract_game.h" #include "../board/arrow_data.h" #include "../board/card_list.h" +#include "../board/counter_state.h" +#include "../zones/card_zone_logic.h" +#include "../zones/hand_zone_logic.h" +#include "../zones/pile_zone_logic.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/protocol/pb/card_attributes.pb.h" +#include "libcockatrice/protocol/pb/game_event.pb.h" +#include "libcockatrice/protocol/pb/game_event_context.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_card.pb.h" +#include "libcockatrice/utility/card_ref.h" #include "player_actions.h" +#include "player_info.h" #include "player_logic.h" +#include "player_manager.h" -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -32,8 +49,9 @@ #include #include #include -#include #include +#include +#include PlayerEventHandler::PlayerEventHandler(PlayerLogic *_player) : QObject(_player), player(_player) { diff --git a/cockatrice/src/game/player/player_event_handler.h b/cockatrice/src/game/player/player_event_handler.h index 300cacd08..88254119b 100644 --- a/cockatrice/src/game/player/player_event_handler.h +++ b/cockatrice/src/game/player/player_event_handler.h @@ -22,14 +22,14 @@ #include "event_processing_options.h" #include -#include +#include #include -#include +#include +#include class CardItem; class CardZoneLogic; class PlayerLogic; - class Event_AttachCard; class Event_ChangeZoneProperties; class Event_CreateArrow; @@ -50,6 +50,9 @@ class Event_SetCardCounter; class Event_SetCounter; class Event_Shuffle; class Event_GameLogNotice; +class GameEventContext; +enum CardAttribute : int; +template class QList; /** * @class PlayerEventHandler diff --git a/cockatrice/src/game/player/player_info.cpp b/cockatrice/src/game/player/player_info.cpp index c4debde0f..aef0d82aa 100644 --- a/cockatrice/src/game/player/player_info.cpp +++ b/cockatrice/src/game/player/player_info.cpp @@ -1,5 +1,7 @@ #include "player_info.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" + PlayerInfo::PlayerInfo(const ServerInfo_User &info, int _id, bool _local, bool _judge) : id(_id), local(_local), judge(_judge) { diff --git a/cockatrice/src/game/player/player_info.h b/cockatrice/src/game/player/player_info.h index 4ec39edbd..58e877f8e 100644 --- a/cockatrice/src/game/player/player_info.h +++ b/cockatrice/src/game/player/player_info.h @@ -7,10 +7,10 @@ #ifndef COCKATRICE_PLAYER_INFO_H #define COCKATRICE_PLAYER_INFO_H -#include "../../game_graphics/player/player_target.h" - #include +#include #include +#include class PlayerInfo : public QObject { diff --git a/cockatrice/src/game/player/player_logic.cpp b/cockatrice/src/game/player/player_logic.cpp index 143df5c57..b545b7088 100644 --- a/cockatrice/src/game/player/player_logic.cpp +++ b/cockatrice/src/game/player/player_logic.cpp @@ -1,33 +1,37 @@ #include "player_logic.h" -#include "../../game_graphics/board/arrow_item.h" #include "../../game_graphics/board/card_item.h" -#include "../../game_graphics/board/counter_general.h" -#include "../../game_graphics/game_scene.h" -#include "../../game_graphics/player/player_target.h" -#include "../../game_graphics/zones/hand_zone.h" -#include "../../game_graphics/zones/pile_zone.h" -#include "../../game_graphics/zones/stack_zone.h" -#include "../../game_graphics/zones/table_zone.h" -#include "../../interface/theme_manager.h" -#include "../../interface/widgets/tabs/tab_game.h" -#include "../board/card_list.h" +#include "../abstract_game.h" +#include "../board/arrow_data.h" +#include "../board/counter_state.h" +#include "../game_meta_info.h" +#include "../zones/hand_zone_logic.h" +#include "../zones/pile_zone_logic.h" +#include "../zones/stack_zone_logic.h" +#include "../zones/table_zone_logic.h" +#include "libcockatrice/protocol/pb/serverinfo_card.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_counter.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" +#include "libcockatrice/utility/zone_names.h" #include "player_actions.h" +#include "player_event_handler.h" +#include "player_info.h" +#include "player_manager.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include +#include +#include PlayerLogic::PlayerLogic(const ServerInfo_User &info, int _id, bool _local, bool _judge, AbstractGame *_parent) : QObject(_parent), game(_parent), playerInfo(new PlayerInfo(info, _id, _local, _judge)), diff --git a/cockatrice/src/game/player/player_logic.h b/cockatrice/src/game/player/player_logic.h index 6923b3afe..59da7cc32 100644 --- a/cockatrice/src/game/player/player_logic.h +++ b/cockatrice/src/game/player/player_logic.h @@ -7,57 +7,48 @@ #ifndef PLAYER_H #define PLAYER_H -#include "../../game_graphics/player/player_area.h" -#include "../../interface/widgets/menus/tearoff_menu.h" -#include "../board/arrow_data.h" -#include "../interface/deck_loader/loaded_deck.h" +#include "../zones/card_zone_logic.h" #include "../zones/hand_zone_logic.h" #include "../zones/pile_zone_logic.h" #include "../zones/stack_zone_logic.h" #include "../zones/table_zone_logic.h" -#include "player_event_handler.h" -#include "player_info.h" -#include "player_manager.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" +#include #include +#include #include #include -#include -#include -#include -#include +#include +#include #include +#include + +// IWYU pragma: keep +// ServerInfo_Card appears inside QList<...> in signal and slot +// signatures, which the moc-generated code needs to be complete. +#include + +class CardItem; +class CounterState; +class QWidget; +class ServerInfo_PlayerProperties; +struct ArrowData; +struct LoadedDeck; +template class QSharedPointer; inline Q_LOGGING_CATEGORY(PlayerLog, "player"); - -namespace google -{ -namespace protobuf -{ -class Message; -} -} // namespace google class AbstractCardItem; class AbstractGame; -class ArrowItem; -class ArrowTarget; -class CardDatabase; -class CardZone; -class CommandContainer; -class GameCommand; -class GameEvent; class PlayerInfo; class PlayerEventHandler; class PlayerActions; -class PlayerMenu; -class QAction; -class QMenu; -class ServerInfo_Arrow; class ServerInfo_Card; class ServerInfo_Counter; class ServerInfo_Player; class ServerInfo_User; -class TabGame; const int MAX_TOKENS_PER_DIALOG = 99; diff --git a/cockatrice/src/game/player/player_manager.cpp b/cockatrice/src/game/player/player_manager.cpp index 8486efbeb..4730805ad 100644 --- a/cockatrice/src/game/player/player_manager.cpp +++ b/cockatrice/src/game/player/player_manager.cpp @@ -1,8 +1,14 @@ #include "player_manager.h" #include "../abstract_game.h" +#include "../game_state.h" +#include "player_info.h" #include "player_logic.h" +#include +#include +#include + PlayerManager::PlayerManager(AbstractGame *_game, int _localPlayerId, bool _localPlayerIsJudge, diff --git a/cockatrice/src/game/player/player_manager.h b/cockatrice/src/game/player/player_manager.h index 504e65396..7a9f7645b 100644 --- a/cockatrice/src/game/player/player_manager.h +++ b/cockatrice/src/game/player/player_manager.h @@ -7,12 +7,17 @@ #ifndef COCKATRICE_PLAYER_MANAGER_H #define COCKATRICE_PLAYER_MANAGER_H +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" + #include #include +#include #include +#include class AbstractGame; class PlayerLogic; + class PlayerManager : public QObject { Q_OBJECT diff --git a/cockatrice/src/game/replay.cpp b/cockatrice/src/game/replay.cpp index dcf3e9b9b..4ab4a6321 100644 --- a/cockatrice/src/game/replay.cpp +++ b/cockatrice/src/game/replay.cpp @@ -1,6 +1,13 @@ #include "replay.h" -#include "../interface/widgets/tabs/tab_game.h" +#include "game_meta_info.h" +#include "game_state.h" +#include "player/player_manager.h" + +#include + +class GameReplay; +class QObject; Replay::Replay(QObject *_parent, const GameReplay *_replay, bool isLocalGame) : AbstractGame(_parent) { diff --git a/cockatrice/src/game/replay.h b/cockatrice/src/game/replay.h index 1c269b273..cc995dbac 100644 --- a/cockatrice/src/game/replay.h +++ b/cockatrice/src/game/replay.h @@ -10,6 +10,11 @@ #include "abstract_game.h" +#include + +class GameReplay; +class QObject; + class Replay : public AbstractGame { Q_OBJECT diff --git a/cockatrice/src/game/zones/card_zone_logic.cpp b/cockatrice/src/game/zones/card_zone_logic.cpp index 7e0585f4e..d997ab9ad 100644 --- a/cockatrice/src/game/zones/card_zone_logic.cpp +++ b/cockatrice/src/game/zones/card_zone_logic.cpp @@ -1,16 +1,25 @@ #include "card_zone_logic.h" +#include "../../client/translation.h" #include "../../game_graphics/board/card_item.h" +#include "../../game_graphics/zones/card_zone.h" #include "../../game_graphics/zones/view_zone.h" +#include "../board/card_list.h" #include "../player/player_actions.h" +#include "../player/player_info.h" #include "../player/player_logic.h" +#include "libcockatrice/card/database/card_database.h" #include "view_zone_logic.h" #include #include +#include +#include +#include #include #include #include +#include /** * @param _player the player that the zone belongs to diff --git a/cockatrice/src/game/zones/card_zone_logic.h b/cockatrice/src/game/zones/card_zone_logic.h index ae97719a9..2e232b258 100644 --- a/cockatrice/src/game/zones/card_zone_logic.h +++ b/cockatrice/src/game/zones/card_zone_logic.h @@ -10,17 +10,18 @@ #include "../../client/translation.h" #include "../board/card_list.h" +#include #include #include +#include +#include + +class CardItem; inline Q_LOGGING_CATEGORY(CardZoneLogicLog, "card_zone_logic"); class PlayerLogic; class ZoneViewZone; -class QMenu; -class QAction; -class QPainter; -class CardDragItem; class CardZoneLogic : public QObject { diff --git a/cockatrice/src/game/zones/hand_zone_logic.cpp b/cockatrice/src/game/zones/hand_zone_logic.cpp index 3bdd15902..cea17d031 100644 --- a/cockatrice/src/game/zones/hand_zone_logic.cpp +++ b/cockatrice/src/game/zones/hand_zone_logic.cpp @@ -3,6 +3,9 @@ #include "../../game_graphics/board/card_item.h" #include "card_zone_algorithms.h" +class PlayerLogic; +class QObject; + HandZoneLogic::HandZoneLogic(PlayerLogic *_player, const QString &_name, bool _hasCardAttr, diff --git a/cockatrice/src/game/zones/hand_zone_logic.h b/cockatrice/src/game/zones/hand_zone_logic.h index 400506248..c7d63bc0d 100644 --- a/cockatrice/src/game/zones/hand_zone_logic.h +++ b/cockatrice/src/game/zones/hand_zone_logic.h @@ -8,6 +8,12 @@ #define COCKATRICE_HAND_ZONE_LOGIC_H #include "card_zone_logic.h" +#include +#include + +class PlayerLogic; +class QObject; + class HandZoneLogic : public CardZoneLogic { Q_OBJECT diff --git a/cockatrice/src/game/zones/pile_zone_logic.cpp b/cockatrice/src/game/zones/pile_zone_logic.cpp index 0f374fb84..40af25cc5 100644 --- a/cockatrice/src/game/zones/pile_zone_logic.cpp +++ b/cockatrice/src/game/zones/pile_zone_logic.cpp @@ -1,6 +1,10 @@ #include "pile_zone_logic.h" #include "../../game_graphics/board/card_item.h" +#include "../board/card_list.h" + +class PlayerLogic; +class QObject; PileZoneLogic::PileZoneLogic(PlayerLogic *_player, const QString &_name, diff --git a/cockatrice/src/game/zones/pile_zone_logic.h b/cockatrice/src/game/zones/pile_zone_logic.h index 522d99b89..ed6841b75 100644 --- a/cockatrice/src/game/zones/pile_zone_logic.h +++ b/cockatrice/src/game/zones/pile_zone_logic.h @@ -8,6 +8,12 @@ #define COCKATRICE_PILE_ZONE_LOGIC_H #include "card_zone_logic.h" +#include +#include + +class PlayerLogic; +class QObject; + class PileZoneLogic : public CardZoneLogic { diff --git a/cockatrice/src/game/zones/stack_zone_logic.cpp b/cockatrice/src/game/zones/stack_zone_logic.cpp index 341d4b0e4..454274971 100644 --- a/cockatrice/src/game/zones/stack_zone_logic.cpp +++ b/cockatrice/src/game/zones/stack_zone_logic.cpp @@ -3,6 +3,9 @@ #include "../../game_graphics/board/card_item.h" #include "card_zone_algorithms.h" +class PlayerLogic; +class QObject; + StackZoneLogic::StackZoneLogic(PlayerLogic *_player, const QString &_name, bool _hasCardAttr, diff --git a/cockatrice/src/game/zones/stack_zone_logic.h b/cockatrice/src/game/zones/stack_zone_logic.h index cce4bd0fa..657d44ecf 100644 --- a/cockatrice/src/game/zones/stack_zone_logic.h +++ b/cockatrice/src/game/zones/stack_zone_logic.h @@ -8,6 +8,12 @@ #define COCKATRICE_STACK_ZONE_LOGIC_H #include "card_zone_logic.h" +#include +#include + +class PlayerLogic; +class QObject; + class StackZoneLogic : public CardZoneLogic { Q_OBJECT diff --git a/cockatrice/src/game/zones/table_zone_logic.cpp b/cockatrice/src/game/zones/table_zone_logic.cpp index a4f033819..07e4a759b 100644 --- a/cockatrice/src/game/zones/table_zone_logic.cpp +++ b/cockatrice/src/game/zones/table_zone_logic.cpp @@ -1,6 +1,13 @@ #include "table_zone_logic.h" #include "../../game_graphics/board/card_item.h" +#include "../board/card_list.h" +#include "libcockatrice/card/card_info.h" + +#include + +class PlayerLogic; +class QObject; TableZoneLogic::TableZoneLogic(PlayerLogic *_player, const QString &_name, diff --git a/cockatrice/src/game/zones/table_zone_logic.h b/cockatrice/src/game/zones/table_zone_logic.h index 6d8d64a20..8078bfd05 100644 --- a/cockatrice/src/game/zones/table_zone_logic.h +++ b/cockatrice/src/game/zones/table_zone_logic.h @@ -8,6 +8,12 @@ #define COCKATRICE_TABLE_ZONE_LOGIC_H #include "card_zone_logic.h" +#include +#include + +class PlayerLogic; +class QObject; + class TableZoneLogic : public CardZoneLogic { Q_OBJECT diff --git a/cockatrice/src/game/zones/view_zone_logic.cpp b/cockatrice/src/game/zones/view_zone_logic.cpp index de00581d1..eb3b7715f 100644 --- a/cockatrice/src/game/zones/view_zone_logic.cpp +++ b/cockatrice/src/game/zones/view_zone_logic.cpp @@ -2,8 +2,14 @@ #include "../../client/settings/cache_settings.h" #include "../../game_graphics/board/card_item.h" +#include "../board/card_list.h" +#include #include + +class PlayerLogic; +class QObject; + /** * @param _player the player that the cards are revealed to. * @param _origZone the zone the cards were revealed from. diff --git a/cockatrice/src/game/zones/view_zone_logic.h b/cockatrice/src/game/zones/view_zone_logic.h index e3080d044..6fae301e4 100644 --- a/cockatrice/src/game/zones/view_zone_logic.h +++ b/cockatrice/src/game/zones/view_zone_logic.h @@ -8,6 +8,11 @@ #define COCKATRICE_VIEW_ZONE_LOGIC_H #include "card_zone_logic.h" +#include + +class PlayerLogic; +class QObject; + class ZoneViewZoneLogic : public CardZoneLogic { Q_OBJECT diff --git a/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp b/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp index 2f43591ac..2e18fca2d 100644 --- a/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp +++ b/cockatrice/src/game_graphics/board/abstract_card_drag_item.cpp @@ -2,12 +2,20 @@ #include "../../client/settings/cache_settings.h" #include "../z_values.h" +#include "abstract_card_item.h" +#include +#include #include -#include #include #include +#include +#include +#include #include +#include + +class QPointF; const QColor GHOST_MASK = QColor(255, 255, 255, 50); diff --git a/cockatrice/src/game_graphics/board/abstract_card_drag_item.h b/cockatrice/src/game_graphics/board/abstract_card_drag_item.h index 1cbeb4fe7..18afdcbb8 100644 --- a/cockatrice/src/game_graphics/board/abstract_card_drag_item.h +++ b/cockatrice/src/game_graphics/board/abstract_card_drag_item.h @@ -7,11 +7,17 @@ #ifndef ABSTRACTCARDDRAGITEM_H #define ABSTRACTCARDDRAGITEM_H -#include "abstract_card_item.h" +#include "../card_dimensions.h" +#include "graphics_item_type.h" -class QGraphicsScene; -class CardZone; -class CardInfo; +#include +#include +#include +#include +#include +#include + +class AbstractCardItem; class AbstractCardDragItem : public QObject, public QGraphicsItem { diff --git a/cockatrice/src/game_graphics/board/abstract_card_item.cpp b/cockatrice/src/game_graphics/board/abstract_card_item.cpp index 3969b7d03..a79c5873e 100644 --- a/cockatrice/src/game_graphics/board/abstract_card_item.cpp +++ b/cockatrice/src/game_graphics/board/abstract_card_item.cpp @@ -3,19 +3,42 @@ #include "../../client/settings/cache_settings.h" #include "../../interface/card_localization.h" #include "../../interface/card_picture_loader/card_picture_loader.h" +#include "../card_dimensions.h" #include "../game_scene.h" #include "../z_values.h" +#include "abstract_graphics_item.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/utility/card_ref.h" +#include +#include #include +#include +#include #include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include #include #include #include #include +#include + +class QSizeF; AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef, PlayerLogic *_owner, int _id) : ArrowTarget(_owner, parent), id(_id), cardRef(cardRef), tapped(false), facedown(false), tapAngle(0), diff --git a/cockatrice/src/game_graphics/board/abstract_card_item.h b/cockatrice/src/game_graphics/board/abstract_card_item.h index 8cbe95282..385f9c32f 100644 --- a/cockatrice/src/game_graphics/board/abstract_card_item.h +++ b/cockatrice/src/game_graphics/board/abstract_card_item.h @@ -8,14 +8,22 @@ #define ABSTRACTCARDITEM_H #include "../animated_item.h" -#include "../card_dimensions.h" #include "arrow_target.h" #include "graphics_item_type.h" +#include +#include +#include +#include +#include #include #include +#include class PlayerLogic; +class CardInfo; +class QPainter; +class QPoint; class AbstractCardItem : public ArrowTarget, public IAnimatedItem { diff --git a/cockatrice/src/game_graphics/board/abstract_counter.cpp b/cockatrice/src/game_graphics/board/abstract_counter.cpp index 4ba04804f..8500b9c51 100644 --- a/cockatrice/src/game_graphics/board/abstract_counter.cpp +++ b/cockatrice/src/game_graphics/board/abstract_counter.cpp @@ -2,21 +2,33 @@ #include "../../client/settings/cache_settings.h" #include "../../client/settings/shortcuts_settings.h" +#include "../../game/board/counter_state.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" #include "../../game_graphics/board/translate_counter_name.h" -#include "../../interface/widgets/tabs/tab_game.h" +#include "../../interface/widgets/menus/tearoff_menu.h" #include #include +#include +#include +#include #include #include #include -#include +#include +#include +#include #include +#include +#include #include #include #include +#include + +class QWidget; AbstractCounter::AbstractCounter(CounterState *state, PlayerLogic *_player, diff --git a/cockatrice/src/game_graphics/board/abstract_counter.h b/cockatrice/src/game_graphics/board/abstract_counter.h index 67b5b4074..7ba686a93 100644 --- a/cockatrice/src/game_graphics/board/abstract_counter.h +++ b/cockatrice/src/game_graphics/board/abstract_counter.h @@ -7,18 +7,21 @@ #ifndef COUNTER_H #define COUNTER_H -#include "../../game/board/counter_state.h" #include "../../interface/widgets/menus/tearoff_menu.h" #include "../player/menu/abstract_player_component.h" +#include #include #include +#include +#include +#include class PlayerLogic; class QAction; -class QKeyEvent; class QMenu; -class QString; +class CounterState; +class QWidget; class AbstractCounter : public QObject, public QGraphicsItem, public AbstractPlayerComponent { diff --git a/cockatrice/src/game_graphics/board/abstract_graphics_item.cpp b/cockatrice/src/game_graphics/board/abstract_graphics_item.cpp index 8da8ab708..50e80d359 100644 --- a/cockatrice/src/game_graphics/board/abstract_graphics_item.cpp +++ b/cockatrice/src/game_graphics/board/abstract_graphics_item.cpp @@ -1,6 +1,14 @@ #include "abstract_graphics_item.h" +#include +#include +#include #include +#include +#include +#include +#include +#include void AbstractGraphicsItem::paintNumberEllipse(int number, int fontSize, diff --git a/cockatrice/src/game_graphics/board/abstract_graphics_item.h b/cockatrice/src/game_graphics/board/abstract_graphics_item.h index 287c2c0b3..ebc2a3761 100644 --- a/cockatrice/src/game_graphics/board/abstract_graphics_item.h +++ b/cockatrice/src/game_graphics/board/abstract_graphics_item.h @@ -7,7 +7,12 @@ #ifndef ABSTRACTGRAPHICSITEM_H #define ABSTRACTGRAPHICSITEM_H -#include +#include +#include +#include + +class QGraphicsItem; +class QPainter; /** * Parent class of all objects that appear in a game. diff --git a/cockatrice/src/game_graphics/board/arrow_item.cpp b/cockatrice/src/game_graphics/board/arrow_item.cpp index 664d44ecc..c5a9b9c5e 100644 --- a/cockatrice/src/game_graphics/board/arrow_item.cpp +++ b/cockatrice/src/game_graphics/board/arrow_item.cpp @@ -2,28 +2,42 @@ #include "arrow_item.h" #include "../../client/settings/cache_settings.h" +#include "../../game/board/arrow_data.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" #include "../game_scene.h" #include "../player/player_target.h" #include "../z_values.h" -#include "../zones/card_zone.h" #include "card_item.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/protocol/pb/color.pb.h" -#include +#include #include #include #include +#include +#include #include +#include +#include +#include +#include +#include #include #include #include #include -#include #include #include #include #include +#include +#include +#include +#include namespace { diff --git a/cockatrice/src/game_graphics/board/arrow_item.h b/cockatrice/src/game_graphics/board/arrow_item.h index 76a2d5d6c..2395165fc 100644 --- a/cockatrice/src/game_graphics/board/arrow_item.h +++ b/cockatrice/src/game_graphics/board/arrow_item.h @@ -6,15 +6,23 @@ #include "arrow_target.h" #include "graphics_item_type.h" +#include #include #include +#include +#include +#include #include +#include #include +#include #include +#include +#include class CardItem; -class QGraphicsSceneMouseEvent; class PlayerLogic; +template class QSharedPointer; class ArrowItem : public QObject, public QGraphicsItem, public IAnimatedItem { diff --git a/cockatrice/src/game_graphics/board/arrow_target.cpp b/cockatrice/src/game_graphics/board/arrow_target.cpp index 79b21d921..024479ee6 100644 --- a/cockatrice/src/game_graphics/board/arrow_target.cpp +++ b/cockatrice/src/game_graphics/board/arrow_target.cpp @@ -1,7 +1,8 @@ #include "arrow_target.h" -#include "../../game/player/player_logic.h" -#include "arrow_item.h" +#include + +class QGraphicsItem; ArrowTarget::ArrowTarget(PlayerLogic *_owner, QGraphicsItem *parent) : AbstractGraphicsItem(parent), owner(_owner) { diff --git a/cockatrice/src/game_graphics/board/arrow_target.h b/cockatrice/src/game_graphics/board/arrow_target.h index bf89c5456..5c55e0e5d 100644 --- a/cockatrice/src/game_graphics/board/arrow_target.h +++ b/cockatrice/src/game_graphics/board/arrow_target.h @@ -9,10 +9,10 @@ #include "abstract_graphics_item.h" -#include +#include class PlayerLogic; -class ArrowItem; +class QGraphicsItem; class ArrowTarget : public AbstractGraphicsItem { diff --git a/cockatrice/src/game_graphics/board/card_drag_item.cpp b/cockatrice/src/game_graphics/board/card_drag_item.cpp index 49467c5c9..265ea759c 100644 --- a/cockatrice/src/game_graphics/board/card_drag_item.cpp +++ b/cockatrice/src/game_graphics/board/card_drag_item.cpp @@ -6,9 +6,20 @@ #include "../zones/view_zone.h" #include "card_item.h" +#include +#include #include +#include +#include #include +#include +#include #include +#include +#include +#include + +class CardZoneLogic; CardDragItem::CardDragItem(CardItem *_item, int _id, diff --git a/cockatrice/src/game_graphics/board/card_drag_item.h b/cockatrice/src/game_graphics/board/card_drag_item.h index 74d25ad04..d5e9a9e83 100644 --- a/cockatrice/src/game_graphics/board/card_drag_item.h +++ b/cockatrice/src/game_graphics/board/card_drag_item.h @@ -9,7 +9,11 @@ #include "abstract_card_drag_item.h" +#include +#include + class CardItem; +class CardZone; class CardDragItem : public AbstractCardDragItem { diff --git a/cockatrice/src/game_graphics/board/card_item.cpp b/cockatrice/src/game_graphics/board/card_item.cpp index c2dc455cc..a04d86c15 100644 --- a/cockatrice/src/game_graphics/board/card_item.cpp +++ b/cockatrice/src/game_graphics/board/card_item.cpp @@ -1,26 +1,52 @@ #include "card_item.h" #include "../../client/settings/cache_settings.h" -#include "../../client/settings/card_counter_settings.h" +#include "../../game/abstract_game.h" +#include "../../game/board/card_state.h" +#include "../../game/game_state.h" #include "../../game/phase.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/player/player_manager.h" +#include "../../game/zones/card_zone_logic.h" +#include "../../game/zones/table_zone_logic.h" #include "../../game/zones/view_zone_logic.h" -#include "../../interface/widgets/tabs/tab_game.h" +#include "../card_dimensions.h" #include "../game_scene.h" -#include "../zones/table_zone.h" -#include "../zones/view_zone.h" #include "arrow_item.h" #include "card_drag_item.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/protocol/pb/serverinfo_cardcounter.pb.h" #include <../../client/settings/card_counter_settings.h> #include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include + +struct CardRef; CardItem::CardItem(PlayerLogic *_owner, QGraphicsItem *parent, diff --git a/cockatrice/src/game_graphics/board/card_item.h b/cockatrice/src/game_graphics/board/card_item.h index 2ba43d03d..df79ef378 100644 --- a/cockatrice/src/game_graphics/board/card_item.h +++ b/cockatrice/src/game_graphics/board/card_item.h @@ -8,18 +8,24 @@ #define CARDITEM_H #include "../../game/board/card_state.h" -#include "../../game/zones/card_zone_logic.h" #include "abstract_card_item.h" +#include "graphics_item_type.h" -#include +#include +#include +#include +#include +#include +#include -class CardDatabase; class CardDragItem; -class CardZone; class ServerInfo_Card; class PlayerLogic; -class QAction; class QColor; +class CardZoneLogic; +class QGraphicsItem; +struct CardRef; +template class QMap; const int ROTATION_DEGREES_PER_FRAME = 10; diff --git a/cockatrice/src/game_graphics/board/counter_general.cpp b/cockatrice/src/game_graphics/board/counter_general.cpp index 379c6f837..4a8bbd6a4 100644 --- a/cockatrice/src/game_graphics/board/counter_general.cpp +++ b/cockatrice/src/game_graphics/board/counter_general.cpp @@ -3,7 +3,20 @@ #include "../../interface/pixel_map_generator.h" #include "abstract_graphics_item.h" +#include #include +#include +#include +#include +#include +#include +#include +#include +#include + +class CounterState; +class PlayerLogic; +class QGraphicsItem; GeneralCounter::GeneralCounter(CounterState *state, PlayerLogic *player, bool useNameForShortcut, QGraphicsItem *parent) : AbstractCounter(state, player, true, useNameForShortcut, parent) diff --git a/cockatrice/src/game_graphics/board/counter_general.h b/cockatrice/src/game_graphics/board/counter_general.h index 0a2e882ce..2e49f11d7 100644 --- a/cockatrice/src/game_graphics/board/counter_general.h +++ b/cockatrice/src/game_graphics/board/counter_general.h @@ -9,6 +9,12 @@ #include "abstract_counter.h" +#include + +class CounterState; +class PlayerLogic; +class QGraphicsItem; + class GeneralCounter : public AbstractCounter { Q_OBJECT diff --git a/cockatrice/src/game_graphics/board/translate_counter_name.cpp b/cockatrice/src/game_graphics/board/translate_counter_name.cpp index 4f1c97657..3a2a5c7c8 100644 --- a/cockatrice/src/game_graphics/board/translate_counter_name.cpp +++ b/cockatrice/src/game_graphics/board/translate_counter_name.cpp @@ -1,5 +1,8 @@ #include "translate_counter_name.h" +#include +#include + const QMap TranslateCounterName::translated = { {"life", QT_TRANSLATE_NOOP("TranslateCounterName", "Life")}, {"w", QT_TRANSLATE_NOOP("TranslateCounterName", "White")}, diff --git a/cockatrice/src/game_graphics/board/translate_counter_name.h b/cockatrice/src/game_graphics/board/translate_counter_name.h index ba3a94fa5..e7e42e5fc 100644 --- a/cockatrice/src/game_graphics/board/translate_counter_name.h +++ b/cockatrice/src/game_graphics/board/translate_counter_name.h @@ -7,8 +7,10 @@ #ifndef TRANSLATECOUNTERNAME_H #define TRANSLATECOUNTERNAME_H +#include +#include +#include #include -#include class TranslateCounterName { diff --git a/cockatrice/src/game_graphics/deckview/deck_view.cpp b/cockatrice/src/game_graphics/deckview/deck_view.cpp index 1acd02a75..c86bc9925 100644 --- a/cockatrice/src/game_graphics/deckview/deck_view.cpp +++ b/cockatrice/src/game_graphics/deckview/deck_view.cpp @@ -2,15 +2,47 @@ #include "../../client/settings/cache_settings.h" #include "../../interface/theme_manager.h" +#include "../board/abstract_card_drag_item.h" +#include "../card_dimensions.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include "libcockatrice/protocol/pb/move_card_to_zone.pb.h" #include +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include #include #include +#include +#include +#include +#include + +class QObject; +class QRectF; +class QWidget; +struct CardRef; DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item, const QPointF &_hotSpot, diff --git a/cockatrice/src/game_graphics/deckview/deck_view.h b/cockatrice/src/game_graphics/deckview/deck_view.h index f996fd4da..3b5b4b6f4 100644 --- a/cockatrice/src/game_graphics/deckview/deck_view.h +++ b/cockatrice/src/game_graphics/deckview/deck_view.h @@ -8,17 +8,30 @@ #define DECKVIEW_H #include "../board/abstract_card_drag_item.h" +#include "../board/abstract_card_item.h" +#include "../board/graphics_item_type.h" +#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include +#include class DeckList; -class InnerDecklistNode; -class CardInfo; class DeckViewCardContainer; class DeckViewCardDragItem; -class MoveCardToZone; +class QObject; +class QWidget; +struct CardRef; class DeckViewCard : public AbstractCardItem { diff --git a/cockatrice/src/game_graphics/deckview/deck_view_container.cpp b/cockatrice/src/game_graphics/deckview/deck_view_container.cpp index bc07ac183..c97767ec7 100644 --- a/cockatrice/src/game_graphics/deckview/deck_view_container.cpp +++ b/cockatrice/src/game_graphics/deckview/deck_view_container.cpp @@ -2,18 +2,36 @@ #include "../../client/settings/cache_settings.h" #include "../../client/settings/shortcuts_settings.h" +#include "../../game/abstract_game.h" +#include "../../game/game_event_handler.h" +#include "../../game/game_state.h" #include "../../interface/card_picture_loader/card_picture_loader.h" +#include "../../interface/deck_loader/deck_file_format.h" #include "../../interface/deck_loader/deck_loader.h" +#include "../../interface/deck_loader/loaded_deck.h" #include "../../interface/widgets/dialogs/dlg_load_deck.h" #include "../../interface/widgets/dialogs/dlg_load_deck_from_clipboard.h" #include "../../interface/widgets/dialogs/dlg_load_deck_from_website.h" #include "../../interface/widgets/dialogs/dlg_load_remote_deck.h" #include "../../interface/widgets/tabs/tab_game.h" #include "../../interface/widgets/visual_deck_storage/visual_deck_storage_widget.h" +#include "../board/abstract_card_item.h" #include "deck_view.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/interfaces/interface_interface_settings_provider.h" +#include "libcockatrice/protocol/pb/move_card_to_zone.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" +#include "libcockatrice/utility/card_ref.h" +#include +#include #include -#include +#include +#include +#include +#include #include #include #include @@ -26,6 +44,9 @@ #include #include #include +#include +#include +#include ToggleButton::ToggleButton(QWidget *parent) : QPushButton(parent), state(false) { diff --git a/cockatrice/src/game_graphics/deckview/deck_view_container.h b/cockatrice/src/game_graphics/deckview/deck_view_container.h index b5317c39a..80b82b6e5 100644 --- a/cockatrice/src/game_graphics/deckview/deck_view_container.h +++ b/cockatrice/src/game_graphics/deckview/deck_view_container.h @@ -7,14 +7,17 @@ #ifndef DECK_VIEW_CONTAINER_H #define DECK_VIEW_CONTAINER_H -#include "../../interface/deck_loader/deck_loader.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/utility/playmat_params.h" #include +#include +#include +#include class QVBoxLayout; class AbstractCardItem; class VisualDeckStorageWidget; -class DeckPreviewWidget; class Response; class TabGame; class DeckView; diff --git a/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.cpp b/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.cpp index 2ffb214f7..90cbed9a1 100644 --- a/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.cpp +++ b/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.cpp @@ -1,7 +1,15 @@ #include "tabbed_deck_view_container.h" -#include "../../interface/widgets/tabs/tab_game.h" +#include "../board/abstract_card_item.h" #include "deck_view.h" +#include "deck_view_container.h" + +#include +#include +#include + +class DeckList; +class TabGame; TabbedDeckViewContainer::TabbedDeckViewContainer(int _playerId, TabGame *parent) : QTabWidget(nullptr), playerId(_playerId), parentGame(parent) diff --git a/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.h b/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.h index 7cfa8c9aa..7d73b78a2 100644 --- a/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.h +++ b/cockatrice/src/game_graphics/deckview/tabbed_deck_view_container.h @@ -6,9 +6,15 @@ #ifndef TABBED_DECK_VIEW_CONTAINER_H #define TABBED_DECK_VIEW_CONTAINER_H -#include "deck_view_container.h" - +#include +#include #include +#include + +class DeckList; +class DeckView; +class DeckViewContainer; +class TabGame; class TabbedDeckViewContainer : public QTabWidget { diff --git a/cockatrice/src/game_graphics/dialogs/dlg_create_token.cpp b/cockatrice/src/game_graphics/dialogs/dlg_create_token.cpp index 6d8ad0534..5ce050380 100644 --- a/cockatrice/src/game_graphics/dialogs/dlg_create_token.cpp +++ b/cockatrice/src/game_graphics/dialogs/dlg_create_token.cpp @@ -2,23 +2,30 @@ #include "../../client/settings/cache_settings.h" #include "../../interface/widgets/cards/card_info_picture_widget.h" -#include "../../main.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include +#include #include #include #include #include #include #include -#include #include +#include #include #include +#include #include +#include +#include #include +#include +#include #include #include -#include #include #include #include @@ -26,6 +33,10 @@ #include #include #include +#include + +class QModelIndex; +class QWidget; DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *parent) : QDialog(parent), predefinedTokens(_predefinedTokens) diff --git a/cockatrice/src/game_graphics/dialogs/dlg_create_token.h b/cockatrice/src/game_graphics/dialogs/dlg_create_token.h index 281e161fc..a03a1046b 100644 --- a/cockatrice/src/game_graphics/dialogs/dlg_create_token.h +++ b/cockatrice/src/game_graphics/dialogs/dlg_create_token.h @@ -8,19 +8,22 @@ #define DLG_CREATETOKEN_H #include +#include +#include +#include +#include class QLabel; class QLineEdit; class QComboBox; class QCheckBox; -class QPushButton; class QRadioButton; -class QCloseEvent; class QTreeView; -class DeckList; class CardDatabaseModel; class TokenDisplayModel; class CardInfoPictureWidget; +class QModelIndex; +class QWidget; struct TokenInfo { diff --git a/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.cpp b/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.cpp index 41c907163..b7cd73d79 100644 --- a/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.cpp +++ b/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.cpp @@ -1,17 +1,24 @@ #include "dlg_move_top_cards_until.h" +#include "libcockatrice/card/card_info.h" + +#include +#include #include #include +#include #include -#include #include #include #include #include -#include +#include #include #include #include +#include + +class QWidget; DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, const MoveTopCardsUntilOptions &options) : QDialog(parent) { diff --git a/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.h b/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.h index ac9d41a94..b9080bcc1 100644 --- a/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.h +++ b/cockatrice/src/game_graphics/dialogs/dlg_move_top_cards_until.h @@ -7,14 +7,19 @@ #ifndef DLG_MOVE_TOP_CARDS_UNTIL_H #define DLG_MOVE_TOP_CARDS_UNTIL_H -#include -#include #include -#include -#include -#include +#include +#include +#include +#include class FilterString; +class QCheckBox; +class QComboBox; +class QDialogButtonBox; +class QLabel; +class QSpinBox; +class QWidget; struct MoveTopCardsUntilOptions { diff --git a/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.cpp b/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.cpp index 4f5d5b861..b17881211 100644 --- a/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.cpp +++ b/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.cpp @@ -1,12 +1,15 @@ #include "dlg_roll_dice.h" #include +#include #include #include +#include #include -#include #include +class QWidget; + DlgRollDice::DlgRollDice(QWidget *parent) : QDialog(parent) { numberOfSidesLabel = new QLabel(tr("Number of sides:")); diff --git a/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.h b/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.h index 15f7dc1ba..4c146a054 100644 --- a/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.h +++ b/cockatrice/src/game_graphics/dialogs/dlg_roll_dice.h @@ -8,9 +8,13 @@ #define DLG_ROLL_DICE_H #include -#include -#include -#include +#include +#include + +class QDialogButtonBox; +class QLabel; +class QSpinBox; +class QWidget; class DlgRollDice : public QDialog { diff --git a/cockatrice/src/game_graphics/game_scene.cpp b/cockatrice/src/game_graphics/game_scene.cpp index e4466f95d..cc3f9f1d3 100644 --- a/cockatrice/src/game_graphics/game_scene.cpp +++ b/cockatrice/src/game_graphics/game_scene.cpp @@ -2,25 +2,50 @@ #include "../client/settings/cache_settings.h" #include "../game/abstract_game.h" +#include "../game/arrow_registry.h" +#include "../game/board/arrow_data.h" #include "../game/player/player_actions.h" +#include "../game/player/player_event_handler.h" +#include "../game/player/player_info.h" #include "../game/player/player_logic.h" -#include "../game_graphics/player/player_graphics_item.h" +#include "../game/zones/card_zone_logic.h" +#include "../game/zones/view_zone_logic.h" +#include "animated_item.h" +#include "board/abstract_card_item.h" +#include "board/arrow_item.h" #include "board/card_item.h" #include "phases_toolbar.h" #include "player/menu/player_menu.h" #include "player/player_graphics_item.h" +#include "player/player_target.h" +#include "zones/card_zone.h" #include "zones/select_zone.h" #include "zones/view_zone.h" #include "zones/view_zone_widget.h" #include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include #include +#include + +class ArrowTarget; /** * @brief Constructs the GameScene. diff --git a/cockatrice/src/game_graphics/game_scene.h b/cockatrice/src/game_graphics/game_scene.h index cf81eec9d..c7cae1e76 100644 --- a/cockatrice/src/game_graphics/game_scene.h +++ b/cockatrice/src/game_graphics/game_scene.h @@ -2,16 +2,33 @@ #define GAMESCENE_H #include "../game/arrow_registry.h" -#include "../game/board/arrow_data.h" -#include "../game/zones/card_zone_logic.h" -#include "animated_item.h" -#include "board/arrow_item.h" #include #include #include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include + +// IWYU pragma: keep +// ServerInfo_Card appears inside QList<...> in signal and slot +// signatures, which the moc-generated code needs to be complete. +#include + +class CardZoneLogic; +class IAnimatedItem; +class QGraphicsItem; +class QPoint; +struct ArrowData; +template class QSharedPointer; inline Q_LOGGING_CATEGORY(GameSceneLog, "game_scene"); inline Q_LOGGING_CATEGORY(GameScenePlayerAdditionRemovalLog, "game_scene.player_addition_removal"); diff --git a/cockatrice/src/game_graphics/game_view.cpp b/cockatrice/src/game_graphics/game_view.cpp index ed6355157..1c92d74ae 100644 --- a/cockatrice/src/game_graphics/game_view.cpp +++ b/cockatrice/src/game_graphics/game_view.cpp @@ -5,13 +5,24 @@ #include "game_scene.h" #include +#include +#include +#include +#include #include #include -#include +#include +#include +#include #include #include +#include +#include +#include +#include #include #include +#include // QRubberBand calls raise() in showEvent() and changeEvent() to stay on top of siblings. // This subclass disables that behavior so dragCountLabel can appear above it. diff --git a/cockatrice/src/game_graphics/game_view.h b/cockatrice/src/game_graphics/game_view.h index a23655513..e57267734 100644 --- a/cockatrice/src/game_graphics/game_view.h +++ b/cockatrice/src/game_graphics/game_view.h @@ -10,11 +10,19 @@ #include "tally/tally.h" #include +#include +#include +#include +#include +#include +#include class GameScene; class QGridLayout; class QLabel; class QRubberBand; +class QAction; +class QWidget; class GameView : public QGraphicsView { diff --git a/cockatrice/src/game_graphics/hand_counter.cpp b/cockatrice/src/game_graphics/hand_counter.cpp index 8dcbcfdaa..9320c1295 100644 --- a/cockatrice/src/game_graphics/hand_counter.cpp +++ b/cockatrice/src/game_graphics/hand_counter.cpp @@ -1,11 +1,22 @@ #include "hand_counter.h" +#include "../game/board/card_list.h" +#include "../game/zones/card_zone_logic.h" #include "../interface/pixel_map_generator.h" -#include "zones/card_zone.h" #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include + +class QGraphicsItem; HandCounter::HandCounter(QGraphicsItem *parent) : AbstractGraphicsItem(parent), number(0) { diff --git a/cockatrice/src/game_graphics/hand_counter.h b/cockatrice/src/game_graphics/hand_counter.h index 9aa65d514..c1f5d09d8 100644 --- a/cockatrice/src/game_graphics/hand_counter.h +++ b/cockatrice/src/game_graphics/hand_counter.h @@ -10,10 +10,10 @@ #include "board/abstract_graphics_item.h" #include "board/graphics_item_type.h" -#include +#include -class QPainter; -class QPixmap; +class QGraphicsItem; +class QPoint; class HandCounter : public AbstractGraphicsItem { diff --git a/cockatrice/src/game_graphics/log/message_log_widget.cpp b/cockatrice/src/game_graphics/log/message_log_widget.cpp index b998a3650..4a9750fca 100644 --- a/cockatrice/src/game_graphics/log/message_log_widget.cpp +++ b/cockatrice/src/game_graphics/log/message_log_widget.cpp @@ -3,20 +3,39 @@ #include "../../client/settings/cache_settings.h" #include "../../client/settings/card_counter_settings.h" #include "../../client/sound_engine.h" +#include "../../client/translation.h" +#include "../../game/abstract_game.h" +#include "../../game/board/card_list.h" #include "../../game/game_state.h" #include "../../game/phase.h" +#include "../../game/player/player_event_handler.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/player/player_manager.h" +#include "../../game/zones/card_zone_logic.h" #include "../../interface/card_localization.h" -#include "../../interface/widgets/tabs/tab_game.h" +#include "../../interface/widgets/server/chat_view/chat_view.h" #include "../board/card_item.h" #include "../board/translate_counter_name.h" +#include "libcockatrice/protocol/pb/game_event_context.pb.h" +#include +#include +#include +#include +#include #include #include #include #include +#include +#include #include +class QWidget; +class ServerInfo_User; +class TabSupervisor; + static QString sanitizeHtml(QString dirty) { return dirty.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """); diff --git a/cockatrice/src/game_graphics/log/message_log_widget.h b/cockatrice/src/game_graphics/log/message_log_widget.h index 375c6df4d..6800ba8ed 100644 --- a/cockatrice/src/game_graphics/log/message_log_widget.h +++ b/cockatrice/src/game_graphics/log/message_log_widget.h @@ -7,14 +7,23 @@ #ifndef MESSAGELOGWIDGET_H #define MESSAGELOGWIDGET_H -#include "../../game/zones/card_zone_logic.h" #include "../../interface/widgets/server/chat_view/chat_view.h" +#include +#include +#include +#include + class AbstractGame; class CardItem; class GameEventContext; class PlayerLogic; class PlayerEventHandler; +class CardZoneLogic; +class QWidget; +class ServerInfo_User; +class TabSupervisor; +template class QList; class MessageLogWidget : public ChatView { diff --git a/cockatrice/src/game_graphics/phases_toolbar.cpp b/cockatrice/src/game_graphics/phases_toolbar.cpp index 3361f9d55..d0a3f74fd 100644 --- a/cockatrice/src/game_graphics/phases_toolbar.cpp +++ b/cockatrice/src/game_graphics/phases_toolbar.cpp @@ -1,17 +1,26 @@ #include "phases_toolbar.h" #include "../interface/pixel_map_generator.h" +#include "board/abstract_graphics_item.h" +#include "libcockatrice/protocol/pb/card_attributes.pb.h" #include -#include +#include #include -#include +#include +#include +#include #include +#include +#include +#include #include #include #include #include #include +#include +#include PhaseButton::PhaseButton(const QString &_name, QGraphicsItem *parent, QAction *_doubleClickAction, bool _highlightable) : QObject(), QGraphicsItem(parent), name(_name), active(false), highlightable(_highlightable), diff --git a/cockatrice/src/game_graphics/phases_toolbar.h b/cockatrice/src/game_graphics/phases_toolbar.h index 39884ef75..376775284 100644 --- a/cockatrice/src/game_graphics/phases_toolbar.h +++ b/cockatrice/src/game_graphics/phases_toolbar.h @@ -8,11 +8,14 @@ #ifndef PHASESTOOLBAR_H #define PHASESTOOLBAR_H -#include "board/abstract_graphics_item.h" - -#include -#include +#include #include +#include +#include +#include + +class QAction; +class QTimer; namespace google { @@ -21,8 +24,6 @@ namespace protobuf class Message; } } // namespace google -class PlayerLogic; -class GameCommand; class PhaseButton : public QObject, public QGraphicsItem { diff --git a/cockatrice/src/game_graphics/player/menu/card_menu.cpp b/cockatrice/src/game_graphics/player/menu/card_menu.cpp index 75ca1b28b..137ec2ed1 100644 --- a/cockatrice/src/game_graphics/player/menu/card_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/card_menu.cpp @@ -1,21 +1,43 @@ #include "card_menu.h" +#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/card_counter_settings.h" #include "../../../client/settings/shortcuts_settings.h" -#include "../../../interface/widgets/tabs/tab_game.h" +#include "../../../game/abstract_game.h" +#include "../../../game/player/player_info.h" +#include "../../../game/player/player_manager.h" +#include "../../../game/zones/card_zone_logic.h" #include "../../board/card_item.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../../game/zones/view_zone_logic.h" +#include "../../game_scene.h" #include "../card_menu_action_type.h" #include "../player_graphics_item.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/utility/card_ref.h" #include "move_menu.h" #include "pt_menu.h" +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include #include #include +#include +#include /** * @brief Creates a circular icon filled with the specified color. diff --git a/cockatrice/src/game_graphics/player/menu/card_menu.h b/cockatrice/src/game_graphics/player/menu/card_menu.h index d67ef3876..337d77b3e 100644 --- a/cockatrice/src/game_graphics/player/menu/card_menu.h +++ b/cockatrice/src/game_graphics/player/menu/card_menu.h @@ -7,12 +7,18 @@ #ifndef COCKATRICE_CARD_MENU_H #define COCKATRICE_CARD_MENU_H +#include #include -#include +#include +#include +#include class CardItem; class PlayerGraphicsItem; class PlayerLogic; +class QAction; +struct CardRef; + class CardMenu : public QMenu { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/custom_zone_menu.cpp b/cockatrice/src/game_graphics/player/menu/custom_zone_menu.cpp index 743746cc8..e16ebc112 100644 --- a/cockatrice/src/game_graphics/player/menu/custom_zone_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/custom_zone_menu.cpp @@ -1,8 +1,14 @@ #include "custom_zone_menu.h" +#include "../../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game_scene.h" #include "../player_graphics_item.h" +#include +#include +#include + CustomZoneMenu::CustomZoneMenu(PlayerGraphicsItem *_player) : player(_player) { menuAction()->setVisible(false); diff --git a/cockatrice/src/game_graphics/player/menu/custom_zone_menu.h b/cockatrice/src/game_graphics/player/menu/custom_zone_menu.h index 46dd58db6..07f5510ca 100644 --- a/cockatrice/src/game_graphics/player/menu/custom_zone_menu.h +++ b/cockatrice/src/game_graphics/player/menu/custom_zone_menu.h @@ -10,8 +10,11 @@ #include "abstract_player_component.h" #include +#include +#include class PlayerGraphicsItem; + class CustomZoneMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/grave_menu.cpp b/cockatrice/src/game_graphics/player/menu/grave_menu.cpp index 6d9364579..580d2642e 100644 --- a/cockatrice/src/game_graphics/player/menu/grave_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/grave_menu.cpp @@ -1,15 +1,28 @@ #include "grave_menu.h" +#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../../../game/player/player_info.h" +#include "../../../game/player/player_manager.h" +#include "../../../game/zones/pile_zone_logic.h" +#include "../../../interface/widgets/menus/tearoff_menu.h" #include "../../game/abstract_game.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../player_graphics_item.h" #include +#include +#include +#include #include +#include +#include +#include #include +class QWidget; + GraveyardMenu::GraveyardMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { createMoveActions(); diff --git a/cockatrice/src/game_graphics/player/menu/grave_menu.h b/cockatrice/src/game_graphics/player/menu/grave_menu.h index 116261e9b..fa285409f 100644 --- a/cockatrice/src/game_graphics/player/menu/grave_menu.h +++ b/cockatrice/src/game_graphics/player/menu/grave_menu.h @@ -10,10 +10,13 @@ #include "../../../interface/widgets/menus/tearoff_menu.h" #include "abstract_player_component.h" -#include -#include +#include class PlayerGraphicsItem; +class QAction; +class QMenu; +class QWidget; + class GraveyardMenu : public TearOffMenu, public AbstractPlayerComponent { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/hand_menu.cpp b/cockatrice/src/game_graphics/player/menu/hand_menu.cpp index ba0702f07..141542cb4 100644 --- a/cockatrice/src/game_graphics/player/menu/hand_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/hand_menu.cpp @@ -2,16 +2,28 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" -#include "../../../game_graphics/zones/hand_zone.h" +#include "../../../game/board/card_list.h" +#include "../../../game/player/player_info.h" +#include "../../../game/player/player_manager.h" +#include "../../../game/zones/hand_zone_logic.h" +#include "../../../interface/widgets/menus/tearoff_menu.h" #include "../../game/abstract_game.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../player_graphics_item.h" #include +#include +#include +#include #include +#include +#include +#include #include +class QWidget; + HandMenu::HandMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { auto *actions = player->getLogic()->getPlayerActions(); diff --git a/cockatrice/src/game_graphics/player/menu/hand_menu.h b/cockatrice/src/game_graphics/player/menu/hand_menu.h index d5204612b..de7726064 100644 --- a/cockatrice/src/game_graphics/player/menu/hand_menu.h +++ b/cockatrice/src/game_graphics/player/menu/hand_menu.h @@ -10,11 +10,12 @@ #include "../../../interface/widgets/menus/tearoff_menu.h" #include "abstract_player_component.h" -#include -#include +#include class PlayerGraphicsItem; -class PlayerActions; +class QAction; +class QMenu; +class QWidget; class HandMenu : public TearOffMenu, public AbstractPlayerComponent { diff --git a/cockatrice/src/game_graphics/player/menu/library_menu.cpp b/cockatrice/src/game_graphics/player/menu/library_menu.cpp index 4c15e09ec..aa389006e 100644 --- a/cockatrice/src/game_graphics/player/menu/library_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/library_menu.cpp @@ -2,15 +2,29 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" -#include "../../../interface/widgets/tabs/tab_game.h" +#include "../../../game/board/card_list.h" +#include "../../../game/player/player_info.h" +#include "../../../game/player/player_manager.h" +#include "../../../game/zones/pile_zone_logic.h" +#include "../../../interface/widgets/menus/tearoff_menu.h" #include "../../game/abstract_game.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../player_graphics_item.h" #include +#include #include +#include +#include +#include +#include #include +#include +#include +#include + +class QWidget; LibraryMenu::LibraryMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { diff --git a/cockatrice/src/game_graphics/player/menu/library_menu.h b/cockatrice/src/game_graphics/player/menu/library_menu.h index bc0e6fb8e..72e90d0ba 100644 --- a/cockatrice/src/game_graphics/player/menu/library_menu.h +++ b/cockatrice/src/game_graphics/player/menu/library_menu.h @@ -11,11 +11,11 @@ #include "abstract_player_component.h" #include -#include +#include class PlayerGraphicsItem; -class PlayerLogic; -class PlayerActions; +class QMenu; +class QWidget; class LibraryMenu : public TearOffMenu, public AbstractPlayerComponent { diff --git a/cockatrice/src/game_graphics/player/menu/move_menu.cpp b/cockatrice/src/game_graphics/player/menu/move_menu.cpp index 632e0ddda..2991100ec 100644 --- a/cockatrice/src/game_graphics/player/menu/move_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/move_menu.cpp @@ -1,11 +1,15 @@ #include "move_menu.h" +#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" +#include "../../game_scene.h" #include "../card_menu_action_type.h" #include "../player_graphics_item.h" +#include + MoveMenu::MoveMenu(PlayerGraphicsItem *player) : QMenu(tr("Move to")) { aMoveToTopLibrary = new QAction(this); diff --git a/cockatrice/src/game_graphics/player/menu/move_menu.h b/cockatrice/src/game_graphics/player/menu/move_menu.h index 150bdbd3c..f1f239abd 100644 --- a/cockatrice/src/game_graphics/player/menu/move_menu.h +++ b/cockatrice/src/game_graphics/player/menu/move_menu.h @@ -7,8 +7,11 @@ #ifndef COCKATRICE_MOVE_MENU_H #define COCKATRICE_MOVE_MENU_H #include +#include class PlayerGraphicsItem; +class QAction; + class MoveMenu : public QMenu { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/player_menu.cpp b/cockatrice/src/game_graphics/player/menu/player_menu.cpp index 7c90211df..44b184cfe 100644 --- a/cockatrice/src/game_graphics/player/menu/player_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/player_menu.cpp @@ -1,16 +1,31 @@ #include "player_menu.h" +#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../../../game/abstract_game.h" +#include "../../../game/player/player_info.h" +#include "../../../game/player/player_logic.h" +#include "../../../game/player/player_manager.h" #include "../../../game_graphics/zones/hand_zone.h" #include "../../../game_graphics/zones/pile_zone.h" #include "../../../game_graphics/zones/table_zone.h" -#include "../../../interface/widgets/tabs/tab_game.h" +#include "../../../interface/widgets/menus/tearoff_menu.h" #include "../../board/card_item.h" #include "../player_graphics_item.h" +#include "abstract_player_component.h" #include "card_menu.h" +#include "custom_zone_menu.h" +#include "grave_menu.h" #include "hand_menu.h" +#include "library_menu.h" +#include "rfg_menu.h" +#include "say_menu.h" +#include "sideboard_menu.h" +#include "tally_menu.h" +#include "utility_menu.h" -#include +#include +#include PlayerMenu::PlayerMenu(PlayerGraphicsItem *_player) : QObject(_player), player(_player) { diff --git a/cockatrice/src/game_graphics/player/menu/player_menu.h b/cockatrice/src/game_graphics/player/menu/player_menu.h index a6e89fab0..97dd2fc56 100644 --- a/cockatrice/src/game_graphics/player/menu/player_menu.h +++ b/cockatrice/src/game_graphics/player/menu/player_menu.h @@ -8,24 +8,28 @@ #define COCKATRICE_PLAYER_MENU_H #include "../../../interface/widgets/menus/tearoff_menu.h" -#include "custom_zone_menu.h" -#include "grave_menu.h" -#include "hand_menu.h" -#include "library_menu.h" -#include "rfg_menu.h" -#include "say_menu.h" -#include "sideboard_menu.h" -#include "tally_menu.h" -#include "utility_menu.h" #include -#include #include -#include +#include +#include class CardItem; class CardMenu; class PlayerGraphicsItem; +class AbstractPlayerComponent; +class CustomZoneMenu; +class GraveyardMenu; +class HandMenu; +class LibraryMenu; +class QMenu; +class RfgMenu; +class SayMenu; +class SideboardMenu; +class TallyMenu; +class UtilityMenu; +struct CardRef; + class PlayerMenu : public QObject { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/pt_menu.cpp b/cockatrice/src/game_graphics/player/menu/pt_menu.cpp index 152461c18..b4f852b43 100644 --- a/cockatrice/src/game_graphics/player/menu/pt_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/pt_menu.cpp @@ -1,10 +1,14 @@ #include "pt_menu.h" +#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" +#include "../../game_scene.h" #include "../player_graphics_item.h" +#include + PtMenu::PtMenu(PlayerGraphicsItem *player) : QMenu(tr("Power / toughness")) { PlayerActions *playerActions = player->getLogic()->getPlayerActions(); diff --git a/cockatrice/src/game_graphics/player/menu/pt_menu.h b/cockatrice/src/game_graphics/player/menu/pt_menu.h index 72f828801..aaf17cead 100644 --- a/cockatrice/src/game_graphics/player/menu/pt_menu.h +++ b/cockatrice/src/game_graphics/player/menu/pt_menu.h @@ -7,8 +7,11 @@ #ifndef COCKATRICE_PT_MENU_H #define COCKATRICE_PT_MENU_H #include +#include class PlayerGraphicsItem; +class QAction; + class PtMenu : public QMenu { diff --git a/cockatrice/src/game_graphics/player/menu/rfg_menu.cpp b/cockatrice/src/game_graphics/player/menu/rfg_menu.cpp index 45abadbf7..98514280f 100644 --- a/cockatrice/src/game_graphics/player/menu/rfg_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/rfg_menu.cpp @@ -1,11 +1,21 @@ #include "rfg_menu.h" +#include "../../../game/player/player_info.h" +#include "../../../game/zones/pile_zone_logic.h" +#include "../../../interface/widgets/menus/tearoff_menu.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../player_graphics_item.h" +#include +#include +#include +#include +#include #include +class QWidget; + RfgMenu::RfgMenu(PlayerGraphicsItem *_player, QWidget *parent) : TearOffMenu(parent), player(_player) { createMoveActions(); diff --git a/cockatrice/src/game_graphics/player/menu/rfg_menu.h b/cockatrice/src/game_graphics/player/menu/rfg_menu.h index f5dd888e4..8e1460316 100644 --- a/cockatrice/src/game_graphics/player/menu/rfg_menu.h +++ b/cockatrice/src/game_graphics/player/menu/rfg_menu.h @@ -10,10 +10,13 @@ #include "../../../interface/widgets/menus/tearoff_menu.h" #include "abstract_player_component.h" -#include -#include +#include class PlayerGraphicsItem; +class QAction; +class QMenu; +class QWidget; + class RfgMenu : public TearOffMenu, public AbstractPlayerComponent { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/say_menu.cpp b/cockatrice/src/game_graphics/player/menu/say_menu.cpp index e7b0b3826..d467c6469 100644 --- a/cockatrice/src/game_graphics/player/menu/say_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/say_menu.cpp @@ -5,7 +5,12 @@ #include "../../game/player/player_logic.h" #include "../player_graphics_item.h" +#include +#include +#include +#include #include + SayMenu::SayMenu(PlayerGraphicsItem *_player) : player(_player) { connect(&SettingsCache::instance().messages(), &MessageSettings::messageMacrosChanged, this, &SayMenu::initSayMenu); diff --git a/cockatrice/src/game_graphics/player/menu/say_menu.h b/cockatrice/src/game_graphics/player/menu/say_menu.h index 3ff160d05..72169d18f 100644 --- a/cockatrice/src/game_graphics/player/menu/say_menu.h +++ b/cockatrice/src/game_graphics/player/menu/say_menu.h @@ -10,8 +10,10 @@ #include "abstract_player_component.h" #include +#include class PlayerGraphicsItem; + class SayMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/sideboard_menu.cpp b/cockatrice/src/game_graphics/player/menu/sideboard_menu.cpp index 6753f743e..1eef3604f 100644 --- a/cockatrice/src/game_graphics/player/menu/sideboard_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/sideboard_menu.cpp @@ -1,10 +1,15 @@ #include "sideboard_menu.h" +#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../../../game/player/player_info.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" #include "../player_graphics_item.h" +#include +#include + SideboardMenu::SideboardMenu(PlayerGraphicsItem *player, QMenu *playerMenu) : QMenu(playerMenu) { aViewSideboard = new QAction(this); diff --git a/cockatrice/src/game_graphics/player/menu/sideboard_menu.h b/cockatrice/src/game_graphics/player/menu/sideboard_menu.h index b3b547291..3e6501c90 100644 --- a/cockatrice/src/game_graphics/player/menu/sideboard_menu.h +++ b/cockatrice/src/game_graphics/player/menu/sideboard_menu.h @@ -10,8 +10,11 @@ #include "abstract_player_component.h" #include +#include class PlayerGraphicsItem; +class QAction; + class SideboardMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/menu/tally_menu.cpp b/cockatrice/src/game_graphics/player/menu/tally_menu.cpp index 08cb6cac9..7ae5b36ce 100644 --- a/cockatrice/src/game_graphics/player/menu/tally_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/tally_menu.cpp @@ -1,7 +1,10 @@ #include "tally_menu.h" #include "../../../client/settings/cache_settings.h" +#include "../../tally/tally.h" +#include "libcockatrice/settings/interface_settings.h" +#include #include TallyMenu::TallyMenu() diff --git a/cockatrice/src/game_graphics/player/menu/tally_menu.h b/cockatrice/src/game_graphics/player/menu/tally_menu.h index 11802fd20..75bd41ac0 100644 --- a/cockatrice/src/game_graphics/player/menu/tally_menu.h +++ b/cockatrice/src/game_graphics/player/menu/tally_menu.h @@ -2,10 +2,13 @@ #define COCKATRICE_TALLY_MENU_H #include "../../../interface/widgets/menus/tearoff_menu.h" -#include "../../tally/tally.h" #include "abstract_player_component.h" -#include +#include + +class QAction; +class QActionGroup; +enum class TallyType; class TallyMenu : public TearOffMenu, public AbstractPlayerComponent { diff --git a/cockatrice/src/game_graphics/player/menu/utility_menu.cpp b/cockatrice/src/game_graphics/player/menu/utility_menu.cpp index a7ea38d9a..7c18b3f4c 100644 --- a/cockatrice/src/game_graphics/player/menu/utility_menu.cpp +++ b/cockatrice/src/game_graphics/player/menu/utility_menu.cpp @@ -1,12 +1,17 @@ #include "utility_menu.h" +#include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" -#include "../../../interface/deck_loader/deck_loader.h" +#include "../../../game/player/player_info.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" +#include "../../game_scene.h" #include "../player_graphics_item.h" -#include "player_menu.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/deck_list/deck_list.h" +#include +#include #include #include diff --git a/cockatrice/src/game_graphics/player/menu/utility_menu.h b/cockatrice/src/game_graphics/player/menu/utility_menu.h index bdc2a81a5..009e4aca3 100644 --- a/cockatrice/src/game_graphics/player/menu/utility_menu.h +++ b/cockatrice/src/game_graphics/player/menu/utility_menu.h @@ -9,10 +9,16 @@ #include "abstract_player_component.h" +#include +#include #include +#include +#include #include +#include class PlayerGraphicsItem; + class UtilityMenu : public QMenu, public AbstractPlayerComponent { Q_OBJECT diff --git a/cockatrice/src/game_graphics/player/player_area.cpp b/cockatrice/src/game_graphics/player/player_area.cpp index 86b8c2d1b..2af642eb5 100644 --- a/cockatrice/src/game_graphics/player/player_area.cpp +++ b/cockatrice/src/game_graphics/player/player_area.cpp @@ -2,6 +2,7 @@ #include "../../interface/theme_manager.h" +#include #include PlayerArea::PlayerArea(QGraphicsItem *parentItem) : QObject(), QGraphicsItem(parentItem) diff --git a/cockatrice/src/game_graphics/player/player_area.h b/cockatrice/src/game_graphics/player/player_area.h index d73547f81..7370a78be 100644 --- a/cockatrice/src/game_graphics/player/player_area.h +++ b/cockatrice/src/game_graphics/player/player_area.h @@ -8,7 +8,14 @@ #define COCKATRICE_PLAYER_AREA_H #include "../board/graphics_item_type.h" -#include "QGraphicsItem" + +#include +#include +#include +#include +#include + +class QGraphicsItem; /** * The entire graphical area belonging to a single player. diff --git a/cockatrice/src/game_graphics/player/player_dialogs.cpp b/cockatrice/src/game_graphics/player/player_dialogs.cpp index 95c225812..74f5de601 100644 --- a/cockatrice/src/game_graphics/player/player_dialogs.cpp +++ b/cockatrice/src/game_graphics/player/player_dialogs.cpp @@ -1,12 +1,21 @@ #include "player_dialogs.h" +#include "../../client/settings/cache_settings.h" #include "../../client/settings/card_counter_settings.h" +#include "../../game/player/player_actions.h" +#include "../../game/player/player_logic.h" #include "../../interface/widgets/utility/get_text_with_max.h" +#include "../board/abstract_counter.h" #include "../board/card_item.h" +#include "../dialogs/dlg_create_token.h" +#include "../dialogs/dlg_move_top_cards_until.h" #include "../dialogs/dlg_roll_dice.h" +#include "../game_scene.h" #include "../player/player_graphics_item.h" +#include #include +#include #include #include diff --git a/cockatrice/src/game_graphics/player/player_dialogs.h b/cockatrice/src/game_graphics/player/player_dialogs.h index f87704f2d..86d7282a2 100644 --- a/cockatrice/src/game_graphics/player/player_dialogs.h +++ b/cockatrice/src/game_graphics/player/player_dialogs.h @@ -1,12 +1,26 @@ #ifndef COCKATRICE_PLAYER_DIALOGS_H #define COCKATRICE_PLAYER_DIALOGS_H -#include "../../game/player/player_actions.h" #include "player_graphics_item.h" -#include -#include +// IWYU pragma: keep +// MoveTopCardsUntilOptions is passed by value to a slot, so the moc-generated +// code needs the complete type. +#include "../dialogs/dlg_move_top_cards_until.h" + +#include +#include +#include +#include +#include +#include +#include + +class CardItem; +class CardRelation; +class PlayerActions; +class QWidget; +struct MoveTopCardsUntilOptions; -class PlayerGraphicsItem; class PlayerDialogs : public QObject { diff --git a/cockatrice/src/game_graphics/player/player_graphics_item.cpp b/cockatrice/src/game_graphics/player/player_graphics_item.cpp index 122ab83be..419816087 100644 --- a/cockatrice/src/game_graphics/player/player_graphics_item.cpp +++ b/cockatrice/src/game_graphics/player/player_graphics_item.cpp @@ -1,26 +1,53 @@ #include "player_graphics_item.h" +#include "../../client/settings/cache_settings.h" +#include "../../game/board/counter_state.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" +#include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" +#include "../../game/zones/hand_zone_logic.h" +#include "../../game/zones/pile_zone_logic.h" +#include "../../game/zones/stack_zone_logic.h" +#include "../../game/zones/table_zone_logic.h" #include "../../interface/card_picture_loader/card_picture_loader.h" #include "../../interface/widgets/cards/art_crop_attribution.h" #include "../../interface/widgets/cards/card_art_utils.h" #include "../../interface/widgets/playmat/playmat_utils.h" -#include "../../interface/widgets/tabs/tab_game.h" -#include "../board/abstract_card_item.h" +#include "../board/abstract_counter.h" #include "../board/counter_general.h" +#include "../card_dimensions.h" #include "../hand_counter.h" #include "../zones/hand_zone.h" #include "../zones/pile_zone.h" #include "../zones/stack_zone.h" #include "../zones/table_zone.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/interfaces/interface_interface_settings_provider.h" +#include "libcockatrice/utility/card_ref.h" #include "menu/player_menu.h" +#include "player_area.h" #include "player_dialogs.h" +#include "player_target.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) { diff --git a/cockatrice/src/game_graphics/player/player_graphics_item.h b/cockatrice/src/game_graphics/player/player_graphics_item.h index e5ae59a61..e1ca0a036 100644 --- a/cockatrice/src/game_graphics/player/player_graphics_item.h +++ b/cockatrice/src/game_graphics/player/player_graphics_item.h @@ -6,12 +6,20 @@ #ifndef COCKATRICE_PLAYER_GRAPHICS_ITEM_H #define COCKATRICE_PLAYER_GRAPHICS_ITEM_H -#include "../../game/player/player_logic.h" -#include "../board/abstract_counter.h" +#include "../board/graphics_item_type.h" #include "../game_scene.h" +#include "libcockatrice/utility/playmat_params.h" #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include class HandZone; class PileZone; @@ -20,7 +28,12 @@ class PlayerMenu; class PlayerTarget; class StackZone; class TableZone; -class ZoneViewZone; +class AbstractCounter; +class CardZone; +class CounterState; +class PlayerArea; +class PlayerLogic; +struct CardRef; class PlayerGraphicsItem : public QGraphicsObject { diff --git a/cockatrice/src/game_graphics/player/player_list_widget.cpp b/cockatrice/src/game_graphics/player/player_list_widget.cpp index a7ec2e4a9..7b358010f 100644 --- a/cockatrice/src/game_graphics/player/player_list_widget.cpp +++ b/cockatrice/src/game_graphics/player/player_list_widget.cpp @@ -2,16 +2,30 @@ #include "../../interface/pixel_map_generator.h" #include "../../interface/widgets/server/user/user_context_menu.h" -#include "../../interface/widgets/server/user/user_list_manager.h" -#include "../../interface/widgets/server/user/user_list_widget.h" -#include "../../interface/widgets/tabs/tab_game.h" -#include "../../interface/widgets/tabs/tab_supervisor.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "user_level.h" -#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include #include -#include +#include + +class QModelIndex; +class QObject; +class QPoint; +class QWidget; PlayerListItemDelegate::PlayerListItemDelegate(QObject *const parent) : QStyledItemDelegate(parent) { diff --git a/cockatrice/src/game_graphics/player/player_list_widget.h b/cockatrice/src/game_graphics/player/player_list_widget.h index f2f0be5fd..b070fe312 100644 --- a/cockatrice/src/game_graphics/player/player_list_widget.h +++ b/cockatrice/src/game_graphics/player/player_list_widget.h @@ -7,18 +7,23 @@ #ifndef PLAYERLISTWIDGET_H #define PLAYERLISTWIDGET_H -#include "../../game/player/player_logic.h" - #include #include +#include #include #include +#include +#include class ServerInfo_PlayerProperties; class TabSupervisor; class AbstractClient; class AbstractGame; class UserContextMenu; +class QModelIndex; +class QObject; +class QPoint; +class QWidget; class PlayerListItemDelegate : public QStyledItemDelegate { diff --git a/cockatrice/src/game_graphics/player/player_target.cpp b/cockatrice/src/game_graphics/player/player_target.cpp index d6c28370d..24734cd42 100644 --- a/cockatrice/src/game_graphics/player/player_target.cpp +++ b/cockatrice/src/game_graphics/player/player_target.cpp @@ -1,16 +1,43 @@ #include "player_target.h" #include "../../client/settings/cache_settings.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" #include "../../interface/pixel_map_generator.h" +#include "../board/abstract_counter.h" +#include "../board/abstract_graphics_item.h" +#include "../board/arrow_target.h" #include "../game_scene.h" +#include "libcockatrice/settings/interface_settings.h" +#include "user_level.h" -#include -#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include + +class CounterState; +class QGraphicsItem; PlayerCounter::PlayerCounter(CounterState *state, PlayerLogic *player, QGraphicsItem *parent) : AbstractCounter(state, player, false, false, parent) diff --git a/cockatrice/src/game_graphics/player/player_target.h b/cockatrice/src/game_graphics/player/player_target.h index 1d06c6274..7780104d2 100644 --- a/cockatrice/src/game_graphics/player/player_target.h +++ b/cockatrice/src/game_graphics/player/player_target.h @@ -14,8 +14,12 @@ #include #include +#include +#include class PlayerLogic; +class CounterState; +class QGraphicsItem; class PlayerCounter : public AbstractCounter, public IAnimatedItem { diff --git a/cockatrice/src/game_graphics/tally/stats_tally.cpp b/cockatrice/src/game_graphics/tally/stats_tally.cpp index 7e05c3fb1..28e280c02 100644 --- a/cockatrice/src/game_graphics/tally/stats_tally.cpp +++ b/cockatrice/src/game_graphics/tally/stats_tally.cpp @@ -4,6 +4,11 @@ #include #include +#include +#include +#include +#include +#include #include static int sumPowers(const QList &cards) diff --git a/cockatrice/src/game_graphics/tally/stats_tally.h b/cockatrice/src/game_graphics/tally/stats_tally.h index e499587eb..cb0bdf81b 100644 --- a/cockatrice/src/game_graphics/tally/stats_tally.h +++ b/cockatrice/src/game_graphics/tally/stats_tally.h @@ -2,6 +2,10 @@ #define COCKATRICE_STATS_TALLY_H #include "tally.h" +#include + +class CardItem; + /** * @brief Extracts and tallies stats from selected cards. */ diff --git a/cockatrice/src/game_graphics/tally/subtype_tally.cpp b/cockatrice/src/game_graphics/tally/subtype_tally.cpp index 2241eb3b2..ccd727405 100644 --- a/cockatrice/src/game_graphics/tally/subtype_tally.cpp +++ b/cockatrice/src/game_graphics/tally/subtype_tally.cpp @@ -1,9 +1,18 @@ #include "subtype_tally.h" #include "../board/card_item.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" #include +#include +#include +#include +#include #include +#include +#include +#include namespace { diff --git a/cockatrice/src/game_graphics/tally/subtype_tally.h b/cockatrice/src/game_graphics/tally/subtype_tally.h index 9926528e0..019a797d4 100644 --- a/cockatrice/src/game_graphics/tally/subtype_tally.h +++ b/cockatrice/src/game_graphics/tally/subtype_tally.h @@ -4,7 +4,6 @@ #include "tally.h" #include -#include class CardItem; diff --git a/cockatrice/src/game_graphics/tally/tally.h b/cockatrice/src/game_graphics/tally/tally.h index 84c54918f..5699758e7 100644 --- a/cockatrice/src/game_graphics/tally/tally.h +++ b/cockatrice/src/game_graphics/tally/tally.h @@ -1,5 +1,6 @@ #ifndef COCKATRICE_TALLY_H #define COCKATRICE_TALLY_H +#include #include class CardItem; diff --git a/cockatrice/src/game_graphics/zones/card_zone.cpp b/cockatrice/src/game_graphics/zones/card_zone.cpp index 3457b681e..d09bb588c 100644 --- a/cockatrice/src/game_graphics/zones/card_zone.cpp +++ b/cockatrice/src/game_graphics/zones/card_zone.cpp @@ -1,10 +1,18 @@ #include "card_zone.h" +#include "../../game/board/card_list.h" +#include "../../game/zones/card_zone_logic.h" +#include "../board/abstract_graphics_item.h" #include "../board/card_item.h" -#include "view_zone.h" +#include #include #include +#include + +class QGraphicsItem; +class QPoint; +class QPointF; CardZone::CardZone(CardZoneLogic *_logic, QGraphicsItem *parent) : AbstractGraphicsItem(parent), menu(nullptr), doubleClickAction(0), logic(_logic) @@ -40,7 +48,7 @@ void CardZone::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * /*event*/) bool CardZone::showContextMenu(const QPoint &screenPos) { if (menu) { - menu->exec(screenPos); + menu->popup(screenPos); return true; } return false; diff --git a/cockatrice/src/game_graphics/zones/card_zone.h b/cockatrice/src/game_graphics/zones/card_zone.h index 4cef6ca80..def3eee14 100644 --- a/cockatrice/src/game_graphics/zones/card_zone.h +++ b/cockatrice/src/game_graphics/zones/card_zone.h @@ -7,12 +7,21 @@ #ifndef CARDZONE_H #define CARDZONE_H -#include "../../game/zones/card_zone_logic.h" #include "../board/abstract_graphics_item.h" #include "../board/graphics_item_type.h" #include -#include +#include +#include + +class CardDragItem; +class CardItem; +class CardZoneLogic; +class QAction; +class QGraphicsItem; +class QMenu; +class QPoint; +template class QList; inline Q_LOGGING_CATEGORY(CardZoneLog, "card_zone"); diff --git a/cockatrice/src/game_graphics/zones/hand_zone.cpp b/cockatrice/src/game_graphics/zones/hand_zone.cpp index 1a8f7a910..3e527c081 100644 --- a/cockatrice/src/game_graphics/zones/hand_zone.cpp +++ b/cockatrice/src/game_graphics/zones/hand_zone.cpp @@ -2,14 +2,27 @@ #include "../../client/settings/cache_settings.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" +#include "../../game/zones/hand_zone_logic.h" #include "../../interface/theme_manager.h" #include "../board/card_drag_item.h" #include "../board/card_item.h" +#include "../card_dimensions.h" +#include +#include #include +#include +#include +#include +#include #include #include +#include + +class QGraphicsItem; HandZone::HandZone(HandZoneLogic *_logic, int _zoneHeight, QGraphicsItem *parent) : SelectZone(_logic, parent), zoneHeight(_zoneHeight) diff --git a/cockatrice/src/game_graphics/zones/hand_zone.h b/cockatrice/src/game_graphics/zones/hand_zone.h index c3f3f252b..5c91d684d 100644 --- a/cockatrice/src/game_graphics/zones/hand_zone.h +++ b/cockatrice/src/game_graphics/zones/hand_zone.h @@ -7,9 +7,16 @@ #ifndef HANDZONE_H #define HANDZONE_H -#include "../../game/zones/hand_zone_logic.h" +#include "../../game/board/card_list.h" #include "select_zone.h" +#include +#include + +class HandZoneLogic; +class QGraphicsItem; +template class QList; + class HandZone : public SelectZone { Q_OBJECT diff --git a/cockatrice/src/game_graphics/zones/pile_zone.cpp b/cockatrice/src/game_graphics/zones/pile_zone.cpp index abdf262f4..77a87a4af 100644 --- a/cockatrice/src/game_graphics/zones/pile_zone.cpp +++ b/cockatrice/src/game_graphics/zones/pile_zone.cpp @@ -1,18 +1,33 @@ #include "pile_zone.h" #include "../../client/settings/cache_settings.h" +#include "../../game/board/card_list.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" #include "../../game/zones/pile_zone_logic.h" #include "../board/card_drag_item.h" #include "../board/card_item.h" -#include "view_zone.h" +#include "../card_dimensions.h" #include +#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include PileZone::PileZone(PileZoneLogic *_logic, QGraphicsItem *parent) : CardZone(_logic, parent) { diff --git a/cockatrice/src/game_graphics/zones/pile_zone.h b/cockatrice/src/game_graphics/zones/pile_zone.h index 099bc6f60..b2d8d0cd2 100644 --- a/cockatrice/src/game_graphics/zones/pile_zone.h +++ b/cockatrice/src/game_graphics/zones/pile_zone.h @@ -7,9 +7,13 @@ #ifndef PILEZONE_H #define PILEZONE_H -#include "../../game/zones/pile_zone_logic.h" #include "card_zone.h" +#include + +class PileZoneLogic; +class QGraphicsItem; + /** * A CardZone where the cards are in a single pile instead of being laid out. * Usually only top card is accessible by clicking. diff --git a/cockatrice/src/game_graphics/zones/select_zone.cpp b/cockatrice/src/game_graphics/zones/select_zone.cpp index 470c70fcf..d69ec32f5 100644 --- a/cockatrice/src/game_graphics/zones/select_zone.cpp +++ b/cockatrice/src/game_graphics/zones/select_zone.cpp @@ -1,13 +1,25 @@ #include "select_zone.h" #include "../../client/settings/cache_settings.h" +#include "../../game/board/card_list.h" +#include "../../game/zones/card_zone_logic.h" #include "../board/card_item.h" #include "../game_scene.h" +#include +#include #include +#include #include +#include +#include +#include +#include +#include #include #include +#include +#include static qreal stackingOffset(qreal cardHeight) { diff --git a/cockatrice/src/game_graphics/zones/select_zone.h b/cockatrice/src/game_graphics/zones/select_zone.h index b5d3ca37a..8a56949e3 100644 --- a/cockatrice/src/game_graphics/zones/select_zone.h +++ b/cockatrice/src/game_graphics/zones/select_zone.h @@ -9,10 +9,16 @@ #include "card_zone.h" +#include #include +#include #include +#include class QGraphicsRectItem; +class CardItem; +class CardZoneLogic; +class QGraphicsItem; /** * A CardZone where the cards are laid out, with each card directly interactable by clicking. diff --git a/cockatrice/src/game_graphics/zones/stack_zone.cpp b/cockatrice/src/game_graphics/zones/stack_zone.cpp index ff62097c7..de1ff8ba9 100644 --- a/cockatrice/src/game_graphics/zones/stack_zone.cpp +++ b/cockatrice/src/game_graphics/zones/stack_zone.cpp @@ -1,15 +1,27 @@ #include "stack_zone.h" +#include "../../game/board/card_list.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" #include "../../game/zones/stack_zone_logic.h" #include "../../interface/theme_manager.h" #include "../board/card_drag_item.h" #include "../board/card_item.h" #include "../card_dimensions.h" +#include +#include +#include +#include #include +#include +#include +#include #include +#include +#include StackZone::StackZone(StackZoneLogic *_logic, int _zoneHeight, QGraphicsItem *parent) : SelectZone(_logic, parent), zoneHeight(_zoneHeight) diff --git a/cockatrice/src/game_graphics/zones/stack_zone.h b/cockatrice/src/game_graphics/zones/stack_zone.h index 96b3f96a6..5dea481b6 100644 --- a/cockatrice/src/game_graphics/zones/stack_zone.h +++ b/cockatrice/src/game_graphics/zones/stack_zone.h @@ -7,9 +7,14 @@ #ifndef STACKZONE_H #define STACKZONE_H -#include "../../game/zones/stack_zone_logic.h" #include "select_zone.h" +#include +#include + +class QGraphicsItem; +class StackZoneLogic; + class StackZone : public SelectZone { Q_OBJECT diff --git a/cockatrice/src/game_graphics/zones/table_zone.cpp b/cockatrice/src/game_graphics/zones/table_zone.cpp index 88e9abe6c..b704b79e0 100644 --- a/cockatrice/src/game_graphics/zones/table_zone.cpp +++ b/cockatrice/src/game_graphics/zones/table_zone.cpp @@ -1,23 +1,50 @@ #include "table_zone.h" #include "../../client/settings/cache_settings.h" +#include "../../game/board/card_list.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" #include "../../game/zones/table_zone_logic.h" #include "../../interface/theme_manager.h" -#include "../board/arrow_item.h" +#include "../board/abstract_card_item.h" #include "../board/card_drag_item.h" #include "../board/card_item.h" #include "../game_scene.h" #include "../z_values.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/protocol/pb/card_attributes.pb.h" +#include +#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include #include #include #include #include +#include + +namespace google +{ +namespace protobuf +{ +class Message; +} // namespace protobuf +} // namespace google const QColor TableZone::BACKGROUND_COLOR = QColor(100, 100, 100); const QColor TableZone::FADE_MASK = QColor(0, 0, 0, 80); diff --git a/cockatrice/src/game_graphics/zones/table_zone.h b/cockatrice/src/game_graphics/zones/table_zone.h index 92915a2ed..ccd1d8e81 100644 --- a/cockatrice/src/game_graphics/zones/table_zone.h +++ b/cockatrice/src/game_graphics/zones/table_zone.h @@ -7,12 +7,26 @@ #ifndef TABLEZONE_H #define TABLEZONE_H -#include "../../game/zones/table_zone_logic.h" #include "../animated_item.h" -#include "../board/abstract_card_item.h" +#include "../card_dimensions.h" #include "select_zone.h" #include +#include +#include +#include +#include +#include +#include + +class CardDragItem; +class CardItem; +class CardZoneLogic; +class QColor; +class QGraphicsItem; +class QPainter; +class TableZoneLogic; +template class QList; /** * @brief TableZone is the grid based rect where CardItems may be placed. diff --git a/cockatrice/src/game_graphics/zones/view_zone.cpp b/cockatrice/src/game_graphics/zones/view_zone.cpp index 5bd5d262f..a2aa124dc 100644 --- a/cockatrice/src/game_graphics/zones/view_zone.cpp +++ b/cockatrice/src/game_graphics/zones/view_zone.cpp @@ -2,16 +2,29 @@ #include "../../client/settings/cache_settings.h" #include "../../game/player/player_actions.h" +#include "../../game/player/player_info.h" #include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" #include "../../game/zones/view_zone_logic.h" #include "../board/card_drag_item.h" #include "../board/card_item.h" +#include "../card_dimensions.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/filters/filter_string.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_zone.pb.h" +#include "libcockatrice/utility/card_ref.h" #include +#include #include -#include +#include +#include #include +#include +#include #include +#include #include #include #include @@ -19,6 +32,9 @@ #include #include #include +#include + +class QGraphicsItem; /** * @param parent the parent QGraphicsWidget containing the reveal zone diff --git a/cockatrice/src/game_graphics/zones/view_zone.h b/cockatrice/src/game_graphics/zones/view_zone.h index 9dfa00ce2..4032da760 100644 --- a/cockatrice/src/game_graphics/zones/view_zone.h +++ b/cockatrice/src/game_graphics/zones/view_zone.h @@ -7,17 +7,29 @@ #ifndef ZONEVIEWERZONE_H #define ZONEVIEWERZONE_H -#include "../../game/zones/view_zone_logic.h" +#include "../../game/board/card_list.h" #include "select_zone.h" #include +#include #include +#include +#include +#include #include -#include +#include +#include + +// IWYU pragma: keep +// ServerInfo_Card appears inside QList<...> in signal and slot +// signatures, which the moc-generated code needs to be complete. +#include + +class QGraphicsItem; +class ZoneViewZoneLogic; inline Q_LOGGING_CATEGORY(ViewZoneLog, "view_zone"); -class ZoneViewWidget; class Response; class ServerInfo_Card; class QGraphicsSceneWheelEvent; diff --git a/cockatrice/src/game_graphics/zones/view_zone_widget.cpp b/cockatrice/src/game_graphics/zones/view_zone_widget.cpp index fa6733413..49d9955e0 100644 --- a/cockatrice/src/game_graphics/zones/view_zone_widget.cpp +++ b/cockatrice/src/game_graphics/zones/view_zone_widget.cpp @@ -1,32 +1,63 @@ #include "view_zone_widget.h" #include "../../client/settings/cache_settings.h" +#include "../../client/translation.h" #include "../../filters/syntax_help.h" +#include "../../game/board/card_list.h" #include "../../game/player/player_actions.h" #include "../../game/player/player_logic.h" +#include "../../game/zones/card_zone_logic.h" +#include "../../game/zones/view_zone_logic.h" #include "../../interface/pixel_map_generator.h" -#include "../board/card_item.h" -#include "../game_scene.h" +#include "../card_dimensions.h" #include "../z_values.h" +#include "libcockatrice/utility/macros.h" #include "view_zone.h" +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include +#include #include -#include -#include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include #include #include #include +#include namespace { -constexpr qreal kTitleBarHeight = 24.0; +qreal titleBarHeight(QWidget *styleWidget) +{ + if (styleWidget) { + return static_cast(styleWidget->style()->pixelMetric(QStyle::PM_TitleBarHeight, nullptr, styleWidget)); + } + return 24.0; +} constexpr qreal kMinVisibleWidth = 100.0; } // namespace @@ -290,7 +321,8 @@ QRectF ZoneViewWidget::closeButtonRect(QWidget *styleWidget) const // query the style for the close button position (handles macOS top-left placement) // Title bar rect MUST be local (0,0-based) for QStyle - const QRect titleBarRect(0, 0, static_cast(frameRectF.width()), static_cast(kTitleBarHeight)); + const qreal tbh = titleBarHeight(styleWidget); + const QRect titleBarRect(0, 0, static_cast(frameRectF.width()), static_cast(tbh)); if (styleWidget) { QStyleOptionTitleBar opt; @@ -319,7 +351,7 @@ QRectF ZoneViewWidget::closeButtonRect(QWidget *styleWidget) const } // Fallback: frame-relative top-right - return QRectF(frameRectF.right() - kTitleBarHeight, frameRectF.top(), kTitleBarHeight, kTitleBarHeight); + return QRectF(frameRectF.right() - tbh, frameRectF.top(), tbh, tbh); } QGraphicsView *ZoneViewWidget::findDragView(QWidget *eventWidget) const @@ -443,8 +475,9 @@ QVariant ZoneViewWidget::itemChange(GraphicsItemChange change, const QVariant &v const qreal minX = sceneRect.left(); const qreal maxX = qMax(minX, sceneRect.right() - kMinVisibleWidth); - const qreal minY = sceneRect.top() + kTitleBarHeight; - const qreal maxY = qMax(minY, sceneRect.bottom() - kTitleBarHeight); + const qreal tbh = titleBarHeight(nullptr); + const qreal minY = sceneRect.top() + tbh; + const qreal maxY = qMax(minY, sceneRect.bottom() - tbh); desiredPos.setX(qBound(minX, desiredPos.x(), maxX)); desiredPos.setY(qBound(minY, desiredPos.y(), maxY)); diff --git a/cockatrice/src/game_graphics/zones/view_zone_widget.h b/cockatrice/src/game_graphics/zones/view_zone_widget.h index de5ad28d5..9fe022b27 100644 --- a/cockatrice/src/game_graphics/zones/view_zone_widget.h +++ b/cockatrice/src/game_graphics/zones/view_zone_widget.h @@ -6,30 +6,34 @@ #ifndef ZONEVIEWWIDGET_H #define ZONEVIEWWIDGET_H -#include "../../game/zones/card_zone_logic.h" - #include #include #include #include #include +#include +#include +#include #include +#include +#include #include +#include + +// IWYU pragma: keep +// ServerInfo_Card appears inside QList<...> in signal and slot +// signatures, which the moc-generated code needs to be complete. +#include -class QLabel; -class QPushButton; -class CardZone; class ZoneViewZone; class PlayerLogic; -class CardDatabase; class QScrollBar; -class GameScene; class ServerInfo_Card; class QGraphicsSceneMouseEvent; class QGraphicsSceneWheelEvent; -class QStyleOption; class QGraphicsView; class QWidget; +class CardZoneLogic; class ScrollableGraphicsProxyWidget : public QGraphicsProxyWidget { diff --git a/cockatrice/src/interface/card_database_update/card_database_update_status_bar.cpp b/cockatrice/src/interface/card_database_update/card_database_update_status_bar.cpp new file mode 100644 index 000000000..721fdd6c8 --- /dev/null +++ b/cockatrice/src/interface/card_database_update/card_database_update_status_bar.cpp @@ -0,0 +1,117 @@ +#include "card_database_update_status_bar.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +/** + * @brief Translated name of one updater stage. + * @param fallback shown when the stage is unknown or not reported yet + */ +QString stageName(CardUpdateStage stage, const QString &fallback) +{ + switch (stage) { + case CardUpdateStage::Download: + return QCoreApplication::translate("CardDatabaseUpdateStatusBar", "Downloading"); + case CardUpdateStage::Scan: + return QCoreApplication::translate("CardDatabaseUpdateStatusBar", "Parsing"); + case CardUpdateStage::Import: + return QCoreApplication::translate("CardDatabaseUpdateStatusBar", "Importing"); + case CardUpdateStage::Unknown: + return fallback; + } + return fallback; +} +} // namespace + +CardDatabaseUpdateStatusBar::CardDatabaseUpdateStatusBar(QWidget *parent) : QWidget(parent) +{ + layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + + stageLabel = new QLabel(this); + progressBar = new QProgressBar(this); + progressBar->setMinimumWidth(120); + + layout->addWidget(stageLabel); + layout->addWidget(progressBar); + + setLayout(layout); + refresh(); + hide(); +} + +QString CardDatabaseUpdateStatusBar::statusText() const +{ + if (!active) { + return {}; + } + const QString name = stageName(progress.stage, tr("Updating the card database")); + if (progress.total <= 0) { + return name; + } + const int percent = static_cast((100.0 * progress.done) / progress.total); + return tr("%1 (%2%)").arg(name).arg(percent); +} + +void CardDatabaseUpdateStatusBar::updateStarted() +{ + active = true; + progress = {}; + refresh(); + show(); +} + +void CardDatabaseUpdateStatusBar::updateProgress(const CardUpdateProgress &progress) +{ + active = true; + this->progress = progress; + refresh(); +} + +void CardDatabaseUpdateStatusBar::updateFinished() +{ + active = false; + progress = {}; + refresh(); + hide(); +} + +void CardDatabaseUpdateStatusBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) { + refresh(); + } + QWidget::changeEvent(event); +} + +void CardDatabaseUpdateStatusBar::refresh() +{ + const QString name = stageName(progress.stage, tr("Updating the card database")); + stageLabel->setText(name); + + const qint64 cappedTotal = qMin(progress.total, INT_MAX); + const qint64 cappedDone = qMin(progress.done, INT_MAX); + const int minimum = 0; + const int maximum = static_cast(cappedTotal); + if (progressBar->minimum() != minimum || progressBar->maximum() != maximum) { + // A zero range is the busy indicator, used until the first report arrives. + progressBar->setRange(minimum, maximum); + } + progressBar->setValue(static_cast(cappedDone)); + + if (active && progress.total > 0) { + const int percent = static_cast((100.0 * progress.done) / progress.total); + setToolTip(tr("Card database update in progress: %1 (%2%)").arg(name).arg(percent)); + } else if (active) { + setToolTip(tr("Card database update in progress.")); + } else { + setToolTip({}); + } +} diff --git a/cockatrice/src/interface/card_database_update/card_database_update_status_bar.h b/cockatrice/src/interface/card_database_update/card_database_update_status_bar.h new file mode 100644 index 000000000..6db3bd225 --- /dev/null +++ b/cockatrice/src/interface/card_database_update/card_database_update_status_bar.h @@ -0,0 +1,68 @@ +#ifndef CARD_DATABASE_UPDATE_STATUS_BAR_H +#define CARD_DATABASE_UPDATE_STATUS_BAR_H + +#include "card_update_progress.h" + +#include +#include +#include + +class QEvent; +class QHBoxLayout; +class QLabel; +class QProgressBar; + +/** + * @class CardDatabaseUpdateStatusBar + * @brief Status bar widget showing what the card database updater (Oracle) is doing. + * + * The updater runs as a separate process, so this widget is the in-client view of + * its progress: it appears when an update starts, tracks the download/scan/import + * stages reported by the updater, and disappears when the update finishes. + */ +class CardDatabaseUpdateStatusBar : public QWidget +{ + Q_OBJECT +public: + /** + * @brief Constructs a hidden progress widget. + * @param parent Parent widget + */ + explicit CardDatabaseUpdateStatusBar(QWidget *parent = nullptr); + + /** + * @brief Human readable description of the running stage, e.g. "Downloading (42%)". + * @return the description, or an empty string when no update is running + */ + QString statusText() const; + +public slots: + /** + * @brief Shows the widget and resets it to the indeterminate state. + */ + void updateStarted(); + + /** + * @brief Shows the progress of one update stage. + */ + void updateProgress(const CardUpdateProgress &progress); + + /** + * @brief Hides the widget and clears the reported progress. + */ + void updateFinished(); + +protected: + void changeEvent(QEvent *event) override; + +private: + void refresh(); + + QHBoxLayout *layout; ///< Horizontal layout holding the stage label and the progress bar + QLabel *stageLabel; ///< Name of the stage currently running + QProgressBar *progressBar; ///< Progress within the current stage + CardUpdateProgress progress; ///< Last reported progress + bool active = false; ///< Whether an update is currently running +}; + +#endif // CARD_DATABASE_UPDATE_STATUS_BAR_H diff --git a/cockatrice/src/interface/card_database_update/card_update_progress.cpp b/cockatrice/src/interface/card_database_update/card_update_progress.cpp new file mode 100644 index 000000000..1f8e500d0 --- /dev/null +++ b/cockatrice/src/interface/card_database_update/card_update_progress.cpp @@ -0,0 +1,59 @@ +#include "card_update_progress.h" + +#include + +namespace +{ +CardUpdateStage parseStage(const QByteArray &token) +{ + if (token == "download") { + return CardUpdateStage::Download; + } + if (token == "scan") { + return CardUpdateStage::Scan; + } + if (token == "import") { + return CardUpdateStage::Import; + } + return CardUpdateStage::Unknown; +} +} // namespace + +std::optional CardUpdateProgress::fromProtocolLine(const QByteArray &line) +{ + const QByteArray trimmed = line.trimmed(); + if (!trimmed.startsWith("PROGRESS ")) { + return std::nullopt; + } + const QList parts = trimmed.split(' '); + if (parts.size() != 4) { + return std::nullopt; + } + bool doneOk = false; + bool totalOk = false; + const qint64 done = parts.at(2).toLongLong(&doneOk); + const qint64 total = parts.at(3).toLongLong(&totalOk); + if (!doneOk || !totalOk || done < 0 || total < 0) { + return std::nullopt; + } + CardUpdateProgress progress; + progress.stage = parseStage(parts.at(1)); + progress.done = done; + progress.total = total; + return progress; +} + +QString CardUpdateProgress::stageToken() const +{ + switch (stage) { + case CardUpdateStage::Download: + return QStringLiteral("download"); + case CardUpdateStage::Scan: + return QStringLiteral("scan"); + case CardUpdateStage::Import: + return QStringLiteral("import"); + case CardUpdateStage::Unknown: + return QStringLiteral("unknown"); + } + return QStringLiteral("unknown"); +} diff --git a/cockatrice/src/interface/card_database_update/card_update_progress.h b/cockatrice/src/interface/card_database_update/card_update_progress.h new file mode 100644 index 000000000..743f32209 --- /dev/null +++ b/cockatrice/src/interface/card_database_update/card_update_progress.h @@ -0,0 +1,42 @@ +#ifndef CARD_UPDATE_PROGRESS_H +#define CARD_UPDATE_PROGRESS_H + +#include +#include +#include +#include + +/** + * @brief One stage of the card database updater's progress protocol. + */ +enum class CardUpdateStage +{ + Download, ///< downloading the source data + Scan, ///< parsing the downloaded data + Import, ///< importing cards into the database + Unknown, ///< a stage the client does not recognize +}; + +/** + * @brief One progress line read from the card database updater's stdout. + */ +struct CardUpdateProgress +{ + /** + * @brief Parses one line of the updater stdout protocol: "PROGRESS ". + * @param line a single stdout line, with or without its trailing newline + * @return the parsed progress, or @c std::nullopt when the line is not a valid progress line + */ + static std::optional fromProtocolLine(const QByteArray &line); + + /** + * @brief Protocol token of the stage ("download", "scan", "import" or "unknown"), for logging. + */ + QString stageToken() const; + + CardUpdateStage stage = CardUpdateStage::Unknown; + qint64 done = 0; + qint64 total = 0; +}; + +#endif // CARD_UPDATE_PROGRESS_H diff --git a/cockatrice/src/interface/card_localization.h b/cockatrice/src/interface/card_localization.h index 1a1e7be5d..39cbd7700 100644 --- a/cockatrice/src/interface/card_localization.h +++ b/cockatrice/src/interface/card_localization.h @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace CardLocalization diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader.cpp b/cockatrice/src/interface/card_picture_loader/card_picture_loader.cpp index 8e34942e1..4f77c7096 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader.cpp +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader.cpp @@ -4,27 +4,45 @@ #include "../pixel_map_generator.h" #include "card_picture_loader_cache_method.h" #include "card_picture_loader_local_schemes.h" +#include "card_picture_loader_status_bar.h" +#include "card_picture_loader_worker.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" #include -#include +#include +#include +#include #include #include +#include #include +#include +#include +#include #include +#include #include -#include -#include -#include +#include +#include #include #include +#include +#include #include +#include +#include #include -#include +#include +#include +#include #include #include #include #include -#include +#include // never cache more than 300 cards at once for a single deck #define CACHED_CARD_PER_DECK_MAX 300 diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader.h b/cockatrice/src/interface/card_picture_loader/card_picture_loader.h index 6224befbf..c6d91570b 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader.h +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader.h @@ -1,12 +1,20 @@ #ifndef CARD_PICTURE_LOADER_H #define CARD_PICTURE_LOADER_H -#include "card_picture_loader_status_bar.h" -#include "card_picture_loader_worker.h" - -#include #include #include +#include +#include + +class CardPictureLoaderStatusBar; +class CardPictureLoaderWorker; +class ExactCard; +class QDateTime; +class QImage; +class QPixmap; +class QSize; +class QString; +template class QList; inline Q_LOGGING_CATEGORY(CardPictureLoaderLog, "card_picture_loader"); inline Q_LOGGING_CATEGORY(CardPictureLoaderCardBackCacheFailLog, "card_picture_loader.card_back_cache_fail"); diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.cpp b/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.cpp index 12165e8f3..1437e23f4 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.cpp +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.cpp @@ -2,11 +2,21 @@ #include "../../client/settings/cache_settings.h" #include "card_picture_loader_local_schemes.h" -#include "card_picture_to_load.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include +#include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include static constexpr int REFRESH_INTERVAL_MS = 10 * 1000; diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.h b/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.h index 44163d1db..009897acc 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.h +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.h @@ -1,8 +1,15 @@ #ifndef PICTURE_LOADER_LOCAL_H #define PICTURE_LOADER_LOCAL_H -#include -#include +#include +#include +#include +#include +#include +#include + +class ExactCard; +class QTimer; inline Q_LOGGING_CATEGORY(CardPictureLoaderLocalLog, "card_picture_loader.local"); diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.cpp b/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.cpp index d1895af06..98364e3cb 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.cpp +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.cpp @@ -1,5 +1,11 @@ #include "card_picture_loader_request_status_display_widget.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" + +#include +#include + CardPictureLoaderRequestStatusDisplayWidget::CardPictureLoaderRequestStatusDisplayWidget(QWidget *parent, const QUrl &_url, const ExactCard &card, diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.h b/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.h index c9a272b68..58051cc1e 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.h +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_request_status_display_widget.h @@ -1,11 +1,16 @@ #ifndef PICTURE_LOADER_REQUEST_STATUS_DISPLAY_WIDGET_H #define PICTURE_LOADER_REQUEST_STATUS_DISPLAY_WIDGET_H -#include +#include #include -#include +#include +#include #include -#include +#include + +class ExactCard; +class QHBoxLayout; +class QUrl; /** * @class CardPictureLoaderRequestStatusDisplayWidget diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.cpp b/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.cpp index 9e7e645bd..3b26c8033 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.cpp +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.cpp @@ -1,7 +1,19 @@ #include "card_picture_loader_status_bar.h" +#include "../widgets/quick_settings/settings_button_widget.h" +#include "../widgets/quick_settings/settings_popup_widget.h" #include "card_picture_loader_request_status_display_widget.h" +#include +#include +#include +#include +#include +#include +#include + +class ExactCard; + CardPictureLoaderStatusBar::CardPictureLoaderStatusBar(QWidget *parent) : QWidget(parent) { layout = new QHBoxLayout(this); diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.h b/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.h index 7f1f509db..2ba386c42 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.h +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_status_bar.h @@ -1,12 +1,16 @@ #ifndef PICTURE_LOADER_STATUS_BAR_H #define PICTURE_LOADER_STATUS_BAR_H -#include "../../interface/widgets/quick_settings/settings_button_widget.h" -#include "card_picture_loader_worker_work.h" - -#include -#include +#include #include +#include + +class ExactCard; +class QHBoxLayout; +class QProgressBar; +class QTimer; +class QUrl; +class SettingsButtonWidget; /** * @class CardPictureLoaderStatusBar diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.cpp b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.cpp index 0fd6a42d5..150b4c544 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.cpp +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.cpp @@ -4,15 +4,34 @@ #include "card_picture_loader_cache_method.h" #include "card_picture_loader_local.h" #include "card_picture_loader_worker_work.h" +#include "card_picture_to_load.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/utility/server_rate_limiter.h" -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include #include +#include +#include +#include #include #include #include +#include #include #include diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.h b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.h index 8b136f309..4b42c6e59 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.h +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker.h @@ -1,21 +1,25 @@ #ifndef PICTURE_LOADER_WORKER_H #define PICTURE_LOADER_WORKER_H -#include "card_picture_loader_local.h" -#include "card_picture_loader_worker_work.h" -#include "card_picture_to_load.h" - -#include #include #include -#include -#include -#include #include +#include #include +#include +#include #include -#include -#include +#include +#include + +class CardPictureLoaderLocal; +class ExactCard; +class QDateTime; +class QImage; +class QNetworkAccessManager; +class QNetworkDiskCache; +class QNetworkReply; +class QThread; #define REDIRECT_HEADER_NAME "redirects" #define REDIRECT_ORIGINAL_URL "original" diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.cpp b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.cpp index 19c6be469..92524384a 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.cpp +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.cpp @@ -2,19 +2,35 @@ #include "../../client/settings/cache_settings.h" #include "card_picture_loader_worker.h" +#include "card_picture_to_load.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/utility/server_rate_limiter.h" #include -#include +#include +#include +#include +#include +#include +#include #include +#include #include #include +#include #include -#include -#include +#include +#include #include +#include +#include ServerRateLimiter CardPictureLoaderWorkerWork::s_rateLimiter; +#include #include +#include +#include // Card back returned by gatherer when card is not found static const QStringList MD5_BLACKLIST = { diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.h b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.h index 84a7dafdb..c3dbcc6e8 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.h +++ b/cockatrice/src/interface/card_picture_loader/card_picture_loader_worker_work.h @@ -1,19 +1,18 @@ #ifndef PICTURE_LOADER_WORKER_WORK_H #define PICTURE_LOADER_WORKER_WORK_H -#include "card_picture_loader_worker.h" #include "card_picture_to_load.h" -#include +#include #include -#include -#include #include -#include #include -#include -#include -#include +#include + +class ExactCard; +class QNetworkReply; +class QUrl; +class ServerRateLimiter; inline Q_LOGGING_CATEGORY(CardPictureLoaderWorkerWorkLog, "card_picture_loader.worker"); diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_to_load.cpp b/cockatrice/src/interface/card_picture_loader/card_picture_to_load.cpp index 4f933207e..e35c417c8 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_to_load.cpp +++ b/cockatrice/src/interface/card_picture_loader/card_picture_to_load.cpp @@ -1,12 +1,22 @@ #include "card_picture_to_load.h" #include "../../client/settings/cache_settings.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" -#include #include +#include +#include +#include #include +#include +#include +#include #include +#include #include +#include #include #include #include diff --git a/cockatrice/src/interface/card_picture_loader/card_picture_to_load.h b/cockatrice/src/interface/card_picture_loader/card_picture_to_load.h index 9e0e7449c..fe56dc4c6 100644 --- a/cockatrice/src/interface/card_picture_loader/card_picture_to_load.h +++ b/cockatrice/src/interface/card_picture_loader/card_picture_to_load.h @@ -1,6 +1,12 @@ #ifndef PICTURE_TO_LOAD_H #define PICTURE_TO_LOAD_H +#include "libcockatrice/card/card_info.h" + +#include +#include +#include +#include #include inline Q_LOGGING_CATEGORY(CardPictureToLoadLog, "card_picture_loader.picture_to_load"); diff --git a/cockatrice/src/interface/deck_loader/card_node_function.cpp b/cockatrice/src/interface/deck_loader/card_node_function.cpp index 9441fe428..8d59a6c15 100644 --- a/cockatrice/src/interface/deck_loader/card_node_function.cpp +++ b/cockatrice/src/interface/deck_loader/card_node_function.cpp @@ -1,5 +1,12 @@ #include "card_node_function.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" + +#include +#include +#include #include #include #include @@ -8,13 +15,14 @@ void CardNodeFunction::SetProviderIdToPreferred::operator()(const InnerDecklistN { Q_UNUSED(node); PrintingInfo preferredPrinting = CardDatabaseManager::query()->getPreferredPrinting(card->getName()); - QString providerId = preferredPrinting.getUuid(); - QString setShortName = preferredPrinting.getSet()->getShortName(); - QString collectorNumber = preferredPrinting.getProperty("num"); + CardSetPtr preferredSet = preferredPrinting.getSet(); + if (!preferredSet) { + return; + } - card->setCardProviderId(providerId); - card->setCardCollectorNumber(collectorNumber); - card->setCardSetShortName(setShortName); + card->setCardProviderId(preferredPrinting.getUuid()); + card->setCardCollectorNumber(preferredPrinting.getProperty("num")); + card->setCardSetShortName(preferredSet->getShortName()); } void CardNodeFunction::ClearPrintingData::operator()(const InnerDecklistNode *node, DecklistCardNode *card) const diff --git a/cockatrice/src/interface/deck_loader/deck_file_format.cpp b/cockatrice/src/interface/deck_loader/deck_file_format.cpp index 3c88cde4e..ba5a44e4c 100644 --- a/cockatrice/src/interface/deck_loader/deck_file_format.cpp +++ b/cockatrice/src/interface/deck_loader/deck_file_format.cpp @@ -1,5 +1,7 @@ #include "deck_file_format.h" +#include + DeckFileFormat::Format DeckFileFormat::getFormatFromName(const QString &fileName) { if (fileName.endsWith(".cod", Qt::CaseInsensitive)) { diff --git a/cockatrice/src/interface/deck_loader/deck_loader.cpp b/cockatrice/src/interface/deck_loader/deck_loader.cpp index f29b4eed2..d413a6c04 100644 --- a/cockatrice/src/interface/deck_loader/deck_loader.cpp +++ b/cockatrice/src/interface/deck_loader/deck_loader.cpp @@ -1,26 +1,51 @@ #include "deck_loader.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" + #include #include +#include #include #include #include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include +#include +#include #include #include +#include #include #include +#include +#include +#include #include -#include +#include #include #include #include #include +#include + +class QTextLength; const QStringList DeckLoader::ACCEPTED_FILE_EXTENSIONS = {"*.cod", "*.dec", "*.dek", "*.txt", "*.mwDeck"}; diff --git a/cockatrice/src/interface/deck_loader/deck_loader.h b/cockatrice/src/interface/deck_loader/deck_loader.h index be0df311d..16402b14b 100644 --- a/cockatrice/src/interface/deck_loader/deck_loader.h +++ b/cockatrice/src/interface/deck_loader/deck_loader.h @@ -7,13 +7,23 @@ #ifndef DECK_LOADER_H #define DECK_LOADER_H +#include "deck_file_format.h" #include "loaded_deck.h" #include -#include -#include -#include +#include +#include +#include #include +#include + +class DeckList; +class DecklistCardNode; +class InnerDecklistNode; +class QPrinter; +class QTextCursor; +class QTextStream; +template class QList; inline Q_LOGGING_CATEGORY(DeckLoaderLog, "deck_loader"); diff --git a/cockatrice/src/interface/intents/intent.h b/cockatrice/src/interface/intents/intent.h index 5d9fdd3d6..ad8d4b5af 100644 --- a/cockatrice/src/interface/intents/intent.h +++ b/cockatrice/src/interface/intents/intent.h @@ -2,6 +2,8 @@ #define COCKATRICE_INTENT_H #include +#include +#include class Intent : public QObject { diff --git a/cockatrice/src/interface/intents/intent_connect_to_server.cpp b/cockatrice/src/interface/intents/intent_connect_to_server.cpp index 1cccc5a23..42ddc97cc 100644 --- a/cockatrice/src/interface/intents/intent_connect_to_server.cpp +++ b/cockatrice/src/interface/intents/intent_connect_to_server.cpp @@ -1,8 +1,14 @@ #include "intent_connect_to_server.h" +#include "contexts/context_connect_to_server.h" #include "intent_disconnect_from_server.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "remote_client.h" #include +#include + +template class QList; IntentConnectToServer::IntentConnectToServer(RemoteClient *_remoteClient, ContextConnectToServer *_context) : Intent(), remoteClient(_remoteClient), context(_context) diff --git a/cockatrice/src/interface/intents/intent_connect_to_server.h b/cockatrice/src/interface/intents/intent_connect_to_server.h index eab4d1a21..50d7f088b 100644 --- a/cockatrice/src/interface/intents/intent_connect_to_server.h +++ b/cockatrice/src/interface/intents/intent_connect_to_server.h @@ -1,9 +1,14 @@ #ifndef COCKATRICE_INTENT_CONNECT_TO_SERVER_H #define COCKATRICE_INTENT_CONNECT_TO_SERVER_H -#include "contexts/context_connect_to_server.h" +#include "abstract_client.h" #include "intent.h" -#include "remote_client.h" + +#include +#include + +class RemoteClient; +struct ContextConnectToServer; class IntentConnectToServer : public Intent { diff --git a/cockatrice/src/interface/intents/intent_disconnect_from_server.cpp b/cockatrice/src/interface/intents/intent_disconnect_from_server.cpp index cb39d7bab..e865c4a2b 100644 --- a/cockatrice/src/interface/intents/intent_disconnect_from_server.cpp +++ b/cockatrice/src/interface/intents/intent_disconnect_from_server.cpp @@ -1,5 +1,7 @@ #include "intent_disconnect_from_server.h" +#include "remote_client.h" + IntentDisconnectFromServer::IntentDisconnectFromServer(RemoteClient *_remoteClient) : Intent(), remoteClient(_remoteClient) { diff --git a/cockatrice/src/interface/intents/intent_disconnect_from_server.h b/cockatrice/src/interface/intents/intent_disconnect_from_server.h index 6e1dfd0c1..5425e973b 100644 --- a/cockatrice/src/interface/intents/intent_disconnect_from_server.h +++ b/cockatrice/src/interface/intents/intent_disconnect_from_server.h @@ -1,8 +1,12 @@ #ifndef COCKATRICE_INTENT_DISCONNECT_FROM_SERVER_H #define COCKATRICE_INTENT_DISCONNECT_FROM_SERVER_H +#include "abstract_client.h" #include "intent.h" -#include "remote_client.h" + +#include + +class RemoteClient; class IntentDisconnectFromServer : public Intent { diff --git a/cockatrice/src/interface/intents/intent_join_server_game.cpp b/cockatrice/src/interface/intents/intent_join_server_game.cpp index b22b200ed..52e02b276 100644 --- a/cockatrice/src/interface/intents/intent_join_server_game.cpp +++ b/cockatrice/src/interface/intents/intent_join_server_game.cpp @@ -3,9 +3,17 @@ #include "../widgets/server/game_selector.h" #include "../widgets/tabs/tab_room.h" #include "../widgets/tabs/tab_supervisor.h" +#include "abstract_client.h" +#include "contexts/context_connect_to_server.h" +#include "contexts/context_join_room.h" #include "intent_join_server_room.h" +#include "remote_client.h" +#include +#include +#include #include +#include IntentJoinServerGame::IntentJoinServerGame(TabSupervisor *_tabSupervisor, RemoteClient *_remoteClient, diff --git a/cockatrice/src/interface/intents/intent_join_server_game.h b/cockatrice/src/interface/intents/intent_join_server_game.h index 5e196df38..5abb31fc5 100644 --- a/cockatrice/src/interface/intents/intent_join_server_game.h +++ b/cockatrice/src/interface/intents/intent_join_server_game.h @@ -3,13 +3,14 @@ #include "contexts/context_join_game.h" #include "intent.h" -#include "remote_client.h" #include #include +#include class TabRoom; class TabSupervisor; +class RemoteClient; class IntentJoinServerGame : public Intent { diff --git a/cockatrice/src/interface/intents/intent_join_server_room.cpp b/cockatrice/src/interface/intents/intent_join_server_room.cpp index d25bc8d17..24349cadf 100644 --- a/cockatrice/src/interface/intents/intent_join_server_room.cpp +++ b/cockatrice/src/interface/intents/intent_join_server_room.cpp @@ -3,8 +3,15 @@ #include "../widgets/tabs/tab_room.h" #include "../widgets/tabs/tab_server.h" #include "../widgets/tabs/tab_supervisor.h" +#include "abstract_client.h" +#include "contexts/context_connect_to_server.h" +#include "contexts/context_join_room.h" #include "intent_connect_to_server.h" +#include "remote_client.h" +#include +#include +#include #include #include diff --git a/cockatrice/src/interface/intents/intent_join_server_room.h b/cockatrice/src/interface/intents/intent_join_server_room.h index 4a5599896..b4febae7b 100644 --- a/cockatrice/src/interface/intents/intent_join_server_room.h +++ b/cockatrice/src/interface/intents/intent_join_server_room.h @@ -1,11 +1,13 @@ #ifndef COCKATRICE_INTENT_JOIN_SERVER_ROOM_H #define COCKATRICE_INTENT_JOIN_SERVER_ROOM_H -#include "contexts/context_join_room.h" #include "intent.h" -#include "remote_client.h" + +#include class TabSupervisor; +class RemoteClient; +struct ContextJoinRoom; class IntentJoinServerRoom : public Intent { diff --git a/cockatrice/src/interface/intents/intent_login.cpp b/cockatrice/src/interface/intents/intent_login.cpp index 7beb63e1d..0d8390015 100644 --- a/cockatrice/src/interface/intents/intent_login.cpp +++ b/cockatrice/src/interface/intents/intent_login.cpp @@ -2,9 +2,13 @@ #include "../../client/settings/cache_settings.h" #include "../widgets/dialogs/dlg_login_prompt.h" +#include "contexts/context_connect_to_server.h" #include "libcockatrice/settings/servers_settings.h" #include +#include +#include +#include IntentGetLoginCredentials::IntentGetLoginCredentials(ContextConnectToServer *_context, bool _promptForMissingCredentials) diff --git a/cockatrice/src/interface/intents/intent_login.h b/cockatrice/src/interface/intents/intent_login.h index 8ffd91a0a..a805f1d75 100644 --- a/cockatrice/src/interface/intents/intent_login.h +++ b/cockatrice/src/interface/intents/intent_login.h @@ -1,9 +1,12 @@ #ifndef COCKATRICE_INTENT_LOGIN_H #define COCKATRICE_INTENT_LOGIN_H -#include "contexts/context_connect_to_server.h" #include "intent.h" +#include + +struct ContextConnectToServer; + class IntentGetLoginCredentials : public Intent { Q_OBJECT diff --git a/cockatrice/src/interface/intents/intent_open_local_deck.cpp b/cockatrice/src/interface/intents/intent_open_local_deck.cpp index 2457bec72..5b673d106 100644 --- a/cockatrice/src/interface/intents/intent_open_local_deck.cpp +++ b/cockatrice/src/interface/intents/intent_open_local_deck.cpp @@ -2,10 +2,14 @@ #include "../deck_loader/deck_file_format.h" #include "../deck_loader/deck_loader.h" +#include "../deck_loader/loaded_deck.h" #include "../widgets/tabs/tab_supervisor.h" #include "intent_wait_for_database_load.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_loader.h" #include +#include IntentOpenLocalDeck::IntentOpenLocalDeck(TabSupervisor *_tabSupervisor, const QString &_file) : Intent(), tabSupervisor(_tabSupervisor), file(_file) diff --git a/cockatrice/src/interface/intents/intent_open_local_deck.h b/cockatrice/src/interface/intents/intent_open_local_deck.h index 97f875e39..0338e9384 100644 --- a/cockatrice/src/interface/intents/intent_open_local_deck.h +++ b/cockatrice/src/interface/intents/intent_open_local_deck.h @@ -4,6 +4,7 @@ #include "intent.h" #include +#include class TabSupervisor; diff --git a/cockatrice/src/interface/intents/intent_open_server_room_by_name.cpp b/cockatrice/src/interface/intents/intent_open_server_room_by_name.cpp index d50f509a0..63aef004b 100644 --- a/cockatrice/src/interface/intents/intent_open_server_room_by_name.cpp +++ b/cockatrice/src/interface/intents/intent_open_server_room_by_name.cpp @@ -2,13 +2,22 @@ #include "../widgets/tabs/tab_room.h" #include "../widgets/tabs/tab_supervisor.h" +#include "contexts/context_connect_to_server.h" #include "intent_connect_to_server.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_room.pb.h" +#include "remote_client.h" +#include +#include #include #include #include #include +class CommandContainer; +class QVariant; + IntentOpenServerRoomByName::IntentOpenServerRoomByName(TabSupervisor *_tabSupervisor, RemoteClient *_remoteClient, std::unique_ptr _context, diff --git a/cockatrice/src/interface/intents/intent_open_server_room_by_name.h b/cockatrice/src/interface/intents/intent_open_server_room_by_name.h index 2f9e716af..e163796fc 100644 --- a/cockatrice/src/interface/intents/intent_open_server_room_by_name.h +++ b/cockatrice/src/interface/intents/intent_open_server_room_by_name.h @@ -1,19 +1,21 @@ #ifndef COCKATRICE_INTENT_OPEN_SERVER_ROOM_BY_NAME_H #define COCKATRICE_INTENT_OPEN_SERVER_ROOM_BY_NAME_H +#include "abstract_client.h" #include "contexts/context_join_room.h" #include "intent.h" -#include "remote_client.h" #include #include #include #include +#include -class TabRoom; class TabSupervisor; class Event_ListRooms; class ServerInfo_Room; +class RemoteClient; +class Response; /** * @brief Connects to the configured server and opens a room identified by its name. diff --git a/cockatrice/src/interface/intents/intent_open_shared_deck.cpp b/cockatrice/src/interface/intents/intent_open_shared_deck.cpp index 016de63e6..8abad3d88 100644 --- a/cockatrice/src/interface/intents/intent_open_shared_deck.cpp +++ b/cockatrice/src/interface/intents/intent_open_shared_deck.cpp @@ -3,11 +3,17 @@ #include "../deck_loader/deck_loader.h" #include "../widgets/dialogs/dlg_shared_decks_preview.h" #include "../widgets/tabs/tab_supervisor.h" +#include "abstract_client.h" +#include "contexts/context_connect_to_server.h" #include "intent_connect_to_server.h" +#include "remote_client.h" +#include #include +#include #include -#include +#include +#include #include #include #include @@ -15,6 +21,11 @@ #include #include #include +#include +#include +#include + +class CommandContainer; IntentOpenSharedDeck::IntentOpenSharedDeck(TabSupervisor *_tabSupervisor, RemoteClient *_remoteClient, diff --git a/cockatrice/src/interface/intents/intent_open_shared_deck.h b/cockatrice/src/interface/intents/intent_open_shared_deck.h index 87812bdea..afce2370f 100644 --- a/cockatrice/src/interface/intents/intent_open_shared_deck.h +++ b/cockatrice/src/interface/intents/intent_open_shared_deck.h @@ -1,20 +1,24 @@ #ifndef COCKATRICE_INTENT_OPEN_SHARED_DECK_H #define COCKATRICE_INTENT_OPEN_SHARED_DECK_H +#include "../deck_loader/loaded_deck.h" #include "contexts/context_open_deck.h" #include "intent.h" -#include "remote_client.h" #include #include #include +#include #include +#include class TabSupervisor; -struct LoadedDeck; class CardDatabaseQuerier; class DlgSharedDecksPreview; class QTimer; +class CommandContainer; +class RemoteClient; +class Response; class IntentOpenSharedDeck : public Intent { diff --git a/cockatrice/src/interface/intents/intent_wait_for_database_load.cpp b/cockatrice/src/interface/intents/intent_wait_for_database_load.cpp index c36378818..7a7da90a4 100644 --- a/cockatrice/src/interface/intents/intent_wait_for_database_load.cpp +++ b/cockatrice/src/interface/intents/intent_wait_for_database_load.cpp @@ -1,5 +1,8 @@ #include "intent_wait_for_database_load.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_loader.h" + #include bool IntentWaitForDatabaseLoad::checkPrecondition() const diff --git a/cockatrice/src/interface/intents/intent_wait_for_database_load.h b/cockatrice/src/interface/intents/intent_wait_for_database_load.h index 72f4a1ffc..715918f04 100644 --- a/cockatrice/src/interface/intents/intent_wait_for_database_load.h +++ b/cockatrice/src/interface/intents/intent_wait_for_database_load.h @@ -3,6 +3,8 @@ #include "intent.h" +#include + class IntentWaitForDatabaseLoad : public Intent { Q_OBJECT diff --git a/cockatrice/src/interface/intents/url_parser.cpp b/cockatrice/src/interface/intents/url_parser.cpp index 707863354..966fd1213 100644 --- a/cockatrice/src/interface/intents/url_parser.cpp +++ b/cockatrice/src/interface/intents/url_parser.cpp @@ -4,22 +4,34 @@ #include "../widgets/tabs/tab_room.h" #include "../widgets/tabs/tab_supervisor.h" #include "../window_main.h" +#include "contexts/context_connect_to_server.h" #include "contexts/context_join_game.h" +#include "contexts/context_join_room.h" #include "contexts/context_open_deck.h" #include "intent.h" #include "intent_join_server_game.h" #include "intent_login.h" #include "intent_open_shared_deck.h" +#include "remote_client.h" #include #include +#include #include +#include +#include +#include #include #include +#include +#include #include #include #include #include +#include +#include +#include inline Q_LOGGING_CATEGORY(UrlParserLog, "url_parser"); diff --git a/cockatrice/src/interface/intents/url_parser.h b/cockatrice/src/interface/intents/url_parser.h index ea29fed53..9b8594275 100644 --- a/cockatrice/src/interface/intents/url_parser.h +++ b/cockatrice/src/interface/intents/url_parser.h @@ -2,8 +2,11 @@ #define COCKATRICE_URL_PARSER_H #include +#include #include +#include #include +#include class Intent; class MainWindow; diff --git a/cockatrice/src/interface/key_signals.cpp b/cockatrice/src/interface/key_signals.cpp index a78997cc2..4c3074139 100644 --- a/cockatrice/src/interface/key_signals.cpp +++ b/cockatrice/src/interface/key_signals.cpp @@ -1,6 +1,9 @@ #include "key_signals.h" +#include +#include #include +#include bool KeySignals::eventFilter(QObject * /*object*/, QEvent *event) { diff --git a/cockatrice/src/interface/key_signals.h b/cockatrice/src/interface/key_signals.h index 30dcee0ba..dbe147ad8 100644 --- a/cockatrice/src/interface/key_signals.h +++ b/cockatrice/src/interface/key_signals.h @@ -8,8 +8,8 @@ #ifndef KEYSIGNALS_H #define KEYSIGNALS_H -#include #include +#include class KeySignals : public QObject { diff --git a/cockatrice/src/interface/layouts/flow_layout.cpp b/cockatrice/src/interface/layouts/flow_layout.cpp index 0d03b7789..ba5e492e3 100644 --- a/cockatrice/src/interface/layouts/flow_layout.cpp +++ b/cockatrice/src/interface/layouts/flow_layout.cpp @@ -15,13 +15,18 @@ #include "flow_layout.h" -#include "../widgets/general/layout_containers/flow_widget.h" - #include #include -#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include FlowLayout::FlowLayout(QWidget *parent, const Qt::Orientation flowDirection, diff --git a/cockatrice/src/interface/layouts/flow_layout.h b/cockatrice/src/interface/layouts/flow_layout.h index 9adcd8bb5..a6e015e3e 100644 --- a/cockatrice/src/interface/layouts/flow_layout.h +++ b/cockatrice/src/interface/layouts/flow_layout.h @@ -12,8 +12,14 @@ #include #include #include +#include #include -#include +#include +#include +#include + +class QLayoutItem; +class QWidget; inline Q_LOGGING_CATEGORY(FlowLayoutLog, "flow_layout", QtInfoMsg); diff --git a/cockatrice/src/interface/layouts/overlap_layout.cpp b/cockatrice/src/interface/layouts/overlap_layout.cpp index a4c13518a..2b4da9138 100644 --- a/cockatrice/src/interface/layouts/overlap_layout.cpp +++ b/cockatrice/src/interface/layouts/overlap_layout.cpp @@ -1,7 +1,15 @@ #include "overlap_layout.h" #include +#include +#include +#include +#include +#include +#include +#include #include +#include /** * @class OverlapLayout diff --git a/cockatrice/src/interface/layouts/overlap_layout.h b/cockatrice/src/interface/layouts/overlap_layout.h index c1b6a8e51..32c74c18a 100644 --- a/cockatrice/src/interface/layouts/overlap_layout.h +++ b/cockatrice/src/interface/layouts/overlap_layout.h @@ -10,7 +10,11 @@ #include #include #include -#include +#include +#include + +class QLayoutItem; +class QWidget; inline Q_LOGGING_CATEGORY(OverlapLayoutLog, "overlap_layout"); diff --git a/cockatrice/src/interface/logger.cpp b/cockatrice/src/interface/logger.cpp index 3e00a0b24..87fdcbd8c 100644 --- a/cockatrice/src/interface/logger.cpp +++ b/cockatrice/src/interface/logger.cpp @@ -5,9 +5,16 @@ #include #include #include +#include +#include #include +#include +#include +#include #include #include +#include +#include #define LOGGER_MAX_ENTRIES 128 #define LOGGER_FILENAME "qdebug.txt" diff --git a/cockatrice/src/interface/logger.h b/cockatrice/src/interface/logger.h index fc6dd70be..2287da804 100644 --- a/cockatrice/src/interface/logger.h +++ b/cockatrice/src/interface/logger.h @@ -8,10 +8,15 @@ #define LOGGER_H #include +#include #include +#include #include #include -#include +#include +#include +#include +#include #if defined(Q_PROCESSOR_X86_32) #define BUILD_ARCHITECTURE "32-bit" diff --git a/cockatrice/src/interface/palette_editor/color_button.cpp b/cockatrice/src/interface/palette_editor/color_button.cpp index e1a490d20..a7db23d31 100644 --- a/cockatrice/src/interface/palette_editor/color_button.cpp +++ b/cockatrice/src/interface/palette_editor/color_button.cpp @@ -1,7 +1,19 @@ #include "color_button.h" +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include + +class QWidget; ColorButton::ColorButton(QWidget *parent) : QToolButton(parent) { diff --git a/cockatrice/src/interface/palette_editor/color_button.h b/cockatrice/src/interface/palette_editor/color_button.h index 4b139ef68..f9991ec6b 100644 --- a/cockatrice/src/interface/palette_editor/color_button.h +++ b/cockatrice/src/interface/palette_editor/color_button.h @@ -3,6 +3,9 @@ #include #include +#include + +class QWidget; class ColorButton : public QToolButton { diff --git a/cockatrice/src/interface/palette_editor/palette_editor_dialog.cpp b/cockatrice/src/interface/palette_editor/palette_editor_dialog.cpp index d5a168708..20e16614a 100644 --- a/cockatrice/src/interface/palette_editor/palette_editor_dialog.cpp +++ b/cockatrice/src/interface/palette_editor/palette_editor_dialog.cpp @@ -1,5 +1,6 @@ #include "palette_editor_dialog.h" +#include "../theme_config.h" #include "../theme_manager.h" #include "palette_generator.h" #include "palette_grid_widget.h" @@ -9,12 +10,22 @@ #include #include #include +#include #include #include +#include #include +#include #include +#include #include +#include +#include #include +#include +#include +#include +#include PaletteEditorDialog::PaletteEditorDialog(const QString &_themeDirPath, const QString &_themeName, QWidget *parent) : QDialog(parent), themeDirPath(_themeDirPath), themeName(_themeName) diff --git a/cockatrice/src/interface/palette_editor/palette_editor_dialog.h b/cockatrice/src/interface/palette_editor/palette_editor_dialog.h index 953902c06..e29a70cb0 100644 --- a/cockatrice/src/interface/palette_editor/palette_editor_dialog.h +++ b/cockatrice/src/interface/palette_editor/palette_editor_dialog.h @@ -3,18 +3,21 @@ #include "../theme_config.h" +#include #include -#include #include +#include +#include class QTimer; - class QLabel; class QComboBox; class QDialogButtonBox; class QPushButton; class PaletteGridWidget; class QuickSetupPanel; +class QFrame; +class QWidget; class PaletteEditorDialog : public QDialog { diff --git a/cockatrice/src/interface/palette_editor/palette_generator.cpp b/cockatrice/src/interface/palette_editor/palette_generator.cpp index 822e57250..c98dcbe03 100644 --- a/cockatrice/src/interface/palette_editor/palette_generator.cpp +++ b/cockatrice/src/interface/palette_editor/palette_generator.cpp @@ -1,6 +1,13 @@ #include "palette_generator.h" +#include "../theme_config.h" + #include +#include +#include +#include +#include +#include // ════════════════════════════════════════════════════════════════════════════ // PaletteGenerator::fromAccent diff --git a/cockatrice/src/interface/palette_editor/palette_grid_widget.cpp b/cockatrice/src/interface/palette_editor/palette_grid_widget.cpp index 97d28b731..de069bc80 100644 --- a/cockatrice/src/interface/palette_editor/palette_grid_widget.cpp +++ b/cockatrice/src/interface/palette_editor/palette_grid_widget.cpp @@ -1,14 +1,25 @@ #include "palette_grid_widget.h" +#include "../theme_config.h" #include "../theme_manager.h" +#include "color_button.h" #include +#include +#include +#include +#include #include #include #include #include +#include +#include #include #include +#include +#include +#include static QList allRoles() { diff --git a/cockatrice/src/interface/palette_editor/palette_grid_widget.h b/cockatrice/src/interface/palette_editor/palette_grid_widget.h index 77cbf1c62..f1ff41ec2 100644 --- a/cockatrice/src/interface/palette_editor/palette_grid_widget.h +++ b/cockatrice/src/interface/palette_editor/palette_grid_widget.h @@ -2,15 +2,19 @@ #define COCKATRICE_PALETTE_GRID_WIDGET_H #include "../theme_config.h" -#include "color_button.h" +#include #include #include -#include +#include #include +#include class QLabel; class QScrollArea; +class ColorButton; +class QVBoxLayout; + // Scrollable grid of ColorButtons — one per (ColorGroup × ColorRole) cell. // Owns the load/read round-trip for PaletteConfig but has no file I/O itself. class PaletteGridWidget : public QWidget diff --git a/cockatrice/src/interface/palette_editor/quick_setup_panel.cpp b/cockatrice/src/interface/palette_editor/quick_setup_panel.cpp index 85098bde5..04f98dcc3 100644 --- a/cockatrice/src/interface/palette_editor/quick_setup_panel.cpp +++ b/cockatrice/src/interface/palette_editor/quick_setup_panel.cpp @@ -1,9 +1,15 @@ #include "quick_setup_panel.h" +#include "color_button.h" + #include +#include #include #include +#include #include +#include +#include QuickSetupPanel::QuickSetupPanel(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/palette_editor/quick_setup_panel.h b/cockatrice/src/interface/palette_editor/quick_setup_panel.h index c83e27cf2..ea402086f 100644 --- a/cockatrice/src/interface/palette_editor/quick_setup_panel.h +++ b/cockatrice/src/interface/palette_editor/quick_setup_panel.h @@ -1,13 +1,14 @@ #ifndef COCKATRICE_QUICK_SETUP_PANEL_H #define COCKATRICE_QUICK_SETUP_PANEL_H -#include "color_button.h" - +#include #include +#include class QHBoxLayout; class QLabel; class QSlider; +class ColorButton; /** * @class QuickSetupPanel diff --git a/cockatrice/src/interface/pixel_map_generator.cpp b/cockatrice/src/interface/pixel_map_generator.cpp index b70dc576f..2f5c4b6dd 100644 --- a/cockatrice/src/interface/pixel_map_generator.cpp +++ b/cockatrice/src/interface/pixel_map_generator.cpp @@ -1,15 +1,37 @@ #include "pixel_map_generator.h" +#include "libcockatrice/network/server/remote/user_level.h" #include "theme_manager.h" #include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include +#include #include +#include +#include +#include #include #include +#include +#include +#include +#include +#include #include +#include +#include #include +#include #define DEFAULT_COLOR_UNREGISTERED "#32c8ec"; #define DEFAULT_COLOR_REGISTERED "#5ed900"; diff --git a/cockatrice/src/interface/pixel_map_generator.h b/cockatrice/src/interface/pixel_map_generator.h index b6e822fd9..7c01bb332 100644 --- a/cockatrice/src/interface/pixel_map_generator.h +++ b/cockatrice/src/interface/pixel_map_generator.h @@ -7,14 +7,20 @@ #ifndef PIXMAPGENERATOR_H #define PIXMAPGENERATOR_H +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" + #include #include #include #include #include +#include +#include #include #include +class QSize; + inline Q_LOGGING_CATEGORY(PixelMapGeneratorLog, "pixel_map_generator"); class PhasePixmapGenerator diff --git a/cockatrice/src/interface/theme_config.cpp b/cockatrice/src/interface/theme_config.cpp index 8293a82cf..652e322c8 100644 --- a/cockatrice/src/interface/theme_config.cpp +++ b/cockatrice/src/interface/theme_config.cpp @@ -1,9 +1,17 @@ #include "theme_config.h" +#include +#include #include #include +#include +#include +#include #include +#include #include +#include +#include bool ThemeConfig::isEmpty() const { diff --git a/cockatrice/src/interface/theme_config.h b/cockatrice/src/interface/theme_config.h index 567aeccda..8b91613f5 100644 --- a/cockatrice/src/interface/theme_config.h +++ b/cockatrice/src/interface/theme_config.h @@ -3,9 +3,10 @@ #include #include -#include #include +#include #include +#include // Application-specific color roles, layered on top of the fixed QPalette role // set. Stored in the same palette-.toml under an [AppColors] section diff --git a/cockatrice/src/interface/theme_manager.cpp b/cockatrice/src/interface/theme_manager.cpp index 08374c8fd..9a96b3e45 100644 --- a/cockatrice/src/interface/theme_manager.cpp +++ b/cockatrice/src/interface/theme_manager.cpp @@ -2,25 +2,40 @@ #include "../../client/settings/cache_settings.h" #include "pixel_map_generator.h" +#include "theme_config.h" #include +#include #include #include +#include #include #include -#include +#include +#include +#include +#include +#include #include +#include #include #include +#include #include -#include +#include #include +#include +#include #include #include #include +#include #include #include +#include #include +#include +#include #define SYSTEM_THEME_NAME "System" #define LEGACY_SYSTEM_THEME_NAME "Default" @@ -96,12 +111,17 @@ struct PaletteColorInfo static QString usableDefaultStyle(const QString &style) { - // The Windows 11 native style is broken: dragging cards across zones can + // Only the OS/default ("System") style is sanitized: the Windows 11 and + // Windows Vista native styles are broken (dragging cards across zones can // shrink the board to a tiny grey window that is unfixable without - // rejoining. It is never usable, so guard against it no matter how it was - // requested (OS default or an explicit "windows11" theme choice) and fall - // back to the Vista style. - return style.compare("windows11", Qt::CaseInsensitive) == 0 ? QStringLiteral("windowsvista") : style; + // rejoining), so a "System" choice falls through to the built-in "windows" + // style (QWindowsStyle) instead. They remain selectable by hand, where the + // settings page warns about them. + if (style.compare("windows11", Qt::CaseInsensitive) == 0 || + style.compare("windowsvista", Qt::CaseInsensitive) == 0) { + return QStringLiteral("windows"); + } + return style; } ThemeManager::ThemeManager(QObject *parent) : QObject(parent) @@ -481,14 +501,13 @@ void ThemeManager::applyStyleAndPalette(const QString &themeName, if (themeName == FUSION_THEME_NAME) { styleName = "Fusion"; } else { + // "System" resolves through the guard, which steers the broken + // Windows native styles to "windows". An explicitly chosen style + // name is honored as-is. styleName = usableDefaultStyle(defaultStyleName); } } - // The Windows 11 style is broken even when selected explicitly in a theme, - // so sanitize the resolved name here rather than trusting the theme config. - styleName = usableDefaultStyle(styleName); - QStyle *style = QStyleFactory::create(styleName); if (!style) { style = QStyleFactory::create(usableDefaultStyle(defaultStyleName)); diff --git a/cockatrice/src/interface/theme_manager.h b/cockatrice/src/interface/theme_manager.h index 4c9d070dc..c1ab65685 100644 --- a/cockatrice/src/interface/theme_manager.h +++ b/cockatrice/src/interface/theme_manager.h @@ -10,21 +10,21 @@ #include "theme_config.h" #include -#include +#include #include #include #include -#include +#include #include +#include #include +#include inline Q_LOGGING_CATEGORY(ThemeManagerLog, "theme_manager"); typedef QMap QStringMap; typedef QMap QBrushMap; -class QApplication; - class ThemeManager : public QObject { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.cpp b/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.cpp index 2199faf30..ef7fb0e0e 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.cpp @@ -1,15 +1,24 @@ #include "color_identity_widget.h" #include "../../../../client/settings/cache_settings.h" +#include "libcockatrice/card/card_info.h" #include "mana_symbol_widget.h" +#include #include -#include +#include +#include +#include #include +#include +#include #include +#include #include +#include #include #include +#include ColorIdentityWidget::ColorIdentityWidget(QWidget *parent, const QString &_colorIdentity) : QWidget(parent), colorIdentity(_colorIdentity) diff --git a/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.h b/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.h index 315ac07d6..3caf1a964 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.h +++ b/cockatrice/src/interface/widgets/cards/additional_info/color_identity_widget.h @@ -7,9 +7,13 @@ #ifndef COLOR_IDENTITY_WIDGET_H #define COLOR_IDENTITY_WIDGET_H -#include +#include +#include #include #include +#include + +class QHBoxLayout; class ColorIdentityWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/cards/additional_info/deck_color_identity.cpp b/cockatrice/src/interface/widgets/cards/additional_info/deck_color_identity.cpp index 62b01511e..13c185a79 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/deck_color_identity.cpp +++ b/cockatrice/src/interface/widgets/cards/additional_info/deck_color_identity.cpp @@ -1,6 +1,11 @@ #include "deck_color_identity.h" +#include "libcockatrice/card/card_info.h" + +#include +#include #include +#include #include #include #include diff --git a/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.cpp b/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.cpp index fcbb69c2e..7da97f88c 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.cpp @@ -1,12 +1,16 @@ #include "mana_cost_widget.h" +#include "libcockatrice/card/card_info.h" #include "mana_symbol_widget.h" #include -#include +#include +#include +#include +#include #include #include -#include +#include ManaCostWidget::ManaCostWidget(QWidget *parent, CardInfoPtr _card) : QWidget(parent), card(_card) { diff --git a/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h b/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h index 8bd2e9bc0..a181f1148 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h +++ b/cockatrice/src/interface/widgets/cards/additional_info/mana_cost_widget.h @@ -7,9 +7,13 @@ #ifndef MANA_COST_WIDGET_H #define MANA_COST_WIDGET_H -#include +#include +#include #include #include +#include + +class QHBoxLayout; class ManaCostWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.cpp b/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.cpp index 18011909f..80dc11852 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.cpp @@ -3,8 +3,16 @@ #include "../../../../client/settings/cache_settings.h" #include "../../../pixel_map_generator.h" +#include +#include #include +#include +#include +#include #include +#include + +class QWidget; ManaSymbolWidget::ManaSymbolWidget(QWidget *parent, QString _symbol, bool _isActive, bool _mayBeToggled) : QLabel(parent), symbol(std::move(_symbol)), isActive(_isActive), mayBeToggled(_mayBeToggled) diff --git a/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.h b/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.h index 705873dff..8dad15785 100644 --- a/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.h +++ b/cockatrice/src/interface/widgets/cards/additional_info/mana_symbol_widget.h @@ -7,8 +7,13 @@ #ifndef MANA_SYMBOL_WIDGET_H #define MANA_SYMBOL_WIDGET_H -#include +#include #include +#include +#include + +class QGraphicsOpacityEffect; +class QWidget; class ManaSymbolWidget : public QLabel { diff --git a/cockatrice/src/interface/widgets/cards/art_crop_attribution.cpp b/cockatrice/src/interface/widgets/cards/art_crop_attribution.cpp index 8ab18ddd9..c4b347047 100644 --- a/cockatrice/src/interface/widgets/cards/art_crop_attribution.cpp +++ b/cockatrice/src/interface/widgets/cards/art_crop_attribution.cpp @@ -1,8 +1,17 @@ #include "art_crop_attribution.h" +#include "libcockatrice/card/printing/printing_info.h" + +#include +#include #include #include #include +#include +#include +#include +#include +#include #include QString buildArtAttribution(const ExactCard &card) diff --git a/cockatrice/src/interface/widgets/cards/art_crop_attribution.h b/cockatrice/src/interface/widgets/cards/art_crop_attribution.h index 0b3fb3d56..b4acbef26 100644 --- a/cockatrice/src/interface/widgets/cards/art_crop_attribution.h +++ b/cockatrice/src/interface/widgets/cards/art_crop_attribution.h @@ -1,7 +1,8 @@ #ifndef COCKATRICE_ART_CROP_ATTRIBUTION_H #define COCKATRICE_ART_CROP_ATTRIBUTION_H -#include +#include +#include class ExactCard; class QPainter; diff --git a/cockatrice/src/interface/widgets/cards/card_art_utils.cpp b/cockatrice/src/interface/widgets/cards/card_art_utils.cpp index b26b73593..ebf79282e 100644 --- a/cockatrice/src/interface/widgets/cards/card_art_utils.cpp +++ b/cockatrice/src/interface/widgets/cards/card_art_utils.cpp @@ -1,7 +1,10 @@ #include "card_art_utils.h" +#include "libcockatrice/card/card_info.h" + #include #include +#include namespace CardArtUtils { diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp index 8df3700c3..b15ac5d23 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp @@ -1,13 +1,33 @@ #include "card_group_display_widget.h" #include "../../../../client/settings/cache_settings.h" +#include "../../general/display/banner_widget.h" +#include "../card_info_picture_widget.h" #include "../card_info_picture_with_text_overlay_widget.h" +#include "../card_size_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h index e5f7c7ee2..f4a555766 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/card_group_display_widget.h @@ -7,15 +7,24 @@ #ifndef CARD_GROUP_DISPLAY_WIDGET_H #define CARD_GROUP_DISPLAY_WIDGET_H -#include "../../general/display/banner_widget.h" -#include "../card_info_picture_with_text_overlay_widget.h" -#include "../card_size_widget.h" - -#include -#include +#include +#include +#include +#include +#include +#include #include +#include #include -#include +#include + +class BannerWidget; +class CardSizeWidget; +class DeckListModel; +class ExactCard; +class QItemSelection; +class QItemSelectionModel; +class QModelIndex; class CardGroupDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp index a192d13d8..3256e0ca8 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp @@ -1,10 +1,20 @@ #include "flat_card_group_display_widget.h" -#include -#include +#include "../../general/display/banner_widget.h" +#include "../../general/layout_containers/flow_widget.h" + +#include +#include +#include +#include +#include #include +#include #include +class CardSizeWidget; +class QItemSelectionModel; + FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, QItemSelectionModel *_selectionModel, diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h index 0772c1ab4..d13dcddb5 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.h @@ -10,6 +10,16 @@ #include "../../general/layout_containers/flow_widget.h" #include "card_group_display_widget.h" +#include +#include +#include +#include + +class CardSizeWidget; +class DeckListModel; +class QItemSelectionModel; +class QWidget; + class FlatCardGroupDisplayWidget : public CardGroupDisplayWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp index dca8ee2a5..6e923cdbe 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp @@ -1,8 +1,20 @@ #include "overlapped_card_group_display_widget.h" +#include "../../general/display/banner_widget.h" +#include "../../general/layout_containers/overlap_widget.h" +#include "../card_size_widget.h" + +#include +#include +#include #include -#include +#include +#include +#include #include +#include + +class QItemSelectionModel; OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, diff --git a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h index 5b4b80d6b..76be3069f 100644 --- a/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.h @@ -10,6 +10,16 @@ #include "../../general/layout_containers/overlap_widget.h" #include "card_group_display_widget.h" +#include +#include +#include +#include + +class CardSizeWidget; +class DeckListModel; +class QItemSelectionModel; +class QWidget; + class OverlappedCardGroupDisplayWidget : public CardGroupDisplayWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp index 577dafe0a..7ec2ee38e 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_display_widget.cpp @@ -1,14 +1,25 @@ #include "card_info_display_widget.h" -#include "../../../game_graphics/board/card_item.h" +#include "../../../game_graphics/board/abstract_card_item.h" +#include "../../../game_graphics/card_dimensions.h" #include "card_info_picture_widget.h" #include "card_info_text_widget.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/utility/card_ref.h" -#include +#include +#include +#include #include +#include +#include #include #include +class QWidget; + CardInfoDisplayWidget::CardInfoDisplayWidget(const CardRef &cardRef, QWidget *parent, Qt::WindowFlags flags) : QFrame(parent, flags), aspectRatio(CardDimensions::HEIGHT_F / CardDimensions::WIDTH_F) { diff --git a/cockatrice/src/interface/widgets/cards/card_info_display_widget.h b/cockatrice/src/interface/widgets/cards/card_info_display_widget.h index f8f33f3d4..65965a63e 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_display_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_info_display_widget.h @@ -7,15 +7,17 @@ #ifndef CARDINFOWIDGET_H #define CARDINFOWIDGET_H -#include #include -#include +#include #include -#include +#include +#include class CardInfoPictureWidget; class CardInfoTextWidget; class AbstractCardItem; +class QWidget; +struct CardRef; class CardInfoDisplayWidget : public QFrame { diff --git a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp index fcccf445a..0f66eb209 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.cpp @@ -1,16 +1,27 @@ #include "card_info_frame_widget.h" #include "../../../client/settings/cache_settings.h" -#include "../../../game_graphics/board/card_item.h" -#include "card_info_display_widget.h" +#include "../../../game_graphics/board/abstract_card_item.h" #include "card_info_picture_widget.h" #include "card_info_text_widget.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include +#include +#include #include #include +#include +#include #include #include #include +#include +#include + +struct CardRef; CardInfoFrameWidget::CardInfoFrameWidget(QWidget *parent) : QTabWidget(parent), viewTransformationButton(nullptr), cardTextOnly(false) diff --git a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.h b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.h index e766fac7a..1f8143785 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_frame_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_info_frame_widget.h @@ -7,16 +7,19 @@ #ifndef CARDFRAME_H #define CARDFRAME_H -#include +#include #include #include -#include +#include class AbstractCardItem; class CardInfoPictureWidget; class CardInfoTextWidget; class QVBoxLayout; class QSplitter; +class QPushButton; +class QWidget; +struct CardRef; class CardInfoFrameWidget : public QTabWidget { diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.cpp index e5b0c4872..5ec4c8a25 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.cpp @@ -1,6 +1,12 @@ #include "card_info_picture_art_crop_widget.h" #include "../../../interface/card_picture_loader/card_picture_loader.h" +#include "libcockatrice/card/printing/exact_card.h" + +#include +#include + +class QWidget; CardInfoPictureArtCropWidget::CardInfoPictureArtCropWidget(QWidget *parent) : CardInfoPictureWidget(parent, false, false) diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.h b/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.h index ce22a1a44..540b0c2fa 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_art_crop_widget.h @@ -9,6 +9,11 @@ #include "card_info_picture_widget.h" +#include +#include + +class QWidget; + class CardInfoPictureArtCropWidget : public CardInfoPictureWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.cpp index 40bef3df3..ba10d4a0f 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.cpp @@ -2,10 +2,17 @@ #include "../../../client/settings/cache_settings.h" #include "../../../interface/card_picture_loader/card_picture_loader.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" #include +#include +#include +#include #include +#include #include +#include /** * @brief Constructs a CardPictureEnlargedWidget. diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.h b/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.h index a158ac6cf..f5ead2a18 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_enlarged_widget.h @@ -8,8 +8,12 @@ #ifndef CARD_PICTURE_ENLARGED_WIDGET_H #define CARD_PICTURE_ENLARGED_WIDGET_H +#include #include #include +#include + +class QSize; class CardInfoPictureEnlargedWidget final : public QWidget { diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp index 2dd21e78a..3c1e1b77f 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_widget.cpp @@ -1,21 +1,47 @@ #include "card_info_picture_widget.h" #include "../../../client/settings/cache_settings.h" -#include "../../../game_graphics/board/card_item.h" #include "../../../interface/card_picture_loader/card_picture_loader.h" #include "../../../interface/widgets/tabs/tab_supervisor.h" #include "../../window_main.h" +#include "../tabs/abstract_tab_deck_editor.h" #include "card_art_utils.h" +#include "card_info_picture_enlarged_widget.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include +#include +#include +#include #include +#include #include +#include +#include #include #include #include -#include +#include +#include static constexpr qreal MTG_CARD_ASPECT_RATIO = 1.396; // static constexpr qreal YUGIOH_CARD_ASPECT_RATIO = 1.457; diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_widget.h b/cockatrice/src/interface/widgets/cards/card_info_picture_widget.h index 4fe84ed0b..8d2d63736 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_widget.h @@ -7,15 +7,20 @@ #ifndef CARD_INFO_PICTURE_H #define CARD_INFO_PICTURE_H -#include "card_info_picture_enlarged_widget.h" - -#include +#include +#include +#include +#include #include #include +#include + +class CardInfoPictureEnlargedWidget; +class QPropertyAnimation; +class QTimer; inline Q_LOGGING_CATEGORY(CardInfoPictureWidgetLog, "card_info_picture_widget"); -class AbstractCardItem; class QMenu; class CardInfoPictureWidget : public QWidget diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.cpp index 000a88b2f..04fe9ab69 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.cpp @@ -1,8 +1,24 @@ #include "card_info_picture_with_text_overlay_widget.h" +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include + +class QWidget; /** * @brief Constructs a CardPictureWithTextOverlay widget. diff --git a/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.h b/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.h index ba978498d..6c547dc13 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_info_picture_with_text_overlay_widget.h @@ -11,8 +11,14 @@ #include "card_info_picture_widget.h" #include -#include +#include #include +#include +#include + +class QPainter; +class QRect; +class QWidget; class CardInfoPictureWithTextOverlayWidget : public CardInfoPictureWidget { diff --git a/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp b/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp index e98c3c02a..fa6cde311 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_info_text_widget.cpp @@ -1,15 +1,26 @@ #include "card_info_text_widget.h" -#include "../../../game_graphics/board/card_item.h" +#include "../../../client/settings/cache_settings.h" #include "../../card_localization.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/settings/cards_display_settings.h" #include #include +#include #include #include +#include +#include +#include #include +#include #include #include +#include +#include CardInfoTextWidget::CardInfoTextWidget(QWidget *parent) : QFrame(parent) { diff --git a/cockatrice/src/interface/widgets/cards/card_info_text_widget.h b/cockatrice/src/interface/widgets/cards/card_info_text_widget.h index 683be5ab5..8223093fe 100644 --- a/cockatrice/src/interface/widgets/cards/card_info_text_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_info_text_widget.h @@ -10,10 +10,13 @@ #include "libcockatrice/card/printing/exact_card.h" #include -#include +#include +#include + class QLabel; class QScrollArea; class QTextEdit; +class QWidget; class CardInfoTextWidget : public QFrame { diff --git a/cockatrice/src/interface/widgets/cards/card_size_widget.cpp b/cockatrice/src/interface/widgets/cards/card_size_widget.cpp index 9cdfd4bce..ab1840591 100644 --- a/cockatrice/src/interface/widgets/cards/card_size_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/card_size_widget.cpp @@ -1,10 +1,19 @@ #include "card_size_widget.h" -#include "../printing_selector/printing_selector.h" -#include "../visual_deck_storage/visual_deck_storage_widget.h" +#include "../general/layout_containers/flow_widget.h" +#include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include /** * @class CardSizeWidget diff --git a/cockatrice/src/interface/widgets/cards/card_size_widget.h b/cockatrice/src/interface/widgets/cards/card_size_widget.h index 46883e792..7de97a5e9 100644 --- a/cockatrice/src/interface/widgets/cards/card_size_widget.h +++ b/cockatrice/src/interface/widgets/cards/card_size_widget.h @@ -9,15 +9,15 @@ #ifndef CARD_SIZE_WIDGET_H #define CARD_SIZE_WIDGET_H -#include "../general/layout_containers/flow_widget.h" - -#include -#include -#include #include #include +#include class QWheelEvent; +class FlowWidget; +class QHBoxLayout; +class QLabel; +class QSlider; class CardSizeWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.cpp b/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.cpp index a4b4eaf54..911e35285 100644 --- a/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.cpp @@ -1,14 +1,38 @@ #include "deck_card_zone_display_widget.h" #include "../../../client/settings/cache_settings.h" +#include "../general/display/banner_widget.h" +#include "../visual_deck_editor/visual_deck_editor_widget.h" +#include "card_group_display_widgets/card_group_display_widget.h" #include "card_group_display_widgets/flat_card_group_display_widget.h" #include "card_group_display_widgets/overlapped_card_group_display_widget.h" +#include "libcockatrice/card/card_info.h" #include "libcockatrice/card/database/card_database_manager.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" #include "libcockatrice/settings/cards_display_settings.h" -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include + +class CardSizeWidget; +class QMouseEvent; DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent, DeckListModel *_deckListModel, diff --git a/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.h b/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.h index f25108834..b7dc3ed3e 100644 --- a/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.h +++ b/cockatrice/src/interface/widgets/cards/deck_card_zone_display_widget.h @@ -7,16 +7,27 @@ #ifndef DECK_CARD_ZONE_DISPLAY_WIDGET_H #define DECK_CARD_ZONE_DISPLAY_WIDGET_H -#include "../general/display/banner_widget.h" -#include "../general/layout_containers/overlap_widget.h" #include "../visual_deck_editor/visual_deck_editor_widget.h" -#include "card_group_display_widgets/card_group_display_widget.h" -#include "card_info_picture_with_text_overlay_widget.h" -#include "card_size_widget.h" -#include +#include +#include +#include +#include +#include +#include #include -#include +#include + +class BannerWidget; +class CardGroupDisplayWidget; +class CardSizeWidget; +class DeckListModel; +class ExactCard; +class OverlapWidget; +class QItemSelection; +class QItemSelectionModel; +class QModelIndex; +class QVBoxLayout; class DeckCardZoneDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.cpp b/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.cpp index 147143e7f..186c55755 100644 --- a/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.cpp +++ b/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.cpp @@ -1,15 +1,15 @@ #include "deck_preview_card_picture_widget.h" #include "../../../client/settings/cache_settings.h" +#include "card_info_picture_widget.h" #include -#include -#include #include -#include -#include +#include #include +class QWidget; + /** * @brief Constructs a CardPictureWithTextOverlay widget. * @param parent The parent widget. diff --git a/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.h b/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.h index 7571bc256..9643c7364 100644 --- a/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.h +++ b/cockatrice/src/interface/widgets/cards/deck_preview_card_picture_widget.h @@ -11,9 +11,12 @@ #include "card_info_picture_with_text_overlay_widget.h" #include -#include -#include -#include +#include +#include +#include + +class QTimer; +class QWidget; class DeckPreviewCardPictureWidget final : public CardInfoPictureWithTextOverlayWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.cpp index 483fc71b0..730043d95 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.cpp @@ -1,9 +1,16 @@ #include "abstract_analytics_panel_widget.h" #include "../../pixel_map_generator.h" +#include "../general/display/banner_widget.h" #include "deck_list_statistics_analyzer.h" +#include +#include #include +#include +#include +#include +#include AbstractAnalyticsPanelWidget::AbstractAnalyticsPanelWidget(QWidget *parent, DeckListStatisticsAnalyzer *analyzer) : QWidget(parent), analyzer(analyzer) diff --git a/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.h b/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.h index 23374a9e1..c1afb78d0 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/abstract_analytics_panel_widget.h @@ -3,12 +3,16 @@ #include "../general/display/banner_widget.h" -#include #include -#include +#include #include +#include class DeckListStatisticsAnalyzer; +class QDialog; +class QHBoxLayout; +class QPushButton; +class QVBoxLayout; class AbstractAnalyticsPanelWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.cpp b/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.cpp index c83e6d982..f1ed5767c 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.cpp @@ -3,8 +3,11 @@ #include "analytics_panel_widget_factory.h" #include +#include #include +class QWidget; + AddAnalyticsPanelDialog::AddAnalyticsPanelDialog(QWidget *parent) : QDialog(parent) { setWindowTitle(tr("Add Analytics Panel")); diff --git a/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.h b/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.h index aa44734c2..f70c1d8f5 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.h +++ b/cockatrice/src/interface/widgets/deck_analytics/add_analytics_panel_dialog.h @@ -2,12 +2,15 @@ #ifndef COCKATRICE_ADD_ANALYTICS_PANEL_DIALOG_H #define COCKATRICE_ADD_ANALYTICS_PANEL_DIALOG_H -#include "analytics_panel_widget_factory.h" - #include #include -#include -#include +#include +#include +#include + +class QDialogButtonBox; +class QVBoxLayout; +class QWidget; class AddAnalyticsPanelDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.cpp b/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.cpp index e807e9d47..79dda527d 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.cpp @@ -2,6 +2,8 @@ #include "abstract_analytics_panel_widget.h" +#include + AnalyticsPanelWidgetFactory &AnalyticsPanelWidgetFactory::instance() { static AnalyticsPanelWidgetFactory f; diff --git a/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.h b/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.h index 6c5856d70..598498980 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_factory.h @@ -1,9 +1,9 @@ #ifndef COCKATRICE_DECK_ANALYTICS_WIDGET_FACTORY_H #define COCKATRICE_DECK_ANALYTICS_WIDGET_FACTORY_H +#include #include #include -#include #include #include diff --git a/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_registrar.h b/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_registrar.h index 70d6df94f..99a6daf5d 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_registrar.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analytics_panel_widget_registrar.h @@ -3,6 +3,8 @@ #include "analytics_panel_widget_factory.h" +#include + class AnalyticsPanelWidgetRegistrar { public: diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config.cpp index 51129a4b4..1c61116e3 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config.cpp @@ -1,5 +1,8 @@ #include "draw_probability_config.h" +#include +#include + QJsonObject DrawProbabilityConfig::toJson() const { QJsonObject o; diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.cpp index 71f88c0fc..28fd4c841 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.cpp @@ -5,6 +5,10 @@ #include #include #include +#include +#include + +class QWidget; DrawProbabilityConfigDialog::DrawProbabilityConfigDialog(QWidget *parent) : QDialog(parent) { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.h index 44b1f0eec..3553db75d 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_config_dialog.h @@ -3,11 +3,13 @@ #include "draw_probability_config.h" #include -#include +#include class QComboBox; class QSpinBox; class QLabel; +class QFormLayout; +class QWidget; class DrawProbabilityConfigDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.cpp index 0107294c7..90d9f58ef 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.cpp @@ -1,21 +1,40 @@ #include "draw_probability_widget.h" +#include "../../../general/display/banner_widget.h" +#include "../../../general/layout_containers/flow_widget.h" +#include "../../abstract_analytics_panel_widget.h" +#include "../../deck_list_statistics_analyzer.h" +#include "deck_list_model.h" #include "draw_probability_config_dialog.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" +#include +#include #include #include -#include -#include -#include #include +#include #include +#include #include +#include +#include +#include #include +#include +#include +#include #include -#include +#include +#include +#include #include #include #include +#include + +class QWidget; DrawProbabilityWidget::DrawProbabilityWidget(QWidget *parent, DeckListStatisticsAnalyzer *analyzer) : AbstractAnalyticsPanelWidget(parent, analyzer) diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.h index 9f7b971b1..7c7bdb50a 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.h @@ -1,16 +1,19 @@ #ifndef COCKATRICE_DRAW_PROBABILITY_WIDGET_H #define COCKATRICE_DRAW_PROBABILITY_WIDGET_H -#include "../../../../layouts/flow_layout.h" -#include "../../../general/layout_containers/flow_widget.h" #include "../../abstract_analytics_panel_widget.h" -#include "../../deck_list_statistics_analyzer.h" #include "draw_probability_config.h" -#include -#include -#include -#include +#include + +class DeckListStatisticsAnalyzer; +class FlowWidget; +class QComboBox; +class QLabel; +class QLineEdit; +class QSpinBox; +class QTableWidget; +class QWidget; class DrawProbabilityWidget : public AbstractAnalyticsPanelWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.cpp index 2f9f60752..41ebdec1e 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.cpp @@ -1,5 +1,9 @@ #include "mana_base_config.h" +#include +#include +#include + QJsonObject ManaBaseConfig::toJson() const { QJsonObject jsonObject; diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.h index d01f88b8b..5fd45af62 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config.h @@ -2,8 +2,9 @@ #ifndef COCKATRICE_MANA_BASE_CONFIG_H #define COCKATRICE_MANA_BASE_CONFIG_H -#include #include +#include +#include #include struct ManaBaseConfig diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.cpp index 83e35d57d..32b54c485 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.cpp @@ -1,6 +1,19 @@ #include "mana_base_config_dialog.h" +#include "../../deck_list_statistics_analyzer.h" + +#include +#include +#include +#include +#include +#include +#include #include +#include +#include + +class QWidget; ManaBaseConfigDialog::ManaBaseConfigDialog(DeckListStatisticsAnalyzer *analyzer, ManaBaseConfig initial, diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.h index a816f154f..b0ae77076 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_config_dialog.h @@ -2,18 +2,20 @@ #ifndef COCKATRICE_MANA_BASE_ADD_DIALOG_H #define COCKATRICE_MANA_BASE_ADD_DIALOG_H -#include "../../deck_list_statistics_analyzer.h" #include "mana_base_config.h" -#include -#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include + +class DeckListStatisticsAnalyzer; +class QComboBox; +class QDialogButtonBox; +class QLabel; +class QListWidget; +class QVBoxLayout; +class QWidget; class ManaBaseConfigDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.cpp index 0093c360b..fc7914b94 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.cpp @@ -3,12 +3,27 @@ #include "../../../general/display/charts/bars/bar_widget.h" #include "../../../general/display/charts/bars/color_bar.h" #include "../../../general/display/charts/pies/color_pie.h" +#include "../../abstract_analytics_panel_widget.h" #include "../../analytics_panel_widget_registrar.h" +#include "../../deck_list_statistics_analyzer.h" #include "mana_base_config_dialog.h" +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include namespace { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.h index 85b2a13b3..7ec5ecefe 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_base/mana_base_widget.h @@ -7,16 +7,17 @@ #ifndef MANA_BASE_WIDGET_H #define MANA_BASE_WIDGET_H -#include "../../../general/display/banner_widget.h" #include "../../abstract_analytics_panel_widget.h" -#include "../../deck_list_statistics_analyzer.h" #include "mana_base_config.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include + +class DeckListStatisticsAnalyzer; +class QHBoxLayout; +class QWidget; class ManaBaseWidget : public AbstractAnalyticsPanelWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.cpp index a0ccedc74..7e15058a4 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.cpp @@ -1,9 +1,21 @@ #include "mana_curve_category_widget.h" +#include "../../../general/display/charts/bars/bar_chart_widget.h" #include "libcockatrice/utility/color.h" #include "libcockatrice/utility/qt_utils.h" #include "mana_curve_config.h" -#include "mana_curve_total_widget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include constexpr int MIN_ROW_HEIGHT = 100; // Minimum readable height per row diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.h index c6aa6f1f0..1794d5cab 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.h @@ -1,12 +1,14 @@ #ifndef COCKATRICE_MANA_CURVE_CATEGORY_WIDGET_H #define COCKATRICE_MANA_CURVE_CATEGORY_WIDGET_H -#include "../../../general/display/charts/bars/bar_chart_widget.h" -#include "mana_curve_config.h" - -#include -#include +#include #include +#include + +class QString; +class QVBoxLayout; +struct ManaCurveConfig; +template class QHash; class ManaCurveCategoryWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.cpp index 0dfef1b66..190642ad9 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.cpp @@ -1,5 +1,9 @@ #include "mana_curve_config.h" +#include +#include +#include + QJsonObject ManaCurveConfig::toJson() const { QJsonObject jsonObject; diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.h index 55222dd98..28224db03 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config.h @@ -2,8 +2,9 @@ #ifndef COCKATRICE_MANA_CURVE_CONFIG_H #define COCKATRICE_MANA_CURVE_CONFIG_H -#include #include +#include +#include #include struct ManaCurveConfig diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.cpp index 9e9ae98a6..c5498ff3e 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.cpp @@ -1,12 +1,22 @@ #include "mana_curve_config_dialog.h" +#include "../../deck_list_statistics_analyzer.h" + +#include #include #include #include +#include #include +#include #include +#include +#include +#include #include +class QWidget; + ManaCurveConfigDialog::ManaCurveConfigDialog(DeckListStatisticsAnalyzer *analyzer, QWidget *parent) : QDialog(parent), analyzer(analyzer) { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.h index 17e6776e5..47ce1b8c2 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_config_dialog.h @@ -1,16 +1,18 @@ #ifndef COCKATRICE_MANA_CURVE_ADD_DIALOG_H #define COCKATRICE_MANA_CURVE_ADD_DIALOG_H -#include "../../deck_list_statistics_analyzer.h" #include "mana_curve_config.h" #include -#include -#include +#include class QListWidget; class QCheckBox; class QComboBox; +class DeckListStatisticsAnalyzer; +class QDialogButtonBox; +class QLabel; +class QWidget; class ManaCurveConfigDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.cpp index c04767015..f1d9ea8c7 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.cpp @@ -2,10 +2,18 @@ #include "../../../general/display/charts/bars/bar_chart_widget.h" #include "libcockatrice/utility/color.h" -#include "libcockatrice/utility/qt_utils.h" #include "mana_curve_config.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include ManaCurveTotalWidget::ManaCurveTotalWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.h index 203f75345..0eaecec96 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.h @@ -1,11 +1,15 @@ #ifndef COCKATRICE_MANA_CURVE_TOTAL_WIDGET_H #define COCKATRICE_MANA_CURVE_TOTAL_WIDGET_H -#include "../../../general/display/charts/bars/bar_chart_widget.h" -#include "mana_curve_config.h" - -#include -#include +#include +#include #include +#include + +class BarChartWidget; +class QHBoxLayout; +class QLabel; +struct ManaCurveConfig; +template class QMap; class ManaCurveTotalWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.cpp index b182bf954..6d93bde54 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.cpp @@ -1,19 +1,23 @@ #include "mana_curve_widget.h" -#include "../../../general/display/charts/bars/bar_chart_background_widget.h" -#include "../../../general/display/charts/bars/bar_chart_widget.h" -#include "../../../general/display/charts/bars/segmented_bar_widget.h" +#include "../../abstract_analytics_panel_widget.h" #include "../../analytics_panel_widget_registrar.h" #include "../../deck_list_statistics_analyzer.h" -#include "libcockatrice/utility/color.h" -#include "libcockatrice/utility/qt_utils.h" +#include "mana_curve_category_widget.h" #include "mana_curve_config_dialog.h" +#include "mana_curve_total_widget.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QWidget; namespace { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.h index d3e56d44c..14c445717 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_widget.h @@ -8,14 +8,17 @@ #define MANA_CURVE_WIDGET_H #include "../../abstract_analytics_panel_widget.h" -#include "mana_curve_category_widget.h" #include "mana_curve_config.h" -#include "mana_curve_total_widget.h" -#include +#include +#include +#include +#include -class SegmentedBarWidget; class DeckListStatisticsAnalyzer; +class ManaCurveCategoryWidget; +class ManaCurveTotalWidget; +class QWidget; class ManaCurveWidget : public AbstractAnalyticsPanelWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.cpp index ee57cb1e2..7a6f0b51a 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.cpp @@ -1,5 +1,9 @@ #include "mana_devotion_config.h" +#include +#include +#include + QJsonObject ManaDevotionConfig::toJson() const { QJsonObject jsonObject; diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.h index 08be146e5..480b2151c 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config.h @@ -1,8 +1,9 @@ #ifndef COCKATRICE_MANA_DEVOTION_CONFIG_H #define COCKATRICE_MANA_DEVOTION_CONFIG_H -#include #include +#include +#include #include struct ManaDevotionConfig diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.cpp index b01c33ba5..0d70fc24d 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.cpp @@ -1,5 +1,19 @@ #include "mana_devotion_config_dialog.h" +#include "../../deck_list_statistics_analyzer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QWidget; + ManaDevotionConfigDialog::ManaDevotionConfigDialog(DeckListStatisticsAnalyzer *analyzer, ManaDevotionConfig initial, QWidget *parent) diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.h index fd804e2af..9c37ec5ad 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_config_dialog.h @@ -2,16 +2,20 @@ #ifndef COCKATRICE_MANA_DEVOTION_ADD_DIALOG_H #define COCKATRICE_MANA_DEVOTION_ADD_DIALOG_H -#include "../../deck_list_statistics_analyzer.h" #include "mana_devotion_config.h" -#include -#include #include -#include -#include -#include -#include +#include +#include +#include + +class DeckListStatisticsAnalyzer; +class QComboBox; +class QDialogButtonBox; +class QLabel; +class QListWidget; +class QVBoxLayout; +class QWidget; class ManaDevotionConfigDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.cpp index 709577ff2..7e1f0c211 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.cpp @@ -3,12 +3,26 @@ #include "../../../general/display/charts/bars/bar_widget.h" #include "../../../general/display/charts/bars/color_bar.h" #include "../../../general/display/charts/pies/color_pie.h" +#include "../../abstract_analytics_panel_widget.h" #include "../../analytics_panel_widget_registrar.h" #include "../../deck_list_statistics_analyzer.h" #include "mana_devotion_config_dialog.h" +#include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.h index af0215305..2b0182c1e 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_devotion/mana_devotion_widget.h @@ -6,11 +6,17 @@ #ifndef MANA_DEVOTION_WIDGET_H #define MANA_DEVOTION_WIDGET_H -#include "../../../general/display/banner_widget.h" #include "../../abstract_analytics_panel_widget.h" #include "mana_devotion_config.h" -#include +#include +#include +#include +#include + +class DeckListStatisticsAnalyzer; +class QHBoxLayout; +class QWidget; class ManaDevotionWidget : public AbstractAnalyticsPanelWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.cpp index 01af9329c..ab321661e 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.cpp @@ -1,5 +1,9 @@ #include "mana_distribution_config.h" +#include +#include +#include + QJsonObject ManaDistributionConfig::toJson() const { QJsonObject o; diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.h index d1aa0f48e..012b0f4a7 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config.h @@ -1,8 +1,8 @@ #ifndef COCKATRICE_MANA_DISTRIBUTION_CONFIG_H #define COCKATRICE_MANA_DISTRIBUTION_CONFIG_H -#include #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.cpp index 325c70028..24b71bae0 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.cpp @@ -1,12 +1,19 @@ #include "mana_distribution_config_dialog.h" +#include #include #include #include #include +#include #include +#include +#include +#include #include +class QWidget; + static const QStringList kColors = {"W", "U", "B", "R", "G", "C"}; ManaDistributionConfigDialog::ManaDistributionConfigDialog(DeckListStatisticsAnalyzer *analyzer, QWidget *parent) diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.h index 57c88e29d..3d21b6bee 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_config_dialog.h @@ -4,14 +4,15 @@ #include "mana_distribution_config.h" #include -#include -#include -#include +#include class QComboBox; class QListWidget; class QCheckBox; class DeckListStatisticsAnalyzer; +class QDialogButtonBox; +class QLabel; +class QWidget; class ManaDistributionConfigDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.cpp index 8a5e14858..4faa105e6 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.cpp @@ -2,7 +2,10 @@ #include "../../../cards/additional_info/mana_symbol_widget.h" +#include +#include #include +#include ManaDistributionSingleDisplayWidget::ManaDistributionSingleDisplayWidget(const QString &colorSymbol, QWidget *parent) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.h index e33d0cec1..2fd3efb2d 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.h @@ -1,10 +1,12 @@ #ifndef COCKATRICE_MANA_DISTRIBUTION_SINGLE_DISPLAY_WIDGET_H #define COCKATRICE_MANA_DISTRIBUTION_SINGLE_DISPLAY_WIDGET_H -#include -#include -#include +#include #include +#include + +class QLabel; +class QProgressBar; class ManaDistributionSingleDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.cpp index 8eaea1426..5543c64df 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.cpp @@ -1,12 +1,21 @@ #include "mana_distribution_widget.h" +#include "../../../general/display/charts/bars/color_bar.h" +#include "../../../general/display/charts/pies/color_pie.h" +#include "../../abstract_analytics_panel_widget.h" #include "../../analytics_panel_widget_registrar.h" +#include "../../deck_list_statistics_analyzer.h" #include "mana_distribution_config_dialog.h" +#include "mana_distribution_single_display_widget.h" -#include -#include -#include +#include +#include +#include +#include +#include +#include #include +#include namespace { diff --git a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.h b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.h index 2d834f3af..6230e0201 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_widget.h @@ -1,17 +1,21 @@ #ifndef COCKATRICE_MANA_DISTRIBUTION_WIDGET_H #define COCKATRICE_MANA_DISTRIBUTION_WIDGET_H -#include "../../../general/display/charts/bars/color_bar.h" -#include "../../../general/display/charts/pies/color_pie.h" #include "../../abstract_analytics_panel_widget.h" -#include "../../deck_list_statistics_analyzer.h" #include "mana_distribution_config.h" -#include "mana_distribution_single_display_widget.h" -#include +#include #include -#include -#include +#include +#include + +class ColorBar; +class ColorPie; +class DeckListStatisticsAnalyzer; +class ManaDistributionSingleDisplayWidget; +class QHBoxLayout; +class QVBoxLayout; +class QWidget; class ManaDistributionWidget : public AbstractAnalyticsPanelWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp index 76552ea2f..9f6257930 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.cpp @@ -1,5 +1,6 @@ #include "deck_analytics_widget.h" +#include "../general/layout_containers/flow_widget.h" #include "abstract_analytics_panel_widget.h" #include "add_analytics_panel_dialog.h" #include "analytics_panel_widget_factory.h" @@ -9,13 +10,19 @@ #include "deck_list_statistics_analyzer.h" #include "resizable_panel.h" +#include +#include #include +#include #include #include +#include #include #include #include #include +#include +#include DeckAnalyticsWidget::DeckAnalyticsWidget(QWidget *parent, DeckListStatisticsAnalyzer *_statsAnalyzer) : QWidget(parent), statsAnalyzer(_statsAnalyzer) diff --git a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h index 3c73deca2..f1e071ff6 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h +++ b/cockatrice/src/interface/widgets/deck_analytics/deck_analytics_widget.h @@ -7,19 +7,22 @@ #ifndef DECK_ANALYTICS_WIDGET_H #define DECK_ANALYTICS_WIDGET_H -#include "../general/layout_containers/flow_widget.h" -#include "abstract_analytics_panel_widget.h" -#include "deck_list_statistics_analyzer.h" -#include "resizable_panel.h" - -#include #include -#include -#include +#include +#include #include #include +#include class LayoutInspector; +class AbstractAnalyticsPanelWidget; +class DeckListStatisticsAnalyzer; +class FlowWidget; +class QCheckBox; +class QPushButton; +class QScrollArea; +class QVBoxLayout; +class ResizablePanel; class DeckAnalyticsWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.cpp b/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.cpp index add13ff21..c2f70759e 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.cpp @@ -1,11 +1,19 @@ #include "deck_list_statistics_analyzer.h" #include "deck_list_model.h" -#include "deck_list_statistics_analyzer.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include #include +#include +#include +#include +#include #include -#include +#include DeckListStatisticsAnalyzer::DeckListStatisticsAnalyzer(QObject *parent, DeckListModel *_model, diff --git a/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.h b/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.h index 52ae751bf..c3643d65f 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.h +++ b/cockatrice/src/interface/widgets/deck_analytics/deck_list_statistics_analyzer.h @@ -1,10 +1,12 @@ #ifndef COCKATRICE_DECK_LIST_STATISTICS_ANALYZER_H #define COCKATRICE_DECK_LIST_STATISTICS_ANALYZER_H -#include "deck_list_model.h" - #include +#include #include +#include +#include +#include #include class DeckListModel; diff --git a/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.cpp b/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.cpp index 250fe1ad3..f46679406 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.cpp +++ b/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.cpp @@ -1,11 +1,34 @@ #include "resizable_panel.h" +#include "abstract_analytics_panel_widget.h" #include "libcockatrice/utility/qt_utils.h" +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include ResizablePanel::ResizablePanel(const QString &_typeId, AbstractAnalyticsPanelWidget *analyticsPanel, QWidget *parent) : QWidget(parent), panel(analyticsPanel), typeId(_typeId) diff --git a/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.h b/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.h index d958ec64d..809703847 100644 --- a/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.h +++ b/cockatrice/src/interface/widgets/deck_analytics/resizable_panel.h @@ -1,19 +1,15 @@ #ifndef COCKATRICE_RESIZABLE_PANEL_H #define COCKATRICE_RESIZABLE_PANEL_H -#include "abstract_analytics_panel_widget.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include +#include + +class AbstractAnalyticsPanelWidget; +class QFrame; +class QPushButton; +class QTimer; class ResizablePanel : public QWidget { diff --git a/cockatrice/src/interface/widgets/deck_editor/card_database_view.cpp b/cockatrice/src/interface/widgets/deck_editor/card_database_view.cpp index 00388a3cd..e8f6398f7 100644 --- a/cockatrice/src/interface/widgets/deck_editor/card_database_view.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/card_database_view.cpp @@ -1,17 +1,35 @@ #include "card_database_view.h" #include "../../../client/settings/cache_settings.h" +#include "../../key_signals.h" #include "card_database_display_model.h" #include "card_database_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include +#include #include +#include #include +#include #include +#include +#include #include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include + +class QWidget; static bool canBeCommander(const CardInfo &cardInfo) { diff --git a/cockatrice/src/interface/widgets/deck_editor/card_database_view.h b/cockatrice/src/interface/widgets/deck_editor/card_database_view.h index 668444199..c095c544d 100644 --- a/cockatrice/src/interface/widgets/deck_editor/card_database_view.h +++ b/cockatrice/src/interface/widgets/deck_editor/card_database_view.h @@ -3,12 +3,19 @@ #include "../../key_signals.h" +#include +#include +#include #include #include #include +#include -class CardDatabaseModel; class CardDatabaseDisplayModel; +class QModelIndex; +class QPoint; +class QWidget; +template class QList; /** * @brief The card database table. diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.cpp index 6269f0323..57ae6eadd 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.cpp @@ -2,10 +2,23 @@ #include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" #include "card_database_view.h" +#include "deck_editor_database_display_widget.h" +#include "deck_list_model.h" #include "deck_state_manager.h" #include "deck_zone_dialog.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include DeckEditorCardDatabaseDockWidget::DeckEditorCardDatabaseDockWidget(AbstractTabDeckEditor *parent) : QDockWidget(parent) { diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.h index 6af2e4432..b73843bc7 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.h @@ -1,12 +1,10 @@ #ifndef COCKATRICE_DECK_EDITOR_CARD_DATABASE_DOCK_WIDGET_H #define COCKATRICE_DECK_EDITOR_CARD_DATABASE_DOCK_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" - #include +#include class AbstractTabDeckEditor; -class CardDatabase; class DeckEditorDatabaseDisplayWidget; class FilterTree; diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp index a78a9c9c5..1b920ea1d 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp @@ -1,8 +1,14 @@ #include "deck_editor_card_info_dock_widget.h" #include "../cards/card_info_frame_widget.h" +#include "../tabs/abstract_tab_deck_editor.h" +#include #include +#include +#include + +class ExactCard; DeckEditorCardInfoDockWidget::DeckEditorCardInfoDockWidget(AbstractTabDeckEditor *parent) : QDockWidget(parent), deckEditor(parent) diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.h index 086ca2ca4..2f204306d 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.h @@ -8,12 +8,13 @@ #ifndef DECK_EDITOR_CARD_INFO_DOCK_WIDGET_H #define DECK_EDITOR_CARD_INFO_DOCK_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../cards/card_info_frame_widget.h" - #include +#include class AbstractTabDeckEditor; +class CardInfoFrameWidget; +class ExactCard; + class DeckEditorCardInfoDockWidget : public QDockWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.cpp index a83e25f5f..7ed398535 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.cpp @@ -2,19 +2,30 @@ #include "../../../client/settings/cache_settings.h" #include "../../../filters/syntax_help.h" -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../../../interface/widgets/tabs/tab_supervisor.h" +#include "../../key_signals.h" #include "../../pixel_map_generator.h" +#include "../utility/custom_line_edit.h" +#include "card_database_display_model.h" +#include "card_database_model.h" #include "card_database_view.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" -#include -#include +#include +#include +#include +#include +#include #include -#include +#include #include #include -#include #include +#include +#include + +class FilterTree; DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(QWidget *parent, CardDatabaseModel *databaseModel) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.h index 5de4d211d..e9edec125 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_database_display_widget.h @@ -8,16 +8,21 @@ #ifndef DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H #define DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../utility/custom_line_edit.h" +#include "libcockatrice/card/card_info.h" -#include +#include #include -#include -#include +#include class CardDatabaseView; -class AbstractTabDeckEditor; +class CardDatabaseDisplayModel; +class CardDatabaseModel; +class ExactCard; +class FilterTree; +class QAction; +class QHBoxLayout; +class QVBoxLayout; +class SearchLineEdit; class DeckEditorDatabaseDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp index 4b141e255..37dd57459 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.cpp @@ -2,28 +2,75 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../../key_signals.h" #include "../../pixel_map_generator.h" #include "../playmat/playmat_settings_dialog.h" -#include "../settings_page/user_interface_settings_page.h" +#include "../quick_settings/settings_button_widget.h" +#include "../tabs/abstract_tab_deck_editor.h" #include "../tabs/api/commander_spellbook/commander_bracket_widget.h" +#include "../utility/custom_line_edit.h" +#include "../visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h" +#include "deck_list_history_manager_widget.h" +#include "deck_list_model.h" #include "deck_list_style_proxy.h" #include "deck_state_manager.h" #include "deck_zone_dialog.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_loader.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" +#include +#include +#include +#include #include +#include +#include #include +#include +#include #include +#include #include +#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include #include #include +#include +#include static int findRestoreIndex(const CardRef &wanted, const QComboBox *combo) { diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h index 1e5f4e677..97ab8823e 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_deck_dock_widget.h @@ -8,27 +8,36 @@ #ifndef DECK_EDITOR_DECK_DOCK_WIDGET_H #define DECK_EDITOR_DECK_DOCK_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" #include "../../key_signals.h" -#include "../utility/custom_line_edit.h" -#include "../visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h" -#include "deck_list_history_manager_widget.h" -#include "deck_list_style_proxy.h" +#include "libcockatrice/card/printing/exact_card.h" -#include -#include #include -#include -#include -#include -#include +#include +#include #include -#include -#include +#include class CommanderBracketWidget; class DeckListModel; class AbstractTabDeckEditor; +class DeckListHistoryManagerWidget; +class DeckListStyleProxy; +class DeckPreviewDeckTagsDisplayWidget; +class DeckStateManager; +class LineEditUnfocusable; +class QAction; +class QCheckBox; +class QComboBox; +class QItemSelectionModel; +class QLabel; +class QMenu; +class QModelIndex; +class QPoint; +class QPushButton; +class QTextEdit; +class QTimer; +class SettingsButtonWidget; + class DeckEditorDeckDockWidget : public QDockWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp index c6b6e4416..0a47333fa 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.cpp @@ -4,11 +4,31 @@ #include "../../../client/settings/shortcuts_settings.h" #include "../../../filters/filter_builder.h" #include "../../../filters/filter_tree_model.h" +#include "../../key_signals.h" #include "../../pixel_map_generator.h" +#include "../tabs/abstract_tab_deck_editor.h" +#include "libcockatrice/filters/filter_card.h" +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include DeckEditorFilterDockWidget::DeckEditorFilterDockWidget(AbstractTabDeckEditor *parent) : QDockWidget(parent), deckEditor(parent) diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.h index b61fc72b5..7bb9c0045 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_filter_dock_widget.h @@ -8,13 +8,18 @@ #ifndef DECK_EDITOR_FILTER_DOCK_WIDGET_H #define DECK_EDITOR_FILTER_DOCK_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" #include "../../key_signals.h" #include +#include class FilterTreeModel; class AbstractTabDeckEditor; +class QAction; +class QPoint; +class QTreeView; +class QWidget; + class DeckEditorFilterDockWidget : public QDockWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp index 06d8d1de7..d45e951ba 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp @@ -2,10 +2,15 @@ #include "../../../client/settings/cache_settings.h" #include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" +#include "../printing_selector/printing_selector.h" +#include "deck_editor_deck_dock_widget.h" #include "printing_disabled_info_widget.h" +#include #include +#include #include +#include DeckEditorPrintingSelectorDockWidget::DeckEditorPrintingSelectorDockWidget(AbstractTabDeckEditor *parent) : QDockWidget(parent), deckEditor(parent) diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.h index 1037b55fb..e20ae932d 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.h @@ -7,13 +7,13 @@ #ifndef DECK_EDITOR_PRINTING_SELECTOR_DOCK_WIDGET_H #define DECK_EDITOR_PRINTING_SELECTOR_DOCK_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../printing_selector/printing_selector.h" - #include +#include class PrintingDisabledInfoWidget; -class TabDeckEditor; +class AbstractTabDeckEditor; +class PrintingSelector; +class QWidget; class DeckEditorPrintingSelectorDockWidget : public QDockWidget { diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.cpp index c93f12b34..209dc7273 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.cpp @@ -1,7 +1,28 @@ #include "deck_list_history_manager_widget.h" #include "../../pixel_map_generator.h" +#include "../quick_settings/settings_button_widget.h" #include "deck_state_manager.h" +#include "libcockatrice/deck_list/deck_list_history_manager.h" +#include "libcockatrice/deck_list/deck_list_memento.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class DeckListStyleProxy; DeckListHistoryManagerWidget::DeckListHistoryManagerWidget(DeckStateManager *_deckStateManager, DeckListStyleProxy *_styleProxy, diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.h b/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.h index ab53912e2..5ed44b0fd 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_history_manager_widget.h @@ -1,18 +1,20 @@ #ifndef COCKATRICE_DECK_EDITOR_DECK_LIST_HISTORY_MANAGER_WIDGET_H #define COCKATRICE_DECK_EDITOR_DECK_LIST_HISTORY_MANAGER_WIDGET_H +#include + +class DeckListStyleProxy; +class QAction; +class QHBoxLayout; +class QLabel; +class QListWidget; +class QListWidgetItem; +class QToolButton; +class SettingsButtonWidget; #ifndef COCKATRICE_DECK_UNDO_WIDGET_H #define COCKATRICE_DECK_UNDO_WIDGET_H -#include "../quick_settings/settings_button_widget.h" -#include "deck_list_style_proxy.h" - -#include -#include -#include #include -#include -#include class DeckStateManager; diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp index e41529b22..1e1aefe58 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.cpp @@ -3,7 +3,10 @@ #include #include #include +#include +#include #include +#include QVariant DeckListStyleProxy::data(const QModelIndex &index, int role) const { diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h index 52b7eea10..e4d1de4f4 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_list_style_proxy.h @@ -2,6 +2,7 @@ #define COCKATRICE_DECK_LIST_STYLE_PROXY_H #include +#include class DeckListStyleProxy : public QIdentityProxyModel { diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp index cfe989e9f..d4715c8d5 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.cpp @@ -1,11 +1,28 @@ #include "deck_state_manager.h" #include "../../../client/settings/cache_settings.h" +#include "../../deck_loader/loaded_deck.h" +#include "deck_list_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/deck_list_memento.h" +#include "libcockatrice/deck_list/deck_list_node_tree.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" +#include +#include #include #include #include #include +#include + +class QModelIndex; DeckStateManager::DeckStateManager(QObject *parent) : QObject(parent), deckList(QSharedPointer(new DeckList)), diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.h b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.h index 2c8b34a39..98876947b 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_state_manager.h @@ -2,13 +2,22 @@ #define COCKATRICE_DECK_STATE_MANAGER_H #include "../../deck_loader/loaded_deck.h" -#include "deck_list_model.h" +#include +#include #include +#include +#include #include #include +#include class DeckListHistoryManager; +class DeckListModel; +class DecklistNodeTree; +class ExactCard; +struct CardRef; +struct PlaymatInfo; /** * @brief This class centralizes the management of the state of the deck in the deck editor tab. diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp b/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp index 9a0be2570..cb9667603 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.cpp @@ -2,10 +2,14 @@ #include #include +#include +#include #include #include +#include #include #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.h b/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.h index 6f55617a8..f4c9c0f9d 100644 --- a/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.h +++ b/cockatrice/src/interface/widgets/deck_editor/deck_zone_dialog.h @@ -8,9 +8,9 @@ #define DECK_ZONE_DIALOG_H #include -#include #include #include +#include class QComboBox; class QDialogButtonBox; diff --git a/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.cpp b/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.cpp index 23670b1b3..b2c4dd303 100644 --- a/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.cpp @@ -3,10 +3,13 @@ #include "../dialogs/override_printing_warning.h" #include +#include #include #include +#include #include -#include +#include +#include PrintingDisabledInfoWidget::PrintingDisabledInfoWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.h b/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.h index 0851ccfad..c14c758ff 100644 --- a/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.h +++ b/cockatrice/src/interface/widgets/deck_editor/printing_disabled_info_widget.h @@ -1,6 +1,7 @@ #ifndef COCKATRICE_PRINTING_DISABLED_INFO_WIDGET_H #define COCKATRICE_PRINTING_DISABLED_INFO_WIDGET_H #include +#include class QPushButton; class QLabel; diff --git a/cockatrice/src/interface/widgets/deck_share/deck_share_utils.cpp b/cockatrice/src/interface/widgets/deck_share/deck_share_utils.cpp index 4343f0aab..0ebdc0647 100644 --- a/cockatrice/src/interface/widgets/deck_share/deck_share_utils.cpp +++ b/cockatrice/src/interface/widgets/deck_share/deck_share_utils.cpp @@ -3,9 +3,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include diff --git a/cockatrice/src/interface/widgets/deck_share/share_bar_widget.h b/cockatrice/src/interface/widgets/deck_share/share_bar_widget.h index ede9fb41b..f97cc6788 100644 --- a/cockatrice/src/interface/widgets/deck_share/share_bar_widget.h +++ b/cockatrice/src/interface/widgets/deck_share/share_bar_widget.h @@ -7,7 +7,9 @@ #ifndef SHARE_BAR_WIDGET_H #define SHARE_BAR_WIDGET_H +#include #include +#include class QLabel; class QLineEdit; diff --git a/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.cpp b/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.cpp index 21ec80e08..3bb829089 100644 --- a/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.cpp +++ b/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.cpp @@ -2,14 +2,20 @@ #include "../cards/additional_info/color_identity_widget.h" #include "../cards/deck_preview_card_picture_widget.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/utility/card_ref.h" #include +#include #include #include #include #include +#include +#include #include #include +#include SharedDeckPreviewWidget::SharedDeckPreviewWidget(QWidget *parent, const CardDatabaseQuerier *querier, diff --git a/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.h b/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.h index bd4c4ee5f..bff7de743 100644 --- a/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.h +++ b/cockatrice/src/interface/widgets/deck_share/shared_deck_preview_widget.h @@ -7,15 +7,15 @@ #ifndef SHARED_DECK_PREVIEW_WIDGET_H #define SHARED_DECK_PREVIEW_WIDGET_H +#include #include +#include class ColorIdentityWidget; class DeckPreviewCardPictureWidget; class QCheckBox; class QFrame; -class QKeyEvent; class QLabel; -class QResizeEvent; class CardDatabaseQuerier; /** diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_connect.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_connect.cpp index 700012d45..7a7e31a58 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_connect.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_connect.cpp @@ -2,19 +2,34 @@ #include "../../../client/settings/cache_settings.h" #include "../../pixel_map_generator.h" +#include "../server/handle_public_servers.h" +#include "../server/user/user_info_connection.h" +#include "libcockatrice/utility/macros.h" #include #include +#include #include #include #include -#include +#include +#include #include +#include #include #include #include +#include +#include +#include +#include +#include +#include #include #include +#include + +class QWidget; DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent) { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_connect.h b/cockatrice/src/interface/widgets/dialogs/dlg_connect.h index 083dad0ad..10cb5366a 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_connect.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_connect.h @@ -7,12 +7,13 @@ #ifndef DLG_CONNECT_H #define DLG_CONNECT_H -#include "../interface/widgets/server/handle_public_servers.h" -#include "../interface/widgets/server/user/user_info_connection.h" - #include #include +#include +#include #include +#include +#include class QCheckBox; class QComboBox; @@ -23,6 +24,9 @@ class QLabel; class QPushButton; class QRadioButton; class QVBoxLayout; +class HandlePublicServers; +class QWidget; +class UserConnection_Information; class DlgConnect : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.cpp index a4a31d78d..f2dd8c1e4 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.cpp @@ -1,7 +1,7 @@ #include "dlg_convert_deck_to_cod_format.h" #include "../../../client/settings/cache_settings.h" -#include "../../deck_loader/deck_loader.h" +#include "../../deck_loader/deck_file_format.h" #include #include @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.h b/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.h index 526582135..de2fb9a63 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_convert_deck_to_cod_format.h @@ -8,14 +8,17 @@ #ifndef DIALOG_CONVERT_DECK_TO_COD_FORMAT_H #define DIALOG_CONVERT_DECK_TO_COD_FORMAT_H -#include #include -#include -#include -#include +#include +#include #include +#include class QWidget; +class QCheckBox; +class QDialogButtonBox; +class QLabel; +class QVBoxLayout; class DialogConvertDeckToCodFormat : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp index 59f3e033d..104b695e6 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp @@ -2,23 +2,35 @@ #include "../../../client/settings/cache_settings.h" #include "../interface/widgets/tabs/tab_room.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/room_commands.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/utility/macros.h" -#include #include +#include #include #include #include #include #include +#include #include #include #include #include +#include +#include #include +#include #include #include #include #include +#include +#include + +class QWidget; void DlgCreateGame::sharedCtor() { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.h b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.h index 61925286d..71b09997c 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_create_game.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_create_game.h @@ -9,7 +9,9 @@ #include #include +#include #include +#include class QCheckBox; class QDialogButtonBox; @@ -22,6 +24,7 @@ class QSpinBox; class Response; class ServerInfo_Game; class TabRoom; +class QWidget; class DlgCreateGame : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.cpp index e9c73b025..9eb064beb 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.cpp @@ -2,9 +2,20 @@ #include "../../../client/settings/cache_settings.h" +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include +#include #include DlgDefaultTagsEditor::DlgDefaultTagsEditor(QWidget *parent) : QDialog(parent) diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.h b/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.h index e584d0731..081701485 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_default_tags_editor.h @@ -9,9 +9,15 @@ #define DLG_DEFAULT_TAGS_EDITOR_H #include -#include -#include -#include +#include + +class QHBoxLayout; +class QLineEdit; +class QListWidget; +class QListWidgetItem; +class QPushButton; +class QVBoxLayout; +class QWidget; class DlgDefaultTagsEditor : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp index 120e20f3e..520ece007 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp @@ -3,12 +3,22 @@ #include #include #include +#include #include +#include +#include #include #include +#include +#include #include +#include +#include #include #include +#include + +class QWidget; DlgEditAvatar::DlgEditAvatar(QWidget *parent) : QDialog(parent), image() { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.h b/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.h index 9ac774b24..4df45711c 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.h @@ -7,16 +7,18 @@ #ifndef DLG_EDITAVATAR_H #define DLG_EDITAVATAR_H -#include +#include #include -#include +#include #include +#include + +class QWidget; inline Q_LOGGING_CATEGORY(DlgEditAvatarLog, "dlg_edit_avatar"); class QLabel; class QPushButton; -class QCheckBox; class DlgEditAvatar : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.cpp index 4310c03fc..59f80c79c 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.cpp @@ -4,12 +4,17 @@ #include #include -#include #include #include +#include +#include +#include #include #include +class QVBoxLayout; +class QWidget; + DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent) { oldPasswordLabel = new QLabel(tr("Old password:")); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.h b/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.h index 85c72233d..e80ede3f3 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_password.h @@ -9,10 +9,11 @@ #include #include +#include +#include class QLabel; -class QPushButton; -class QCheckBox; +class QWidget; class DlgEditPassword : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.cpp index a56aa8e35..cbf61a394 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.cpp @@ -2,25 +2,41 @@ #include "../../pixel_map_generator.h" #include "../interface/widgets/utility/get_text_with_max.h" +#include "card_database_display_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" #include +#include #include #include #include #include #include +#include #include -#include +#include #include #include #include +#include +#include +#include #include #include +#include +#include +#include #include #include #include #include #include +#include + +class QWidget; DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nullptr) { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.h b/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.h index 202212e98..cde89d22b 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.h @@ -8,7 +8,11 @@ #define DLG_EDIT_TOKENS_H #include +#include +#include +#include #include +#include class QModelIndex; class CardDatabaseModel; @@ -17,6 +21,7 @@ class QLabel; class QComboBox; class QLineEdit; class QTreeView; +class QWidget; class DlgEditTokens : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.cpp index 85b95f335..ffe8391a0 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.cpp @@ -4,10 +4,18 @@ #include #include -#include #include +#include +#include +#include +#include +#include +#include #include +class QVBoxLayout; +class QWidget; + DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QString realName) : QDialog(parent) { emailLabel = new QLabel(tr("Email:")); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.h b/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.h index 35a8bfb46..0385c2bbe 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_edit_user.h @@ -10,10 +10,11 @@ #include #include #include +#include +#include class QLabel; -class QPushButton; -class QCheckBox; +class QWidget; class DlgEditUser : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.cpp index 7e174a228..cd3c3893e 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.cpp @@ -1,15 +1,25 @@ #include "dlg_filter_games.h" +#include "../server/games_model.h" + #include #include -#include #include #include #include +#include #include #include -#include +#include +#include +#include +#include #include +#include +#include +#include + +class QWidget; DlgFilterGames::DlgFilterGames(const QMap &_allGameTypes, const GamesProxyModel *_gamesProxyModel, diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.h b/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.h index 1cf822b89..d7c11d0f1 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_filter_games.h @@ -7,20 +7,23 @@ #ifndef DLG_FILTER_GAMES_H #define DLG_FILTER_GAMES_H -#include "../interface/widgets/server/games_model.h" +#include "../server/game_filter_configs.h" -#include -#include #include #include #include +#include +#include #include +#include class QCheckBox; class QComboBox; class QGroupBox; class QLineEdit; class QSpinBox; +class GamesProxyModel; +class QWidget; class DlgFilterGames : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.cpp index c21955373..3ee74faab 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.cpp @@ -4,12 +4,16 @@ #include #include -#include +#include #include #include +#include +#include #include #include +class QWidget; + DlgForgotPasswordChallenge::DlgForgotPasswordChallenge(QWidget *parent) : QDialog(parent) { QString lastfphost; diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.h b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.h index d32e2fc3e..f5678af17 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_challenge.h @@ -7,13 +7,13 @@ #ifndef DLG_FORGOTPASSWORDCHALLENGE_H #define DLG_FORGOTPASSWORDCHALLENGE_H -#include #include #include +#include +#include class QLabel; -class QPushButton; -class QCheckBox; +class QWidget; class DlgForgotPasswordChallenge : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.cpp index 4ee0c9c88..0cb1773b6 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.cpp @@ -4,12 +4,16 @@ #include #include -#include +#include #include #include +#include +#include #include #include +class QWidget; + DlgForgotPasswordRequest::DlgForgotPasswordRequest(QWidget *parent) : QDialog(parent) { QString lastfphost; diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.h b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.h index 2cf352e0d..ff255c748 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_request.h @@ -7,13 +7,13 @@ #ifndef DLG_FORGOTPASSWORDREQUEST_H #define DLG_FORGOTPASSWORDREQUEST_H -#include #include #include +#include +#include class QLabel; -class QPushButton; -class QCheckBox; +class QWidget; class DlgForgotPasswordRequest : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.cpp index 2800d5c0c..6c1b95b43 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.cpp @@ -4,12 +4,18 @@ #include #include -#include +#include #include #include +#include +#include +#include #include #include +class QVBoxLayout; +class QWidget; + DlgForgotPasswordReset::DlgForgotPasswordReset(QWidget *parent) : QDialog(parent) { QString lastfphost; diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.h b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.h index 8a443b906..995d67359 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_forgot_password_reset.h @@ -7,13 +7,13 @@ #ifndef DLG_FORGOTPASSWORDRESET_H #define DLG_FORGOTPASSWORDRESET_H -#include #include #include +#include +#include class QLabel; -class QPushButton; -class QCheckBox; +class QWidget; class DlgForgotPasswordReset : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.cpp index b5451bb2c..cf503856f 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.cpp @@ -6,13 +6,18 @@ #include #include -#include #include #include +#include #include +#include #include #include #include +#include +#include + +class QWidget; DlgInviteToGame::DlgInviteToGame(TabSupervisor *_tabSupervisor, const QString &_inviteUrl, diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.h b/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.h index bbb589bdb..cfcc48733 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_invite_to_game.h @@ -8,12 +8,16 @@ #define DLG_INVITE_TO_GAME_H #include +#include +#include #include +#include class QLineEdit; class QPushButton; class TabSupervisor; class UserListWidget; +class QWidget; class DlgInviteToGame : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp index 626ebed50..cbf24db87 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp @@ -3,8 +3,13 @@ #include "../../../client/settings/cache_settings.h" #include "../../deck_loader/deck_loader.h" +#include +#include #include #include + +class QWidget; + DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck")) { QString startingDir = SettingsCache::instance().recents().getLatestDeckDirPath(); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.h b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.h index 27d658902..5ba07c01d 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck.h @@ -9,6 +9,9 @@ #define DLG_LOAD_DECK_H #include +#include + +class QWidget; /** * The file dialog for "Load Deck" operations. diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp index a3242c797..2c0fd3f6f 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp @@ -9,12 +9,19 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#include #include +#include + +class QWidget; /** * Creates the main layout and connects the signals that are common to all versions of this window diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.h b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.h index dce9d712c..f3cbb7b62 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.h @@ -8,13 +8,16 @@ #ifndef DLG_LOAD_DECK_FROM_CLIPBOARD_H #define DLG_LOAD_DECK_FROM_CLIPBOARD_H -#include "../../deck_loader/loaded_deck.h" +#include "libcockatrice/deck_list/deck_list.h" -#include #include +#include +#include class QPlainTextEdit; class QPushButton; +class QCheckBox; +class QWidget; /** * Base class for dialog windows for actions that involve loading decks from text input. diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.cpp index ba00873d9..88b7e2bb3 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.cpp @@ -1,16 +1,37 @@ #include "dlg_load_deck_from_website.h" +#include "../../deck_loader/card_node_function.h" +#include "parsers/deck_link_to_api_transformer.h" +#include "parsers/interface_json_deck_parser.h" + #include +#include #include +#include #include #include #include #include +#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include #include +class QWidget; + DlgLoadDeckFromWebsite::DlgLoadDeckFromWebsite(QWidget *parent) : QDialog(parent) { nam = new QNetworkAccessManager(this); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.h b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.h index 2890148b9..3f6e759f2 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_deck_from_website.h @@ -8,15 +8,21 @@ #ifndef DLG_LOAD_DECK_FROM_WEBSITE_H #define DLG_LOAD_DECK_FROM_WEBSITE_H -#include "../client/network/parsers/deck_link_to_api_transformer.h" #include "../client/network/parsers/interface_json_deck_parser.h" +#include "libcockatrice/deck_list/deck_list.h" #include -#include -#include #include -#include -#include +#include +#include + +class QLabel; +class QLineEdit; +class QNetworkAccessManager; +class QVBoxLayout; +class QWidget; +enum class DeckProvider; +template class QSharedPointer; inline Q_LOGGING_CATEGORY(DlgLoadDeckFromWebsiteLog, "dlg_load_deck_from_website"); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.cpp index ffe08bec9..a56009fe4 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.cpp @@ -3,9 +3,13 @@ #include "../interface/widgets/server/remote/remote_decklist_tree_widget.h" #include +#include #include +#include #include +class QWidget; + DlgLoadRemoteDeck::DlgLoadRemoteDeck(AbstractClient *_client, QWidget *parent) : QDialog(parent), client(_client) { dirView = new RemoteDeckList_TreeWidget(client); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.h b/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.h index 9c81e9ae3..cfec16d90 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_load_remote_deck.h @@ -9,12 +9,13 @@ #define DLG_STARTGAME_H #include +#include class RemoteDeckList_TreeWidget; class QModelIndex; class AbstractClient; -class QPushButton; class QDialogButtonBox; +class QWidget; class DlgLoadRemoteDeck : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp index eca0ec658..858deb751 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp @@ -7,10 +7,13 @@ #include #include #include +#include #include #include #include +class QWidget; + DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent) { numberPlayersLabel = new QLabel(tr("Players:"), this); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.h b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.h index 4307581a4..0725a08db 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.h @@ -11,6 +11,9 @@ #define DLG_LOCAL_GAME_OPTIONS_H #include +#include + +class QWidget; struct LocalGameOptions { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.cpp index 86647ef26..0a18a759f 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.cpp @@ -7,6 +7,8 @@ #include #include +class QWidget; + DlgLoginPrompt::DlgLoginPrompt(const QString &serverText, QWidget *parent) : QDialog(parent) { setWindowTitle(tr("Sign in")); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.h b/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.h index e47924058..47bf3bcf4 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_login_prompt.h @@ -8,9 +8,12 @@ #define DLG_LOGIN_PROMPT_H #include +#include +#include class QCheckBox; class QLineEdit; +class QWidget; /** * @brief Small sign-in dialog used when a cockatrice:// link needs credentials diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.cpp index 556c270be..dbfe38e26 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.cpp @@ -4,21 +4,42 @@ #include "../../pixel_map_generator.h" #include "../interface/card_picture_loader/card_picture_loader.h" #include "../interface/widgets/utility/custom_line_edit.h" +#include "libcockatrice/card/database/card_database.h" +#include +#include +#include #include +#include #include +#include #include #include #include #include #include +#include #include +#include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include #include +#include #include +#include #include +#include +#include #include #include #include @@ -157,12 +178,6 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent) sortWarning->setLayout(sortWarningLayout); sortWarning->setVisible(false); - includeRebalancedCards = SettingsCache::instance().cardsDisplay().getIncludeRebalancedCards(); - QCheckBox *includeRebalancedCardsCheckBox = - new QCheckBox(tr("Include cards rebalanced for Alchemy [requires restart]")); - includeRebalancedCardsCheckBox->setChecked(includeRebalancedCards); - connect(includeRebalancedCardsCheckBox, &QAbstractButton::toggled, this, &WndSets::includeRebalancedCardsChanged); - buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, this, &WndSets::actSave); connect(buttonBox, &QDialogButtonBox::rejected, this, &WndSets::actRestore); @@ -176,9 +191,8 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent) mainLayout->addWidget(enableSomeButton, 2, 1); mainLayout->addWidget(disableSomeButton, 2, 2); mainLayout->addWidget(sortWarning, 3, 1, 1, 2); - mainLayout->addWidget(includeRebalancedCardsCheckBox, 4, 1, 1, 2); - mainLayout->addWidget(hintsGroupBox, 5, 1, 1, 2); - mainLayout->addWidget(buttonBox, 6, 1, 1, 2); + mainLayout->addWidget(hintsGroupBox, 4, 1, 1, 2); + mainLayout->addWidget(buttonBox, 5, 1, 1, 2); mainLayout->setColumnStretch(1, 1); mainLayout->setColumnStretch(2, 1); @@ -249,15 +263,9 @@ void WndSets::resetSort() sortWarning->setVisible(false); } -void WndSets::includeRebalancedCardsChanged(bool _includeRebalancedCards) -{ - includeRebalancedCards = _includeRebalancedCards; -} - void WndSets::actSave() { model->save(CardDatabaseManager::getInstance()); - SettingsCache::instance().cardsDisplay().setIncludeRebalancedCards(includeRebalancedCards); CardPictureLoader::clearPixmapCache(); const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->reloadCardDatabasesAndNotify(); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.h b/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.h index 2ed5eca0f..67b4c90b1 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.h @@ -7,12 +7,11 @@ #ifndef DLG_MANAGE_SETS_H #define DLG_MANAGE_SETS_H -#include -#include -#include #include +#include +#include +#include -class CardDatabase; class LineEditUnfocusable; class QGroupBox; class QItemSelection; @@ -20,7 +19,14 @@ class QPushButton; class QTreeView; class SetsDisplayModel; class SetsModel; -class SetsProxyModel; +class QAction; +class QDialogButtonBox; +class QGridLayout; +class QHBoxLayout; +class QLabel; +class QToolBar; +class QWidget; +template class QSet; class WndSets : public QMainWindow { @@ -46,7 +52,6 @@ private: int sortIndex; Qt::SortOrder sortOrder; bool setOrderIsSorted; - bool includeRebalancedCards; enum { NO_SETS_SELECTED, @@ -81,7 +86,6 @@ private slots: void actDisableResetButton(const QString &filterText); void actSort(int index); void actIgnoreWarning(); - void includeRebalancedCardsChanged(bool _includeRebalancedCardsChanged); }; #endif diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.cpp index 1af83bfb5..52c9eaef0 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.cpp @@ -2,7 +2,11 @@ #include "../utility/report_utils.h" #include "abstract_client.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_report.pb.h" +#include +#include #include #include #include @@ -10,16 +14,22 @@ #include #include #include -#include +#include #include +#include #include #include +#include #include #include #include #include #include #include +#include +#include + +class QWidget; namespace { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.h b/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.h index 09b1963dd..dc9f90d2d 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_my_reports.h @@ -3,8 +3,9 @@ #include #include -#include +#include #include +#include class AbstractClient; class QTableWidget; @@ -12,6 +13,8 @@ class QTextEdit; class QLineEdit; class QPushButton; class QLabel; +class QWidget; +class Response; class DlgMyReports : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_register.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_register.cpp index 6d022861c..9e32e87d1 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_register.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_register.cpp @@ -10,14 +10,23 @@ #include #include #include +#include #include +#include #include +#include #include #include +#include +#include +#include #include +#include #include #include +class QWidget; + DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent) { // ── Server picker ────────────────────────────────────────────────── diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_register.h b/cockatrice/src/interface/widgets/dialogs/dlg_register.h index ce14eb427..10ea98543 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_register.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_register.h @@ -5,12 +5,16 @@ #include #include #include +#include +#include +#include class HandlePublicServers; class QLabel; class QPushButton; class QRadioButton; class UserConnection_Information; +class QWidget; class DlgRegister : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_report_user.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_report_user.cpp index 7b855af96..b1ae479fe 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_report_user.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_report_user.cpp @@ -1,21 +1,31 @@ #include "dlg_report_user.h" #include "abstract_client.h" +#include "libcockatrice/protocol/pb/response.pb.h" #include #include +#include #include #include #include #include +#include #include +#include #include #include +#include #include #include +#include #include #include #include +#include +#include + +class QWidget; DlgReportUser::DlgReportUser(AbstractClient *_client, const QString &_reportedUser, diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_report_user.h b/cockatrice/src/interface/widgets/dialogs/dlg_report_user.h index f8d5938ce..c7fce055d 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_report_user.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_report_user.h @@ -2,7 +2,8 @@ #define COCKATRICE_DLG_REPORT_USER_H #include -#include +#include +#include class AbstractClient; class QComboBox; @@ -10,6 +11,8 @@ class QDialogButtonBox; class QLineEdit; class QTextEdit; class QLabel; +class QWidget; +class Response; class DlgReportUser : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp index 8eed083e1..55c6569f7 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp @@ -1,26 +1,59 @@ #include "dlg_select_set_for_cards.h" #include "../../deck_loader/card_node_function.h" -#include "../../deck_loader/deck_loader.h" #include "../deck_editor/deck_state_manager.h" #include "../interface/widgets/cards/card_info_picture_widget.h" #include "../interface/widgets/general/layout_containers/flow_widget.h" +#include "deck_list_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include #include -#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include #include #include #include +#include +#include #include +#include #include -#include -#include +#include +#include +#include +#include DlgSelectSetForCards::DlgSelectSetForCards(QWidget *parent, DeckStateManager *deckStateManger) : QDialog(parent), deckStateManager(deckStateManger) diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.h b/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.h index 4528552d0..89cc43662 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_select_set_for_cards.h @@ -7,19 +7,23 @@ #ifndef DLG_SELECT_SET_FOR_CARDS_H #define DLG_SELECT_SET_FOR_CARDS_H -#include "../interface/widgets/general/layout_containers/flow_widget.h" - -#include #include -#include -#include +#include #include -#include -#include -#include +#include +#include +#include +#include class DeckStateManager; class SetEntryWidget; // Forward declaration +class FlowWidget; +class QCheckBox; +class QLabel; +class QListWidget; +class QPushButton; +class QScrollArea; +class QVBoxLayout; class DlgSelectSetForCards : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp index 581920dbc..d41c948eb 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp @@ -8,6 +8,7 @@ #include "../../../client/settings/cache_settings.h" #include "../../pixel_map_generator.h" #include "../main.h" +#include "../settings_page/abstract_settings_page.h" #include "../settings_page/appearance_settings_page.h" #include "../settings_page/deck_editor_settings_page.h" #include "../settings_page/general_settings_page.h" @@ -18,33 +19,59 @@ #include "../settings_page/sound_settings_page.h" #include "../settings_page/storage_settings_page.h" #include "../settings_page/user_interface_settings_page.h" +#include "libcockatrice/card/database/card_database.h" #include "libcockatrice/card/database/card_database_loader.h" #include "libcockatrice/card/database/card_database_manager.h" +#include #include +#include +#include +#include #include +#include +#include #include +#include +#include +#include #include #include #include #include +#include #include +#include #include #include #include +#include +#include +#include +#include +#include #include #include +#include #include #include #include #include #include +#include +#include #include #include +#include #include #include +#include +#include #include #include +#include + +class QModelIndex; /** * @brief Wraps a widget in a scroll area for long settings pages diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_settings.h b/cockatrice/src/interface/widgets/dialogs/dlg_settings.h index 845c0b4d6..1f15e76d5 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_settings.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_settings.h @@ -7,9 +7,15 @@ #define DLG_SETTINGS_H #include +#include #include +#include +#include +#include class QPushButton; +class QModelIndex; +class QWidget; inline Q_LOGGING_CATEGORY(DlgSettingsLog, "dlg_settings"); @@ -17,7 +23,6 @@ class QStackedWidget; class QToolButton; class QListView; class QLineEdit; - class AbstractSettingsPage; class SettingsSearchModel; class SettingsSearchDelegate; diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.cpp index 897d32062..eec80a7e8 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.cpp @@ -9,16 +9,21 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include -#include #include #include +#include + +class QWidget; +template class QSharedPointer; DlgShareDeck::DlgShareDeck(AbstractClient *_client, const QSharedPointer &_deck, QWidget *_parent) : QDialog(_parent), client(_client), deck(_deck), shareTimeoutTimer(new QTimer(this)) diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.h b/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.h index 162fa3677..108a8c38b 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_share_deck.h @@ -9,6 +9,7 @@ #include #include +#include class AbstractClient; class CommandContainer; @@ -17,6 +18,8 @@ class QDialogButtonBox; class QLineEdit; class QTimer; class Response; +class QWidget; +template class QSharedPointer; /** * @brief Slim dialog to create a temporary share for the deck open in the editor. diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.cpp index cd7ecdcdd..8ad91dcaf 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.cpp @@ -3,14 +3,19 @@ #include "../deck_share/shared_deck_preview_widget.h" #include "../general/layout_containers/flow_widget.h" -#include +#include #include #include +#include #include #include +#include #include -#include +#include #include +#include + +class QWidget; DlgSharedDecksPreview::DlgSharedDecksPreview(QWidget *parent, const CardDatabaseQuerier *querier, diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.h b/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.h index 31820e3a0..fab7ba6bf 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_shared_decks_preview.h @@ -3,14 +3,17 @@ #include #include +#include +#include +#include class FlowWidget; -class QCloseEvent; class QLabel; class QPushButton; class ServerInfo_DeckShareItem; class SharedDeckPreviewWidget; class CardDatabaseQuerier; +class QWidget; /** * @brief Non-modal preview of the decks contained in a shared-deck link. diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.cpp index 4322beb8c..3d50480cc 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.cpp @@ -2,9 +2,17 @@ #include "../../../client/settings/cache_settings.h" +#include #include +#include +#include +#include +#include +#include #include +class QWidget; + DlgStartupCardCheck::DlgStartupCardCheck(QWidget *parent) : QDialog(parent) { setWindowTitle(tr("Card Update Check")); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.h b/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.h index d26610983..0d0fb6670 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_startup_card_check.h @@ -7,12 +7,15 @@ #ifndef DLG_STARTUP_CARD_CHECK_H #define DLG_STARTUP_CARD_CHECK_H -#include #include -#include -#include -#include -#include +#include + +class QButtonGroup; +class QDialogButtonBox; +class QLabel; +class QRadioButton; +class QVBoxLayout; +class QWidget; class DlgStartupCardCheck : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp index 3d3619bf0..511ff1c7d 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp @@ -7,9 +7,19 @@ #include #include #include +#include #include +#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include #define MIN_TIP_IMAGE_HEIGHT 200 #define MIN_TIP_IMAGE_WIDTH 200 diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.h b/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.h index e493481d0..689814115 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.h @@ -7,12 +7,15 @@ #ifndef DLG_TIPOFDAY_H #define DLG_TIPOFDAY_H -#include #include -#include -#include #include -#include +#include + +class QDialogButtonBox; +class QHBoxLayout; +class QPixmap; +class QVBoxLayout; +class QWidget; inline Q_LOGGING_CATEGORY(DlgTipOfTheDayLog, "dlg_tip_of_the_day"); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp index bac270580..76bb13248 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp @@ -4,18 +4,33 @@ #include "../client/network/update/client/client_update_checker.h" #include "../client/network/update/client/release_channel.h" #include "../interface/window_main.h" +#include "update/client/update_downloader.h" +#include +#include #include +#include +#include #include +#include #include #include #include +#include +#include #include +#include +#include +#include #include #include +#include +#include +#include #include #include -#include +#include +#include #include // Executable that, when it sits next to the downloaded update installer, is installed instead of diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_update.h b/cockatrice/src/interface/widgets/dialogs/dlg_update.h index 2cef46e70..026a54a8c 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_update.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_update.h @@ -7,17 +7,24 @@ #ifndef DLG_UPDATE_H #define DLG_UPDATE_H -#include "../client/network/update/client/update_downloader.h" +#include "../../../client/network/update/client/release_channel.h" -#include +#include #include -#include -#include +#include +#include +#include +#include + +class QDialogButtonBox; +class QLabel; +class QProgressBar; +class QPushButton; +class QWidget; +class UpdateDownloader; inline Q_LOGGING_CATEGORY(DlgUpdateLog, "dlg_update"); -class Release; - class DlgUpdate : public QDialog { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_view_log.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_view_log.cpp index 957e039c0..d55e800a1 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_view_log.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_view_log.cpp @@ -4,13 +4,18 @@ #include "../../logger.h" #include +#include #include +#include +#include #include #include #include #include #include +class QWidget; + DlgViewLog::DlgViewLog(QWidget *parent) : QDialog(parent) { logArea = new QPlainTextEdit; diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_view_log.h b/cockatrice/src/interface/widgets/dialogs/dlg_view_log.h index 5c7315b50..d63ff5ffc 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_view_log.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_view_log.h @@ -7,11 +7,14 @@ #ifndef DLG_VIEWLOG_H #define DLG_VIEWLOG_H -#include #include +#include +#include class QPlainTextEdit; -class QCloseEvent; +class QCheckBox; +class QPushButton; +class QWidget; class DlgViewLog : public QDialog { diff --git a/cockatrice/src/interface/widgets/dialogs/override_printing_warning.cpp b/cockatrice/src/interface/widgets/dialogs/override_printing_warning.cpp index 33d102f5e..57f7ff7f5 100644 --- a/cockatrice/src/interface/widgets/dialogs/override_printing_warning.cpp +++ b/cockatrice/src/interface/widgets/dialogs/override_printing_warning.cpp @@ -3,7 +3,13 @@ #include "../../card_picture_loader/card_picture_loader.h" #include "../../client/settings/cache_settings.h" +#include +#include +#include #include + +class QWidget; + bool OverridePrintingWarning::execMessageBox(QWidget *parent, bool enable) { QString message; diff --git a/cockatrice/src/interface/widgets/dialogs/override_printing_warning.h b/cockatrice/src/interface/widgets/dialogs/override_printing_warning.h index f2c926fc3..6c5891373 100644 --- a/cockatrice/src/interface/widgets/dialogs/override_printing_warning.h +++ b/cockatrice/src/interface/widgets/dialogs/override_printing_warning.h @@ -1,6 +1,7 @@ #ifndef COCKATRICE_OVERRIDE_PRINTING_WARN_H #define COCKATRICE_OVERRIDE_PRINTING_WARN_H -#include + +class QWidget; namespace OverridePrintingWarning { diff --git a/cockatrice/src/interface/widgets/dialogs/path_safety_warning.cpp b/cockatrice/src/interface/widgets/dialogs/path_safety_warning.cpp new file mode 100644 index 000000000..d8eabd72d --- /dev/null +++ b/cockatrice/src/interface/widgets/dialogs/path_safety_warning.cpp @@ -0,0 +1,34 @@ +#include "path_safety_warning.h" + +#include "../../client/settings/cache_settings.h" + +#include +#include +#include +#include +#include + +class QWidget; + +bool PathSafetyWarning::confirmOutsideProgramDir(QWidget *parent, const QString &path) +{ + if (SettingsCache::instance().getIsPortableBuild()) { + return true; + } + + if (!PathsSettings::isInsideDir(path, QCoreApplication::applicationDirPath())) { + return true; + } + + QMessageBox box(QMessageBox::Warning, QObject::tr("Path inside the program directory"), + QObject::tr("'%1' is inside the Cockatrice program directory.\n\n" + "Files stored there can be deleted by an update or by uninstalling " + "Cockatrice, so this change was not applied. Choose a location outside " + "the program directory.") + .arg(path), + QMessageBox::Ok, parent); + box.setTextFormat(Qt::PlainText); + box.exec(); + + return false; +} diff --git a/cockatrice/src/interface/widgets/dialogs/path_safety_warning.h b/cockatrice/src/interface/widgets/dialogs/path_safety_warning.h new file mode 100644 index 000000000..058df3e4b --- /dev/null +++ b/cockatrice/src/interface/widgets/dialogs/path_safety_warning.h @@ -0,0 +1,25 @@ +#ifndef COCKATRICE_PATH_SAFETY_WARNING_H +#define COCKATRICE_PATH_SAFETY_WARNING_H + +class QString; +class QWidget; + +namespace PathSafetyWarning +{ + +/** + * @brief Warns when the user tries to configure a data path inside the program directory. + * + * Shows a message box explaining that files kept there can be deleted by an + * update or by uninstalling Cockatrice. Portable builds are always exempt: + * their data lives beside the executables by design. + * + * @param parent The parent widget + * @param path The path the user is trying to configure + * @return true when the path is outside the program directory and safe to apply + */ +bool confirmOutsideProgramDir(QWidget *parent, const QString &path); + +} // namespace PathSafetyWarning + +#endif // COCKATRICE_PATH_SAFETY_WARNING_H diff --git a/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.cpp b/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.cpp index 66170792a..3463fe6df 100644 --- a/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.cpp +++ b/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.cpp @@ -2,11 +2,20 @@ #include #include -#include +#include +#include +#include +#include #include +#include #include +#include +#include +#include #include +class QObject; + #define TIPDDBMODEL_COLUMNS 3 TipOfTheDay::TipOfTheDay(QString _title, QString _content, QString _imagePath, QDate _date) diff --git a/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.h b/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.h index 9cda07e2b..4e6e23567 100644 --- a/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.h +++ b/cockatrice/src/interface/widgets/dialogs/tip_of_the_day.h @@ -9,6 +9,12 @@ #include #include +#include +#include +#include + +class QObject; +template class QList; class TipOfTheDay { diff --git a/cockatrice/src/interface/widgets/general/background_sources.h b/cockatrice/src/interface/widgets/general/background_sources.h index 423111bb6..775d55895 100644 --- a/cockatrice/src/interface/widgets/general/background_sources.h +++ b/cockatrice/src/interface/widgets/general/background_sources.h @@ -9,7 +9,10 @@ #include #include +#include #include +#include +#include class BackgroundSources { diff --git a/cockatrice/src/interface/widgets/general/display/background_plate_widget.cpp b/cockatrice/src/interface/widgets/general/display/background_plate_widget.cpp index aad259900..fd9ad67a8 100644 --- a/cockatrice/src/interface/widgets/general/display/background_plate_widget.cpp +++ b/cockatrice/src/interface/widgets/general/display/background_plate_widget.cpp @@ -1,9 +1,9 @@ #include "background_plate_widget.h" -#include #include #include -#include +#include +#include BackgroundPlateWidget::BackgroundPlateWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/general/display/background_plate_widget.h b/cockatrice/src/interface/widgets/general/display/background_plate_widget.h index 1fc1bc3ba..6634069c4 100644 --- a/cockatrice/src/interface/widgets/general/display/background_plate_widget.h +++ b/cockatrice/src/interface/widgets/general/display/background_plate_widget.h @@ -2,6 +2,7 @@ #define COCKATRICE_BACKGROUND_PLATE_WIDGET_H #include +#include class BackgroundPlateWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/display/banner_widget.cpp b/cockatrice/src/interface/widgets/general/display/banner_widget.cpp index 31f384cac..baf46bbba 100644 --- a/cockatrice/src/interface/widgets/general/display/banner_widget.cpp +++ b/cockatrice/src/interface/widgets/general/display/banner_widget.cpp @@ -2,10 +2,15 @@ #include "../../../pixel_map_generator.h" +#include +#include +#include #include -#include #include -#include +#include +#include +#include +#include BannerWidget::BannerWidget(QWidget *parent, const QString &text, Qt::Orientation orientation, int transparency_) : QWidget(parent), gradientOrientation(orientation), transparency(qBound(0, transparency_, 100)) diff --git a/cockatrice/src/interface/widgets/general/display/banner_widget.h b/cockatrice/src/interface/widgets/general/display/banner_widget.h index 77a05abb6..06556089b 100644 --- a/cockatrice/src/interface/widgets/general/display/banner_widget.h +++ b/cockatrice/src/interface/widgets/general/display/banner_widget.h @@ -10,8 +10,10 @@ #define BANNER_WIDGET_H #include -#include +#include #include +#include +#include class BannerWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.cpp b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.cpp index f7ca669f3..3ea2df6bd 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.cpp +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.cpp @@ -1,5 +1,17 @@ #include "bar_chart_background_widget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + BarChartBackgroundWidget::BarChartBackgroundWidget(QWidget *parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.h b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.h index 06a17c7c6..1fc8a3bde 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.h +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_background_widget.h @@ -1,8 +1,8 @@ #ifndef COCKATRICE_BAR_CHART_BACKGROUND_WIDGET_H #define COCKATRICE_BAR_CHART_BACKGROUND_WIDGET_H -#include #include +#include class BarChartBackgroundWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.cpp b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.cpp index 04315d0ce..484ac861d 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.cpp +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.cpp @@ -1,9 +1,20 @@ #include "bar_chart_widget.h" +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include #include +#include +#include BarChartWidget::BarChartWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.h b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.h index e80a3f8e8..a596c094a 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.h +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_chart_widget.h @@ -2,9 +2,12 @@ #define COCKATRICE_BAR_CHART_WIDGET_H #include +#include #include +#include #include #include +#include struct BarSegment { diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.cpp b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.cpp index 2194b6b03..82d15d5be 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.cpp +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.cpp @@ -2,6 +2,10 @@ #include #include +#include +#include +#include +#include BarWidget::BarWidget(QString label, int value, int total, QColor barColor, QWidget *parent) : QWidget(parent), label(std::move(label)), value(value), total(total), barColor(barColor) diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.h b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.h index 05814f15b..18da1f939 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.h +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/bar_widget.h @@ -8,7 +8,11 @@ #ifndef BAR_WIDGET_H #define BAR_WIDGET_H +#include +#include #include +#include +#include class BarWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.cpp b/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.cpp index 1087c621e..28118cc9c 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.cpp +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.cpp @@ -2,10 +2,21 @@ #include "libcockatrice/utility/color.h" +#include #include +#include #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include ColorBar::ColorBar(const QMap &_colors, QWidget *parent) : QWidget(parent), colors(GameSpecificColors::MTG::sortManaMapWUBRGCFirst(_colors)) diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.h b/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.h index 1d435cec1..3acb7f97f 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.h +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/color_bar.h @@ -2,9 +2,13 @@ #define COCKATRICE_COLOR_BAR_H #include -#include +#include +#include #include #include +#include + +template class QMap; /** * @class ColorBar diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.cpp b/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.cpp index 3726dd061..33195a518 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.cpp +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.cpp @@ -1,5 +1,13 @@ #include "percent_bar_widget.h" +#include +#include +#include +#include +#include +#include +#include + PercentBarWidget::PercentBarWidget(QWidget *parent, double initialValue) : QWidget(parent), valueToDisplay(initialValue) { setMinimumSize(50, 10); diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.h b/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.h index 9cd6039c8..f12cb8ae7 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.h +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/percent_bar_widget.h @@ -8,8 +8,9 @@ #ifndef PERCENT_BAR_WIDGET_H #define PERCENT_BAR_WIDGET_H -#include #include +#include +#include class PercentBarWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.cpp b/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.cpp index 03c69373a..5a3130964 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.cpp +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.cpp @@ -1,9 +1,19 @@ #include "segmented_bar_widget.h" +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include #include +#include +#include SegmentedBarWidget::SegmentedBarWidget(QString label, QVector segments, int total, QWidget *parent) : QWidget(parent), label(std::move(label)), segments(std::move(segments)), total(total) diff --git a/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.h b/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.h index 4df54e42e..c8c7dc2b9 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.h +++ b/cockatrice/src/interface/widgets/general/display/charts/bars/segmented_bar_widget.h @@ -2,8 +2,12 @@ #define COCKATRICE_SEGMENTED_BAR_WIDGET_H #include +#include +#include +#include #include #include +#include class SegmentedBarWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.cpp b/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.cpp index bd4641981..82542a663 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.cpp +++ b/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.cpp @@ -2,10 +2,22 @@ #include "libcockatrice/utility/color.h" +#include +#include #include #include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include +#include ColorPie::ColorPie(const QMap &_colors, QWidget *parent) : QWidget(parent), colors(GameSpecificColors::MTG::sortManaMapWUBRGCFirst(_colors)) diff --git a/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.h b/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.h index 60d8e18f2..0fe023f63 100644 --- a/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.h +++ b/cockatrice/src/interface/widgets/general/display/charts/pies/color_pie.h @@ -1,6 +1,12 @@ #ifndef COCKATRICE_COLOR_PIE_H #define COCKATRICE_COLOR_PIE_H +#include +#include +#include +#include + +class QPoint; #ifndef COLOR_PIE_H #define COLOR_PIE_H diff --git a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.cpp b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.cpp index f485e0040..0609eb16a 100644 --- a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.cpp +++ b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.cpp @@ -1,7 +1,16 @@ #include "dynamic_font_size_label.h" -#define FONT_PRECISION (0.5) -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FONT_PRECISION (0.5) DynamicFontSizeLabel::DynamicFontSizeLabel(QWidget *parent, Qt::WindowFlags f) : QLabel(parent, f) { diff --git a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.h b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.h index c9b159b02..cd029902a 100644 --- a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.h +++ b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_label.h @@ -9,6 +9,12 @@ #include #include +#include +#include +#include +#include + +class QWidget; class DynamicFontSizeLabel : public QLabel { diff --git a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.cpp b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.cpp index 653b2cd5c..25e8ca48f 100644 --- a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.cpp +++ b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.cpp @@ -2,7 +2,14 @@ #include "dynamic_font_size_label.h" +#include +#include +#include #include +#include +#include +#include +#include DynamicFontSizePushButton::DynamicFontSizePushButton(QWidget *parent) : QPushButton(parent) { diff --git a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.h b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.h index 540abfe6b..dfbb03d20 100644 --- a/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.h +++ b/cockatrice/src/interface/widgets/general/display/dynamic_font_size_push_button.h @@ -7,9 +7,12 @@ #ifndef DYNAMICFONTSIZEPUSHBUTTON_H #define DYNAMICFONTSIZEPUSHBUTTON_H -#include +#include #include -#include +#include +#include + +class QWidget; class DynamicFontSizePushButton : public QPushButton { diff --git a/cockatrice/src/interface/widgets/general/display/labeled_input.cpp b/cockatrice/src/interface/widgets/general/display/labeled_input.cpp index ee26c78d9..40ee91bcc 100644 --- a/cockatrice/src/interface/widgets/general/display/labeled_input.cpp +++ b/cockatrice/src/interface/widgets/general/display/labeled_input.cpp @@ -1,5 +1,12 @@ #include "labeled_input.h" +#include +#include +#include +#include +#include +#include + LabeledInput::LabeledInput(QWidget *parent, const QString &labelText) : QWidget(parent) { label = new QLabel(labelText, this); diff --git a/cockatrice/src/interface/widgets/general/display/labeled_input.h b/cockatrice/src/interface/widgets/general/display/labeled_input.h index 838dfb280..a07d50dbb 100644 --- a/cockatrice/src/interface/widgets/general/display/labeled_input.h +++ b/cockatrice/src/interface/widgets/general/display/labeled_input.h @@ -7,11 +7,15 @@ #ifndef LABELED_INPUT_H #define LABELED_INPUT_H -#include -#include -#include -#include +#include +#include #include +#include + +class QComboBox; +class QHBoxLayout; +class QLabel; +class QSpinBox; class LabeledInput final : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/display/shadow_background_label.cpp b/cockatrice/src/interface/widgets/general/display/shadow_background_label.cpp index 7db18c57d..e1218a6fb 100644 --- a/cockatrice/src/interface/widgets/general/display/shadow_background_label.cpp +++ b/cockatrice/src/interface/widgets/general/display/shadow_background_label.cpp @@ -1,7 +1,13 @@ #include "shadow_background_label.h" -#include +#include +#include #include +#include +#include +#include + +class QWidget; /** * @class ShadowBackgroundLabel diff --git a/cockatrice/src/interface/widgets/general/display/shadow_background_label.h b/cockatrice/src/interface/widgets/general/display/shadow_background_label.h index 69232691e..e64b9ca5b 100644 --- a/cockatrice/src/interface/widgets/general/display/shadow_background_label.h +++ b/cockatrice/src/interface/widgets/general/display/shadow_background_label.h @@ -8,6 +8,10 @@ #define STYLEDLABEL_H #include +#include +#include + +class QWidget; class ShadowBackgroundLabel : public QLabel { diff --git a/cockatrice/src/interface/widgets/general/home_styled_button.cpp b/cockatrice/src/interface/widgets/general/home_styled_button.cpp index c7bdd1e5e..7f23827bc 100644 --- a/cockatrice/src/interface/widgets/general/home_styled_button.cpp +++ b/cockatrice/src/interface/widgets/general/home_styled_button.cpp @@ -1,9 +1,19 @@ #include "home_styled_button.h" +#include +#include #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QWidget; HomeStyledButton::HomeStyledButton(const QString &text, QPair _gradientColors, QWidget *parent) : QPushButton(text, parent), gradientColors(_gradientColors) diff --git a/cockatrice/src/interface/widgets/general/home_styled_button.h b/cockatrice/src/interface/widgets/general/home_styled_button.h index f8d97e9aa..55ac5550f 100644 --- a/cockatrice/src/interface/widgets/general/home_styled_button.h +++ b/cockatrice/src/interface/widgets/general/home_styled_button.h @@ -6,7 +6,13 @@ #ifndef HOME_STYLED_BUTTON_H #define HOME_STYLED_BUTTON_H +#include +#include #include +#include +#include + +class QWidget; class HomeStyledButton : public QPushButton { diff --git a/cockatrice/src/interface/widgets/general/home_widget.cpp b/cockatrice/src/interface/widgets/general/home_widget.cpp index 648d315f9..c77fd76fd 100644 --- a/cockatrice/src/interface/widgets/general/home_widget.cpp +++ b/cockatrice/src/interface/widgets/general/home_widget.cpp @@ -2,25 +2,68 @@ #include "../../../client/settings/cache_settings.h" #include "../../../interface/widgets/tabs/tab_supervisor.h" +#include "../../deck_loader/deck_file_format.h" +#include "../../deck_loader/deck_loader.h" +#include "../../deck_loader/loaded_deck.h" #include "../../pixel_map_generator.h" +#include "../../theme_config.h" #include "../../theme_manager.h" #include "../../window_main.h" #include "../cards/art_crop_attribution.h" +#include "../cards/card_info_picture_art_crop_widget.h" +#include "abstract_client.h" #include "background_sources.h" #include "home_styled_button.h" #include "home_tab_button_color.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_loader.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/utility/card_ref.h" +#include +#include +#include +#include +#include +#include #include +#include #include #include +#include +#include +#include #include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include #include +#include +#include +#include +#include HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor) : QWidget(parent), tabSupervisor(_tabSupervisor), background(themePixmap(QStringLiteral("backgrounds/home"))) diff --git a/cockatrice/src/interface/widgets/general/home_widget.h b/cockatrice/src/interface/widgets/general/home_widget.h index 1cadc4a67..fb9566cad 100644 --- a/cockatrice/src/interface/widgets/general/home_widget.h +++ b/cockatrice/src/interface/widgets/general/home_widget.h @@ -7,16 +7,23 @@ #ifndef HOME_WIDGET_H #define HOME_WIDGET_H -#include "../../../interface/widgets/tabs/tab_supervisor.h" -#include "../cards/card_info_picture_art_crop_widget.h" -#include "home_styled_button.h" +#include "libcockatrice/deck_list/deck_list.h" -#include +#include +#include +#include #include #include +#include class QGridLayout; class QLabel; +class CardInfoPictureArtCropWidget; +class ExactCard; +class HomeStyledButton; +class QGroupBox; +class QTimer; +class TabSupervisor; class HomeWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.cpp b/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.cpp index 01c9ac34e..6a6025ec2 100644 --- a/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.cpp +++ b/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.cpp @@ -6,10 +6,17 @@ #include "flow_widget.h" +#include "../../../layouts/flow_layout.h" + +#include #include #include +#include +#include +#include #include #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.h b/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.h index 4d52db3f1..dbf33d07f 100644 --- a/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.h +++ b/cockatrice/src/interface/widgets/general/layout_containers/flow_widget.h @@ -8,13 +8,17 @@ #ifndef FLOW_WIDGET_H #define FLOW_WIDGET_H -#include "../../../layouts/flow_layout.h" - -#include -#include #include -#include #include +#include +#include +#include + +class FlowLayout; +class QHBoxLayout; +class QKeyEvent; +class QLayoutItem; +class QScrollArea; inline Q_LOGGING_CATEGORY(FlowWidgetLog, "flow_widget", QtInfoMsg); inline Q_LOGGING_CATEGORY(FlowWidgetSizeLog, "flow_widget.size", QtInfoMsg); diff --git a/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.cpp b/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.cpp index 97068978d..8cfe190e2 100644 --- a/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.cpp +++ b/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.cpp @@ -1,7 +1,11 @@ #include "overlap_control_widget.h" +#include "../display/labeled_input.h" #include "overlap_widget.h" +#include +#include + OverlapControlWidget::OverlapControlWidget(int overlapPercentage, int maxColumns, int maxRows, diff --git a/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.h b/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.h index 104a97da9..c5639110f 100644 --- a/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.h +++ b/cockatrice/src/interface/widgets/general/layout_containers/overlap_control_widget.h @@ -6,12 +6,14 @@ #ifndef OVERLAP_CONTROL_WIDGET_H #define OVERLAP_CONTROL_WIDGET_H -#include "../display/labeled_input.h" -#include "overlap_widget.h" - -#include -#include #include +#include +#include + +class LabeledInput; +class OverlapWidget; +class QHBoxLayout; +class QSlider; class OverlapControlWidget final : public QWidget { diff --git a/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.cpp b/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.cpp index 1c4ee30ab..03240211c 100644 --- a/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.cpp +++ b/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.cpp @@ -1,9 +1,9 @@ #include "overlap_widget.h" -#include "../../../layouts/flow_layout.h" +#include "../../../layouts/overlap_layout.h" +#include #include -#include /** * @class OverlapWidget diff --git a/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.h b/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.h index 62c620201..c103c5f80 100644 --- a/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.h +++ b/cockatrice/src/interface/widgets/general/layout_containers/overlap_widget.h @@ -7,9 +7,12 @@ #ifndef OVERLAP_WIDGET_H #define OVERLAP_WIDGET_H -#include "../../../layouts/overlap_layout.h" - +#include #include +#include +#include + +class OverlapLayout; class OverlapWidget final : public QWidget { diff --git a/cockatrice/src/interface/widgets/menus/deck_editor_menu.cpp b/cockatrice/src/interface/widgets/menus/deck_editor_menu.cpp index 6e27b4e42..b0503ec22 100644 --- a/cockatrice/src/interface/widgets/menus/deck_editor_menu.cpp +++ b/cockatrice/src/interface/widgets/menus/deck_editor_menu.cpp @@ -2,9 +2,14 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../deck_editor/deck_editor_filter_dock_widget.h" #include "../tabs/abstract_tab_deck_editor.h" +#include +#include +#include #include + DeckEditorMenu::DeckEditorMenu(AbstractTabDeckEditor *parent) : QMenu(parent), deckEditor(parent) { aNewDeck = new QAction(QString(), this); diff --git a/cockatrice/src/interface/widgets/menus/deck_editor_menu.h b/cockatrice/src/interface/widgets/menus/deck_editor_menu.h index 08ce7bba1..904fbb6f4 100644 --- a/cockatrice/src/interface/widgets/menus/deck_editor_menu.h +++ b/cockatrice/src/interface/widgets/menus/deck_editor_menu.h @@ -8,8 +8,11 @@ #define DECK_EDITOR_MENU_H #include +#include class AbstractTabDeckEditor; +class QAction; + class DeckEditorMenu : public QMenu { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/onboarding/first_run_wizard.cpp b/cockatrice/src/interface/widgets/onboarding/first_run_wizard.cpp index 4af02fe4f..426811ec2 100644 --- a/cockatrice/src/interface/widgets/onboarding/first_run_wizard.cpp +++ b/cockatrice/src/interface/widgets/onboarding/first_run_wizard.cpp @@ -10,7 +10,6 @@ #include "shader_banner_widget.h" #include "step_indicator_widget.h" -#include #include #include #include @@ -18,6 +17,10 @@ #include #include #include +#include +#include + +class QWidget; FirstRunWizard::FirstRunWizard(QWidget *parent) : QDialog(parent) { @@ -182,10 +185,10 @@ void FirstRunWizard::onCardDatabaseUpdateFinished(bool success) } } -void FirstRunWizard::onCardDatabaseUpdateProgress(const QString &stage, qint64 done, qint64 total) +void FirstRunWizard::onCardDatabaseUpdateProgress(const CardUpdateProgress &progress) { if (cardDatabasePage) { - cardDatabasePage->onUpdateProgress(stage, done, total); + cardDatabasePage->onUpdateProgress(progress); } } diff --git a/cockatrice/src/interface/widgets/onboarding/first_run_wizard.h b/cockatrice/src/interface/widgets/onboarding/first_run_wizard.h index 21d7b6e06..812985a9f 100644 --- a/cockatrice/src/interface/widgets/onboarding/first_run_wizard.h +++ b/cockatrice/src/interface/widgets/onboarding/first_run_wizard.h @@ -1,8 +1,13 @@ #ifndef FIRST_RUN_WIZARD_H #define FIRST_RUN_WIZARD_H +#include "../../card_database_update/card_update_progress.h" + #include #include +#include +#include +#include class BannerHost; class FirstRunWizardPage; @@ -11,6 +16,7 @@ class CardDatabaseSetupPage; class QLabel; class QPushButton; class QStackedWidget; +class QWidget; /** @brief Polished first-run onboarding flow: card database setup, theme * selection, server account setup, and a handful of key preferences. @@ -38,7 +44,7 @@ public slots: void onCardDatabaseUpdateFinished(bool success); /** @brief Forwarded from MainWindow while the background card database update process runs. */ - void onCardDatabaseUpdateProgress(const QString &stage, qint64 done, qint64 total); + void onCardDatabaseUpdateProgress(const CardUpdateProgress &progress); protected: void closeEvent(QCloseEvent *event) override; diff --git a/cockatrice/src/interface/widgets/onboarding/first_run_wizard_page.h b/cockatrice/src/interface/widgets/onboarding/first_run_wizard_page.h index bdcd123bd..e7b818810 100644 --- a/cockatrice/src/interface/widgets/onboarding/first_run_wizard_page.h +++ b/cockatrice/src/interface/widgets/onboarding/first_run_wizard_page.h @@ -1,7 +1,9 @@ #ifndef FIRST_RUN_WIZARD_PAGE_H #define FIRST_RUN_WIZARD_PAGE_H +#include #include +#include /** @brief Base class for a single step of FirstRunWizard. * diff --git a/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.cpp b/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.cpp index 2107ea8bf..16a1d2254 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.cpp +++ b/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.cpp @@ -1,8 +1,14 @@ #include "account_setup_page.h" +#include "../first_run_wizard_page.h" + #include #include +#include #include +#include + +class QWidget; AccountSetupPage::AccountSetupPage(QWidget *parent) : FirstRunWizardPage(parent) { diff --git a/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.h b/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.h index 0d9b76699..344b4e41a 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.h +++ b/cockatrice/src/interface/widgets/onboarding/pages/account_setup_page.h @@ -3,8 +3,11 @@ #include "../first_run_wizard_page.h" +#include + class QLabel; class QPushButton; +class QWidget; /** @brief First-run account step. Does NOT embed DlgRegister's fields: they exist * to be handed to ConnectionController's network registration flow, which diff --git a/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.cpp b/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.cpp index 50e8ff63d..cb53a25f3 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.cpp +++ b/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.cpp @@ -1,23 +1,31 @@ #include "card_database_setup_page.h" #include "../../client/settings/cache_settings.h" +#include "../first_run_wizard_page.h" +#include "libcockatrice/card/database/card_database.h" #include #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include +#include +#include +#include #include #include #include +#include CardDatabaseSetupPage::CardDatabaseSetupPage(QWidget *parent) : FirstRunWizardPage(parent) { @@ -180,21 +188,29 @@ void CardDatabaseSetupPage::onUpdateFinished(bool success) } } -void CardDatabaseSetupPage::onUpdateProgress(const QString &stage, qint64 done, qint64 total) +void CardDatabaseSetupPage::onUpdateProgress(const CardUpdateProgress &progress) { if (state != State::Running) { return; } + const qint64 total = progress.total; + const qint64 done = progress.done; progressBar->setRange(0, total > 0 ? static_cast(qMin(total, INT_MAX)) : 0); progressBar->setValue(static_cast(qMin(done, INT_MAX))); if (total > 0) { const int percent = static_cast((100.0 * done) / total); - if (stage == QLatin1String("download")) { - statusLabel->setText(tr("Downloading the card database (%1%)…").arg(percent)); - } else if (stage == QLatin1String("scan")) { - statusLabel->setText(tr("Parsing the card database (%1%)…").arg(percent)); - } else if (stage == QLatin1String("import")) { - statusLabel->setText(tr("Importing cards (%1%)…").arg(percent)); + switch (progress.stage) { + case CardUpdateStage::Download: + statusLabel->setText(tr("Downloading the card database (%1%)…").arg(percent)); + break; + case CardUpdateStage::Scan: + statusLabel->setText(tr("Parsing the card database (%1%)…").arg(percent)); + break; + case CardUpdateStage::Import: + statusLabel->setText(tr("Importing cards (%1%)…").arg(percent)); + break; + case CardUpdateStage::Unknown: + break; } } } diff --git a/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.h b/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.h index 870e759ea..a84223497 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.h +++ b/cockatrice/src/interface/widgets/onboarding/pages/card_database_setup_page.h @@ -1,9 +1,13 @@ #ifndef CARD_DATABASE_SETUP_PAGE_H #define CARD_DATABASE_SETUP_PAGE_H +#include "../../../card_database_update/card_update_progress.h" #include "../first_run_wizard_page.h" #include +#include +#include +#include class QComboBox; class QLabel; @@ -30,7 +34,7 @@ public: void retranslateUi() override; void onUpdateFinished(bool success); - void onUpdateProgress(const QString &stage, qint64 done, qint64 total); + void onUpdateProgress(const CardUpdateProgress &progress); signals: void updateRequested(); diff --git a/cockatrice/src/interface/widgets/onboarding/pages/finish_page.cpp b/cockatrice/src/interface/widgets/onboarding/pages/finish_page.cpp index 4205fa532..1adf35282 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/finish_page.cpp +++ b/cockatrice/src/interface/widgets/onboarding/pages/finish_page.cpp @@ -1,7 +1,13 @@ #include "finish_page.h" +#include "../first_run_wizard_page.h" + #include +#include #include +#include + +class QWidget; FinishPage::FinishPage(QWidget *parent) : FirstRunWizardPage(parent) { diff --git a/cockatrice/src/interface/widgets/onboarding/pages/finish_page.h b/cockatrice/src/interface/widgets/onboarding/pages/finish_page.h index 40ebc6ed0..b78e40ec5 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/finish_page.h +++ b/cockatrice/src/interface/widgets/onboarding/pages/finish_page.h @@ -3,7 +3,10 @@ #include "../first_run_wizard_page.h" +#include + class QLabel; +class QWidget; class FinishPage : public FirstRunWizardPage { diff --git a/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.cpp b/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.cpp index fceb34deb..da08e3a12 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.cpp +++ b/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.cpp @@ -2,6 +2,7 @@ #include "../../client/settings/cache_settings.h" #include "../../client/sound_engine.h" +#include "../first_run_wizard_page.h" #include "libcockatrice/settings/interface_settings.h" #include "libcockatrice/settings/sound_settings.h" #include "libcockatrice/settings/tabs_settings.h" @@ -9,10 +10,16 @@ #include #include #include +#include #include #include +#include #include +#include #include +#include +#include +#include namespace { diff --git a/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.h b/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.h index eed1b3aed..18d6c0e8f 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.h +++ b/cockatrice/src/interface/widgets/onboarding/pages/preferences_setup_page.h @@ -3,10 +3,13 @@ #include "../first_run_wizard_page.h" +#include + class QCheckBox; class QComboBox; class QGroupBox; class QLabel; +class QWidget; /** @brief A curated subset of settings for the user to adjust. **/ diff --git a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp index 797fe4425..66554d85c 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp +++ b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.cpp @@ -1,10 +1,12 @@ #include "theme_setup_page.h" +#include "../../../theme_config.h" #include "../../client/settings/cache_settings.h" #include "../../interface/palette_editor/palette_generator.h" #include "../../interface/palette_editor/quick_setup_panel.h" #include "../../interface/theme_manager.h" #include "../../interface/widgets/general/background_sources.h" +#include "../first_run_wizard_page.h" #include "libcockatrice/settings/appearance_settings.h" #include @@ -12,12 +14,21 @@ #include #include #include -#include +#include +#include +#include #include +#include #include +#include +#include #include +#include +#include +#include #include -#include + +class QWidget; namespace { diff --git a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h index 16a3c9a5d..b0d717043 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h +++ b/cockatrice/src/interface/widgets/onboarding/pages/theme_setup_page.h @@ -3,9 +3,14 @@ #include "../first_run_wizard_page.h" +#include +#include +#include + class QComboBox; class QGroupBox; class QuickSetupPanel; +class QWidget; /** @brief First-run theme step. Reuses the same building blocks as Appearance * settings and the Palette Editor (ThemeManager, PaletteConfig, diff --git a/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.cpp b/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.cpp index 16e0719d2..71d2fa409 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.cpp +++ b/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.cpp @@ -3,15 +3,23 @@ #include "../../../../main.h" #include "../../client/settings/cache_settings.h" #include "../../settings_page/general_settings_page.h" +#include "../first_run_wizard_page.h" #include "libcockatrice/settings/personal_settings.h" #include +#include #include #include #include +#include #include -#include +#include #include +#include +#include +#include + +class QWidget; WelcomePage::WelcomePage(QWidget *parent) : FirstRunWizardPage(parent) { diff --git a/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.h b/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.h index 93b24d83d..289034ab1 100644 --- a/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.h +++ b/cockatrice/src/interface/widgets/onboarding/pages/welcome_page.h @@ -3,8 +3,11 @@ #include "../first_run_wizard_page.h" +#include + class QComboBox; class QLabel; +class QWidget; class WelcomePage : public FirstRunWizardPage { diff --git a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp index 0b9f65783..c17399957 100644 --- a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp +++ b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.cpp @@ -1,16 +1,27 @@ #include "shader_banner_widget.h" +#include "../../theme_config.h" #include "../../theme_manager.h" #include "banner_shader_config.h" #include "brand_colors.h" #include +#include +#include +#include #include +#include #include #include #include -#include +#include #include +#include +#include +#include +#include +#include +#include namespace { diff --git a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h index ac47b1141..6fa0c703f 100644 --- a/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h +++ b/cockatrice/src/interface/widgets/onboarding/shader_banner_widget.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include class BannerShaderConfig; class QQuickWidget; diff --git a/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.cpp b/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.cpp index d25e8544b..004bdcc11 100644 --- a/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.cpp +++ b/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.cpp @@ -1,7 +1,13 @@ #include "step_indicator_widget.h" +#include +#include #include #include +#include +#include +#include +#include StepIndicatorWidget::StepIndicatorWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.h b/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.h index 1b85be04f..d2b5dfcb5 100644 --- a/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.h +++ b/cockatrice/src/interface/widgets/onboarding/step_indicator_widget.h @@ -2,6 +2,7 @@ #define STEP_INDICATOR_WIDGET_H #include +#include /** @brief Row of dots showing progress through a fixed-length sequence of steps, * in the style of a mobile/OS setup flow. Purely presentational. */ diff --git a/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.cpp b/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.cpp index e970f8413..f77aefb33 100644 --- a/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.cpp +++ b/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.cpp @@ -1,6 +1,9 @@ #include "playmat_collection_dialog.h" #include "../../../client/settings/cache_settings.h" +#include "libcockatrice/interfaces/interface_interface_settings_provider.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" #include "playmat_settings_dialog.h" #include @@ -8,10 +11,15 @@ #include #include #include +#include #include +#include #include +#include #include +class QWidget; + PlaymatCollectionDialog::PlaymatCollectionDialog(QWidget *parent) : QDialog(parent) { setMinimumWidth(420); diff --git a/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.h b/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.h index 167893f8e..a04cfdf54 100644 --- a/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.h +++ b/cockatrice/src/interface/widgets/playmat/playmat_collection_dialog.h @@ -2,13 +2,15 @@ #define COCKATRICE_PLAYMAT_COLLECTION_DIALOG_H #include +#include #include +#include class QComboBox; class QLabel; class QListWidget; -class QListWidgetItem; class QPushButton; +class QWidget; /** * @brief Dialog for editing the user-level playmat collection. diff --git a/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.cpp b/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.cpp index 130daadf4..881866292 100644 --- a/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.cpp +++ b/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.cpp @@ -3,13 +3,22 @@ #include "../cards/art_crop_attribution.h" #include "playmat_utils.h" +#include +#include +#include #include #include #include #include -#include +#include +#include +#include +#include +#include #include +#include #include +#include namespace { diff --git a/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.h b/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.h index 88b9ec41d..5e54e96eb 100644 --- a/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.h +++ b/cockatrice/src/interface/widgets/playmat/playmat_preview_widget.h @@ -1,10 +1,15 @@ #ifndef COCKATRICE_PLAYMAT_PREVIEW_WIDGET_H #define COCKATRICE_PLAYMAT_PREVIEW_WIDGET_H -#include +#include "libcockatrice/utility/playmat_params.h" + #include +#include +#include +#include #include -#include +#include +#include /** * @brief Interactive crop surface showing how a playmat card art will appear diff --git a/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.cpp b/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.cpp index 9459c5ea9..5a4457d34 100644 --- a/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.cpp +++ b/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.cpp @@ -6,6 +6,11 @@ #include "../utility/completer_utils.h" #include "card_database_display_model.h" #include "card_database_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" #include "playmat_preview_widget.h" #include @@ -15,14 +20,18 @@ #include #include #include -#include #include #include -#include -#include +#include #include +#include +#include +#include #include +#include #include +#include +#include PlaymatSettingsDialog::PlaymatSettingsDialog(const CardRef &initialCard, const PlaymatParams &initialParams, diff --git a/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.h b/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.h index 9ef306a5f..07833af25 100644 --- a/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.h +++ b/cockatrice/src/interface/widgets/playmat/playmat_settings_dialog.h @@ -1,9 +1,14 @@ #ifndef COCKATRICE_PLAYMAT_SETTINGS_DIALOG_H #define COCKATRICE_PLAYMAT_SETTINGS_DIALOG_H +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" + #include +#include #include -#include +#include +#include class QCheckBox; class QComboBox; diff --git a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp index 579106540..bad88ddbb 100644 --- a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.cpp @@ -1,8 +1,21 @@ #include "all_zones_card_amount_widget.h" #include "../general/display/shadow_background_label.h" +#include "card_amount_widget.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include +#include +#include +#include #include +#include +#include +#include + +class DeckStateManager; /** * @brief Constructor for the AllZonesCardAmountWidget class. diff --git a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h index 325dd1c1b..cefabe293 100644 --- a/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/all_zones_card_amount_widget.h @@ -7,11 +7,15 @@ #ifndef ALL_ZONES_CARD_AMOUNT_WIDGET_H #define ALL_ZONES_CARD_AMOUNT_WIDGET_H -#include "../../deck_loader/deck_loader.h" -#include "card_amount_widget.h" - #include -#include +#include + +class CardAmountWidget; +class DeckStateManager; +class ExactCard; +class QLabel; +class QSlider; +class QVBoxLayout; class AllZonesCardAmountWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp index ff47e7b9c..4b5040741 100644 --- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.cpp @@ -1,9 +1,30 @@ #include "card_amount_widget.h" #include "../deck_editor/deck_state_manager.h" +#include "../general/display/dynamic_font_size_push_button.h" +#include "deck_list_model.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QModelIndex; /** * @brief Constructs a widget for displaying and controlling the card count in a specific zone. diff --git a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h index 2780e3ad2..6f5889fc7 100644 --- a/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/card_amount_widget.h @@ -8,15 +8,17 @@ #ifndef CARD_AMOUNT_WIDGET_H #define CARD_AMOUNT_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../general/display/dynamic_font_size_push_button.h" +#include "libcockatrice/card/printing/exact_card.h" -#include -#include -#include +#include #include -#include -#include +#include + +class DeckStateManager; +class DynamicFontSizePushButton; +class QHBoxLayout; +class QLabel; +class QSlider; class CardAmountWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp index f16b4885c..27ae61b94 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp @@ -1,19 +1,38 @@ #include "printing_selector.h" #include "../../../client/settings/cache_settings.h" -#include "../../../interface/card_picture_loader/card_picture_loader.h" -#include "../../../interface/widgets/dialogs/dlg_select_set_for_cards.h" +#include "../cards/card_size_widget.h" #include "../deck_editor/deck_state_manager.h" +#include "../general/layout_containers/flow_widget.h" +#include "../quick_settings/settings_button_widget.h" +#include "../tabs/abstract_tab_deck_editor.h" +#include "deck_list_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" #include "printing_selector_card_display_widget.h" #include "printing_selector_card_search_widget.h" #include "printing_selector_card_selection_widget.h" #include "printing_selector_card_sorting_widget.h" #include "printing_selector_placeholder_widget.h" -#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include #include +#include /** * @brief Constructs a PrintingSelector widget to display and manage card printings. diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h index 14d73f836..b9cb27ecd 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h @@ -7,18 +7,20 @@ #ifndef PRINTING_SELECTOR_H #define PRINTING_SELECTOR_H -#include "../cards/card_size_widget.h" -#include "../general/layout_containers/flow_widget.h" -#include "../quick_settings/settings_button_widget.h" -#include "printing_selector_placeholder_widget.h" - -#include -#include -#include -#include #include #include -#include +#include + +class CardSizeWidget; +class FlowWidget; +class PrintingSelectorPlaceholderWidget; +class QCheckBox; +class QHBoxLayout; +class QString; +class QTimer; +class QVBoxLayout; +class SettingsButtonWidget; +template class QMap; #define BATCH_SIZE 10 @@ -33,8 +35,8 @@ class DeckStateManager; class PrintingSelectorCardSearchWidget; class PrintingSelectorCardSelectionWidget; class PrintingSelectorCardSortingWidget; -class PrintingSelectorViewOptionsWidget; class AbstractTabDeckEditor; + class PrintingSelector : public QWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp index edeba86d1..1c3cb635d 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp @@ -1,11 +1,22 @@ #include "printing_selector_card_display_widget.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "printing_selector.h" #include "printing_selector_card_overlay_widget.h" #include "set_name_and_collectors_number_display_widget.h" -#include +#include +#include +#include +#include #include -#include +#include + +class AbstractTabDeckEditor; +class DeckStateManager; +class QSlider; /** * @brief Constructs a PrintingSelectorCardDisplayWidget to display card information. diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h index 4de561f4f..f0a378fd3 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_display_widget.h @@ -7,12 +7,25 @@ #ifndef PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H #define PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "printing_selector_card_overlay_widget.h" -#include "set_name_and_collectors_number_display_widget.h" +#include "libcockatrice/card/printing/exact_card.h" + +// IWYU pragma: keep +// ZoneCounts appears inside a QMap in a slot signature, so the moc-generated +// code needs the complete type. +#include "printing_selector.h" #include -#include +#include + +class AbstractTabDeckEditor; +class DeckStateManager; +class PrintingSelectorCardOverlayWidget; +class QSlider; +class QString; +class QVBoxLayout; +class SetNameAndCollectorsNumberDisplayWidget; +struct ZoneCounts; +template class QMap; class PrintingSelectorCardDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp index e8816847e..bec9100a6 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp @@ -3,23 +3,46 @@ #include "../../../client/settings/cache_settings.h" #include "../../card_picture_loader/card_picture_loader.h" #include "../cards/card_info_picture_widget.h" -#include "printing_selector_card_display_widget.h" +#include "../tabs/abstract_tab_deck_editor.h" +#include "all_zones_card_amount_widget.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include #include +#include #include +#include +#include #include #include +#include #include #include #include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include #include -#include +#include + +class DeckStateManager; namespace { diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h index fbcfa9230..20d8f7b4b 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.h @@ -7,14 +7,20 @@ #ifndef PRINTING_SELECTOR_CARD_OVERLAY_WIDGET_H #define PRINTING_SELECTOR_CARD_OVERLAY_WIDGET_H -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "all_zones_card_amount_widget.h" -#include "set_name_and_collectors_number_display_widget.h" +#include "libcockatrice/card/printing/exact_card.h" -#include +#include +#include class QAction; class QMenu; +class AbstractTabDeckEditor; +class AllZonesCardAmountWidget; +class CardInfoPictureWidget; +class DeckStateManager; +class QLabel; +class QPoint; +class QSlider; class PrintingSelectorCardOverlayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.cpp index 3c42f06dc..718e24ea0 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.cpp @@ -1,5 +1,11 @@ #include "printing_selector_card_search_widget.h" +#include "printing_selector.h" + +#include +#include +#include + /** * @brief Constructs a PrintingSelectorCardSearchWidget for searching cards by set name or set code. * diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.h index 3efabe13c..d54cf5fbc 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_search_widget.h @@ -7,11 +7,14 @@ #ifndef PRINTING_SELECTOR_CARD_SEARCH_WIDGET_H #define PRINTING_SELECTOR_CARD_SEARCH_WIDGET_H -#include "printing_selector.h" - -#include -#include +#include #include +#include + +class PrintingSelector; +class QHBoxLayout; +class QLineEdit; +class QTimer; class PrintingSelectorCardSearchWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.cpp index 2eb2ef245..da66591b3 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.cpp @@ -1,7 +1,12 @@ #include "printing_selector_card_selection_widget.h" #include "../../../interface/widgets/dialogs/dlg_select_set_for_cards.h" -#include "../tabs/abstract_tab_deck_editor.h" +#include "printing_selector.h" + +#include +#include + +class DeckStateManager; /** * @brief Constructs a PrintingSelectorCardSelectionWidget for navigating through cards in the deck. diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.h index 0aa56c9d8..c619c5327 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_selection_widget.h @@ -7,11 +7,13 @@ #ifndef PRINTING_SELECTOR_CARD_SELECTION_WIDGET_H #define PRINTING_SELECTOR_CARD_SELECTION_WIDGET_H -#include "printing_selector.h" - -#include -#include #include +#include + +class DeckStateManager; +class PrintingSelector; +class QHBoxLayout; +class QPushButton; class PrintingSelectorCardSelectionWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.cpp index f4a05cfc7..f47ba0746 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.cpp @@ -1,11 +1,26 @@ #include "printing_selector_card_sorting_widget.h" #include "../../../client/settings/cache_settings.h" +#include "deck_list_model.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include "printing_selector.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include const QString PrintingSelectorCardSortingWidget::SORT_OPTIONS_ALPHABETICAL = tr("Alphabetical"); const QString PrintingSelectorCardSortingWidget::SORT_OPTIONS_PREFERENCE = tr("Preference"); diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.h index bb5b60cdc..1cd99457b 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.h @@ -7,11 +7,20 @@ #ifndef PRINTING_SELECTOR_CARD_SORTING_WIDGET_H #define PRINTING_SELECTOR_CARD_SORTING_WIDGET_H -#include "printing_selector.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/printing_info.h" -#include -#include +#include +#include +#include #include +#include + +class DeckListModel; +class PrintingSelector; +class QComboBox; +class QHBoxLayout; +class QPushButton; class PrintingSelectorCardSortingWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp index aee34bccd..7f9ad66c8 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp @@ -1,5 +1,10 @@ #include "printing_selector_placeholder_widget.h" +#include +#include +#include +#include + PrintingSelectorPlaceholderWidget::PrintingSelectorPlaceholderWidget(QWidget *parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h index abf030c69..6702d325a 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h @@ -1,9 +1,11 @@ #ifndef COCKATRICE_PRINTING_SELECTOR_PLACEHOLDER_WIDGET_H #define COCKATRICE_PRINTING_SELECTOR_PLACEHOLDER_WIDGET_H -#include -#include #include +#include + +class QLabel; +class QVBoxLayout; class PrintingSelectorPlaceholderWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp index e12775a04..9bc92ad90 100644 --- a/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp @@ -1,6 +1,11 @@ #include "set_name_and_collectors_number_display_widget.h" -#include +#include +#include +#include +#include +#include +#include /** * @class SetNameAndCollectorsNumberDisplayWidget diff --git a/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.h b/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.h index 140f190df..54e580b67 100644 --- a/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.h +++ b/cockatrice/src/interface/widgets/printing_selector/set_name_and_collectors_number_display_widget.h @@ -8,10 +8,12 @@ #ifndef SET_NAME_AND_COLLECTORS_NUMBER_DISPLAY_WIDGET_H #define SET_NAME_AND_COLLECTORS_NUMBER_DISPLAY_WIDGET_H -#include -#include -#include +#include #include +#include + +class QLabel; +class QVBoxLayout; class SetNameAndCollectorsNumberDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.cpp b/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.cpp index 881c3e3ac..981ed843c 100644 --- a/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.cpp +++ b/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.cpp @@ -1,11 +1,21 @@ #include "settings_button_widget.h" #include "../../pixel_map_generator.h" +#include "settings_popup_widget.h" #include #include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include SettingsButtonWidget::SettingsButtonWidget(QWidget *parent) : QWidget(parent), button(new QToolButton(this)), popup(new SettingsPopupWidget(nullptr)) diff --git a/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.h b/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.h index 1dc52ac72..015300bf8 100644 --- a/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.h +++ b/cockatrice/src/interface/widgets/quick_settings/settings_button_widget.h @@ -8,10 +8,14 @@ #ifndef SETTINGS_BUTTON_WIDGET_H #define SETTINGS_BUTTON_WIDGET_H -#include "settings_popup_widget.h" - -#include +#include #include +#include + +class QHBoxLayout; +class QPixmap; +class QToolButton; +class SettingsPopupWidget; class SettingsButtonWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.cpp b/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.cpp index 8389caea9..7ace155a7 100644 --- a/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.cpp +++ b/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.cpp @@ -1,10 +1,14 @@ #include "settings_popup_widget.h" #include -#include +#include #include +#include #include #include +#include +#include +#include SettingsPopupWidget::SettingsPopupWidget(QWidget *parent) : QWidget(parent, Qt::Popup | Qt::FramelessWindowHint) { diff --git a/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.h b/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.h index 01e86abfe..61b2cb013 100644 --- a/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.h +++ b/cockatrice/src/interface/widgets/quick_settings/settings_popup_widget.h @@ -8,10 +8,11 @@ #ifndef SETTINGS_POPUP_WIDGET_H #define SETTINGS_POPUP_WIDGET_H -#include -#include -#include #include +#include + +class QScrollArea; +class QVBoxLayout; class SettingsPopupWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/replay/replay_manager.cpp b/cockatrice/src/interface/widgets/replay/replay_manager.cpp index c51b96b6c..f3f1da2c4 100644 --- a/cockatrice/src/interface/widgets/replay/replay_manager.cpp +++ b/cockatrice/src/interface/widgets/replay/replay_manager.cpp @@ -1,10 +1,16 @@ #include "replay_manager.h" #include "../../../client/settings/cache_settings.h" +#include "../../../game/player/event_processing_options.h" +#include "libcockatrice/protocol/pb/game_event.pb.h" +#include "libcockatrice/protocol/pb/game_event_container.pb.h" +#include "libcockatrice/protocol/pb/game_replay.pb.h" #include +#include #include #include +#include static constexpr int TIMER_INTERVAL_MS = 200; static constexpr int EMPTY_SECTION_MARGIN_MS = 500; diff --git a/cockatrice/src/interface/widgets/replay/replay_manager.h b/cockatrice/src/interface/widgets/replay/replay_manager.h index 81e66824d..3b33deada 100644 --- a/cockatrice/src/interface/widgets/replay/replay_manager.h +++ b/cockatrice/src/interface/widgets/replay/replay_manager.h @@ -3,11 +3,14 @@ #include "../../../game/player/event_processing_options.h" +#include #include -#include +#include +#include class GameReplay; class QTimer; +class GameEventContainer; /** * @brief This class handles all logic to do with playing back replays diff --git a/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.cpp b/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.cpp index 5d58705d2..5b3829af2 100644 --- a/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.cpp +++ b/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.cpp @@ -1,10 +1,14 @@ #include "replay_quick_settings_widget.h" #include "../../../client/settings/cache_settings.h" +#include "../quick_settings/settings_button_widget.h" +#include "libcockatrice/utility/macros.h" +#include #include #include #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.h b/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.h index a337ea0a6..d0be7d58d 100644 --- a/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.h +++ b/cockatrice/src/interface/widgets/replay/replay_quick_settings_widget.h @@ -5,7 +5,12 @@ #include #include +#include +#include #include +#include + +class QWidget; class ReplayQuickSettingsWidget : public SettingsButtonWidget { diff --git a/cockatrice/src/interface/widgets/replay/replay_timeline_widget.cpp b/cockatrice/src/interface/widgets/replay/replay_timeline_widget.cpp index fe4ac330b..48a43dba8 100644 --- a/cockatrice/src/interface/widgets/replay/replay_timeline_widget.cpp +++ b/cockatrice/src/interface/widgets/replay/replay_timeline_widget.cpp @@ -1,9 +1,15 @@ #include "replay_timeline_widget.h" -#include "../../../client/settings/cache_settings.h" - +#include +#include +#include #include #include +#include +#include +#include +#include +#include static constexpr int BIN_LENGTH = 5000; static constexpr int MIN_RESOLUTION_MS = 1000; diff --git a/cockatrice/src/interface/widgets/replay/replay_timeline_widget.h b/cockatrice/src/interface/widgets/replay/replay_timeline_widget.h index 47d19a741..2c277228f 100644 --- a/cockatrice/src/interface/widgets/replay/replay_timeline_widget.h +++ b/cockatrice/src/interface/widgets/replay/replay_timeline_widget.h @@ -7,13 +7,9 @@ #ifndef REPLAY_TIMELINE_WIDGET #define REPLAY_TIMELINE_WIDGET -#include "../../../game/player/event_processing_options.h" - -#include +#include #include - -class QPaintEvent; -class QTimer; +#include class ReplayTimelineWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/replay/replay_widget.cpp b/cockatrice/src/interface/widgets/replay/replay_widget.cpp index c92771f8c..07b4e72ce 100644 --- a/cockatrice/src/interface/widgets/replay/replay_widget.cpp +++ b/cockatrice/src/interface/widgets/replay/replay_widget.cpp @@ -3,12 +3,21 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" #include "../../pixel_map_generator.h" -#include "../interface/widgets/tabs/tab_game.h" +#include "libcockatrice/settings/interface_settings.h" #include "replay_manager.h" #include "replay_quick_settings_widget.h" +#include "replay_timeline_widget.h" +#include #include +#include +#include +#include +#include #include +#include + +class GameReplay; ReplayWidget::ReplayWidget(QWidget *parent, GameReplay *replay) : QWidget(parent), replayPlayButton(nullptr), replayFastForwardButton(nullptr), aReplaySkipForward(nullptr), diff --git a/cockatrice/src/interface/widgets/replay/replay_widget.h b/cockatrice/src/interface/widgets/replay/replay_widget.h index 6d2b7a043..74aace570 100644 --- a/cockatrice/src/interface/widgets/replay/replay_widget.h +++ b/cockatrice/src/interface/widgets/replay/replay_widget.h @@ -8,15 +8,18 @@ #ifndef REPLAY_WIDGET_H #define REPLAY_WIDGET_H -#include "replay_timeline_widget.h" +#include "../../../game/player/event_processing_options.h" -#include #include -#include +#include class ReplayManager; class ReplayQuickSettingsWidget; -class TabGame; +class GameEventContainer; +class GameReplay; +class QAction; +class QToolButton; +class ReplayTimelineWidget; /** * @brief The top-level widget that is put in the replay dock widget. diff --git a/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp b/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp index 91a7cb965..037a4a1e5 100644 --- a/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp +++ b/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp @@ -4,22 +4,47 @@ #include "../../client/sound_engine.h" #include "../../interface/card_localization.h" #include "../../interface/pixel_map_generator.h" -#include "../../interface/widgets/tabs/tab_account.h" +#include "../../tabs/tab_supervisor.h" #include "../user/user_context_menu.h" #include "../user/user_list_manager.h" #include "../user/user_list_proxy.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/protocol/pb/event_room_say.pb.h" +#include "room_message_type.h" #include +#include +#include #include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include +#include +#include #include #include #include +#include +#include +#include + +class QPoint; const QColor DEFAULT_MENTION_COLOR = QColor(194, 31, 47); diff --git a/cockatrice/src/interface/widgets/server/chat_view/chat_view.h b/cockatrice/src/interface/widgets/server/chat_view/chat_view.h index 06e3a0ed8..3fa7224e5 100644 --- a/cockatrice/src/interface/widgets/server/chat_view/chat_view.h +++ b/cockatrice/src/interface/widgets/server/chat_view/chat_view.h @@ -8,22 +8,34 @@ #ifndef CHATVIEW_H #define CHATVIEW_H -#include "../../interface/widgets/tabs/tab_supervisor.h" -#include "../user/user_list_widget.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" -#include #include +#include +#include +#include +#include +#include +#include #include +#include #include #include +#include #include #include +#include class AbstractGame; -class QTextTable; -class QMouseEvent; class UserContextMenu; class UserListProxy; +class QAction; +class QPoint; +class QUrl; +class QWidget; +class TabSupervisor; +struct CardRef; +template class QFlags; class UserMessagePosition { diff --git a/cockatrice/src/interface/widgets/server/game_filter_configs.h b/cockatrice/src/interface/widgets/server/game_filter_configs.h index 5cb048669..93ca010d8 100644 --- a/cockatrice/src/interface/widgets/server/game_filter_configs.h +++ b/cockatrice/src/interface/widgets/server/game_filter_configs.h @@ -1,6 +1,11 @@ #ifndef COCKATRICE_GAME_FILTER_CONFIGS_H #define COCKATRICE_GAME_FILTER_CONFIGS_H +#include +#include +#include +#include +#include #include /** @@ -12,7 +17,9 @@ struct GameFilterConfigs static constexpr int DEFAULT_MAX_PLAYERS_MAX = 99; bool hideBuddiesOnlyGames = false; - bool hideIgnoredUserGames = false; + // Defaults to true to match GameFiltersSettings::isHideIgnoredUserGames(), so freshly loaded + // filters compare equal to a default-constructed config. + bool hideIgnoredUserGames = true; bool hideFullGames = false; bool hideGamesThatStarted = false; bool hidePasswordProtectedGames = false; diff --git a/cockatrice/src/interface/widgets/server/game_selector.cpp b/cockatrice/src/interface/widgets/server/game_selector.cpp index 659325987..6922bfe64 100644 --- a/cockatrice/src/interface/widgets/server/game_selector.cpp +++ b/cockatrice/src/interface/widgets/server/game_selector.cpp @@ -1,32 +1,54 @@ #include "game_selector.h" +#include "../../../client/settings/cache_settings.h" #include "../../pixel_map_generator.h" #include "../interface/widgets/dialogs/dlg_create_game.h" #include "../interface/widgets/dialogs/dlg_filter_games.h" -#include "../interface/widgets/tabs/tab_account.h" -#include "../interface/widgets/tabs/tab_game.h" #include "../interface/widgets/tabs/tab_room.h" #include "../interface/widgets/tabs/tab_supervisor.h" #include "../interface/widgets/utility/get_text_with_max.h" #include "game_link.h" +#include "game_selector_quick_filter_toolbar.h" #include "games_model.h" +#include "libcockatrice/protocol/pb/event_add_to_list.pb.h" +#include "libcockatrice/protocol/pb/event_remove_from_list.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include "user/user_list_manager.h" +#include #include #include #include #include #include +#include +#include +#include +#include #include +#include #include +#include +#include +#include #include +#include +#include +#include #include #include #include #include #include -#include #include +#include +#include +#include + +class QModelIndex; +class QPoint; +class QWidget; +template class QList; GameSelector::GameSelector(AbstractClient *_client, TabSupervisor *_tabSupervisor, @@ -91,6 +113,17 @@ GameSelector::GameSelector(AbstractClient *_client, quickFilterToolBar->setVisible( SettingsCache::instance().userInterface().getShowGameSelectorFilterToolbar()); }); + // The quick-filter toolbar only updates the in-memory model, so persist every change. + // Otherwise each new GameSelector (room switch, reconnect, restart) would revert to stale + // saved values and e.g. hide full/started games the user had unchecked. The save is + // debounced so typing in the search field does not rewrite the settings file on every + // keystroke; a pending save is flushed in the destructor. + filterSaveDebounceTimer.setSingleShot(true); + filterSaveDebounceTimer.setInterval(500); + connect(&filterSaveDebounceTimer, &QTimer::timeout, this, + [this] { gameListProxyModel->saveFilterParameters(gameTypeMap); }); + connect(gameListProxyModel, &GamesProxyModel::filtersChanged, this, + [this] { filterSaveDebounceTimer.start(); }); } else { quickFilterToolBar = nullptr; } @@ -165,6 +198,18 @@ GameSelector::GameSelector(AbstractClient *_client, connect(client, &AbstractClient::removeFromListEventReceived, this, &GameSelector::processRemoveFromListEvent); } +GameSelector::~GameSelector() +{ + // Nothing else persists quick-filter toolbar edits: the toolbar only updates the in-memory model, + // and the debounced timer above is the sole writer for that path (actSetFilter/actClearFilter save + // synchronously, but the toolbar does not). Flush a pending debounced save so edits made within + // the debounce interval before destruction are not lost on room switch, reconnect, or close. + if (filterSaveDebounceTimer.isActive()) { + filterSaveDebounceTimer.stop(); + gameListProxyModel->saveFilterParameters(gameTypeMap); + } +} + void GameSelector::ignoreListReceived(const QList &) { gameListProxyModel->refresh(); diff --git a/cockatrice/src/interface/widgets/server/game_selector.h b/cockatrice/src/interface/widgets/server/game_selector.h index 9af39cf50..e3407abea 100644 --- a/cockatrice/src/interface/widgets/server/game_selector.h +++ b/cockatrice/src/interface/widgets/server/game_selector.h @@ -1,25 +1,35 @@ #ifndef GAMESELECTOR_H #define GAMESELECTOR_H -#include "game_selector_quick_filter_toolbar.h" #include "game_type_map.h" #include -#include -#include -#include +#include +#include +// IWYU pragma: keep +// ServerInfo_User appears by value and inside QList in slot signatures, so the +// moc-generated code needs the complete type. +#include class QTreeView; class GamesModel; class GamesProxyModel; class QPushButton; -class QCheckBox; -class QLabel; class AbstractClient; class TabSupervisor; class TabRoom; class ServerInfo_Game; class Response; +class Event_AddToList; +class Event_RemoveFromList; +class GameSelectorQuickFilterToolBar; +class QModelIndex; +class QPoint; +class QString; +class QWidget; +class ServerInfo_User; +template class QMap; +template class QList; /** * @class GameSelector @@ -139,6 +149,9 @@ private: const bool showFilters; /**< Determines whether filter buttons are displayed. */ GameTypeMap gameTypeMap; /**< Mapping of game types for the current room. */ + QTimer filterSaveDebounceTimer; /**< Delays persisting quick-filter edits so typing does not rewrite the settings + file on every keystroke. */ + /** * @brief Updates the widget title to reflect the current number of displayed games. * @@ -202,6 +215,7 @@ public: const bool restoresettings, const bool _showfilters, QWidget *parent = nullptr); + ~GameSelector() override; /** * @brief Updates UI text for translation/localization. diff --git a/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp b/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp index d668b1c33..0fc3d879c 100644 --- a/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp +++ b/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp @@ -1,12 +1,22 @@ #include "game_selector_quick_filter_toolbar.h" +#include "game_filter_configs.h" #include "games_model.h" -#include "user/user_list_manager.h" #include #include #include #include +#include +#include +#include +#include +#include +#include +#include + +class TabSupervisor; +template class QMap; GameSelectorQuickFilterToolBar::GameSelectorQuickFilterToolBar(QWidget *parent, TabSupervisor *_tabSupervisor, diff --git a/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.h b/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.h index 9b7b6e61f..99ed179b5 100644 --- a/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.h +++ b/cockatrice/src/interface/widgets/server/game_selector_quick_filter_toolbar.h @@ -1,12 +1,19 @@ #ifndef COCKATRICE_GAME_SELECTOR_QUICK_FILTER_TOOLBAR_H #define COCKATRICE_GAME_SELECTOR_QUICK_FILTER_TOOLBAR_H -#include "../tabs/tab_supervisor.h" -#include "games_model.h" - -#include -#include #include +#include +#include + +class GamesProxyModel; +class QCheckBox; +class QComboBox; +class QHBoxLayout; +class QLineEdit; +class QString; +class TabSupervisor; +struct GameFilterConfigs; +template class QMap; class GameSelectorQuickFilterToolBar : public QWidget { diff --git a/cockatrice/src/interface/widgets/server/games_model.cpp b/cockatrice/src/interface/widgets/server/games_model.cpp index 127badbb2..315d51d9e 100644 --- a/cockatrice/src/interface/widgets/server/games_model.cpp +++ b/cockatrice/src/interface/widgets/server/games_model.cpp @@ -2,13 +2,26 @@ #include "../../../client/settings/cache_settings.h" #include "../interface/pixel_map_generator.h" -#include "../interface/widgets/tabs/tab_account.h" -#include "user/user_list_manager.h" -#include "user/user_list_widget.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "user/user_list_proxy.h" +#include "user_level.h" +#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include @@ -510,6 +523,9 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow) const void GamesProxyModel::refresh() { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)) + beginFilterChange(); +#endif #if (QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)) endFilterChange(QSortFilterProxyModel::Direction::Rows); #else diff --git a/cockatrice/src/interface/widgets/server/games_model.h b/cockatrice/src/interface/widgets/server/games_model.h index b5f86c291..9bf54b83a 100644 --- a/cockatrice/src/interface/widgets/server/games_model.h +++ b/cockatrice/src/interface/widgets/server/games_model.h @@ -4,13 +4,18 @@ #include "game_filter_configs.h" #include "game_type_map.h" +#include #include -#include +#include +#include #include -#include +#include #include +#include +#include class UserListProxy; +class QObject; /** * @class GamesModel diff --git a/cockatrice/src/interface/widgets/server/handle_public_servers.cpp b/cockatrice/src/interface/widgets/server/handle_public_servers.cpp index f5d682c36..08b7837dd 100644 --- a/cockatrice/src/interface/widgets/server/handle_public_servers.cpp +++ b/cockatrice/src/interface/widgets/server/handle_public_servers.cpp @@ -2,10 +2,19 @@ #include "../../../client/settings/cache_settings.h" +#include +#include #include +#include +#include #include +#include +#include #include +#include +#include #include +#include #define PUBLIC_SERVERS_JSON "https://cockatrice.github.io/public-servers.json" diff --git a/cockatrice/src/interface/widgets/server/handle_public_servers.h b/cockatrice/src/interface/widgets/server/handle_public_servers.h index fa924b183..bacc7d3bf 100644 --- a/cockatrice/src/interface/widgets/server/handle_public_servers.h +++ b/cockatrice/src/interface/widgets/server/handle_public_servers.h @@ -9,8 +9,17 @@ #include "user/user_info_connection.h" +#include +#include +#include +#include +#include +#include +#include + class QNetworkReply; class QNetworkAccessManager; +class QVariant; /** * This class is used to update the servers.ini file and ensure diff --git a/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.cpp b/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.cpp index df9dfbf53..74e403ea8 100644 --- a/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.cpp +++ b/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.cpp @@ -1,14 +1,23 @@ #include "remote_decklist_tree_widget.h" +#include "libcockatrice/protocol/pb/response.pb.h" + +#include #include #include +#include +#include #include +#include #include #include #include #include #include +class QObject; +class QWidget; + RemoteDeckList_TreeModel::DirectoryNode::DirectoryNode(const QString &_name, RemoteDeckList_TreeModel::DirectoryNode *_parent) : RemoteDeckList_TreeModel::Node(_name, _parent) diff --git a/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.h b/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.h index 2cf09aff7..d553ffe9e 100644 --- a/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.h +++ b/cockatrice/src/interface/widgets/server/remote/remote_decklist_tree_widget.h @@ -8,13 +8,23 @@ #ifndef REMOTEDECKLIST_TREEWIDGET_H #define REMOTEDECKLIST_TREEWIDGET_H +#include #include +#include +#include +#include +#include +#include #include +#include +#include class Response; class AbstractClient; class QSortFilterProxyModel; class ServerInfo_DeckStorage_TreeItem; +class QObject; +class QWidget; class RemoteDeckList_TreeModel : public QAbstractItemModel { @@ -22,6 +32,7 @@ class RemoteDeckList_TreeModel : public QAbstractItemModel public: class DirectoryNode; class FileNode; + class Node { protected: diff --git a/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.cpp b/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.cpp index d62bf81aa..c131c3cbf 100644 --- a/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.cpp +++ b/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.cpp @@ -1,16 +1,27 @@ #include "remote_replay_list_tree_widget.h" #include "../../../pixel_map_generator.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_replay_match.pb.h" +#include +#include #include #include +#include #include +#include +#include +#include #include #include #include #include #include +class QObject; +class QWidget; + const int RemoteReplayList_TreeModel::numberOfColumns = 6; RemoteReplayList_TreeModel::MatchNode::MatchNode(const ServerInfo_ReplayMatch &_matchInfo) diff --git a/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.h b/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.h index 10e698aee..e99702e60 100644 --- a/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.h +++ b/cockatrice/src/interface/widgets/server/remote/remote_replay_list_tree_widget.h @@ -9,21 +9,30 @@ #ifndef REMOTEREPLAYLIST_TREEWIDGET_H #define REMOTEREPLAYLIST_TREEWIDGET_H -#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include class Response; class AbstractClient; class QSortFilterProxyModel; +class QObject; +class QWidget; class RemoteReplayList_TreeModel : public QAbstractItemModel { Q_OBJECT private: - class MatchNode; class ReplayNode; + class Node { protected: diff --git a/cockatrice/src/interface/widgets/server/user/user_avatar_provider.cpp b/cockatrice/src/interface/widgets/server/user/user_avatar_provider.cpp index c115caa47..cb5f84eef 100644 --- a/cockatrice/src/interface/widgets/server/user/user_avatar_provider.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_avatar_provider.cpp @@ -1,8 +1,15 @@ #include "user_avatar_provider.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" + +#include #include #include #include +#include +#include UserAvatarProvider::UserAvatarProvider(AbstractClient *client, QObject *parent) : QObject(parent), client(client) { diff --git a/cockatrice/src/interface/widgets/server/user/user_avatar_provider.h b/cockatrice/src/interface/widgets/server/user/user_avatar_provider.h index 44491e544..c1e75bc1c 100644 --- a/cockatrice/src/interface/widgets/server/user/user_avatar_provider.h +++ b/cockatrice/src/interface/widgets/server/user/user_avatar_provider.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include class AbstractClient; diff --git a/cockatrice/src/interface/widgets/server/user/user_card_art_provider.cpp b/cockatrice/src/interface/widgets/server/user/user_card_art_provider.cpp index 2ba745715..d84bd5804 100644 --- a/cockatrice/src/interface/widgets/server/user/user_card_art_provider.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_card_art_provider.cpp @@ -2,9 +2,22 @@ #include "../../../card_picture_loader/card_picture_loader.h" #include "../../cards/card_art_utils.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_loader.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include +#include #include +#include +#include +#include #include +#include +#include static QString makeKey(const QString &user, const QString &card, const QString &providerId) { diff --git a/cockatrice/src/interface/widgets/server/user/user_card_art_provider.h b/cockatrice/src/interface/widgets/server/user/user_card_art_provider.h index e8283a891..ce9225b00 100644 --- a/cockatrice/src/interface/widgets/server/user/user_card_art_provider.h +++ b/cockatrice/src/interface/widgets/server/user/user_card_art_provider.h @@ -1,12 +1,16 @@ #ifndef COCKATRICE_USER_CARD_ART_PROVIDER_H #define COCKATRICE_USER_CARD_ART_PROVIDER_H +#include #include #include #include #include #include -#include +#include +#include + +class ExactCard; class UserCardArtProvider : public QObject { diff --git a/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.cpp b/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.cpp index d49e3d540..f8b57cfc2 100644 --- a/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.cpp @@ -3,30 +3,50 @@ #include "../../../card_picture_loader/card_picture_loader.h" #include "../../cards/art_crop_attribution.h" #include "../../utility/completer_utils.h" -#include "card/card_search_model.h" #include "card_database_display_model.h" #include "card_database_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" #include "user_card_art_provider.h" #include "user_list_painter.h" +#include +#include +#include #include #include #include +#include #include #include -#include #include #include #include +#include +#include #include #include #include +#include +#include #include -#include +#include +#include +#include +#include +#include #include +#include #include +#include #include #include +#include +#include +#include namespace { diff --git a/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.h b/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.h index 24e14dce5..bfba8b007 100644 --- a/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.h +++ b/cockatrice/src/interface/widgets/server/user/user_card_settings_dialog.h @@ -3,24 +3,26 @@ #include "user_list_painter.h" -#include #include +#include #include +#include +#include +#include +#include +#include class QCompleter; -class QFocusEvent; class QGroupBox; -class QKeyEvent; -class QMouseEvent; class QLineEdit; class QDoubleSpinBox; class QLabel; class QPushButton; -class QWheelEvent; class CardDatabaseModel; class CardDatabaseDisplayModel; class CardSearchModel; class CardCompleterProxyModel; +class QComboBox; /** * @brief Interactive preview of the user list banner art. diff --git a/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp b/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp index f95ad88e4..c8fe97cda 100644 --- a/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_context_menu.cpp @@ -1,20 +1,42 @@ #include "user_context_menu.h" +#include "../../../../game/abstract_game.h" +#include "../../../../game/game_event_handler.h" +#include "../../../../game/game_meta_info.h" #include "../../dialogs/dlg_report_user.h" -#include "../../interface/widgets/tabs/tab_account.h" -#include "../../interface/widgets/tabs/tab_game.h" #include "../../interface/widgets/tabs/tab_supervisor.h" #include "../chat_view/chat_view.h" +#include "../game_link.h" #include "../game_selector.h" +#include "../game_type_map.h" +#include "libcockatrice/protocol/pb/admin_commands.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_ban.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_gametype.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_room.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_warning.pb.h" #include "user_info_box.h" +#include "user_level.h" #include "user_list_dialog.h" #include "user_list_manager.h" #include "user_list_proxy.h" #include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -27,6 +49,10 @@ #include #include #include +#include +#include + +class QVariant; UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *parent, AbstractGame *_game) : QObject(parent), client(_tabSupervisor->getClient()), tabSupervisor(_tabSupervisor), diff --git a/cockatrice/src/interface/widgets/server/user/user_context_menu.h b/cockatrice/src/interface/widgets/server/user/user_context_menu.h index 0922eae94..2536819a4 100644 --- a/cockatrice/src/interface/widgets/server/user/user_context_menu.h +++ b/cockatrice/src/interface/widgets/server/user/user_context_menu.h @@ -11,19 +11,22 @@ #include #include +#include #include #include +#include +#include + class AbstractGame; class UserListProxy; class AbstractClient; class ChatView; class CommandContainer; class QAction; -class QMenu; class QPoint; class Response; -class ServerInfo_User; class TabSupervisor; +class QWidget; class UserContextMenu : public QObject { diff --git a/cockatrice/src/interface/widgets/server/user/user_info_box.cpp b/cockatrice/src/interface/widgets/server/user/user_info_box.cpp index 3d89cecf5..ff3d9a224 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_box.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_info_box.cpp @@ -5,20 +5,36 @@ #include "../../interface/widgets/dialogs/dlg_edit_password.h" #include "../../interface/widgets/dialogs/dlg_edit_user.h" #include "../../interface/widgets/utility/get_text_with_max.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/utility/days_years_between.h" #include "user_card_settings_dialog.h" +#include "user_level.h" +#include "user_list_painter.h" +#include +#include #include +#include +#include +#include #include #include -#include #include +#include +#include #include +#include +#include +#include +#include #include #include #include #include #include #include +#include +#include UserInfoBox::UserInfoBox(AbstractClient *_client, bool _editable, QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags), client(_client), editable(_editable) diff --git a/cockatrice/src/interface/widgets/server/user/user_info_box.h b/cockatrice/src/interface/widgets/server/user/user_info_box.h index 955cb9d3d..6bc571a37 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_box.h +++ b/cockatrice/src/interface/widgets/server/user/user_info_box.h @@ -7,13 +7,15 @@ #ifndef USERINFOBOX_H #define USERINFOBOX_H -#include #include +#include #include +#include #include #include #include -#include +#include +#include class AbstractClient; class Response; diff --git a/cockatrice/src/interface/widgets/server/user/user_info_connection.cpp b/cockatrice/src/interface/widgets/server/user/user_info_connection.cpp index f934960f8..d23ac63ba 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_connection.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_info_connection.cpp @@ -2,7 +2,10 @@ #include "../../../../client/settings/cache_settings.h" -#include +#include +#include +#include +#include #include #include diff --git a/cockatrice/src/interface/widgets/server/user/user_info_connection.h b/cockatrice/src/interface/widgets/server/user/user_info_connection.h index 6278815a9..b44d97d42 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_connection.h +++ b/cockatrice/src/interface/widgets/server/user/user_info_connection.h @@ -7,12 +7,11 @@ #ifndef USERCONNECTION_INFORMATION_H #define USERCONNECTION_INFORMATION_H -#include -#include -#include #include -#include -#include +#include +#include +#include +#include inline Q_LOGGING_CATEGORY(UserInfoConnectionLog, "user_info_connection"); diff --git a/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp b/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp index 967de2f2c..c3e880084 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_info_popup.cpp @@ -4,26 +4,61 @@ #include "../../interface/pixel_map_generator.h" #include "../../interface/theme_manager.h" #include "../../interface/widgets/tabs/tab_supervisor.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" +#include "user_level.h" #include "user_list_painter.h" #include +#include +#include +#include +#include +#include +#include #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include +#include #include -#include -#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#include +#include #include #include -#include #include #include +#include +#include +#include + +class QAction; /// Qt stylesheets accept #aarrggbb, which is QColor::name(QColor::HexArgb). static QString colorStr(const QColor &color) diff --git a/cockatrice/src/interface/widgets/server/user/user_info_popup.h b/cockatrice/src/interface/widgets/server/user/user_info_popup.h index ed7320fba..f2a91d025 100644 --- a/cockatrice/src/interface/widgets/server/user/user_info_popup.h +++ b/cockatrice/src/interface/widgets/server/user/user_info_popup.h @@ -1,24 +1,29 @@ #ifndef COCKATRICE_USER_INFO_POPUP_H #define COCKATRICE_USER_INFO_POPUP_H -#include "../../interface/widgets/server/game_type_map.h" #include "user_list_painter.h" +#include #include -#include -#include +#include #include -#include +#include +#include #include -#include -#include -#include #include +#include +#include +#include class AbstractClient; class QLabel; class QPushButton; class TabSupervisor; +class QListView; +class QPoint; +class QStandardItemModel; +class Response; +template class QMap; // ── Roles ───────────────────────────────────────────────────────────────────── diff --git a/cockatrice/src/interface/widgets/server/user/user_list_dialog.cpp b/cockatrice/src/interface/widgets/server/user/user_list_dialog.cpp index fc5b520ad..605c89734 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_dialog.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_list_dialog.cpp @@ -1,17 +1,26 @@ #include "user_list_dialog.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" + #include #include +#include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include +#include + +class QWidget; BanDialog::BanDialog(const ServerInfo_User &info, QWidget *parent) : QDialog(parent) { diff --git a/cockatrice/src/interface/widgets/server/user/user_list_dialog.h b/cockatrice/src/interface/widgets/server/user/user_list_dialog.h index fa7d5de92..e10fca5bb 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_dialog.h +++ b/cockatrice/src/interface/widgets/server/user/user_list_dialog.h @@ -2,7 +2,8 @@ #define COCKATRICE_USER_LIST_DIALOG_H #include -#include +#include +#include class QComboBox; class QLabel; @@ -11,6 +12,8 @@ class QRadioButton; class QSpinBox; class QLineEdit; class QCheckBox; +class QWidget; +class ServerInfo_User; class BanDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/server/user/user_list_manager.cpp b/cockatrice/src/interface/widgets/server/user/user_list_manager.cpp index 216420006..385a969fd 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_manager.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_list_manager.cpp @@ -1,8 +1,11 @@ #include "user_list_manager.h" -#include "../../client/sound_engine.h" -#include "user_info_box.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include +#include +#include #include #include #include diff --git a/cockatrice/src/interface/widgets/server/user/user_list_manager.h b/cockatrice/src/interface/widgets/server/user/user_list_manager.h index 6238f0799..b2ff69286 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_manager.h +++ b/cockatrice/src/interface/widgets/server/user/user_list_manager.h @@ -10,18 +10,22 @@ #include "user_list_proxy.h" #include -#include +#include +#include +#include +// IWYU pragma: keep +// ServerInfo_User appears by value and inside QList in slot signatures, so the +// moc-generated code needs the complete type. #include class AbstractClient; class Event_AddToList; -class Event_ListRooms; class Event_RemoveFromList; class Event_UserJoined; class Event_UserLeft; class Response; class ServerInfo_User; -class TabSupervisor; +template class QList; class UserListManager : public QObject, public UserListProxy { diff --git a/cockatrice/src/interface/widgets/server/user/user_list_painter.cpp b/cockatrice/src/interface/widgets/server/user/user_list_painter.cpp index 34a3d6ae1..08eaaaff7 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_painter.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_list_painter.cpp @@ -1,14 +1,35 @@ #include "user_list_painter.h" #include "../../interface/pixel_map_generator.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include #include +#include #include #include +#include +#include +#include +#include +#include static constexpr int RowHeight = 72; static constexpr int AvatarSize = 36; diff --git a/cockatrice/src/interface/widgets/server/user/user_list_painter.h b/cockatrice/src/interface/widgets/server/user/user_list_painter.h index 352a01f6b..e7293a097 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_painter.h +++ b/cockatrice/src/interface/widgets/server/user/user_list_painter.h @@ -5,16 +5,19 @@ #include #include -#include #include -#include #include +#include #include +#include +#include class QPainter; class QModelIndex; class QStyleOptionViewItem; class ServerInfo_User; +class QPixmap; +template class QMap; struct CardArtParams { diff --git a/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.cpp b/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.cpp index 937058024..78d45d120 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.cpp @@ -1,12 +1,13 @@ #include "user_list_panel_widget.h" #include "../../../../client/settings/cache_settings.h" -#include "user_list_manager.h" #include "user_list_widget.h" #include +#include +#include +#include #include -#include #include namespace diff --git a/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.h b/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.h index 7ae14dfcf..088365bbc 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.h +++ b/cockatrice/src/interface/widgets/server/user/user_list_panel_widget.h @@ -8,7 +8,9 @@ #include "user_list_widget.h" +#include #include +#include class AbstractClient; class QLineEdit; diff --git a/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp b/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp index 3b8fc08b7..b3fd1d1a9 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp @@ -4,18 +4,64 @@ #include "../../interface/pixel_map_generator.h" #include "../../interface/theme_manager.h" #include "../../interface/widgets/tabs/tab_supervisor.h" +#include "user_avatar_provider.h" +#include "user_card_art_provider.h" #include "user_context_menu.h" +#include "user_info_popup.h" +#include "user_level.h" +#include "user_list_manager.h" #include "user_list_painter.h" +#include "user_list_proxy.h" +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include #include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include +#include #include +#include + +class QPixmap; +struct GameInviteOption; namespace UserListRoles { diff --git a/cockatrice/src/interface/widgets/server/user/user_list_widget.h b/cockatrice/src/interface/widgets/server/user/user_list_widget.h index 9802387b2..8093222ea 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_widget.h +++ b/cockatrice/src/interface/widgets/server/user/user_list_widget.h @@ -7,33 +7,34 @@ #ifndef USERLIST_H #define USERLIST_H -#include "../../cards/card_info_picture_art_crop_widget.h" -#include "../../interface/widgets/server/game_link.h" -#include "user_avatar_provider.h" -#include "user_card_art_provider.h" -#include "user_info_popup.h" -#include "user_list_manager.h" -#include "user_list_painter.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" -#include #include +#include +#include #include +#include #include -#include #include #include -#include -#include +#include +#include -class QTreeWidget; -class ServerInfo_User; class AbstractClient; class TabSupervisor; -class Response; -class CommandContainer; class UserContextMenu; class UserListWidget; -class QShowEvent; +class QModelIndex; +class QPixmap; +class QPoint; +class QTimer; +class QWidget; +class UserAvatarProvider; +class UserCardArtProvider; +class UserInfoPopup; +class UserListManager; +struct CardArtParams; +struct GameInviteOption; class UserListItemDelegate : public QStyledItemDelegate { diff --git a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp index 9a70e94c5..9c43d1f7b 100644 --- a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp @@ -2,14 +2,22 @@ #include "settings_search_model.h" +#include #include #include #include #include +#include #include +#include #include +#include #include #include +#include +#include +#include +#include /** * @brief Recursively collects all widgets within a layout diff --git a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h index 3140f94f3..722a91e62 100644 --- a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h @@ -3,6 +3,7 @@ #include #include +#include #define WIKI_CUSTOM_PIC_URL "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Picture-Download-URLs" #define WIKI_CUSTOM_SHORTCUTS "https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts" diff --git a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp index 415eef6b9..4c38459c6 100644 --- a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.cpp @@ -1,29 +1,44 @@ #include "appearance_settings_page.h" #include "../../../client/settings/cache_settings.h" -#include "../../../client/settings/card_counter_settings.h" #include "../../client/settings/card_counter_settings.h" #include "../../palette_editor/palette_editor_dialog.h" +#include "../../theme_config.h" #include "../dialogs/override_printing_warning.h" #include "../general/home_tab_button_color.h" #include "../interface/theme_manager.h" #include "../interface/widgets/general/background_sources.h" #include "../playmat/playmat_collection_dialog.h" -#include "../playmat/playmat_settings_dialog.h" +#include "libcockatrice/interfaces/interface_interface_settings_provider.h" +#include "libcockatrice/utility/macros.h" +#include #include +#include #include +#include #include +#include #include -#include +#include #include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include #include #include #include #include +#include AppearanceSettingsPage::AppearanceSettingsPage() { @@ -59,15 +74,10 @@ AppearanceSettingsPage::AppearanceSettingsPage() connect(&schemeCombo, &QComboBox::currentIndexChanged, this, [this] { themeManager->setColorScheme(schemeCombo.currentData().toString()); }); - // Qt widget style; "System" lets the application decide + // Qt widget style; "System" lets the application decide. The broken Windows + // native styles are still offered, but selecting one raises a warning. styleCombo.addItem(tr("System"), QStringLiteral("System")); for (const QString &key : QStyleFactory::keys()) { - // The Windows 11 native style is broken (board rendering glitches when - // moving cards), so never offer it; it is already sanitized at apply - // time in ThemeManager. - if (key.compare("windows11", Qt::CaseInsensitive) == 0) { - continue; - } styleCombo.addItem(key, key); } @@ -77,6 +87,7 @@ AppearanceSettingsPage::AppearanceSettingsPage() connect(&styleCombo, &QComboBox::currentIndexChanged, this, [this] { themeManager->setStyleName(styleCombo.currentData().toString()); }); + connect(&styleCombo, &QComboBox::currentIndexChanged, this, &AppearanceSettingsPage::updateStyleWarning); connect(themeManager, &ThemeManager::themeChanged, this, [this, dirPath] { const QString newDir = themeManager->getAvailableThemes().value(SettingsCache::instance().getThemeName()); @@ -93,6 +104,8 @@ AppearanceSettingsPage::AppearanceSettingsPage() const int styleIdx = currentStyle.isEmpty() ? 0 : styleCombo.findData(currentStyle); styleCombo.setCurrentIndex(styleIdx >= 0 ? styleIdx : 0); styleCombo.blockSignals(false); + + updateStyleWarning(); }); connect(&editPaletteButton, &QPushButton::clicked, this, &AppearanceSettingsPage::editPalette); @@ -105,7 +118,11 @@ AppearanceSettingsPage::AppearanceSettingsPage() themeGrid->addWidget(&schemeCombo, 2, 1); themeGrid->addWidget(&styleComboLabel, 3, 0); themeGrid->addWidget(&styleCombo, 3, 1); - themeGrid->addWidget(&editPaletteButton, 4, 1); + themeGrid->addWidget(&styleWarningLabel, 4, 0, 1, 2); + themeGrid->addWidget(&editPaletteButton, 5, 1); + + styleWarningLabel.setWordWrap(true); + styleWarningLabel.setAlignment(Qt::AlignLeft | Qt::AlignVCenter); themeGroupBox = new QGroupBox; themeGroupBox->setLayout(themeGrid); @@ -450,6 +467,14 @@ void AppearanceSettingsPage::updateHomeTabSettingsVisibility() homeTabDisplayCardNameCheckBox.setVisible(visible); } +void AppearanceSettingsPage::updateStyleWarning() +{ + const QString style = styleCombo.currentData().toString(); + const bool broken = + style.compare("windows11", Qt::CaseInsensitive) == 0 || style.compare("windowsvista", Qt::CaseInsensitive) == 0; + styleWarningLabel.setVisible(broken); +} + void AppearanceSettingsPage::showShortcutsChanged(QT_STATE_CHANGED_T value) { SettingsCache::instance().userInterface().setShowShortcuts(value); @@ -512,6 +537,11 @@ void AppearanceSettingsPage::retranslateUi() schemeComboLabel.setText(tr("Active theme palette:")); styleComboLabel.setText(tr("Active theme style:")); styleCombo.setToolTip(tr("Qt widget style saved to this theme (\"System\" lets the application decide)")); + styleWarningLabel.setText( + tr("Warning: the Windows 11 and Windows Vista styles are buggy and can render controls such as combo boxes " + "unreadable, especially in dark mode. Fusion is the recommended style on every platform: it is Qt's " + "cross-platform style and the one Cockatrice is developed against.")); + updateStyleWarning(); editPaletteButton.setText(tr("Edit theme palette")); homeTabGroupBox->setTitle(tr("Home tab settings")); diff --git a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h index bec4cd72f..8afd326a3 100644 --- a/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/appearance_settings_page.h @@ -5,11 +5,14 @@ #include #include -#include #include +#include #include #include #include +#include + +class QGroupBox; class AppearanceSettingsPage : public AbstractSettingsPage { @@ -19,6 +22,7 @@ private slots: void openThemeLocation(); void editPalette(); void updateHomeTabSettingsVisibility(); + void updateStyleWarning(); void showShortcutsChanged(QT_STATE_CHANGED_T enabled); void overrideAllCardArtWithPersonalPreferenceToggled(QT_STATE_CHANGED_T enabled); @@ -34,6 +38,7 @@ private: QComboBox schemeCombo; QLabel styleComboLabel; QComboBox styleCombo; + QLabel styleWarningLabel; QPushButton editPaletteButton; QLabel homeTabBackgroundSourceLabel; diff --git a/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.cpp index bdbb38c95..31178ba4c 100644 --- a/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.cpp @@ -2,21 +2,42 @@ #include "../../../client/settings/cache_settings.h" #include "../../pixel_map_generator.h" +#include "../dialogs/path_safety_warning.h" #include "update/card_spoiler/spoiler_background_updater.h" +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include #include +#include #include #include +#include +#include +#include #include #include +#include +#include +#include #include #include +#include +#include #include #include #include #include +#include +#include DeckEditorSettingsPage::DeckEditorSettingsPage() { @@ -343,6 +364,9 @@ void DeckEditorSettingsPage::spoilerPathButtonClicked() if (lsPath.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, lsPath + "/spoiler.xml")) { + return; + } mpSpoilerSavePathLineEdit->setText(lsPath + "/spoiler.xml"); SettingsCache::instance().paths().setSpoilerDatabasePath(lsPath + "/spoiler.xml"); diff --git a/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.h b/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.h index 23e33fa20..47f840191 100644 --- a/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/deck_editor_settings_page.h @@ -4,10 +4,17 @@ #include "abstract_settings_page.h" #include -#include #include -#include #include +#include +#include + +class QAction; +class QGroupBox; +class QLineEdit; +class QListWidget; +class QListWidgetItem; +class QModelIndex; class DeckEditorSettingsPage : public AbstractSettingsPage { diff --git a/cockatrice/src/interface/widgets/settings_page/general_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/general_settings_page.cpp index 57099fb4a..fa8938b32 100644 --- a/cockatrice/src/interface/widgets/settings_page/general_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/general_settings_page.cpp @@ -1,18 +1,32 @@ #include "general_settings_page.h" #include "../../../client/settings/cache_settings.h" +#include "../dialogs/path_safety_warning.h" #include "../interface/card_picture_loader/card_picture_loader.h" #include "../main.h" #include "../server/user/user_info_connection.h" #include "update/client/release_channel.h" +#include #include +#include +#include #include #include #include +#include #include +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include #include #include #include @@ -22,6 +36,9 @@ #include #include #include +#include +#include +#include enum startupCardUpdateCheckBehaviorIndex { @@ -145,12 +162,18 @@ GeneralSettingsPage::GeneralSettingsPage() newVersionOracleCheckBox.setChecked(settings.updates().getNotifyAboutNewVersion()); + cardDatabaseUpdateTrayNotificationCheckBox.setChecked(settings.updates().getCardDatabaseUpdateTrayNotification()); + + connect(&cardDatabaseUpdateTrayNotificationCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings.updates(), + &UpdatesSettings::setCardDatabaseUpdateTrayNotification); + auto *cardDatabaseGrid = new QGridLayout; cardDatabaseGrid->addWidget(&startupCardUpdateCheckBehaviorLabel, 0, 0); cardDatabaseGrid->addWidget(&startupCardUpdateCheckBehaviorSelector, 0, 1); cardDatabaseGrid->addWidget(&cardUpdateCheckIntervalLabel, 1, 0); cardDatabaseGrid->addWidget(&cardUpdateCheckIntervalSpinBox, 1, 1); cardDatabaseGrid->addWidget(&lastCardUpdateCheckDateLabel, 2, 1); + cardDatabaseGrid->addWidget(&cardDatabaseUpdateTrayNotificationCheckBox, 3, 0, 1, 2); cardDatabaseGroupBox = new QGroupBox; cardDatabaseGroupBox->setLayout(cardDatabaseGrid); @@ -356,6 +379,9 @@ void GeneralSettingsPage::deckPathButtonClicked() if (path.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, path)) { + return; + } deckPathEdit->setText(path); SettingsCache::instance().paths().setDeckPath(path); @@ -367,6 +393,9 @@ void GeneralSettingsPage::filtersPathButtonClicked() if (path.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, path)) { + return; + } filtersPathEdit->setText(path); SettingsCache::instance().paths().setFiltersPath(path); @@ -378,6 +407,9 @@ void GeneralSettingsPage::replaysPathButtonClicked() if (path.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, path)) { + return; + } replaysPathEdit->setText(path); SettingsCache::instance().paths().setReplaysPath(path); @@ -389,6 +421,9 @@ void GeneralSettingsPage::picsPathButtonClicked() if (path.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, path)) { + return; + } picsPathEdit->setText(path); SettingsCache::instance().paths().setPicsPath(path); @@ -400,6 +435,9 @@ void GeneralSettingsPage::cardDatabasePathButtonClicked() if (path.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, path)) { + return; + } cardDatabasePathEdit->setText(path); SettingsCache::instance().paths().setCardDatabasePath(path); @@ -411,6 +449,9 @@ void GeneralSettingsPage::customCardDatabaseButtonClicked() if (path.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, path)) { + return; + } customCardDatabasePathEdit->setText(path); SettingsCache::instance().paths().setCustomCardDatabasePath(path); @@ -422,6 +463,9 @@ void GeneralSettingsPage::tokenDatabasePathButtonClicked() if (path.isEmpty()) { return; } + if (!PathSafetyWarning::confirmOutsideProgramDir(this, path)) { + return; + } tokenDatabasePathEdit->setText(path); SettingsCache::instance().paths().setTokenDatabasePath(path); @@ -549,6 +593,7 @@ void GeneralSettingsPage::retranslateUi() tr("Always update in the background")); cardUpdateCheckIntervalLabel.setText(tr("Check for card database updates every")); cardUpdateCheckIntervalSpinBox.setSuffix(tr(" days")); + cardDatabaseUpdateTrayNotificationCheckBox.setText(tr("Notify in the system tray while the card database updates")); QDate lastCheckDate = settings.updates().getLastCardUpdateCheck(); int daysAgo = lastCheckDate.daysTo(QDate::currentDate()); diff --git a/cockatrice/src/interface/widgets/settings_page/general_settings_page.h b/cockatrice/src/interface/widgets/settings_page/general_settings_page.h index 07e0ba3a9..fcf1c78d0 100644 --- a/cockatrice/src/interface/widgets/settings_page/general_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/general_settings_page.h @@ -5,11 +5,16 @@ #include #include -#include #include #include -#include #include +#include +#include +#include + +class QGroupBox; +class QLineEdit; +class QPushButton; inline Q_LOGGING_CATEGORY(GeneralSettingsPageLog, "general_settings_page"); @@ -70,6 +75,7 @@ private: QLabel cardUpdateCheckIntervalLabel; QSpinBox cardUpdateCheckIntervalSpinBox; QLabel lastCardUpdateCheckDateLabel; + QCheckBox cardDatabaseUpdateTrayNotificationCheckBox; QCheckBox showTipsOnStartup; QLabel startupTabLabel; diff --git a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp index 68e3f2ac7..9494155af 100644 --- a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.cpp @@ -3,14 +3,27 @@ #include "../../../client/settings/cache_settings.h" #include "../../pixel_map_generator.h" #include "../interface/widgets/utility/get_text_with_max.h" +#include "libcockatrice/utility/macros.h" +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include #include +#include +#include #include #include #include #include +#include MessagesSettingsPage::MessagesSettingsPage() { diff --git a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h index 4d491136f..e85e6cca7 100644 --- a/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/messages_settings_page.h @@ -4,10 +4,15 @@ #include "abstract_settings_page.h" #include -#include #include -#include +#include #include +#include + +class QAction; +class QGroupBox; +class QLineEdit; +class QListWidget; class MessagesSettingsPage : public AbstractSettingsPage { diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp index 2fdff3bce..bf35b7557 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp @@ -7,7 +7,24 @@ #include "settings_search_model.h" +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QObject; SettingsSearchDelegate::SettingsSearchDelegate(QObject *parent) : QStyledItemDelegate(parent) { diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h index aa296049a..2e48a3de9 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h @@ -6,8 +6,14 @@ #ifndef COCKATRICE_SETTINGS_SEARCH_DELEGATE_H #define COCKATRICE_SETTINGS_SEARCH_DELEGATE_H +#include #include +#include +#include #include +#include + +class QObject; /** * @brief Custom paint delegate for settings search result items diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp b/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp index 71f859d4b..015a7d45d 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp @@ -6,7 +6,14 @@ #include "settings_search_model.h" #include +#include +#include +#include +#include #include +#include + +class QObject; SettingsSearchModel::SettingsSearchModel(QObject *parent) : QAbstractListModel(parent) { diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_model.h b/cockatrice/src/interface/widgets/settings_page/settings_search_model.h index 0b590f180..902a29312 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_model.h +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_model.h @@ -7,9 +7,17 @@ #define COCKATRICE_SETTINGS_SEARCH_MODEL_H #include +#include #include +#include +#include #include -#include +#include +#include +#include + +class QObject; +class QWidget; /** * @brief Represents a single searchable setting entry diff --git a/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp index 1277d0e49..ea7ed745c 100644 --- a/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.cpp @@ -8,8 +8,17 @@ #include "../interface/widgets/utility/sequence_edit.h" #include +#include +#include +#include +#include #include +#include +#include +#include +#include #include +#include ShortcutSettingsPage::ShortcutSettingsPage() { diff --git a/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.h b/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.h index 05391df77..6ae7fbfa7 100644 --- a/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/shortcut_settings_page.h @@ -3,14 +3,18 @@ #include "abstract_settings_page.h" -#include -#include -#include -#include +#include +#include class SequenceEdit; class ShortcutTreeView; class SearchLineEdit; +class QGridLayout; +class QGroupBox; +class QHBoxLayout; +class QLabel; +class QPushButton; +class QVBoxLayout; class ShortcutSettingsPage : public AbstractSettingsPage { diff --git a/cockatrice/src/interface/widgets/settings_page/sound_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/sound_settings_page.cpp index 2bd776671..05725bb42 100644 --- a/cockatrice/src/interface/widgets/settings_page/sound_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/sound_settings_page.cpp @@ -3,10 +3,21 @@ #include "../../../client/settings/cache_settings.h" #include "../client/sound_engine.h" +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include SoundSettingsPage::SoundSettingsPage() { diff --git a/cockatrice/src/interface/widgets/settings_page/sound_settings_page.h b/cockatrice/src/interface/widgets/settings_page/sound_settings_page.h index f90bcbc5a..acaa4f7c4 100644 --- a/cockatrice/src/interface/widgets/settings_page/sound_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/sound_settings_page.h @@ -5,10 +5,13 @@ #include #include -#include #include #include -#include +#include + +class QGroupBox; +class QSlider; +class QSpinBox; class SoundSettingsPage : public AbstractSettingsPage { diff --git a/cockatrice/src/interface/widgets/settings_page/storage_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/storage_settings_page.cpp index 4aad91115..a71296820 100644 --- a/cockatrice/src/interface/widgets/settings_page/storage_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/storage_settings_page.cpp @@ -5,12 +5,21 @@ #include "../../card_picture_loader/card_picture_loader_local_schemes.h" #include "../interface/card_picture_loader/card_picture_loader.h" +#include #include #include +#include +#include +#include #include +#include +#include +#include +#include #include #include #include +#include StorageSettingsPage::StorageSettingsPage() { diff --git a/cockatrice/src/interface/widgets/settings_page/storage_settings_page.h b/cockatrice/src/interface/widgets/settings_page/storage_settings_page.h index 5c8a00981..1c9a35323 100644 --- a/cockatrice/src/interface/widgets/settings_page/storage_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/storage_settings_page.h @@ -3,11 +3,13 @@ #include "abstract_settings_page.h" -#include -#include #include #include #include +#include + +class QComboBox; +class QGroupBox; class StorageSettingsPage : public AbstractSettingsPage { diff --git a/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.cpp index 03b9455fa..0a5f57e1f 100644 --- a/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.cpp @@ -3,13 +3,22 @@ #include "../../../client/settings/cache_settings.h" #include "../interface/widgets/tabs/tab_supervisor.h" #include "../tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.h" +#include "libcockatrice/utility/macros.h" +#include #include +#include +#include +#include +#include +#include +#include #include #include #include #include #include +#include enum visualDeckStoragePromptForConversionIndex { diff --git a/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.h b/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.h index 277c5461e..297d80c35 100644 --- a/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/user_interface_settings_page.h @@ -5,13 +5,14 @@ #include #include -#include #include #include #include #include -#include #include +#include + +class QGroupBox; class UserInterfaceSettingsPage : public AbstractSettingsPage { diff --git a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp index 6423c581b..4044f03db 100644 --- a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp +++ b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.cpp @@ -11,35 +11,49 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../../deck_loader/deck_file_format.h" +#include "../../deck_loader/deck_loader.h" +#include "../../deck_loader/loaded_deck.h" #include "../cards/additional_info/deck_color_identity.h" +#include "../cards/card_info_frame_widget.h" #include "../client/network/interfaces/deck_stats_interface.h" #include "../client/network/interfaces/tapped_out_interface.h" +#include "../deck_editor/deck_editor_card_database_dock_widget.h" +#include "../deck_editor/deck_editor_card_info_dock_widget.h" +#include "../deck_editor/deck_editor_deck_dock_widget.h" +#include "../deck_editor/deck_editor_filter_dock_widget.h" +#include "../deck_editor/deck_editor_printing_selector_dock_widget.h" #include "../deck_editor/deck_state_manager.h" #include "../interface/card_picture_loader/card_picture_loader.h" -#include "../interface/pixel_map_generator.h" #include "../interface/widgets/dialogs/dlg_load_deck.h" #include "../interface/widgets/dialogs/dlg_load_deck_from_clipboard.h" #include "../interface/widgets/dialogs/dlg_load_deck_from_website.h" #include "../interface/widgets/dialogs/dlg_share_deck.h" +#include "../menus/deck_editor_menu.h" +#include "../printing_selector/printing_selector.h" #include "../utility/visibility_change_listener.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/utility/card_ref.h" #include "tab_supervisor.h" #include -#include #include #include +#include #include -#include -#include +#include +#include +#include +#include #include #include #include -#include #include -#include -#include -#include +#include #include +#include #include #include #include @@ -50,6 +64,8 @@ #include #include #include +#include +#include /** * @brief Constructs the AbstractTabDeckEditor. diff --git a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h index dae8f5b0a..1782e7afd 100644 --- a/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h +++ b/cockatrice/src/interface/widgets/tabs/abstract_tab_deck_editor.h @@ -9,48 +9,31 @@ #define TAB_GENERIC_DECK_EDITOR_H #include "../../deck_loader/deck_loader.h" -#include "../interface/widgets/deck_editor/deck_editor_card_database_dock_widget.h" -#include "../interface/widgets/deck_editor/deck_editor_card_info_dock_widget.h" -#include "../interface/widgets/deck_editor/deck_editor_database_display_widget.h" -#include "../interface/widgets/deck_editor/deck_editor_deck_dock_widget.h" -#include "../interface/widgets/deck_editor/deck_editor_filter_dock_widget.h" -#include "../interface/widgets/deck_editor/deck_editor_printing_selector_dock_widget.h" -#include "../interface/widgets/menus/deck_editor_menu.h" -#include "../interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h" +#include "libcockatrice/card/card_info.h" #include "tab.h" -#include +#include +#include +#include +#include class DeckStateManager; class CardDatabaseModel; -class CardDatabaseDisplayModel; - -class CardInfoFrameWidget; -class DeckLoader; class DeckEditorMenu; class DeckEditorCardInfoDockWidget; class DeckEditorCardDatabaseDockWidget; class DeckEditorDeckDockWidget; class DeckEditorFilterDockWidget; class DeckEditorPrintingSelectorDockWidget; -class DeckPreviewDeckTagsDisplayWidget; class Response; class FilterTree; -class FilterTreeModel; -class FilterBuilder; - -class QTreeView; -class QTextEdit; -class QLabel; -class QComboBox; -class QGroupBox; class QMessageBox; -class QHBoxLayout; -class QVBoxLayout; -class QPushButton; class QDockWidget; class QMenu; class QAction; +class ExactCard; +class TabSupervisor; +struct LoadedDeck; /** * @class AbstractTabDeckEditor diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.cpp index 40882db04..8d023cd61 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.cpp @@ -2,6 +2,9 @@ #include #include +#include +#include +#include void ArchidektDeckListingApiResponse::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.h index 723c65ce2..c42bc1315 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/archidekt_deck_listing_api_response.h @@ -4,8 +4,9 @@ #include "deck_listings/archidekt_api_response_deck_listing_container.h" #include -#include +#include #include +#include class ArchidektDeckListingApiResponse { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.cpp index 46c229156..d118301bb 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.cpp @@ -1,5 +1,9 @@ #include "archidekt_api_response_card.h" +#include +#include +#include + void ArchidektApiResponseCard::fromJson(const QJsonObject &json) { id = json.value("id").toInt(); diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.h index 559580da2..8e9e0b12a 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card.h @@ -3,11 +3,10 @@ #include "archidekt_api_response_edition.h" -#include -#include #include +#include #include -#include +#include class ArchidektApiResponseCard { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.cpp index f51d0f3e7..14b13a4ed 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.cpp @@ -1,5 +1,11 @@ #include "archidekt_api_response_card_entry.h" +#include +#include +#include +#include +#include + void ArchidektApiResponseCardEntry::fromJson(const QJsonObject &json) { id = json.value("id").toInt(); diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.h index 118cf5b13..eb7c4190c 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_card_entry.h @@ -3,11 +3,10 @@ #include "archidekt_api_response_card.h" -#include -#include #include +#include #include -#include +#include struct Category { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.cpp index 122617a22..73836b9c8 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.cpp @@ -1,5 +1,9 @@ #include "archidekt_api_response_edition.h" +#include +#include +#include + void ArchidektApiResponseEdition::fromJson(const QJsonObject &json) { editionCode = json.value("editioncode").toString(); diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.h index b898cd816..63d29652f 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/card/archidekt_api_response_edition.h @@ -1,11 +1,8 @@ #ifndef COCKATRICE_ARCHIDEKT_API_RESPONSE_EDITION_H #define COCKATRICE_ARCHIDEKT_API_RESPONSE_EDITION_H -#include -#include #include #include -#include class ArchidektApiResponseEdition { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.cpp index a27d8d961..362ac0f63 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.cpp @@ -1,6 +1,13 @@ #include "archidekt_api_response_deck.h" #include "../card/archidekt_api_response_card_entry.h" +#include "../deck_listings/archidekt_api_response_deck_owner.h" + +#include +#include +#include +#include +#include void ArchidektApiResponseDeck::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.h index b539d9dd1..6af0a01c5 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck.h @@ -1,15 +1,14 @@ #ifndef COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_H #define COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_H -#include "../card/archidekt_api_response_card.h" #include "../card/archidekt_api_response_card_entry.h" #include "../deck_listings/archidekt_api_response_deck_owner.h" #include "archidekt_api_response_deck_category.h" -#include -#include #include +#include #include +#include #include class ArchidektApiResponseDeck diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.cpp index 990293bc6..0df8b9f68 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.cpp @@ -1,5 +1,9 @@ #include "archidekt_api_response_deck_category.h" +#include +#include +#include + void ArchidektApiResponseDeckCategory::fromJson(const QJsonObject &json) { id = json.value("id").toInt(); diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.h index 5e218b6a4..b31743643 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck/archidekt_api_response_deck_category.h @@ -1,15 +1,8 @@ #ifndef COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_CATEGORY_H #define COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_CATEGORY_H -#include "../card/archidekt_api_response_card.h" -#include "../card/archidekt_api_response_card_entry.h" -#include "../deck_listings/archidekt_api_response_deck_owner.h" - -#include -#include #include #include -#include class ArchidektApiResponseDeckCategory { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.cpp index 416621b41..0f5290f02 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.cpp @@ -3,8 +3,10 @@ #include "archidekt_api_response_deck_owner.h" #include -#include #include +#include +#include +#include void ArchidektApiResponseDeckListingContainer::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.h index 8924bb3f5..904d6b624 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_listing_container.h @@ -3,11 +3,11 @@ #include "archidekt_api_response_deck_owner.h" -#include -#include #include +#include +#include #include -#include +#include class ArchidektApiResponseDeckListingContainer { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.cpp index 3d6eac03d..67b80d67a 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.cpp @@ -1,5 +1,9 @@ #include "archidekt_api_response_deck_owner.h" +#include +#include +#include + void ArchidektApiResponseDeckOwner::fromJson(const QJsonObject &json) { id = json.value("id").toInt(); diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.h index df3f48fd2..f63d6af0e 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/api_response/deck_listings/archidekt_api_response_deck_owner.h @@ -1,11 +1,11 @@ #ifndef COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_OWNER_H #define COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_OWNER_H -#include -#include #include +#include #include -#include +#include +#include class ArchidektApiResponseDeckOwner { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp index 657ef3dbe..555ec7ec5 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.cpp @@ -2,16 +2,39 @@ #include "../../../../../../client/settings/cache_settings.h" #include "../../../../../deck_loader/card_node_function.h" -#include "../../../../../deck_loader/deck_loader.h" -#include "../../../../cards/card_size_widget.h" +#include "../../../../../deck_loader/loaded_deck.h" #include "../../../../cards/deck_card_zone_display_widget.h" #include "../../../../visual_deck_editor/visual_deck_display_options_widget.h" +#include "../../../../visual_deck_editor/visual_deck_editor_widget.h" #include "../api_response/archidekt_formats.h" +#include "../api_response/card/archidekt_api_response_card.h" +#include "../api_response/card/archidekt_api_response_card_entry.h" +#include "../api_response/card/archidekt_api_response_edition.h" #include "../api_response/deck/archidekt_api_response_deck.h" +#include "deck_list_model.h" +#include "libcockatrice/deck_list/deck_list.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#include +#include + +class CardSizeWidget; ArchidektApiResponseDeckDisplayWidget::ArchidektApiResponseDeckDisplayWidget(QWidget *parent, ArchidektApiResponseDeck _response, diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h index aaf272718..cdacc70b3 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_display_widget.h @@ -1,18 +1,22 @@ #ifndef COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_DISPLAY_WIDGET_H #define COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_DISPLAY_WIDGET_H -#include "../../../../../deck_loader/deck_loader.h" -#include "../../../../cards/card_size_widget.h" -#include "../../../../general/layout_containers/flow_widget.h" -#include "../../../../visual_deck_editor/visual_deck_display_options_widget.h" #include "../api_response/deck/archidekt_api_response_deck.h" -#include "deck_list_model.h" -#include -#include -#include -#include +#include +#include +#include #include +#include + +class CardSizeWidget; +class DeckListModel; +class QHBoxLayout; +class QPushButton; +class QScrollArea; +class QVBoxLayout; +class VisualDeckDisplayOptionsWidget; +struct LoadedDeck; /** * @class ArchidektApiResponseDeckDisplayWidget diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.cpp index c35c2d0b8..b5e28fcf5 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.cpp @@ -1,17 +1,30 @@ #include "archidekt_api_response_deck_entry_display_widget.h" #include "../../../../../card_picture_loader/card_picture_loader.h" -#include "../../../../cards/card_info_picture_with_text_overlay_widget.h" #include "../../../../general/display/background_plate_widget.h" #include "../../../../general/display/charts/bars/color_bar.h" +#include "../../../../general/display/shadow_background_label.h" +#include "../api_response/deck_listings/archidekt_api_response_deck_listing_container.h" +#include "../api_response/deck_listings/archidekt_api_response_deck_owner.h" #include "archidekt_deck_preview_image_display_widget.h" -#include +#include +#include +#include #include #include #include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #define ARCHIDEKT_DEFAULT_IMAGE "https://storage.googleapis.com/topdekt-user/images/archidekt_deck_card_shadow.jpg" diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h index 575a81b5f..e8ed8561d 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_entry_display_widget.h @@ -1,17 +1,20 @@ #ifndef COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_ENTRY_DISPLAY_WIDGET_H #define COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_ENTRY_DISPLAY_WIDGET_H -#include "../../../../cards/card_info_picture_with_text_overlay_widget.h" #include "../api_response/deck_listings/archidekt_api_response_deck_listing_container.h" -#include "archidekt_deck_preview_image_display_widget.h" -#include -#include -#include -#include +#include +#include +#include #include +#include class BackgroundPlateWidget; +class ArchidektDeckPreviewImageDisplayWidget; +class QLabel; +class QNetworkAccessManager; +class QNetworkReply; +class QVBoxLayout; /** * @class ArchidektApiResponseDeckEntryDisplayWidget diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.cpp index 21e8e3f9a..9c4ea59ab 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.cpp @@ -1,8 +1,18 @@ #include "archidekt_api_response_deck_listings_display_widget.h" -#include "../../../../cards/card_info_picture_with_text_overlay_widget.h" +#include "../../../../cards/card_size_widget.h" +#include "../../../../general/layout_containers/flow_widget.h" +#include "../api_response/archidekt_deck_listing_api_response.h" +#include "../api_response/deck_listings/archidekt_api_response_deck_listing_container.h" #include "archidekt_api_response_deck_entry_display_widget.h" +#include +#include +#include +#include +#include +#include + ArchidektApiResponseDeckListingsDisplayWidget::ArchidektApiResponseDeckListingsDisplayWidget( QWidget *parent, ArchidektDeckListingApiResponse response, diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h index f9a887aa4..a9a7da7a1 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_api_response_deck_listings_display_widget.h @@ -1,15 +1,15 @@ #ifndef COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_LISTINGS_DISPLAY_WIDGET_H #define COCKATRICE_ARCHIDEKT_API_RESPONSE_DECK_LISTINGS_DISPLAY_WIDGET_H -#include "../../../../cards/card_size_widget.h" -#include "../../../../general/layout_containers/flow_widget.h" -#include "../api_response/archidekt_deck_listing_api_response.h" - -#include -#include -#include -#include +#include #include +#include + +class ArchidektDeckListingApiResponse; +class CardSizeWidget; +class FlowWidget; +class QHBoxLayout; +class QNetworkAccessManager; /** * @class ArchidektApiResponseDeckListingsDisplayWidget diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.cpp index ced08491e..97383534f 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.cpp @@ -1,7 +1,11 @@ #include "archidekt_deck_preview_image_display_widget.h" -#include -#include +#include "../../../../general/display/shadow_background_label.h" + +#include +#include +#include +#include ArchidektDeckPreviewImageDisplayWidget::ArchidektDeckPreviewImageDisplayWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.h index 053823c45..991f27b6a 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/display/archidekt_deck_preview_image_display_widget.h @@ -1,10 +1,11 @@ #ifndef COCKATRICE_ARCHIDEKT_DECK_PREVIEW_IMAGE_DISPLAY_WIDGET_H #define COCKATRICE_ARCHIDEKT_DECK_PREVIEW_IMAGE_DISPLAY_WIDGET_H -#include "../../../../general/display/shadow_background_label.h" - -#include #include +#include + +class QLabel; +class ShadowBackgroundLabel; /** * @class ArchidektDeckPreviewImageDisplayWidget diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp b/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp index 888197f53..02badf1aa 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.cpp @@ -3,31 +3,54 @@ #include "../../../../../client/settings/cache_settings.h" #include "../../../../pixel_map_generator.h" #include "../../../cards/additional_info/mana_symbol_widget.h" +#include "../../../cards/card_size_widget.h" +#include "../../../quick_settings/settings_button_widget.h" #include "../../../utility/completer_utils.h" +#include "../../tab.h" #include "../../tab_supervisor.h" #include "api_response/archidekt_deck_listing_api_response.h" +#include "api_response/deck/archidekt_api_response_deck.h" +#include "card_database_display_model.h" +#include "card_database_model.h" #include "display/archidekt_api_response_deck_display_widget.h" #include "display/archidekt_api_response_deck_listings_display_widget.h" +#include +#include +#include #include -#include +#include #include -#include #include #include #include #include +#include +#include +#include +#include #include #include +#include +#include #include -#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include -#include -#include #include +#include +#include #include TabArchidekt::TabArchidekt(TabSupervisor *_tabSupervisor) diff --git a/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.h b/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.h index e837e672b..015b8590b 100644 --- a/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.h +++ b/cockatrice/src/interface/widgets/tabs/api/archidekt/tab_archidekt.h @@ -1,26 +1,35 @@ #ifndef COCKATRICE_TAB_ARCHIDEKT_H #define COCKATRICE_TAB_ARCHIDEKT_H -#include "../../interface/widgets/cards/card_size_widget.h" -#include "../../interface/widgets/quick_settings/settings_button_widget.h" #include "../../tab.h" -#include "display/archidekt_api_response_deck_listings_display_widget.h" +#include "libcockatrice/card/card_info.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include #include -#include -#include -#include -#include +#include +#include + +class ArchidektApiResponseDeckListingsDisplayWidget; +class CardSizeWidget; +class QCheckBox; +class QComboBox; +class QHBoxLayout; +class QLabel; +class QLineEdit; +class QNetworkAccessManager; +class QNetworkReply; +class QPushButton; +class QScrollArea; +class QSpinBox; +class QTimer; +class QVBoxLayout; +class QWidget; +class SettingsButtonWidget; +class TabSupervisor; /** Base API link for Archidekt deck search */ inline QString archidektApiLink = "https://archidekt.com/api/decks/v3/?name="; diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.cpp index 3c95a4553..aa892d0d4 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.cpp @@ -1,5 +1,7 @@ #include "card_in_deck_request.h" +#include + CardInDeckRequest CardInDeckRequest::fromJson(const QJsonObject &json) { CardInDeckRequest request; diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.h index b7eb96211..6bcaca42f 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/card_in_deck_request.h @@ -1,6 +1,7 @@ #ifndef COCKATRICE_CARD_IN_DECK_REQUEST_H #define COCKATRICE_CARD_IN_DECK_REQUEST_H #include +#include struct CardInDeckRequest { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_card_result.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_card_result.cpp index 14558d234..0ae5dd360 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_card_result.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_card_result.cpp @@ -1,5 +1,7 @@ #include "commander_spellbook_card_result.h" +#include + CommanderSpellbookCardResult CommanderSpellbookCardResult::fromJson(const QJsonObject &json) { CommanderSpellbookCardResult result; diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.cpp index 166469353..ac259f3aa 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.cpp @@ -1,6 +1,14 @@ #include "commander_spellbook_deck_request.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include "libcockatrice/utility/card_ref.h" + #include +#include +#include +#include +#include #include CommanderSpellbookDeckRequest CommanderSpellbookDeckRequest::fromJson(const QJsonObject &json) diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.h index 46d8e053b..002f7666f 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_deck_request.h @@ -1,11 +1,12 @@ #ifndef COCKATRICE_COMMANDER_SPELLBOOK_DECK_REQUEST_H #define COCKATRICE_COMMANDER_SPELLBOOK_DECK_REQUEST_H #include "card_in_deck_request.h" -#include "libcockatrice/deck_list/deck_list.h" #include #include +class DeckList; + struct CommanderSpellbookDeckRequest { static CommanderSpellbookDeckRequest fromJson(const QJsonObject &json); diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.cpp index c3640ce79..35ba954a1 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.cpp @@ -1,5 +1,9 @@ #include "commander_spellbook_estimate_bracket_result.h" +#include +#include +#include + EstimateBracketResult EstimateBracketResult::fromJson(const QJsonObject &json) { EstimateBracketResult result; diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.h index bb589a901..c9c152d35 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_estimate_bracket_result.h @@ -6,6 +6,7 @@ #include #include +#include struct EstimateBracketResult { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.cpp index bbc23e15e..53630a69e 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.cpp @@ -1,5 +1,7 @@ #include "commander_spellbook_variant_result.h" +#include + CommanderSpellbookVariantResult CommanderSpellbookVariantResult::fromJson(const QJsonObject &json) { CommanderSpellbookVariantResult result; diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.h index d908f1299..49f45f92c 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/api_response/commander_spellbook_variant_result.h @@ -3,6 +3,7 @@ #include #include +#include struct CommanderSpellbookVariantResult { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.cpp index b85129a3f..8e0448faa 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.cpp @@ -4,6 +4,8 @@ #include +class DeckList; + CommanderBracketService &CommanderBracketService::instance() { static CommanderBracketService service; diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.h index e0c2a9d55..22962cc95 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_service.h @@ -1,10 +1,15 @@ #ifndef COCKATRICE_COMMANDER_BRACKET_SERVICE_H #define COCKATRICE_COMMANDER_BRACKET_SERVICE_H +#include "api_response/commander_spellbook_estimate_bracket_result.h" #include "commander_spellbook_api_accessor.h" -#include "libcockatrice/deck_list/deck_list.h" #include +#include +#include +#include + +class DeckList; struct CommanderBracketEstimate { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp index 2cbbedfa4..06a76dd19 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.cpp @@ -3,7 +3,9 @@ #include "../../../../../client/settings/cache_settings.h" #include "../../../../pixel_map_generator.h" #include "commander_bracket_service.h" +#include "libcockatrice/deck_list/deck_list.h" +#include #include #include #include @@ -11,11 +13,17 @@ #include #include #include +#include +#include #include +#include #include #include #include #include +#include + +template class QSharedPointer; CommanderBracketWidget::CommanderBracketWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.h index a45610fcf..f5b2b7958 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_bracket_widget.h @@ -4,12 +4,17 @@ #include "commander_spellbook_bracket_explainer.h" #include +#include #include -#include +#include +#include class QLabel; class QToolButton; struct CommanderBracketEstimate; +class DeckList; +class QObject; +template class QSharedPointer; class CommanderBracketWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.cpp index 590692d98..bd8d9379d 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.cpp @@ -1,13 +1,21 @@ #include "commander_spellbook_api_accessor.h" #include "api_response/commander_spellbook_deck_request.h" +#include "api_response/commander_spellbook_estimate_bracket_result.h" +#include #include #include +#include +#include #include +#include #include +#include #include +class DeckList; + static const QUrl ESTIMATE_BRACKET_URL(QStringLiteral("https://backend.commanderspellbook.com/estimate-bracket")); CommanderSpellbookApiAccessor &CommanderSpellbookApiAccessor::instance() diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.h index 682a48524..98e7e3710 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_api_accessor.h @@ -1,12 +1,15 @@ #ifndef COCKATRICE_COMMANDER_SPELLBOOK_API_ACCESSOR_H #define COCKATRICE_COMMANDER_SPELLBOOK_API_ACCESSOR_H -#include "api_response/commander_spellbook_estimate_bracket_result.h" - #include -#include #include -#include +#include +#include +#include + +class DeckList; +class QNetworkReply; +struct EstimateBracketResult; class CommanderSpellbookApiAccessor final : public QObject { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.cpp index fc308ed60..06250f1ea 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.cpp @@ -1,5 +1,9 @@ #include "commander_spellbook_bracket_explainer.h" +#include "api_response/commander_spellbook_card_result.h" +#include "api_response/commander_spellbook_estimate_bracket_result.h" +#include "api_response/commander_spellbook_variant_result.h" + static QString cardList(const QList &cards, int max = 5) { QStringList names; diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.h index 9ed499742..3ab317df9 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/commander_spellbook_bracket_explainer.h @@ -1,6 +1,12 @@ #ifndef COCKATRICE_COMMANDER_SPELLBOOK_BRACKET_EXPLAINER_H #define COCKATRICE_COMMANDER_SPELLBOOK_BRACKET_EXPLAINER_H -#include "api_response/commander_spellbook_estimate_bracket_result.h" + +#include +#include +#include +#include + +struct EstimateBracketResult; namespace CommanderBracketNames { diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.cpp b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.cpp index 90b490efe..22200ffa2 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.cpp @@ -2,9 +2,16 @@ #include "../../../../../client/settings/cache_settings.h" +#include #include -#include +#include +#include +#include +#include +#include +#include #include +#include #include static const QUrl COMMANDER_BRACKET_JSON_URL(QStringLiteral("https://cockatrice.github.io/commander-brackets.json")); diff --git a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.h b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.h index b8348b13c..39bddba05 100644 --- a/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.h +++ b/cockatrice/src/interface/widgets/tabs/api/commander_spellbook/handle_commander_brackets.h @@ -1,9 +1,12 @@ #ifndef COCKATRICE_HANDLE_COMMANDER_BRACKETS_H #define COCKATRICE_HANDLE_COMMANDER_BRACKETS_H -#include #include #include +#include +#include + +class QNetworkAccessManager; class HandleCommanderBrackets : public QObject { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.cpp index 145a3fca0..411fdd5ed 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include void EdhrecApiResponseArchidektLink::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.h index d265c164d..0786550fe 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.h @@ -1,7 +1,9 @@ #ifndef ARCHIDEKTENTRY_H #define ARCHIDEKTENTRY_H +#include #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_average_deck_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_average_deck_api_response.cpp index 1297fc157..b6ecac0af 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_average_deck_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_average_deck_api_response.cpp @@ -1,7 +1,13 @@ #include "edhrec_average_deck_api_response.h" +#include "../archidekt_links/edhrec_api_response_archidekt_links.h" +#include "../cards/edhrec_api_response_card_container.h" +#include "../commander/edhrec_commander_api_response_average_deck_statistics.h" + #include #include +#include +#include void EdhrecAverageDeckApiResponse::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp index 1cb070c30..324dce52a 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp @@ -1,10 +1,14 @@ #include "edhrec_deck_api_response.h" -#include #include #include -#include +#include +#include +#include +#include +#include #include +#include void EdhrecDeckApiResponse::fromJson(const QJsonArray &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h index 7bc97c431..a47fcc10b 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.h @@ -7,7 +7,9 @@ #ifndef EDHREC_DECK_API_RESPONSE_H #define EDHREC_DECK_API_RESPONSE_H -#include "../../../../../../deck_loader/deck_loader.h" +#include "libcockatrice/deck_list/deck_list.h" + +#include class EdhrecDeckApiResponse { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/card_prices/edhrec_api_response_card_prices.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/card_prices/edhrec_api_response_card_prices.cpp index 1231d147a..26502f1de 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/card_prices/edhrec_api_response_card_prices.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/card_prices/edhrec_api_response_card_prices.cpp @@ -1,6 +1,8 @@ #include "edhrec_api_response_card_prices.h" #include +#include +#include void CardPrices::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.cpp index 3fef8be34..8660cac50 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include void EdhrecApiResponseCardContainer::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.h index d76dda490..70d39474d 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.h @@ -11,6 +11,7 @@ #include "edhrec_commander_api_response_commander_details.h" #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_details.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_details.cpp index a4a746c61..ebf09d2a9 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_details.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_details.cpp @@ -1,6 +1,8 @@ #include "edhrec_api_response_card_details.h" #include +#include +#include EdhrecApiResponseCardDetails::EdhrecApiResponseCardDetails() : synergy(0.0), inclusion(0), numDecks(0), potentialDecks(0) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.cpp index 72d6fe2cc..0cf585ee9 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.cpp @@ -1,6 +1,10 @@ #include "edhrec_api_response_card_list.h" #include +#include +#include +#include +#include EdhrecApiResponseCardList::EdhrecApiResponseCardList() { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.h index 2df29de0c..d6e0d7f75 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.h @@ -9,7 +9,7 @@ #include "edhrec_api_response_card_details.h" -#include +#include #include #include diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.cpp index 7b220603e..7383677c8 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.cpp @@ -1,6 +1,11 @@ #include "edhrec_commander_api_response_commander_details.h" +#include "../card_prices/edhrec_api_response_card_prices.h" + #include +#include +#include +#include void EdhrecCommanderApiResponseCommanderDetails::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.h index 293e9a150..a0858e9d2 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.h @@ -10,6 +10,8 @@ #include "../card_prices/edhrec_api_response_card_prices.h" #include +#include +#include #include #include diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response.cpp index da2a9c052..1e0304e8a 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response.cpp @@ -1,7 +1,12 @@ #include "edhrec_commander_api_response.h" +#include "../archidekt_links/edhrec_api_response_archidekt_links.h" +#include "../cards/edhrec_api_response_card_container.h" + #include #include +#include +#include void EdhrecCommanderApiResponse::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response_average_deck_statistics.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response_average_deck_statistics.cpp index 74cce5322..996ec3c0c 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response_average_deck_statistics.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response_average_deck_statistics.cpp @@ -1,5 +1,7 @@ #include "edhrec_commander_api_response_average_deck_statistics.h" +#include + void EdhrecCommanderApiResponseAverageDeckStatistics::fromJson(const QJsonObject &json) { creature = json.value("creature").toInt(0); diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.cpp index 26122ce89..4df2f3523 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.cpp @@ -1,7 +1,10 @@ #include "edhrec_top_cards_api_response.h" +#include "../cards/edhrec_api_response_card_container.h" + #include -#include +#include +#include void EdhrecTopCardsApiResponse::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.h index 695498e2b..cdf0d4a71 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.h @@ -9,6 +9,7 @@ #include "../cards/edhrec_api_response_card_container.h" +#include #include class EdhrecTopCardsApiResponse diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.cpp index 83b10c9e5..c1bf71cb2 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.cpp @@ -1,7 +1,10 @@ #include "edhrec_top_commanders_api_response.h" +#include "../cards/edhrec_api_response_card_container.h" + #include -#include +#include +#include void EdhrecTopCommandersApiResponse::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.h index 10aa51ff4..4579632c6 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.h @@ -9,6 +9,7 @@ #include "../cards/edhrec_api_response_card_container.h" +#include #include class EdhrecTopCommandersApiResponse diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.cpp index 56eb4fa4f..cf6ea5df8 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.cpp @@ -1,7 +1,10 @@ #include "edhrec_top_tags_api_response.h" +#include "../cards/edhrec_api_response_card_container.h" + #include -#include +#include +#include void EdhrecTopTagsApiResponse::fromJson(const QJsonObject &json) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.h index 0337d94f8..e6e25d97b 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.h @@ -9,6 +9,7 @@ #include "../cards/edhrec_api_response_card_container.h" +#include #include class EdhrecTopTagsApiResponse diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp index 75902daad..0ba74fd60 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp @@ -1,5 +1,13 @@ #include "edhrec_api_response_card_prices_display_widget.h" +#include "../../api_response/card_prices/edhrec_api_response_card_prices.h" + +#include +#include +#include +#include +#include + EdhrecApiResponseCardPricesDisplayWidget::EdhrecApiResponseCardPricesDisplayWidget(QWidget *parent, const CardPrices &_cardPrices) : QWidget(parent), cardPrices(_cardPrices) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.h index 8943ae9f3..75fe033dc 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.h @@ -9,9 +9,11 @@ #include "../../api_response/card_prices/edhrec_api_response_card_prices.h" -#include -#include #include +#include + +class QGridLayout; +class QLabel; class EdhrecApiResponseCardPricesDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp index 00c1741df..0728b3154 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp @@ -1,10 +1,21 @@ #include "edhrec_api_response_card_details_display_widget.h" +#include "../../../../../cards/card_info_picture_widget.h" +#include "../../../../../cards/card_size_widget.h" #include "../../../../../general/display/background_plate_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_details.h" #include "../../tab_edhrec_main.h" +#include "edhrec_api_response_card_inclusion_display_widget.h" +#include "edhrec_api_response_card_synergy_display_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include #include +#include +#include +#include #include +#include EdhrecApiResponseCardDetailsDisplayWidget::EdhrecApiResponseCardDetailsDisplayWidget( QWidget *parent, diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.h index b09cc4e04..d738f4685 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.h @@ -7,15 +7,18 @@ #ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H #define EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H -#include "../../../../../cards/card_info_picture_widget.h" -#include "../../../../../general/display/background_plate_widget.h" #include "../../api_response/cards/edhrec_api_response_card_details.h" -#include "edhrec_api_response_card_inclusion_display_widget.h" -#include "edhrec_api_response_card_synergy_display_widget.h" -#include -#include +#include #include +#include + +class BackgroundPlateWidget; +class CardInfoPictureWidget; +class EdhrecApiResponseCardInclusionDisplayWidget; +class EdhrecApiResponseCardSynergyDisplayWidget; +class QLabel; +class QVBoxLayout; class EdhrecApiResponseCardDetailsDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.cpp index 8292b00ea..6786b006e 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.cpp @@ -1,5 +1,13 @@ #include "edhrec_api_response_card_inclusion_display_widget.h" +#include "../../../../../general/display/charts/bars/percent_bar_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_details.h" + +#include +#include +#include +#include + EdhrecApiResponseCardInclusionDisplayWidget::EdhrecApiResponseCardInclusionDisplayWidget( QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.h index 516d820eb..61a1bd645 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.h @@ -7,12 +7,14 @@ #ifndef EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H #define EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H -#include "../../../../../general/display/charts/bars/percent_bar_widget.h" #include "../../api_response/cards/edhrec_api_response_card_details.h" -#include -#include #include +#include + +class PercentBarWidget; +class QLabel; +class QVBoxLayout; class EdhrecApiResponseCardInclusionDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp index 841ef315b..5295b92d5 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp @@ -1,9 +1,19 @@ #include "edhrec_api_response_card_list_display_widget.h" #include "../../../../../general/display/banner_widget.h" +#include "../../../../../general/layout_containers/flow_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_details.h" +#include "../../api_response/cards/edhrec_api_response_card_list.h" #include "edhrec_api_response_card_details_display_widget.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include EdhrecApiResponseCardListDisplayWidget::EdhrecApiResponseCardListDisplayWidget(QWidget *parent, EdhrecApiResponseCardList toDisplay) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.h index 555da6ecf..20bdad8ea 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.h @@ -8,12 +8,14 @@ #define EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H #include "../../../../../general/display/banner_widget.h" -#include "../../../../../general/layout_containers/flow_widget.h" -#include "../../api_response/cards/edhrec_api_response_card_list.h" -#include -#include +#include #include +#include + +class EdhrecApiResponseCardList; +class FlowWidget; +class QVBoxLayout; class EdhrecApiResponseCardListDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.cpp index 9d5571a8f..5f4b02327 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.cpp @@ -1,5 +1,13 @@ #include "edhrec_api_response_card_synergy_display_widget.h" +#include "../../../../../general/display/charts/bars/percent_bar_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_details.h" + +#include +#include +#include +#include + EdhrecApiResponseCardSynergyDisplayWidget::EdhrecApiResponseCardSynergyDisplayWidget( QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.h index 5800b5497..71cca6ca4 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.h @@ -7,12 +7,14 @@ #ifndef EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H #define EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H -#include "../../../../../general/display/charts/bars/percent_bar_widget.h" #include "../../api_response/cards/edhrec_api_response_card_details.h" -#include -#include #include +#include + +class PercentBarWidget; +class QLabel; +class QVBoxLayout; class EdhrecApiResponseCardSynergyDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp index 40a803e77..3da050edd 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp @@ -1,11 +1,20 @@ #include "edhrec_api_response_commander_details_display_widget.h" #include "../../../../../cards/card_info_picture_widget.h" +#include "../../../../../cards/card_size_widget.h" +#include "../../api_response/cards/edhrec_commander_api_response_commander_details.h" #include "../../tab_edhrec_main.h" #include "../card_prices/edhrec_api_response_card_prices_display_widget.h" -#include "edhrec_commander_api_response_bracket_navigation_widget.h" +#include "edhrec_commander_api_response_navigation_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include +#include +#include +#include +#include #include +#include EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget( QWidget *parent, diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.h index 4201ce3b3..197263512 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.h @@ -7,16 +7,19 @@ #ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H #define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H -#include "../../../../../cards/card_info_picture_widget.h" #include "../../api_response/cards/edhrec_commander_api_response_commander_details.h" -#include "../card_prices/edhrec_api_response_card_prices_display_widget.h" -#include "edhrec_commander_api_response_navigation_widget.h" -#include -#include +#include #include +#include class EdhrecCommanderApiResponseNavigationWidget; +class CardInfoPictureWidget; +class EdhrecApiResponseCardPricesDisplayWidget; +class QHBoxLayout; +class QLabel; +class QVBoxLayout; + class EdhrecCommanderResponseCommanderDetailsDisplayWidget : public QWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.cpp index c3ab23e41..b26a7e574 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.cpp @@ -1,6 +1,12 @@ #include "edhrec_commander_api_response_bracket_navigation_widget.h" +#include +#include +#include +#include #include +#include +#include EdhrecCommanderApiResponseBracketNavigationWidget::EdhrecCommanderApiResponseBracketNavigationWidget( QWidget *parent, diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.h index 713ef2791..a741b6696 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.h @@ -1,11 +1,16 @@ #ifndef COCKATRICE_EDHREC_COMMANDER_API_RESPONSE_BRACKET_NAVIGATION_WIDGET_H #define COCKATRICE_EDHREC_COMMANDER_API_RESPONSE_BRACKET_NAVIGATION_WIDGET_H -#include -#include +#include #include -#include +#include +#include #include +#include + +class QGridLayout; +class QLabel; +class QPushButton; class EdhrecCommanderApiResponseBracketNavigationWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.cpp index 1845c020d..48704d010 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.cpp @@ -1,6 +1,12 @@ #include "edhrec_commander_api_response_budget_navigation_widget.h" +#include +#include +#include +#include #include +#include +#include EdhrecCommanderApiResponseBudgetNavigationWidget::EdhrecCommanderApiResponseBudgetNavigationWidget( QWidget *parent, diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h index 666edba16..8013d1d6b 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h @@ -1,11 +1,16 @@ #ifndef COCKATRICE_EDHREC_COMMANDER_API_RESPONSE_BUDGET_NAVIGATION_WIDGET_H #define COCKATRICE_EDHREC_COMMANDER_API_RESPONSE_BUDGET_NAVIGATION_WIDGET_H -#include -#include +#include #include -#include +#include +#include #include +#include + +class QGridLayout; +class QLabel; +class QPushButton; class EdhrecCommanderApiResponseBudgetNavigationWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.cpp index 230858d6c..111d91b91 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.cpp @@ -1,15 +1,30 @@ #include "edhrec_commander_api_response_display_widget.h" -#include "../../../../../cards/card_info_picture_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_container.h" +#include "../../api_response/cards/edhrec_api_response_card_list.h" #include "../../api_response/commander/edhrec_commander_api_response.h" #include "../cards/edhrec_api_response_card_list_display_widget.h" #include "edhrec_api_response_commander_details_display_widget.h" +#include +#include +#include +#include +#include #include +#include +#include #include #include +#include #include +#include #include +#include +#include +#include + +class QModelIndex; EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget(QWidget *parent, EdhrecCommanderApiResponse response, diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.h index 80da8a7f8..5ada40df3 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.h @@ -7,11 +7,14 @@ #ifndef EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H #define EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H -#include "../../api_response/commander/edhrec_commander_api_response.h" - -#include -#include +#include #include +#include + +class EdhrecCommanderApiResponse; +class QHBoxLayout; +class QScrollArea; +class QVBoxLayout; class EdhrecCommanderApiResponseDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp index c42d2ed90..fd02c4261 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp @@ -1,6 +1,12 @@ #include "edhrec_commander_api_response_navigation_widget.h" #include "../../tab_edhrec_main.h" +#include "edhrec_commander_api_response_bracket_navigation_widget.h" +#include "edhrec_commander_api_response_budget_navigation_widget.h" + +#include +#include +#include EdhrecCommanderApiResponseNavigationWidget::EdhrecCommanderApiResponseNavigationWidget( QWidget *parent, diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.h index 9b46b54ba..737558625 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.h @@ -7,14 +7,16 @@ #ifndef EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H #define EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H -#include "edhrec_api_response_commander_details_display_widget.h" -#include "edhrec_commander_api_response_bracket_navigation_widget.h" -#include "edhrec_commander_api_response_budget_navigation_widget.h" +#include "../../api_response/cards/edhrec_commander_api_response_commander_details.h" -#include -#include -#include +#include #include +#include + +class EdhrecCommanderApiResponseBracketNavigationWidget; +class EdhrecCommanderApiResponseBudgetNavigationWidget; +class QGridLayout; +class QPushButton; class EdhrecCommanderApiResponseNavigationWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp index ae07c9dc8..6f32db102 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp @@ -1,8 +1,17 @@ #include "edhrec_top_cards_api_response_display_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_container.h" +#include "../../api_response/cards/edhrec_api_response_card_list.h" #include "../../api_response/top_cards/edhrec_top_cards_api_response.h" #include "../cards/edhrec_api_response_card_list_display_widget.h" +#include +#include +#include +#include +#include +#include + EdhrecTopCardsApiResponseDisplayWidget::EdhrecTopCardsApiResponseDisplayWidget(QWidget *parent, EdhrecTopCardsApiResponse response) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.h index 30998391c..8b5ddfad0 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.h @@ -7,12 +7,13 @@ #ifndef EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H #define EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H -#include "../../api_response/top_cards/edhrec_top_cards_api_response.h" - -#include -#include -#include #include +#include + +class EdhrecTopCardsApiResponse; +class QHBoxLayout; +class QScrollArea; +class QVBoxLayout; class EdhrecTopCardsApiResponseDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp index 13f54a979..4ab333fd4 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp @@ -1,8 +1,20 @@ #include "edhrec_top_commanders_api_response_display_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_container.h" +#include "../../api_response/cards/edhrec_api_response_card_list.h" #include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h" #include "../cards/edhrec_api_response_card_list_display_widget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + EdhrecTopCommandersApiResponseDisplayWidget::EdhrecTopCommandersApiResponseDisplayWidget( QWidget *parent, EdhrecTopCommandersApiResponse response) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.h index 2b9563ea5..8471a8dda 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.h @@ -7,12 +7,13 @@ #ifndef EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H #define EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H -#include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h" - -#include -#include -#include #include +#include + +class EdhrecTopCommandersApiResponse; +class QHBoxLayout; +class QScrollArea; +class QVBoxLayout; class EdhrecTopCommandersApiResponseDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.cpp index 91a1ce3fa..9c7ce8d06 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.cpp @@ -1,8 +1,17 @@ #include "edhrec_top_tags_api_response_display_widget.h" +#include "../../api_response/cards/edhrec_api_response_card_container.h" +#include "../../api_response/cards/edhrec_api_response_card_list.h" #include "../../api_response/top_tags/edhrec_top_tags_api_response.h" #include "../cards/edhrec_api_response_card_list_display_widget.h" +#include +#include +#include +#include +#include +#include + EdhrecTopTagsApiResponseDisplayWidget::EdhrecTopTagsApiResponseDisplayWidget(QWidget *parent, EdhrecTopTagsApiResponse response) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.h index 4a4fc8991..2c13d069f 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.h @@ -7,11 +7,13 @@ #ifndef EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H #define EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H -#include "../../api_response/top_tags/edhrec_top_tags_api_response.h" - -#include -#include #include +#include + +class EdhrecTopTagsApiResponse; +class QHBoxLayout; +class QScrollArea; +class QVBoxLayout; class EdhrecTopTagsApiResponseDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.cpp index 10389f4eb..3aa395126 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.cpp @@ -1,16 +1,26 @@ #include "tab_edhrec.h" +#include "../../tab.h" #include "api_response/commander/edhrec_commander_api_response.h" #include "display/commander/edhrec_commander_api_response_display_widget.h" +#include "libcockatrice/card/card_info.h" +#include +#include #include #include #include #include +#include #include #include +#include #include -#include +#include +#include +#include + +class TabSupervisor; TabEdhRec::TabEdhRec(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor) { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.h index 5ce36c9cf..4e3c9c8ba 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec.h @@ -8,10 +8,16 @@ #define TAB_EDHREC_H #include "../../tab.h" -#include "display/commander/edhrec_commander_api_response_display_widget.h" -#include +#include +#include #include +#include + +class EdhrecCommanderApiResponseDisplayWidget; +class QNetworkAccessManager; +class QNetworkReply; +class TabSupervisor; class TabEdhRec : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.cpp b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.cpp index 500eab13a..ca575dc02 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.cpp +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.cpp @@ -1,6 +1,9 @@ #include "tab_edhrec_main.h" #include "../../../../../client/settings/cache_settings.h" +#include "../../../../deck_loader/loaded_deck.h" +#include "../../../cards/card_size_widget.h" +#include "../../../quick_settings/settings_button_widget.h" #include "../../../utility/completer_utils.h" #include "../../tab_supervisor.h" #include "api_response/average_deck/edhrec_average_deck_api_response.h" @@ -18,13 +21,17 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include +#include #include #include @@ -134,6 +141,8 @@ void TabEdhRecMain::setCard(CardInfoPtr _cardToQuery, bool isCommander) return; } + emit tabTextChanged(this, getTabText()); + QString cardName = cardToQuery->getName(); QString formattedName = cardName.toLower().replace(" ", "-").remove(QRegularExpression("[^a-z0-9\\-]")); diff --git a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.h b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.h index a7ed83efd..5d0245ed4 100644 --- a/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.h +++ b/cockatrice/src/interface/widgets/tabs/api/edhrec/tab_edhrec_main.h @@ -7,16 +7,25 @@ #ifndef TAB_EDHREC_MAIN_H #define TAB_EDHREC_MAIN_H -#include "../../interface/widgets/cards/card_size_widget.h" -#include "../../interface/widgets/quick_settings/settings_button_widget.h" #include "../../tab.h" -#include "display/commander/edhrec_commander_api_response_display_widget.h" +#include "libcockatrice/card/card_info.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include + +class CardSizeWidget; +class EdhrecCommanderApiResponseDisplayWidget; +class QHBoxLayout; +class QLineEdit; +class QNetworkAccessManager; +class QNetworkReply; +class QPushButton; +class QVBoxLayout; +class QWidget; +class SettingsButtonWidget; +class TabSupervisor; class TabEdhRecMain : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/tab.cpp b/cockatrice/src/interface/widgets/tabs/tab.cpp index 3dcb3b523..5ef4d18b8 100644 --- a/cockatrice/src/interface/widgets/tabs/tab.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab.cpp @@ -1,12 +1,17 @@ #include "tab.h" #include "../interface/widgets/cards/card_info_display_widget.h" +#include "libcockatrice/utility/card_ref.h" #include "tab_supervisor.h" #include -#include -#include +#include +#include +#include #include +#include +#include +#include Tab::Tab(TabSupervisor *_tabSupervisor) : QMainWindow(_tabSupervisor), tabSupervisor(_tabSupervisor), contentsChanged(false), infoPopup(0) diff --git a/cockatrice/src/interface/widgets/tabs/tab.h b/cockatrice/src/interface/widgets/tabs/tab.h index bddf325e2..e114f9bd9 100644 --- a/cockatrice/src/interface/widgets/tabs/tab.h +++ b/cockatrice/src/interface/widgets/tabs/tab.h @@ -7,12 +7,16 @@ #ifndef TAB_H #define TAB_H +#include #include +#include #include +#include class QMenu; class TabSupervisor; class CardInfoDisplayWidget; +class QPoint; class Tab : public QMainWindow { diff --git a/cockatrice/src/interface/widgets/tabs/tab_account.cpp b/cockatrice/src/interface/widgets/tabs/tab_account.cpp index dbcf50966..e55dc55d0 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_account.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_account.cpp @@ -6,10 +6,17 @@ #include "../interface/widgets/server/user/user_list_manager.h" #include "../interface/widgets/server/user/user_list_widget.h" #include "../interface/widgets/utility/custom_line_edit.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include "tab_supervisor.h" +#include +#include +#include #include +#include #include +#include #include #include #include @@ -19,6 +26,7 @@ #include #include #include +#include TabAccount::TabAccount(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User &userInfo) : Tab(_tabSupervisor), client(_client) diff --git a/cockatrice/src/interface/widgets/tabs/tab_account.h b/cockatrice/src/interface/widgets/tabs/tab_account.h index 68054c7a1..ab2c4b38d 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_account.h +++ b/cockatrice/src/interface/widgets/tabs/tab_account.h @@ -9,11 +9,16 @@ #include "tab.h" +#include +#include +#include +// IWYU pragma: keep +// ServerInfo_User appears by value and inside QList in slot signatures, so the +// moc-generated code needs the complete type. #include class AbstractClient; class Event_AddToList; -class Event_ListRooms; class Event_RemoveFromList; class Event_UserJoined; class Event_UserLeft; @@ -23,6 +28,8 @@ class Response; class ServerInfo_User; class UserInfoBox; class UserListWidget; +class TabSupervisor; +template class QList; class TabAccount : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/tab_admin.cpp b/cockatrice/src/interface/widgets/tabs/tab_admin.cpp index 16f17e03e..cfbd00538 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_admin.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_admin.cpp @@ -1,19 +1,31 @@ #include "tab_admin.h" +#include "libcockatrice/protocol/pb/response.pb.h" + #include #include #include +#include #include #include #include #include #include +#include +#include +#include #include #include #include #include #include #include +#include +#include + +class CommandContainer; +class QVariant; +class TabSupervisor; ShutdownDialog::ShutdownDialog(QWidget *parent) : QDialog(parent) { diff --git a/cockatrice/src/interface/widgets/tabs/tab_admin.h b/cockatrice/src/interface/widgets/tabs/tab_admin.h index 0da098ba5..8eb139a8e 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_admin.h +++ b/cockatrice/src/interface/widgets/tabs/tab_admin.h @@ -10,15 +10,17 @@ #include "tab.h" #include -#include -#include +#include +#include class AbstractClient; - class QGroupBox; class QPushButton; class QSpinBox; class QLineEdit; +class QWidget; +class Response; +class TabSupervisor; class ShutdownDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.cpp b/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.cpp index 999bc3db0..1fc2854ce 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.cpp @@ -1,16 +1,39 @@ #include "tab_card_art_rules.h" #include "../utility/completer_utils.h" +#include "card_database_display_model.h" +#include "card_database_model.h" +#include "libcockatrice/card/card_info.h" #include "libcockatrice/card/database/card_database_manager.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include +#include #include #include #include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include #include #include +#include + +class QObject; +class TabSupervisor; CardArtRulesModel::CardArtRulesModel(AbstractClient *client, QObject *parent) : QAbstractTableModel(parent), client(client) diff --git a/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.h b/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.h index b9ea2ca83..f34300179 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.h +++ b/cockatrice/src/interface/widgets/tabs/tab_card_art_rules.h @@ -1,16 +1,28 @@ #ifndef COCKATRICE_DLG_CARD_ART_RULES_H #define COCKATRICE_DLG_CARD_ART_RULES_H -#include "card/card_search_model.h" -#include "tab_supervisor.h" +#include "tab.h" #include -#include -#include -#include -#include +#include +#include +#include +#include +#include class AbstractClient; +class CardCompleterProxyModel; +class CardDatabaseDisplayModel; +class CardDatabaseModel; +class CardSearchModel; +class QComboBox; +class QCompleter; +class QLineEdit; +class QObject; +class QPushButton; +class QTableView; +class Response; +class TabSupervisor; class CardArtRulesModel : public QAbstractTableModel { diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_editor.cpp b/cockatrice/src/interface/widgets/tabs/tab_deck_editor.cpp index 8439aef70..7ca179cea 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_deck_editor.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_deck_editor.cpp @@ -2,28 +2,28 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../deck_editor/deck_editor_card_database_dock_widget.h" +#include "../deck_editor/deck_editor_card_info_dock_widget.h" +#include "../deck_editor/deck_editor_deck_dock_widget.h" +#include "../deck_editor/deck_editor_printing_selector_dock_widget.h" #include "../deck_editor/deck_state_manager.h" -#include "../filters/filter_builder.h" -#include "../interface/pixel_map_generator.h" -#include "../interface/widgets/cards/card_info_frame_widget.h" #include "../interface/widgets/deck_editor/deck_editor_filter_dock_widget.h" #include "../interface/widgets/menus/deck_editor_menu.h" -#include "tab_supervisor.h" #include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include +#include + +class TabSupervisor; /** * @brief Constructs a new TabDeckEditor object. diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_editor.h b/cockatrice/src/interface/widgets/tabs/tab_deck_editor.h index 14be59cd7..afe62e962 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_deck_editor.h +++ b/cockatrice/src/interface/widgets/tabs/tab_deck_editor.h @@ -1,17 +1,11 @@ #ifndef WINDOW_DECKEDITOR_H #define WINDOW_DECKEDITOR_H -#include "../../key_signals.h" -#include "../interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h" #include "abstract_tab_deck_editor.h" -#include +#include -class CardDatabaseModel; -class CardDatabaseDisplayModel; -class DeckListModel; - -class QLabel; +class TabSupervisor; /** * @class TabDeckEditor diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp index 41ebb17a2..44d04bd24 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.cpp @@ -1,32 +1,55 @@ #include "tab_deck_storage.h" #include "../../../client/settings/cache_settings.h" +#include "../../deck_loader/deck_file_format.h" #include "../../deck_loader/deck_loader.h" +#include "../../deck_loader/loaded_deck.h" #include "../../pixel_map_generator.h" #include "../cards/additional_info/deck_color_identity.h" #include "../deck_share/deck_share_utils.h" #include "../deck_share/share_bar_widget.h" #include "../interface/widgets/server/remote/remote_decklist_tree_widget.h" #include "../interface/widgets/utility/get_text_with_max.h" +#include "abstract_client.h" +#include "libcockatrice/protocol/pb/commands.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" +#include +#include #include #include -#include #include #include #include +#include +#include #include +#include #include #include #include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include +#include +#include +#include #include #include #include @@ -38,12 +61,17 @@ #include #include #include -#include #include #include #include #include #include +#include +#include +#include +#include + +class TabSupervisor; namespace { diff --git a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h index f8d585880..35a4649c7 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h +++ b/cockatrice/src/interface/widgets/tabs/tab_deck_storage.h @@ -11,22 +11,26 @@ #include "../interface/widgets/server/remote/remote_decklist_tree_widget.h" #include "tab.h" +#include +#include #include +#include #include +#include struct LoadedDeck; class ServerInfo_User; -class AbstractClient; class QTreeView; class QFileSystemModel; class QToolBar; -class QTreeWidget; -class QTreeWidgetItem; class QGroupBox; class QTimer; class CommandContainer; class Response; class ShareBarWidget; +class QAction; +class QModelIndex; +class TabSupervisor; class TabDeckStorage : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/tab_developer.cpp b/cockatrice/src/interface/widgets/tabs/tab_developer.cpp index 39652ef7d..d641a1ea5 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_developer.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_developer.cpp @@ -6,21 +6,35 @@ #include "tab_developer.h" +#include "libcockatrice/protocol/pb/response.pb.h" + +#include #include #include +#include #include #include #include +#include #include +#include +#include #include #include +#include #include #include +#include +#include #include +#include #include #include #include #include +#include + +class TabSupervisor; static constexpr int DEFAULT_AUTO_REFRESH_INTERVAL_SECS = 30; diff --git a/cockatrice/src/interface/widgets/tabs/tab_developer.h b/cockatrice/src/interface/widgets/tabs/tab_developer.h index 727a56bcb..1a4e5904f 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_developer.h +++ b/cockatrice/src/interface/widgets/tabs/tab_developer.h @@ -9,6 +9,10 @@ #include "tab.h" +#include +#include +#include + class AbstractClient; class QCheckBox; class QLabel; @@ -17,6 +21,7 @@ class QSpinBox; class QTableWidget; class QTimer; class Response; +class TabSupervisor; class TabDeveloper : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.cpp b/cockatrice/src/interface/widgets/tabs/tab_game.cpp index 23976340b..4cf5919ba 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_game.cpp @@ -2,11 +2,16 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../../../game/abstract_game.h" +#include "../../../game/game_event_handler.h" +#include "../../../game/game_meta_info.h" +#include "../../../game/game_state.h" +#include "../../../game/player/player_info.h" +#include "../../../game/player/player_manager.h" +#include "../../../game_graphics/board/abstract_card_item.h" #include "../game/game.h" #include "../game/player/player_logic.h" #include "../game/replay.h" -#include "../game_graphics/board/arrow_item.h" -#include "../game_graphics/board/card_item.h" #include "../game_graphics/deckview/deck_view_container.h" #include "../game_graphics/deckview/tabbed_deck_view_container.h" #include "../game_graphics/game_scene.h" @@ -25,37 +30,48 @@ #include "../interface/widgets/server/user/user_list_manager.h" #include "../interface/widgets/utility/completer_utils.h" #include "../interface/widgets/utility/line_edit_completer.h" -#include "../interface/window_main.h" #include "../main.h" +#include "../menus/tearoff_menu.h" +#include "../replay/replay_widget.h" #include "../utility/visibility_change_listener.h" #include "card/card_completer_proxy_model.h" #include "card/card_search_model.h" #include "card_database_display_model.h" #include "card_database_model.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" +#include "libcockatrice/utility/card_ref.h" #include "tab_supervisor.h" #include #include #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include +#include #include #include #include -#include +#include #include #include -#include -#include #include #include #include @@ -63,6 +79,18 @@ #include #include #include +#include +#include +#include + +class Event_GameJoined; +namespace google +{ +namespace protobuf +{ +class Message; +} // namespace protobuf +} // namespace google TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay) : Tab(_tabSupervisor), sayLabel(nullptr), sayEdit(nullptr) @@ -1032,6 +1060,12 @@ void TabGame::setCardMenu(CardMenu *menu) return; } + if (aCardMenu->menu() && aCardMenu->menu()->isVisible()) { + aCardMenu->menu()->hide(); + if (gameView && gameView->viewport()) { + gameView->viewport()->update(); + } + } if (menu) { aCardMenu->setMenu(menu); } else { diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.h b/cockatrice/src/interface/widgets/tabs/tab_game.h index 29a2f40a3..7bc52202f 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.h +++ b/cockatrice/src/interface/widgets/tabs/tab_game.h @@ -9,47 +9,55 @@ #ifndef TAB_GAME_H #define TAB_GAME_H -#include "../game/abstract_game.h" -#include "../game/player/player_logic.h" -#include "../game_graphics/log/message_log_widget.h" -#include "../interface/widgets/menus/tearoff_menu.h" -#include "../interface/widgets/replay/replay_widget.h" #include "tab.h" -#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include +// IWYU pragma: keep +// ServerInfo_User appears by value and inside QList in slot signatures, so the +// moc-generated code needs the complete type. +#include class CardMenu; -class ServerInfo_PlayerProperties; class TabbedDeckViewContainer; +class AbstractGame; +class Event_GameJoined; +class GameEventContext; +class MessageLogWidget; +class PlayerLogic; +class QAction; +class QCompleter; +class QStringListModel; +class QWidget; +class ServerInfo_Player; +class ServerInfo_User; +class TabSupervisor; +class TearOffMenu; +struct CardRef; +struct LoadedDeck; + inline Q_LOGGING_CATEGORY(TabGameLog, "tab_game"); class UserListProxy; -class DeckViewContainer; class AbstractClient; -class CardDatabase; class GameView; class GameScene; class ReplayWidget; class CardInfoFrameWidget; -class QTimer; -class QSplitter; class QLabel; class QPushButton; -class QToolButton; class QMenu; -class ZoneViewLayout; -class ZoneViewWidget; class PhasesToolbar; class PlayerListWidget; -class ReplayTimelineWidget; -class CardZone; class AbstractCardItem; -class CardItem; class QVBoxLayout; -class QHBoxLayout; class GameReplay; class LineEditCompleter; class QDockWidget; diff --git a/cockatrice/src/interface/widgets/tabs/tab_home.cpp b/cockatrice/src/interface/widgets/tabs/tab_home.cpp index 7a79b1785..1358645d0 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_home.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_home.cpp @@ -1,5 +1,9 @@ #include "tab_home.h" +#include "../general/home_widget.h" + +class TabSupervisor; + TabHome::TabHome(TabSupervisor *_tabSupervisor, AbstractClient *_client) : Tab(_tabSupervisor), client(_client) { homeWidget = new HomeWidget(this, tabSupervisor); diff --git a/cockatrice/src/interface/widgets/tabs/tab_home.h b/cockatrice/src/interface/widgets/tabs/tab_home.h index 3aae19c2b..bc86348cb 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_home.h +++ b/cockatrice/src/interface/widgets/tabs/tab_home.h @@ -7,12 +7,14 @@ #ifndef TAB_HOME_H #define TAB_HOME_H -#include "../interface/widgets/general/home_widget.h" #include "tab.h" -#include +#include +#include class AbstractClient; +class HomeWidget; +class TabSupervisor; class TabHome : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/tab_logs.cpp b/cockatrice/src/interface/widgets/tabs/tab_logs.cpp index f73d06b57..9f17afea2 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_logs.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_logs.cpp @@ -1,23 +1,35 @@ #include "tab_logs.h" #include "../interface/widgets/utility/custom_line_edit.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_chat_message.pb.h" #include #include #include #include #include +#include #include #include #include +#include +#include #include #include #include +#include +#include +#include #include #include #include #include #include +#include +#include + +class TabSupervisor; TabLog::TabLog(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool _canUseDeveloperCommands) : Tab(_tabSupervisor), client(_client), canUseDeveloperCommands(_canUseDeveloperCommands) diff --git a/cockatrice/src/interface/widgets/tabs/tab_logs.h b/cockatrice/src/interface/widgets/tabs/tab_logs.h index 8e914ea64..fc8ef1ea0 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_logs.h +++ b/cockatrice/src/interface/widgets/tabs/tab_logs.h @@ -9,7 +9,8 @@ #include "tab.h" -#include +#include +#include class AbstractClient; class LineEditUnfocusable; @@ -24,9 +25,8 @@ class QWidget; class QGridLayout; class QVBoxLayout; class QTableWidget; -class CommandContainer; class Response; -class AbstractClient; +class TabSupervisor; class TabLog : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/tab_message.cpp b/cockatrice/src/interface/widgets/tabs/tab_message.cpp index 418843178..65186e396 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_message.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_message.cpp @@ -6,12 +6,18 @@ #include "../interface/widgets/server/user/user_list_manager.h" #include "../interface/widgets/utility/custom_line_edit.h" #include "../main.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "tab_supervisor.h" +#include #include -#include +#include #include +#include +#include #include #include +#include #include #include #include @@ -19,6 +25,7 @@ #include #include #include +#include TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, diff --git a/cockatrice/src/interface/widgets/tabs/tab_message.h b/cockatrice/src/interface/widgets/tabs/tab_message.h index 0e6d66d4c..bea58ecb3 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_message.h +++ b/cockatrice/src/interface/widgets/tabs/tab_message.h @@ -10,6 +10,13 @@ #include "tab.h" #include +#include +#include +#include + +class QAction; +class QMenu; +class TabSupervisor; inline Q_LOGGING_CATEGORY(TabMessageLog, "tab_message"); diff --git a/cockatrice/src/interface/widgets/tabs/tab_moderation.cpp b/cockatrice/src/interface/widgets/tabs/tab_moderation.cpp index b9c37f1af..09a640540 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_moderation.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_moderation.cpp @@ -1,8 +1,13 @@ #include "tab_moderation.h" #include "abstract_client.h" -#include "tab_supervisor.h" +#include "libcockatrice/protocol/pb/admin_commands.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_moderator_login.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user_alt.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user_session.pb.h" +#include #include #include #include @@ -10,12 +15,17 @@ #include #include #include +#include #include #include +#include #include +#include #include +#include #include #include +#include #include #include #include @@ -26,6 +36,10 @@ #include #include #include +#include +#include + +class TabSupervisor; namespace { diff --git a/cockatrice/src/interface/widgets/tabs/tab_moderation.h b/cockatrice/src/interface/widgets/tabs/tab_moderation.h index 0a534992b..e352e90bb 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_moderation.h +++ b/cockatrice/src/interface/widgets/tabs/tab_moderation.h @@ -3,7 +3,9 @@ #include "tab.h" -#include +#include +#include +#include class AbstractClient; class QGroupBox; @@ -12,6 +14,8 @@ class QLineEdit; class QPushButton; class QTableWidget; class QTextEdit; +class Response; +class TabSupervisor; /** * Staff investigation tool. Lets moderators look up a user's account data, diff --git a/cockatrice/src/interface/widgets/tabs/tab_public_decks.cpp b/cockatrice/src/interface/widgets/tabs/tab_public_decks.cpp index d13f9d1e3..6bf3f6be7 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_public_decks.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_public_decks.cpp @@ -2,6 +2,7 @@ #include "../../../client/settings/cache_settings.h" #include "../../deck_loader/deck_loader.h" +#include "../../deck_loader/loaded_deck.h" #include "../cards/card_size_widget.h" #include "../general/layout_containers/flow_widget.h" #include "../visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.h" @@ -12,14 +13,21 @@ #include "../visual_deck_storage/visual_deck_storage_tag_filter_widget.h" #include "tab_supervisor.h" -#include +#include +#include +#include +#include #include #include +#include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -27,6 +35,7 @@ #include #include #include +#include TabPublicDecks::TabPublicDecks(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_userName) : Tab(_tabSupervisor), client(_client), userName(_userName) diff --git a/cockatrice/src/interface/widgets/tabs/tab_public_decks.h b/cockatrice/src/interface/widgets/tabs/tab_public_decks.h index 492fdeafa..847479e78 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_public_decks.h +++ b/cockatrice/src/interface/widgets/tabs/tab_public_decks.h @@ -8,11 +8,13 @@ #include "tab.h" +#include +#include + class AbstractClient; class CommandContainer; class DeckPreviewColorIdentityFilterWidget; class FlowWidget; -class PublicDeckPreviewWidget; class QLabel; class QToolButton; class RemotePublicDecksModel; @@ -20,6 +22,7 @@ class Response; class VisualDeckStorageQuickSettingsWidget; class VisualDeckStorageSearchWidget; class VisualDeckStorageTagFilterWidget; +class TabSupervisor; /** * @brief A visual grid of the public decks published by another user. diff --git a/cockatrice/src/interface/widgets/tabs/tab_replays.cpp b/cockatrice/src/interface/widgets/tabs/tab_replays.cpp index e26bea2a3..52bc4cd8f 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_replays.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_replays.cpp @@ -3,22 +3,51 @@ #include "../../../client/settings/cache_settings.h" #include "../../pixel_map_generator.h" #include "../interface/widgets/server/remote/remote_replay_list_tree_widget.h" -#include "tab_game.h" +#include "libcockatrice/protocol/pb/commands.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_replay.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_replay_match.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" +#include +#include #include #include +#include #include +#include #include #include +#include +#include #include +#include #include #include #include +#include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include #include @@ -32,6 +61,11 @@ #include #include #include +#include +#include +#include + +class TabSupervisor; inline Q_LOGGING_CATEGORY(TabReplaysLog, "replays_tab"); diff --git a/cockatrice/src/interface/widgets/tabs/tab_replays.h b/cockatrice/src/interface/widgets/tabs/tab_replays.h index aa4ec039c..e29e29bd7 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_replays.h +++ b/cockatrice/src/interface/widgets/tabs/tab_replays.h @@ -10,19 +10,26 @@ #include "tab.h" +#include +#include #include +// IWYU pragma: keep +// GameReplay is a protobuf message passed through the openReplay signal, +// so the moc-generated code needs the complete type. +#include +#include class ServerInfo_User; class Response; -class AbstractClient; class QTreeView; class QFileSystemModel; -class QToolBar; class QGroupBox; class RemoteReplayList_TreeWidget; -class GameReplay; class Event_ReplayAdded; class CommandContainer; +class QAction; +class QModelIndex; +class TabSupervisor; class TabReplays : public Tab { diff --git a/cockatrice/src/interface/widgets/tabs/tab_report.cpp b/cockatrice/src/interface/widgets/tabs/tab_report.cpp index 0b9108f9b..9018e2477 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_report.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_report.cpp @@ -1,12 +1,18 @@ #include "tab_report.h" +#include "../server/user/user_context_menu.h" #include "../utility/report_utils.h" #include "abstract_client.h" +#include "libcockatrice/protocol/pb/response.pb.h" #include "tab_supervisor.h" +#include +#include #include #include #include +#include +#include #include #include #include @@ -15,21 +21,26 @@ #include #include #include -#include #include +#include #include #include #include +#include #include #include #include #include +#include #include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -41,6 +52,8 @@ #include #include #include +#include +#include namespace { @@ -110,6 +123,10 @@ TabReport::TabReport(TabSupervisor *_tabSupervisor, AbstractClient *_client) : T table->horizontalHeader()->setSectionResizeMode(COL_REPORTED, QHeaderView::Stretch); table->horizontalHeader()->setSectionResizeMode(COL_REPORTER, QHeaderView::ResizeToContents); connect(table, &QTableWidget::itemSelectionChanged, this, &TabReport::onSelectionChanged); + table->setContextMenuPolicy(Qt::CustomContextMenu); + connect(table, &QTableWidget::customContextMenuRequested, this, &TabReport::showTableContextMenu); + userContextMenu = new UserContextMenu(tabSupervisor, this); + connect(userContextMenu, &UserContextMenu::openMessageDialog, this, &TabReport::openMessageDialog); descGroup = new QGroupBox; descriptionEdit = new QTextEdit; @@ -221,14 +238,14 @@ TabReport::TabReport(TabSupervisor *_tabSupervisor, AbstractClient *_client) : T assignButton = new QPushButton; resolveButton = new QPushButton; - resolveWithNoteButton = new QPushButton; dismissButton = new QPushButton; + reopenButton = new QPushButton; viewReplayButton = new QPushButton; joinGameButton = new QPushButton; connect(assignButton, &QPushButton::clicked, this, &TabReport::assignReport); - connect(resolveButton, &QPushButton::clicked, this, [this]() { resolveReport(false, false); }); - connect(resolveWithNoteButton, &QPushButton::clicked, this, [this]() { resolveReport(false, true); }); - connect(dismissButton, &QPushButton::clicked, this, [this]() { resolveReport(true, true); }); + connect(resolveButton, &QPushButton::clicked, this, [this]() { resolveReport(false); }); + connect(dismissButton, &QPushButton::clicked, this, [this]() { resolveReport(true); }); + connect(reopenButton, &QPushButton::clicked, this, &TabReport::reopenReport); connect(viewReplayButton, &QPushButton::clicked, this, &TabReport::viewReplay); connect(joinGameButton, &QPushButton::clicked, this, &TabReport::joinGame); @@ -237,8 +254,8 @@ TabReport::TabReport(TabSupervisor *_tabSupervisor, AbstractClient *_client) : T auto *actionBar = new QHBoxLayout; actionBar->addWidget(assignButton); actionBar->addWidget(resolveButton); - actionBar->addWidget(resolveWithNoteButton); actionBar->addWidget(dismissButton); + actionBar->addWidget(reopenButton); actionBar->addSpacing(20); actionBar->addWidget(viewReplayButton); actionBar->addWidget(joinGameButton); @@ -262,6 +279,7 @@ TabReport::TabReport(TabSupervisor *_tabSupervisor, AbstractClient *_client) : T void TabReport::retranslateUi() { + userContextMenu->retranslateUi(); searchEdit->setPlaceholderText(tr("Search by username, category...")); statusFilter->clear(); statusFilter->addItem(tr("All Statuses"), ""); @@ -302,9 +320,10 @@ void TabReport::retranslateUi() statsGroup->setTitle(tr("Report Statistics")); assignButton->setText(tr("Assign to Me")); - resolveButton->setText(tr("Resolve")); - resolveWithNoteButton->setText(tr("Resolve with note...")); + resolveButton->setText(tr("Resolve...")); dismissButton->setText(tr("Dismiss...")); + reopenButton->setText(tr("Reopen...")); + reopenButton->setToolTip(tr("Available for resolved or dismissed reports.")); viewReplayButton->setText(tr("View Replay")); joinGameButton->setText(tr("Join Game")); } @@ -336,6 +355,7 @@ void TabReport::reportListResponse(const Response &response) refreshButton->setEnabled(true); if (response.response_code() != Response::RespOk) { + pendingStatusMessage.clear(); statusLabel->setText(tr("Failed to load reports.")); return; } @@ -349,6 +369,11 @@ void TabReport::reportListResponse(const Response &response) applyFilters(); updateStats(); + if (!pendingStatusMessage.isEmpty()) { + statusLabel->setText(pendingStatusMessage); + pendingStatusMessage.clear(); + } + if (selectedReportIdBeforeRefresh >= 0) { bool found = false; for (int row = 0; row < table->rowCount(); ++row) { @@ -484,6 +509,36 @@ void TabReport::onSelectionChanged() updateActionStates(); } +void TabReport::showTableContextMenu(const QPoint &pos) +{ + QTableWidgetItem *clickedItem = table->itemAt(pos); + if (!clickedItem || clickedItem->row() < 0) { + return; + } + + const int row = clickedItem->row(); + const QTableWidgetItem *reportedItem = table->item(row, COL_REPORTED); + const QTableWidgetItem *idItem = table->item(row, COL_ID); + if (!reportedItem || !idItem || reportedItem->text().isEmpty()) { + return; + } + + int userLevel = ServerInfo_User::IsUser; + const int reportId = idItem->data(Qt::UserRole).toInt(); + for (const ServerInfo_Report &r : filteredReports) { + if (r.report_id() == reportId) { + if (r.reported_user_level() != 0) { + userLevel = r.reported_user_level(); + } + break; + } + } + + table->selectRow(row); + userContextMenu->showContextMenu(table->viewport()->mapToGlobal(pos), reportedItem->text(), + UserLevelFlags(userLevel)); +} + void TabReport::loadReportDetails(int reportId) { detailsRequestedReportId = reportId; @@ -567,8 +622,8 @@ void TabReport::updateActionStates() const QString status = QString::fromStdString(report.status()); assignButton->setEnabled(status == "open"); resolveButton->setEnabled(status == "open" || status == "assigned"); - resolveWithNoteButton->setEnabled(status == "open" || status == "assigned"); dismissButton->setEnabled(status == "open" || status == "assigned"); + reopenButton->setEnabled(status == "resolved" || status == "dismissed"); const bool hasGameId = report.game_id() > 0; const bool hasReplay = hasGameId && report.has_replay_id() && report.replay_id() > 0; @@ -580,8 +635,8 @@ void TabReport::setActionsEnabled(bool enabled) { assignButton->setEnabled(enabled); resolveButton->setEnabled(enabled); - resolveWithNoteButton->setEnabled(enabled); dismissButton->setEnabled(enabled); + reopenButton->setEnabled(enabled); viewReplayButton->setEnabled(false); joinGameButton->setEnabled(false); commentButton->setEnabled(enabled); @@ -635,7 +690,7 @@ void TabReport::assignReport() void TabReport::assignResponse(const Response &response) { if (response.response_code() == Response::RespOk) { - statusLabel->setText(tr("Assigned.")); + pendingStatusMessage = tr("Assigned."); refreshList(); } else { statusLabel->setText(tr("Assignment failed.")); @@ -643,22 +698,19 @@ void TabReport::assignResponse(const Response &response) } } -void TabReport::resolveReport(bool dismissed, bool promptNote) +void TabReport::resolveReport(bool dismissed) { const int reportId = selectedReportId(); if (reportId < 0) { return; } - QString note; - if (promptNote) { - bool ok; - note = QInputDialog::getText(this, dismissed ? tr("Dismiss Report") : tr("Resolve Report"), - dismissed ? tr("Optional note:") : tr("Resolution note (optional):"), - QLineEdit::Normal, QString(), &ok); - if (!ok) { - return; - } + bool ok; + QString note = QInputDialog::getText(this, dismissed ? tr("Dismiss Report") : tr("Resolve Report"), + dismissed ? tr("Optional note:") : tr("Resolution note (optional):"), + QLineEdit::Normal, QString(), &ok); + if (!ok) { + return; } setActionsEnabled(false); @@ -679,7 +731,46 @@ void TabReport::resolveReport(bool dismissed, bool promptNote) void TabReport::resolveResponse(const Response &response) { if (response.response_code() == Response::RespOk) { - statusLabel->setText(tr("Done.")); + pendingStatusMessage = tr("Done."); + refreshList(); + } else { + statusLabel->setText(tr("Action failed.")); + updateActionStates(); + } +} + +void TabReport::reopenReport() +{ + const int reportId = selectedReportId(); + if (reportId < 0) { + return; + } + + bool ok; + QString note = QInputDialog::getText(this, tr("Reopen Report"), tr("Reopening note (optional):"), QLineEdit::Normal, + QString(), &ok); + if (!ok) { + return; + } + + setActionsEnabled(false); + statusLabel->setText(tr("Reopening...")); + + Command_ReportReopen cmd; + cmd.set_report_id(reportId); + if (!note.isEmpty()) { + cmd.set_reopen_note(note.toStdString()); + } + + PendingCommand *pend = client->prepareModeratorCommand(cmd); + connect(pend, &PendingCommand::finished, this, &TabReport::reopenResponse); + client->sendCommand(pend); +} + +void TabReport::reopenResponse(const Response &response) +{ + if (response.response_code() == Response::RespOk) { + pendingStatusMessage = tr("Reopened."); refreshList(); } else { statusLabel->setText(tr("Action failed.")); diff --git a/cockatrice/src/interface/widgets/tabs/tab_report.h b/cockatrice/src/interface/widgets/tabs/tab_report.h index b62a99ce2..32ebe1a3f 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_report.h +++ b/cockatrice/src/interface/widgets/tabs/tab_report.h @@ -4,8 +4,10 @@ #include "tab.h" #include -#include +#include +#include #include +#include class AbstractClient; class QCheckBox; @@ -19,6 +21,9 @@ class QTableWidget; class QTextEdit; class QTimer; class GameReplay; +class Response; +class TabSupervisor; +class UserContextMenu; class TabReport : public Tab { @@ -34,15 +39,17 @@ public: signals: void openReplay(GameReplay *replay); void requestJoinGame(int gameId, int roomId); + void openMessageDialog(const QString &userName, bool focus); private slots: void refreshList(); void reportListResponse(const Response &response); void assignReport(); void assignResponse(const Response &response); - void resolveReport(bool dismissed, bool promptNote); + void resolveReport(bool dismissed); void resolveResponse(const Response &response); void onSelectionChanged(); + void showTableContextMenu(const QPoint &pos); void viewReplay(); void viewReplayResponse(const Response &response); void joinGame(); @@ -53,6 +60,8 @@ private slots: void reportDetailsResponse(const Response &response); void requestStats(); void statsResponse(const Response &response); + void reopenReport(); + void reopenResponse(const Response &response); private: int selectedReportId() const; @@ -82,12 +91,13 @@ private: QPushButton *commentButton; QPushButton *assignButton; QPushButton *resolveButton; - QPushButton *resolveWithNoteButton; QPushButton *dismissButton; + QPushButton *reopenButton; QPushButton *viewReplayButton; QPushButton *joinGameButton; QLabel *statusLabel; QTimer *refreshTimer; + UserContextMenu *userContextMenu; QGroupBox *userContextGroup; QLabel *userContextName; @@ -105,6 +115,7 @@ private: QLabel *userContextNotesLabel; QLabel *userContextRecentReportsLabel; QString lastRequestedUser; + QString pendingStatusMessage; QGroupBox *statsGroup; QLabel *statsTotalLabel; QLabel *statsTrendLabel; diff --git a/cockatrice/src/interface/widgets/tabs/tab_room.cpp b/cockatrice/src/interface/widgets/tabs/tab_room.cpp index 866324367..67106ba34 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_room.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_room.cpp @@ -11,27 +11,39 @@ #include "../interface/widgets/server/user/user_list_panel_widget.h" #include "../interface/widgets/server/user/user_list_widget.h" #include "../main.h" +#include "../server/game_type_map.h" +#include "../server/user/user_list_proxy.h" #include "../utility/completer_utils.h" +#include "../utility/line_edit_completer.h" #include "card/card_completer_proxy_model.h" #include "card/card_search_model.h" #include "card_database_display_model.h" #include "card_database_model.h" -#include "tab_account.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/room_event.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_gametype.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include "tab_supervisor.h" +#include "user_level.h" +#include #include +#include #include +#include +#include +#include +#include #include #include -#include -#include #include #include #include +#include #include #include #include -#include +#include #include #include #include @@ -46,6 +58,8 @@ #include #include #include +#include +#include TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, diff --git a/cockatrice/src/interface/widgets/tabs/tab_room.h b/cockatrice/src/interface/widgets/tabs/tab_room.h index 7d01d5cf6..031056145 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_room.h +++ b/cockatrice/src/interface/widgets/tabs/tab_room.h @@ -8,16 +8,21 @@ #ifndef TAB_ROOM_H #define TAB_ROOM_H -#include "../interface/widgets/utility/line_edit_completer.h" #include "tab.h" -#include -#include +#include #include -#include +#include +#include +#include class UserListProxy; -class UserListManager; +class QAction; +class QGroupBox; +class QMenu; +class QStringListModel; +class TabSupervisor; + namespace google { namespace protobuf @@ -30,12 +35,9 @@ class UserListWidget; class UserListPanelWidget; class QLabel; class ChatView; -class QPushButton; -class QTextTable; class QCompleter; class RoomEvent; class ServerInfo_Room; -class ServerInfo_Game; class Event_ListGames; class Event_JoinRoom; class Event_LeaveRoom; diff --git a/cockatrice/src/interface/widgets/tabs/tab_server.cpp b/cockatrice/src/interface/widgets/tabs/tab_server.cpp index fca32094c..0f3e76c76 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_server.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_server.cpp @@ -1,14 +1,20 @@ #include "tab_server.h" -#include "../interface/widgets/server/user/user_list_widget.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_room.pb.h" #include "tab_supervisor.h" #include #include -#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -16,6 +22,9 @@ #include #include #include +#include + +class TabRoom; RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) : QGroupBox(parent), client(_client) { diff --git a/cockatrice/src/interface/widgets/tabs/tab_server.h b/cockatrice/src/interface/widgets/tabs/tab_server.h index 121ff814d..eb2f572fe 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_server.h +++ b/cockatrice/src/interface/widgets/tabs/tab_server.h @@ -12,20 +12,21 @@ #include #include #include -#include -#include +#include +#include +#include class AbstractClient; -class QTextEdit; -class QLabel; -class UserListWidget; class QPushButton; - class Event_ListRooms; class Event_ServerMessage; class Response; class ServerInfo_Room; class CommandContainer; +class QTextBrowser; +class QTreeWidget; +class QWidget; +class TabSupervisor; class RoomSelector : public QGroupBox { diff --git a/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp b/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp index 0dc246eaa..2352d7d7b 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_supervisor.cpp @@ -2,14 +2,27 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include "../../../game/abstract_game.h" +#include "../../../game/game_event_handler.h" +#include "../../../game/game_meta_info.h" +#include "../../deck_loader/loaded_deck.h" +#include "../../intents/contexts/context_connect_to_server.h" +#include "../../intents/contexts/context_join_game.h" +#include "../../intents/contexts/context_join_room.h" +#include "../../intents/intent.h" #include "../../intents/intent_join_server_game.h" #include "../interface/pixel_map_generator.h" #include "../interface/widgets/server/game_link.h" #include "../interface/widgets/server/user/user_list_manager.h" -#include "../interface/widgets/server/user/user_list_widget.h" #include "../main.h" +#include "abstract_tab_deck_editor.h" #include "api/archidekt/tab_archidekt.h" +#include "api/edhrec/tab_edhrec.h" #include "api/edhrec/tab_edhrec_main.h" +#include "latency_tracker.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_gametype.pb.h" +#include "tab.h" #include "tab_account.h" #include "tab_admin.h" #include "tab_card_art_rules.h" @@ -27,14 +40,31 @@ #include "tab_room.h" #include "tab_server.h" #include "tab_visual_database_display.h" +#include "user_level.h" #include "visual_deck_editor/tab_deck_editor_visual.h" -#include "visual_deck_editor/tab_deck_editor_visual_tab_widget.h" #include "visual_deck_storage/tab_deck_storage_visual.h" +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include #include +#include #include #include #include @@ -45,11 +75,16 @@ #include #include #include -#include #include #include #include #include +#include +#include +#include +#include + +class QWidget; QRect MacOSTabFixStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const { @@ -884,6 +919,7 @@ void TabSupervisor::openTabReport() myAddTab(tabReport, aTabReport); connect(tabReport, &TabReport::openReplay, this, &TabSupervisor::openReplay); connect(tabReport, &TabReport::requestJoinGame, this, &TabSupervisor::joinReportGame); + connect(tabReport, &TabReport::openMessageDialog, this, &TabSupervisor::addMessageTab); connect(tabReport, &QObject::destroyed, this, [this] { tabReport = nullptr; aTabReport->setChecked(false); diff --git a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h index 1a4f7f749..9c7dc48d1 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_supervisor.h +++ b/cockatrice/src/interface/widgets/tabs/tab_supervisor.h @@ -8,29 +8,36 @@ #ifndef TAB_SUPERVISOR_H #define TAB_SUPERVISOR_H -#include "../../deck_loader/deck_loader.h" #include "../interface/widgets/server/game_link.h" -#include "../interface/widgets/server/user/user_list_proxy.h" -#include "abstract_tab_deck_editor.h" -#include "api/archidekt/tab_archidekt.h" -#include "api/edhrec/tab_edhrec.h" -#include "api/edhrec/tab_edhrec_main.h" -#include "tab_visual_database_display.h" -#include "visual_deck_editor/tab_deck_editor_visual.h" -#include "visual_deck_storage/tab_deck_storage_visual.h" +#include "libcockatrice/card/card_info.h" #include +#include #include #include +#include #include +#include +#include #include #include +#include class TabCardArtRules; +class AbstractTabDeckEditor; +class QAction; +class QWidget; +class TabArchidekt; +class TabDeckEditorVisual; +class TabDeckStorageVisual; +class TabEdhRec; +class TabEdhRecMain; +class TabVisualDatabaseDisplay; +struct LoadedDeck; + inline Q_LOGGING_CATEGORY(TabSupervisorLog, "tab_supervisor"); class UserListManager; -class QMenu; class AbstractClient; class Tab; class TabServer; @@ -56,7 +63,6 @@ class Event_NotifyUser; class ServerInfo_Room; class ServerInfo_User; class GameReplay; -class DeckList; class MacOSTabFixStyle : public QProxyStyle { diff --git a/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.cpp b/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.cpp index 3112e7ada..f4b007072 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.cpp @@ -1,6 +1,7 @@ #include "tab_visual_database_display.h" -#include "tab_deck_editor.h" +#include "../visual_database_display/visual_database_display_widget.h" +#include "card_database_model.h" #include "tab_supervisor.h" #include diff --git a/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.h b/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.h index 3a4bcd6ea..31633f10c 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.h +++ b/cockatrice/src/interface/widgets/tabs/tab_visual_database_display.h @@ -8,8 +8,14 @@ #define TAB_VISUAL_DATABASE_DISPLAY_H #include "../interface/widgets/visual_database_display/visual_database_display_widget.h" +#include "libcockatrice/card/card_info.h" #include "tab.h" +#include +#include + +class TabSupervisor; + class TabVisualDatabaseDisplay : public Tab { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp index 0f43893d3..be7255dc3 100644 --- a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp +++ b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.cpp @@ -2,37 +2,53 @@ #include "../../../../client/settings/cache_settings.h" #include "../../../../client/settings/shortcuts_settings.h" -#include "../../cards/card_info_display_widget.h" +#include "../../../deck_loader/loaded_deck.h" +#include "../../deck_editor/deck_editor_card_database_dock_widget.h" +#include "../../deck_editor/deck_editor_card_info_dock_widget.h" +#include "../../deck_editor/deck_editor_deck_dock_widget.h" +#include "../../deck_editor/deck_editor_filter_dock_widget.h" +#include "../../deck_editor/deck_editor_printing_selector_dock_widget.h" #include "../../deck_editor/deck_state_manager.h" #include "../../deck_editor/deck_zone_dialog.h" -#include "../../filters/filter_builder.h" -#include "../../interface/pixel_map_generator.h" -#include "../../interface/widgets/cards/card_info_frame_widget.h" #include "../../interface/widgets/deck_analytics/deck_analytics_widget.h" #include "../../interface/widgets/visual_deck_editor/visual_deck_editor_widget.h" -#include "../tab_deck_editor.h" +#include "../../menus/deck_editor_menu.h" +#include "../../visual_database_display/visual_database_display_widget.h" +#include "../../visual_deck_editor/visual_deck_editor_sample_hand_widget.h" #include "../tab_supervisor.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" #include "tab_deck_editor_visual_tab_widget.h" #include -#include -#include -#include +#include +#include +#include #include -#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include -#include -#include -#include +#include +#include +#include +#include #include #include #include +#include +#include #include -#include -#include #include #include +#include +#include /** * @brief Constructs the TabDeckEditorVisual instance. diff --git a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.h b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.h index fb09578c4..f5eb9981a 100644 --- a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.h +++ b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual.h @@ -1,8 +1,19 @@ #ifndef WINDOW_DECKEDITORVISUAL_H #define WINDOW_DECKEDITORVISUAL_H -#include "../tab.h" -#include "tab_deck_editor_visual_tab_widget.h" +#include "../abstract_tab_deck_editor.h" + +#include +#include +#include + +class ExactCard; +class QDockWidget; +class QHBoxLayout; +class QVBoxLayout; +class QWidget; +class TabDeckEditorVisualTabWidget; +class TabSupervisor; /** * @class TabDeckEditorVisual diff --git a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.cpp b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.cpp index 5ccfcc28f..8e01ff983 100644 --- a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.cpp +++ b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.cpp @@ -1,7 +1,24 @@ #include "tab_deck_editor_visual_tab_widget.h" +#include "../../deck_analytics/deck_analytics_widget.h" +#include "../../deck_analytics/deck_list_statistics_analyzer.h" +#include "../../deck_editor/deck_editor_deck_dock_widget.h" #include "../../interface/widgets/visual_database_display/visual_database_display_widget.h" +#include "../../visual_deck_editor/visual_deck_editor_sample_hand_widget.h" +#include "../../visual_deck_editor/visual_deck_editor_widget.h" #include "../abstract_tab_deck_editor.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" + +#include +#include +#include +#include +#include + +class CardDatabaseModel; +class DeckListModel; +class QMouseEvent; /** * @brief Constructs the TabDeckEditorVisualTabWidget. diff --git a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.h b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.h index 4f04b51f6..fff978f42 100644 --- a/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.h +++ b/cockatrice/src/interface/widgets/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.h @@ -1,16 +1,25 @@ #ifndef TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H #define TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H -#include "../../interface/widgets/deck_analytics/deck_analytics_widget.h" -#include "../../interface/widgets/printing_selector/printing_selector.h" -#include "../../interface/widgets/visual_database_display/visual_database_display_widget.h" -#include "../../interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h" -#include "../../interface/widgets/visual_deck_editor/visual_deck_editor_widget.h" -#include "../abstract_tab_deck_editor.h" +#include "libcockatrice/card/card_info.h" +#include +#include #include -#include -#include +#include + +class AbstractTabDeckEditor; +class CardDatabaseModel; +class DeckAnalyticsWidget; +class DeckListModel; +class DeckListStatisticsAnalyzer; +class ExactCard; +class PrintingSelector; +class QVBoxLayout; +class QWidget; +class VisualDatabaseDisplayWidget; +class VisualDeckEditorSampleHandWidget; +class VisualDeckEditorWidget; /** * @class TabDeckEditorVisualTabWidget diff --git a/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.cpp b/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.cpp index 03df76b03..cb6dfab9c 100644 --- a/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.cpp +++ b/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.cpp @@ -1,23 +1,30 @@ #include "tab_deck_storage_visual.h" #include "../../../../client/settings/cache_settings.h" +#include "../../../deck_loader/deck_file_format.h" #include "../../../deck_loader/deck_loader.h" +#include "../../../deck_loader/loaded_deck.h" #include "../../cards/additional_info/deck_color_identity.h" #include "../../deck_share/deck_share_utils.h" +#include "../../deck_share/share_bar_widget.h" #include "../../interface/widgets/visual_deck_storage/visual_deck_storage_widget.h" +#include "../tab.h" #include "../tab_supervisor.h" #include #include #include +#include +#include #include #include #include #include #include -#include #include #include +#include +#include TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor, AbstractClient *_client) : Tab(_tabSupervisor), visualDeckStorageWidget(new VisualDeckStorageWidget(this)), client(_client), diff --git a/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.h b/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.h index 7cd4e7d17..13a078fce 100644 --- a/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.h +++ b/cockatrice/src/interface/widgets/tabs/visual_deck_storage/tab_deck_storage_visual.h @@ -10,22 +10,18 @@ #include "../../deck_share/share_bar_widget.h" #include "../tab.h" +#include +#include #include #include +#include struct LoadedDeck; -class AbstractClient; class CommandContainer; -class DeckPreviewWidget; -class QFileSystemModel; -class QGroupBox; class QTimer; -class QToolBar; -class QTreeView; -class QTreeWidget; -class QTreeWidgetItem; class Response; class VisualDeckStorageWidget; +class TabSupervisor; class TabDeckStorageVisual final : public Tab { diff --git a/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp b/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp index 29bf2263e..8042fb9fc 100644 --- a/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp +++ b/cockatrice/src/interface/widgets/utility/card_completer_delegate.cpp @@ -2,18 +2,42 @@ #include "../../pixel_map_generator.h" #include "../cards/additional_info/mana_cost_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/set/card_set.h" +#include +#include +#include +#include #include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include +#include +#include #include #include #include #include +#include + +class QObject; +template class QSharedPointer; // --------------------------------------------------------------------------- // Internal colour helpers diff --git a/cockatrice/src/interface/widgets/utility/card_completer_delegate.h b/cockatrice/src/interface/widgets/utility/card_completer_delegate.h index 78667f56b..ad81d86e4 100644 --- a/cockatrice/src/interface/widgets/utility/card_completer_delegate.h +++ b/cockatrice/src/interface/widgets/utility/card_completer_delegate.h @@ -9,10 +9,16 @@ #include #include -#include +#include #include +#include class CardInfo; +class QObject; +class QPainter; +class QPoint; +class QRect; +template class QSharedPointer; /** * @brief Paints styled card completer popup rows. diff --git a/cockatrice/src/interface/widgets/utility/card_completer_styler.cpp b/cockatrice/src/interface/widgets/utility/card_completer_styler.cpp index 6794ccbb4..1ddcc4200 100644 --- a/cockatrice/src/interface/widgets/utility/card_completer_styler.cpp +++ b/cockatrice/src/interface/widgets/utility/card_completer_styler.cpp @@ -2,20 +2,37 @@ #include "../cards/card_info_picture_enlarged_widget.h" #include "card_completer_delegate.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" #include "reversed_completer_model.h" +#include #include #include +#include #include #include +#include #include +#include #include +#include #include +#include #include +#include #include +#include +#include +#include +#include #include #include #include +#include +#include + +template class QSharedPointer; namespace { @@ -132,7 +149,9 @@ bool CardCompleterStyler::handlePopupKeyPress(QKeyEvent *event) const int newRow = qBound(0, currentRow + step, rowCount - 1); if (newRow != currentRow) { - popup->setCurrentIndex(completer->completionModel()->index(newRow, completer->completionColumn())); + const QModelIndex newIndex = completer->completionModel()->index(newRow, completer->completionColumn()); + popup->selectionModel()->setCurrentIndex(newIndex, + QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); } return true; @@ -161,7 +180,8 @@ void CardCompleterStyler::ensureClosestSelected() const int closestRow = rowCount - 1; if (currentRow != closestRow) { - popup->setCurrentIndex(completionModel->index(closestRow, completer->completionColumn())); + popup->selectionModel()->setCurrentIndex(completionModel->index(closestRow, completer->completionColumn()), + QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); } } diff --git a/cockatrice/src/interface/widgets/utility/card_completer_styler.h b/cockatrice/src/interface/widgets/utility/card_completer_styler.h index 616e3fe61..9245c9095 100644 --- a/cockatrice/src/interface/widgets/utility/card_completer_styler.h +++ b/cockatrice/src/interface/widgets/utility/card_completer_styler.h @@ -9,6 +9,7 @@ #include #include +#include class CardInfoPictureEnlargedWidget; class QCompleter; diff --git a/cockatrice/src/interface/widgets/utility/compact_push_button.cpp b/cockatrice/src/interface/widgets/utility/compact_push_button.cpp index cf98bfede..7df105d15 100644 --- a/cockatrice/src/interface/widgets/utility/compact_push_button.cpp +++ b/cockatrice/src/interface/widgets/utility/compact_push_button.cpp @@ -1,5 +1,9 @@ #include "compact_push_button.h" +#include +#include +#include + CompactPushButton::CompactPushButton(QWidget *parent) : QPushButton(parent) { setCheckable(true); diff --git a/cockatrice/src/interface/widgets/utility/compact_push_button.h b/cockatrice/src/interface/widgets/utility/compact_push_button.h index b0017beee..fa8c8080a 100644 --- a/cockatrice/src/interface/widgets/utility/compact_push_button.h +++ b/cockatrice/src/interface/widgets/utility/compact_push_button.h @@ -1,7 +1,12 @@ #ifndef COCKATRICE_COMPACT_PUSH_BUTTON_H #define COCKATRICE_COMPACT_PUSH_BUTTON_H +#include #include +#include +#include + +class QWidget; class CompactPushButton : public QPushButton { diff --git a/cockatrice/src/interface/widgets/utility/completer_utils.cpp b/cockatrice/src/interface/widgets/utility/completer_utils.cpp index 23ddb30b0..f1cd9c6a7 100644 --- a/cockatrice/src/interface/widgets/utility/completer_utils.cpp +++ b/cockatrice/src/interface/widgets/utility/completer_utils.cpp @@ -3,19 +3,66 @@ #include "../../../client/settings/cache_settings.h" #include "card_completer_styler.h" +#include #include #include +#include #include +#include +#include #include +#include #include +#include +#include +#include #include #include #include -#include #include +#include namespace { +/** + * @brief Paints the mention popup's current row with a visible highlight. + * + * A completer popup is a transient window that is usually not the application's + * active window, so the style paints a selected row using the palette's + * Inactive highlight group. Most themes set that colour close to the popup + * background, which hides the current completion entirely. Mirror the active + * highlight into the inactive group so the selection stays visible. + */ +class MentionCompleterDelegate : public QStyledItemDelegate +{ +public: + explicit MentionCompleterDelegate(QAbstractItemView *view) : QStyledItemDelegate(view), view(view) + { + } + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override + { + QStyleOptionViewItem opt = option; + opt.showDecorationSelected = true; + + if (view->currentIndex() == index) { + opt.state |= QStyle::State_HasFocus; + } + + if (opt.state & QStyle::State_Selected) { + opt.palette.setColor(QPalette::Inactive, QPalette::Highlight, + opt.palette.color(QPalette::Active, QPalette::Highlight)); + opt.palette.setColor(QPalette::Inactive, QPalette::HighlightedText, + opt.palette.color(QPalette::Active, QPalette::HighlightedText)); + } + + QStyledItemDelegate::paint(painter, opt, index); + } + +private: + QAbstractItemView *view; +}; + void applyCardSearchLanguage(CardSearchModel *searchModel) { const CardsDisplaySettings &cardsDisplay = SettingsCache::instance().cardsDisplay(); @@ -68,5 +115,11 @@ QCompleter *createMentionCompleter(QStringListModel *model, QObject *parent) completer->setCaseSensitivity(Qt::CaseInsensitive); completer->setMaxVisibleItems(5); completer->setFilterMode(Qt::MatchStartsWith); + + // Force the popup to be created so the highlight delegate can be installed; + // otherwise QCompleter's own delegate hides the selection on most themes. + QAbstractItemView *popup = completer->popup(); + popup->setItemDelegate(new MentionCompleterDelegate(popup)); + return completer; } diff --git a/cockatrice/src/interface/widgets/utility/custom_line_edit.cpp b/cockatrice/src/interface/widgets/utility/custom_line_edit.cpp index 05f56c275..d524041c3 100644 --- a/cockatrice/src/interface/widgets/utility/custom_line_edit.cpp +++ b/cockatrice/src/interface/widgets/utility/custom_line_edit.cpp @@ -3,11 +3,17 @@ #include "../../../client/settings/cache_settings.h" #include "../../../client/settings/shortcuts_settings.h" +#include +#include +#include #include +#include #include -#include +#include +#include #include -#include +#include +#include LineEditUnfocusable::LineEditUnfocusable(QWidget *parent) : QLineEdit(parent) { diff --git a/cockatrice/src/interface/widgets/utility/custom_line_edit.h b/cockatrice/src/interface/widgets/utility/custom_line_edit.h index 8c389b797..4d256d3dc 100644 --- a/cockatrice/src/interface/widgets/utility/custom_line_edit.h +++ b/cockatrice/src/interface/widgets/utility/custom_line_edit.h @@ -8,6 +8,7 @@ #define CUSTOMLINEEDIT_H #include +#include class QTreeView; class QKeyEvent; diff --git a/cockatrice/src/interface/widgets/utility/get_text_with_max.cpp b/cockatrice/src/interface/widgets/utility/get_text_with_max.cpp index 134352eb3..1a1bc924d 100644 --- a/cockatrice/src/interface/widgets/utility/get_text_with_max.cpp +++ b/cockatrice/src/interface/widgets/utility/get_text_with_max.cpp @@ -2,6 +2,8 @@ #include +class QWidget; + QString getTextWithMax(QWidget *parent, const QString &title, const QString &label, diff --git a/cockatrice/src/interface/widgets/utility/get_text_with_max.h b/cockatrice/src/interface/widgets/utility/get_text_with_max.h index 424bb0c6a..f1c89c703 100644 --- a/cockatrice/src/interface/widgets/utility/get_text_with_max.h +++ b/cockatrice/src/interface/widgets/utility/get_text_with_max.h @@ -8,8 +8,11 @@ #define GETTEXTWITHMAX_H #include -#include +#include #include +#include + +class QWidget; QString getTextWithMax(QWidget *parent, const QString &title, diff --git a/cockatrice/src/interface/widgets/utility/line_edit_completer.cpp b/cockatrice/src/interface/widgets/utility/line_edit_completer.cpp index 3a678029d..d692fb41b 100644 --- a/cockatrice/src/interface/widgets/utility/line_edit_completer.cpp +++ b/cockatrice/src/interface/widgets/utility/line_edit_completer.cpp @@ -1,8 +1,18 @@ #include "line_edit_completer.h" +#include #include +#include +#include #include +#include #include +#include +#include +#include +#include + +class QWidget; LineEditCompleter::LineEditCompleter(QWidget *parent) : LineEditUnfocusable(parent) { @@ -40,47 +50,99 @@ void LineEditCompleter::focusOutEvent(QFocusEvent *e) { LineEditUnfocusable::focusOutEvent(e); - // Only commit the highlighted completion when focus moves away via Tab. + // Commit completion when focus moves away via Tab if popup is visible. // Other focus losses (e.g. the unfocus shortcut / Escape) must simply close // the popup without inserting anything. - if (e->reason() != Qt::TabFocusReason) { - hideCompleterPopups(); + bool popupWasVisible = false; + for (auto &info : completers) { + if (info.completer->popup()->isVisible()) { + popupWasVisible = true; + const QModelIndex currentIndex = info.completer->popup()->currentIndex(); + QString completionText; + if (currentIndex.isValid()) { + completionText = currentIndex.data().toString(); + } else { + completionText = info.completer->currentCompletion(); + } + if (!completionText.isEmpty()) { + insertCompletion(info.completer, completionText); + } + } + } + hideCompleterPopups(); + + if (popupWasVisible && e->reason() == Qt::TabFocusReason) { + // Refocus the edit so Tab doesn't move focus away + // Use a queued connection to ensure focus is restored after the focus change completes + QMetaObject::invokeMethod(this, "setFocus", Qt::QueuedConnection); + e->accept(); return; } - for (auto &info : completers) { - if (!info.completer->popup()->isVisible()) { - continue; - } - - const QModelIndex currentIndex = info.completer->popup()->currentIndex(); - if (currentIndex.isValid()) { - insertCompletion(info.completer, currentIndex.data().toString()); - } + if (popupWasVisible) { + return; } - - hideCompleterPopups(); } void LineEditCompleter::keyPressEvent(QKeyEvent *event) { - LineEditUnfocusable::keyPressEvent(event); - if (event->key() == Qt::Key_Escape) { - hideCompleterPopups(); + if (hasVisibleCompleterPopup()) { + event->ignore(); + hideCompleterPopups(); + return; + } + LineEditUnfocusable::keyPressEvent(event); return; } + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter || event->key() == Qt::Key_Space) { + for (auto &info : completers) { + if (info.completer->popup()->isVisible()) { + event->ignore(); + const QModelIndex currentIndex = info.completer->popup()->currentIndex(); + QString completionText; + if (currentIndex.isValid()) { + completionText = currentIndex.data().toString(); + } else { + completionText = info.completer->currentCompletion(); + } + if (!completionText.isEmpty()) { + insertCompletion(info.completer, completionText); + } + hideCompleterPopups(); + return; + } + } + } + + if (event->key() == Qt::Key_Tab) { + // Let Tab proceed normally; focusOutEvent will handle completion if popup is visible + LineEditUnfocusable::keyPressEvent(event); + return; + } + + LineEditUnfocusable::keyPressEvent(event); + QString textValue = text(); int cursorPos = cursorPosition(); CompleterInfo *active = nullptr; QString prefix; + // An open "[[" card link takes precedence over a mention: while the cursor is + // inside it, an earlier "@" must not shadow the card completer. + const int openCardPos = textValue.lastIndexOf("[[", cursorPos - 1); + const int closeCardPos = openCardPos == -1 ? -1 : textValue.indexOf("]]", openCardPos + 2); + const bool insideCardLink = openCardPos != -1 && (closeCardPos == -1 || closeCardPos >= cursorPos); + for (auto &info : completers) { bool triggered = false; switch (info.trigger) { case CompleterTrigger::Mention: { + if (insideCardLink) { + break; + } int triggerPos = textValue.lastIndexOf("@", cursorPos - 1); if (triggerPos != -1 && (triggerPos == 0 || textValue[triggerPos - 1].isSpace())) { triggered = true; @@ -124,6 +186,17 @@ void LineEditCompleter::keyPressEvent(QKeyEvent *event) } active->completer->complete(); + + // The popup opens without a current row, so nothing is highlighted and there + // is no visual indication of what Enter will insert. Select the row that + // currentCompletion() would use so the current mention stays visible. + auto *completionModel = active->completer->completionModel(); + const int currentRow = active->completer->currentRow(); + if (currentRow >= 0 && currentRow < completionModel->rowCount()) { + active->completer->popup()->selectionModel()->setCurrentIndex( + completionModel->index(currentRow, active->completer->completionColumn()), + QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + } } void LineEditCompleter::insertCompletion(const QString &completion) diff --git a/cockatrice/src/interface/widgets/utility/line_edit_completer.h b/cockatrice/src/interface/widgets/utility/line_edit_completer.h index 369b7b553..c141682bf 100644 --- a/cockatrice/src/interface/widgets/utility/line_edit_completer.h +++ b/cockatrice/src/interface/widgets/utility/line_edit_completer.h @@ -10,12 +10,12 @@ #include "custom_line_edit.h" -#include -#include -#include #include #include -#include +#include + +class QCompleter; +class QWidget; enum class CompleterTrigger { diff --git a/cockatrice/src/interface/widgets/utility/report_utils.cpp b/cockatrice/src/interface/widgets/utility/report_utils.cpp index aa4558e5c..d7fc083c6 100644 --- a/cockatrice/src/interface/widgets/utility/report_utils.cpp +++ b/cockatrice/src/interface/widgets/utility/report_utils.cpp @@ -1,12 +1,20 @@ #include "report_utils.h" +#include "libcockatrice/protocol/pb/serverinfo_report.pb.h" + #include #include +#include +#include #include #include +#include #include +#include #include #include +#include +#include namespace report_utils { @@ -92,10 +100,27 @@ void renderReportDetails(QTextEdit *chatLogEdit, const QString &moderatorPrefix, const QString &nonModeratorPrefix) { + QString details; + if (report.has_resolution_note() && !report.resolution_note().empty()) { + details = QObject::tr("Resolution note: %1").arg(QString::fromStdString(report.resolution_note())); + } + if (report.has_resolution_time()) { + QString resolvedBy = QObject::tr("unknown"); + if (report.has_resolved_by_name() && !report.resolved_by_name().empty()) { + resolvedBy = QString::fromStdString(report.resolved_by_name()); + } + if (!details.isEmpty()) { + details += "\n"; + } + details += QObject::tr("Resolved at %1 by %2").arg(formatReportTime(report.resolution_time()), resolvedBy); + } + if (report.has_chat_log() && !report.chat_log().empty()) { - chatLogEdit->setPlainText(QString::fromStdString(report.chat_log())); + const QString chatLog = QString::fromStdString(report.chat_log()); + chatLogEdit->setPlainText( + details.isEmpty() ? chatLog : details + "\n\n" + QObject::tr("=== Chat Log ===") + "\n" + chatLog); } else { - chatLogEdit->clear(); + chatLogEdit->setPlainText(details); } commentsEdit->clear(); diff --git a/cockatrice/src/interface/widgets/utility/report_utils.h b/cockatrice/src/interface/widgets/utility/report_utils.h index c6cc96c18..679989486 100644 --- a/cockatrice/src/interface/widgets/utility/report_utils.h +++ b/cockatrice/src/interface/widgets/utility/report_utils.h @@ -2,10 +2,11 @@ #define REPORT_UTILS_H #include -#include +#include class QTableWidget; class QTextEdit; +class ServerInfo_Report; namespace report_utils { diff --git a/cockatrice/src/interface/widgets/utility/reversed_completer_model.cpp b/cockatrice/src/interface/widgets/utility/reversed_completer_model.cpp index 1bc9ba14b..3702798fd 100644 --- a/cockatrice/src/interface/widgets/utility/reversed_completer_model.cpp +++ b/cockatrice/src/interface/widgets/utility/reversed_completer_model.cpp @@ -1,7 +1,10 @@ #include "reversed_completer_model.h" #include +#include +#include #include +#include #include void ReversedCompleterModel::setSourceModel(QAbstractItemModel *sourceModel) diff --git a/cockatrice/src/interface/widgets/utility/reversed_completer_model.h b/cockatrice/src/interface/widgets/utility/reversed_completer_model.h index 64233a1b0..cf4b44974 100644 --- a/cockatrice/src/interface/widgets/utility/reversed_completer_model.h +++ b/cockatrice/src/interface/widgets/utility/reversed_completer_model.h @@ -8,8 +8,8 @@ #define REVERSED_COMPLETER_MODEL_H #include - -class QAbstractItemModel; +#include +#include /** * @brief A completer model that can present its rows bottom-to-top. diff --git a/cockatrice/src/interface/widgets/utility/sequence_edit.cpp b/cockatrice/src/interface/widgets/utility/sequence_edit.cpp index 06561a41d..e92287c9a 100644 --- a/cockatrice/src/interface/widgets/utility/sequence_edit.cpp +++ b/cockatrice/src/interface/widgets/utility/sequence_edit.cpp @@ -4,8 +4,16 @@ #include "../../../client/settings/shortcuts_settings.h" #include "../../pixel_map_generator.h" +#include +#include +#include #include #include +#include +#include +#include +#include +#include #include SequenceEdit::SequenceEdit(const QString &_shortcutName, QWidget *parent) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/utility/sequence_edit.h b/cockatrice/src/interface/widgets/utility/sequence_edit.h index 28e18d42f..0cdd48ceb 100644 --- a/cockatrice/src/interface/widgets/utility/sequence_edit.h +++ b/cockatrice/src/interface/widgets/utility/sequence_edit.h @@ -7,10 +7,15 @@ #ifndef SEQUENCEEDIT_H #define SEQUENCEEDIT_H -#include -#include -#include +#include +#include #include +#include +#include + +class QKeyEvent; +class QLineEdit; +class QPushButton; class SequenceEdit : public QWidget { diff --git a/cockatrice/src/interface/widgets/utility/visibility_change_listener.h b/cockatrice/src/interface/widgets/utility/visibility_change_listener.h index 10928caf6..f154918d6 100644 --- a/cockatrice/src/interface/widgets/utility/visibility_change_listener.h +++ b/cockatrice/src/interface/widgets/utility/visibility_change_listener.h @@ -2,6 +2,9 @@ #define COCKATRICE_VISIBILITY_LISTENER_H #include +#include + +class QWidget; /** * @brief This filter listens to the visibility changes of a target widget, emitting signals whenever the visibility of diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp index 57c6da762..cf815ace0 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp @@ -1,8 +1,19 @@ #include "visual_database_display_color_filter_widget.h" #include "../cards/additional_info/mana_symbol_widget.h" +#include "filter_tree_model.h" +#include "libcockatrice/filters/filter_card.h" +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include /** diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.h index 497d25fce..38812b02a 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.h @@ -7,11 +7,16 @@ #ifndef VISUAL_DATABASE_DISPLAY_COLOR_FILTER_WIDGET_H #define VISUAL_DATABASE_DISPLAY_COLOR_FILTER_WIDGET_H -#include "../../../filters/filter_tree_model.h" - -#include -#include +#include +#include +#include +#include #include +#include + +class FilterTreeModel; +class QComboBox; +class QHBoxLayout; class VisualDatabaseDisplayColorFilterCircleWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp index 76a611d52..fd005b315 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp @@ -1,13 +1,28 @@ #include "visual_database_display_filter_save_load_widget.h" #include "../../../client/settings/cache_settings.h" +#include "../general/layout_containers/flow_widget.h" +#include "filter_tree_model.h" +#include "libcockatrice/filters/filter_card.h" #include "visual_database_filter_display_widget.h" -#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include +#include VisualDatabaseDisplayFilterSaveLoadWidget::VisualDatabaseDisplayFilterSaveLoadWidget(QWidget *parent, FilterTreeModel *_filterModel) diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.h index 459633e42..ea8a0ed6b 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.h @@ -7,17 +7,19 @@ #ifndef VISUAL_DATABASE_DISPLAY_FILTER_SAVE_LOAD_WIDGET_H #define VISUAL_DATABASE_DISPLAY_FILTER_SAVE_LOAD_WIDGET_H -#include "../../../filters/filter_tree_model.h" -#include "../general/layout_containers/flow_widget.h" - -#include -#include -#include -#include +#include #include -#include -#include +#include +#include +#include #include +#include + +class FilterTreeModel; +class FlowWidget; +class QLineEdit; +class QPushButton; +class QVBoxLayout; class VisualDatabaseDisplayFilterSaveLoadWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.cpp index a59a068dd..3e9d9e525 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.cpp @@ -2,9 +2,36 @@ #include "../../pixel_map_generator.h" #include "../deck_editor/card_database_view.h" +#include "../quick_settings/settings_button_widget.h" +#include "card_database_display_model.h" +#include "visual_database_display_filter_save_load_widget.h" +#include "visual_database_display_format_legality_filter_widget.h" +#include "visual_database_display_main_type_filter_widget.h" +#include "visual_database_display_name_filter_widget.h" +#include "visual_database_display_set_filter_widget.h" +#include "visual_database_display_sub_type_filter_widget.h" #include "visual_database_display_widget.h" +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class DeckListModel; VisualDatabaseDisplayFilterToolbarWidget::VisualDatabaseDisplayFilterToolbarWidget(VisualDatabaseDisplayWidget *_parent, DeckListModel *deckListModel) diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.h index 8a3555455..f97310c1b 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.h @@ -1,14 +1,22 @@ #ifndef COCKATRICE_VISUAL_DATABASE_DISPLAY_FILTER_TOOLBAR_WIDGET_H #define COCKATRICE_VISUAL_DATABASE_DISPLAY_FILTER_TOOLBAR_WIDGET_H -#include "visual_database_display_filter_save_load_widget.h" -#include "visual_database_display_format_legality_filter_widget.h" -#include "visual_database_display_main_type_filter_widget.h" -#include "visual_database_display_name_filter_widget.h" -#include "visual_database_display_set_filter_widget.h" -#include "visual_database_display_sub_type_filter_widget.h" +#include "../general/layout_containers/flow_widget.h" + +#include class VisualDatabaseDisplayWidget; +class DeckListModel; +class QComboBox; +class QGroupBox; +class QLabel; +class SettingsButtonWidget; +class VisualDatabaseDisplayFilterSaveLoadWidget; +class VisualDatabaseDisplayFormatLegalityFilterWidget; +class VisualDatabaseDisplayMainTypeFilterWidget; +class VisualDatabaseDisplayNameFilterWidget; +class VisualDatabaseDisplaySetFilterWidget; +class VisualDatabaseDisplaySubTypeFilterWidget; class VisualDatabaseDisplayFilterToolbarWidget : public FlowWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.cpp index 633f07af7..a5725ff3f 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.cpp @@ -1,14 +1,29 @@ #include "visual_database_display_format_legality_filter_widget.h" #include "../../../filters/filter_tree_model.h" +#include "../general/layout_containers/flow_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/filters/filter_card.h" #include "visual_database_display_filter_button.h" +#include +#include +#include #include +#include +#include #include +#include +#include #include #include +#include +#include +#include #include #include +#include +#include VisualDatabaseDisplayFormatLegalityFilterWidget::VisualDatabaseDisplayFormatLegalityFilterWidget( QWidget *parent, diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.h index 1b1a1382e..e94593e67 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.h @@ -1,16 +1,17 @@ #ifndef COCKATRICE_VISUAL_DATABASE_DISPLAY_FORMAT_LEGALITY_FILTER_WIDGET_H #define COCKATRICE_VISUAL_DATABASE_DISPLAY_FORMAT_LEGALITY_FILTER_WIDGET_H -#include "../../../filters/filter_tree_model.h" -#include "../general/layout_containers/flow_widget.h" - -#include #include -#include -#include -#include -#include +#include #include +#include + +class FilterTreeModel; +class FlowWidget; +class QLabel; +class QPushButton; +class QSpinBox; +class QVBoxLayout; class VisualDatabaseDisplayFormatLegalityFilterWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.cpp index c44489c1b..eff0fe10b 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.cpp @@ -1,14 +1,27 @@ #include "visual_database_display_main_type_filter_widget.h" #include "../../../filters/filter_tree_model.h" +#include "../general/layout_containers/flow_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/filters/filter_card.h" #include "visual_database_display_filter_button.h" +#include +#include +#include #include +#include +#include #include +#include +#include #include #include +#include +#include #include #include +#include VisualDatabaseDisplayMainTypeFilterWidget::VisualDatabaseDisplayMainTypeFilterWidget(QWidget *parent, FilterTreeModel *_filterModel) diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.h index 6dec58319..b5a6f332c 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.h @@ -7,15 +7,17 @@ #ifndef VISUAL_DATABASE_DISPLAY_MAIN_TYPE_FILTER_WIDGET_H #define VISUAL_DATABASE_DISPLAY_MAIN_TYPE_FILTER_WIDGET_H -#include "../../../filters/filter_tree_model.h" -#include "../general/layout_containers/flow_widget.h" - -#include #include -#include -#include -#include +#include #include +#include + +class FilterTreeModel; +class FlowWidget; +class QLabel; +class QPushButton; +class QSpinBox; +class QVBoxLayout; class VisualDatabaseDisplayMainTypeFilterWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.cpp index 3fa1a782a..d3e497b21 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.cpp @@ -1,11 +1,26 @@ #include "visual_database_display_name_filter_widget.h" #include "../../../interface/widgets/dialogs/dlg_load_deck_from_clipboard.h" -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../deck_editor/deck_state_manager.h" +#include "../general/layout_containers/flow_widget.h" +#include "deck_list_model.h" +#include "filter_tree_model.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/filters/filter_card.h" +#include "libcockatrice/filters/filter_tree.h" #include "visual_database_display_filter_button.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include VisualDatabaseDisplayNameFilterWidget::VisualDatabaseDisplayNameFilterWidget(QWidget *parent, FilterTreeModel *_filterModel, diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.h index 0c10408ae..1629cb93b 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.h @@ -7,14 +7,17 @@ #ifndef VISUAL_DATABASE_DISPLAY_NAME_FILTER_WIDGET_H #define VISUAL_DATABASE_DISPLAY_NAME_FILTER_WIDGET_H -#include "../../../filters/filter_tree_model.h" -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../general/layout_containers/flow_widget.h" - -#include #include -#include +#include #include +#include + +class DeckListModel; +class FilterTreeModel; +class FlowWidget; +class QLineEdit; +class QPushButton; +class QVBoxLayout; class VisualDatabaseDisplayNameFilterWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.cpp index 358c3ed88..3d76fb78a 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.cpp @@ -2,15 +2,35 @@ #include "../../../client/settings/cache_settings.h" #include "../../../filters/filter_tree_model.h" +#include "../general/layout_containers/flow_widget.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/card/set/card_set_list.h" +#include "libcockatrice/filters/filter_card.h" +#include "libcockatrice/utility/macros.h" #include "visual_database_display_filter_button.h" +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include #include +#include +#include #include +#include #include #include #include +#include VisualDatabaseDisplayRecentSetFilterSettingsWidget::VisualDatabaseDisplayRecentSetFilterSettingsWidget(QWidget *parent) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.h index bcc5e93c2..468e97e0d 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_set_filter_widget.h @@ -7,16 +7,19 @@ #ifndef VISUAL_DATABASE_DISPLAY_SET_FILTER_WIDGET_H #define VISUAL_DATABASE_DISPLAY_SET_FILTER_WIDGET_H -#include "../../../filters/filter_tree_model.h" -#include "../general/layout_containers/flow_widget.h" - -#include -#include #include -#include -#include -#include +#include #include +#include + +class FilterTreeModel; +class FlowWidget; +class QCheckBox; +class QHBoxLayout; +class QLineEdit; +class QPushButton; +class QSpinBox; +class QVBoxLayout; class VisualDatabaseDisplayRecentSetFilterSettingsWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp index 6d4bcb58e..705bb8efa 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp @@ -1,15 +1,28 @@ #include "visual_database_display_sub_type_filter_widget.h" #include "../../../filters/filter_tree_model.h" +#include "../general/layout_containers/flow_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/filters/filter_card.h" #include "visual_database_display_filter_button.h" +#include +#include +#include #include #include +#include +#include #include +#include +#include #include #include +#include +#include #include #include +#include VisualDatabaseDisplaySubTypeFilterWidget::VisualDatabaseDisplaySubTypeFilterWidget(QWidget *parent, FilterTreeModel *_filterModel) diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h index d713c7f99..7929063fd 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h @@ -7,14 +7,18 @@ #ifndef VISUAL_DATABASE_DISPLAY_SUB_TYPE_FILTER_WIDGET_H #define VISUAL_DATABASE_DISPLAY_SUB_TYPE_FILTER_WIDGET_H -#include "../../../filters/filter_tree_model.h" -#include "../general/layout_containers/flow_widget.h" - -#include #include -#include -#include +#include #include +#include + +class FilterTreeModel; +class FlowWidget; +class QLabel; +class QLineEdit; +class QPushButton; +class QSpinBox; +class QVBoxLayout; class VisualDatabaseDisplaySubTypeFilterWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.cpp index 6e0fee53f..599ac97b4 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.cpp @@ -3,21 +3,52 @@ #include "../../../client/settings/cache_settings.h" #include "../../../filters/filter_tree_model.h" #include "../../../filters/syntax_help.h" +#include "../../key_signals.h" #include "../../pixel_map_generator.h" +#include "../cards/card_info_picture_widget.h" #include "../cards/card_info_picture_with_text_overlay_widget.h" +#include "../cards/card_size_widget.h" #include "../deck_editor/card_database_view.h" +#include "../general/layout_containers/flow_widget.h" #include "../utility/custom_line_edit.h" +#include "card_database_display_model.h" +#include "card_database_model.h" +#include "deck_list_model.h" +#include "libcockatrice/card/card_localization.h" +#include "libcockatrice/card/database/card_database_loader.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/filters/filter_card.h" +#include "libcockatrice/filters/filter_tree.h" #include "visual_database_display_color_filter_widget.h" -#include "visual_database_display_filter_save_load_widget.h" -#include "visual_database_display_main_type_filter_widget.h" -#include "visual_database_display_name_filter_widget.h" -#include "visual_database_display_set_filter_widget.h" -#include "visual_database_display_sub_type_filter_widget.h" +#include "visual_database_display_filter_toolbar_widget.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -25,6 +56,8 @@ #include #include +class QMouseEvent; + VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent, CardDatabaseModel *database_model, DeckListModel *deckListModel) diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.h index d161ce362..9771e55c1 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_display_widget.h @@ -7,25 +7,38 @@ #ifndef VISUAL_DATABASE_DISPLAY_WIDGET_H #define VISUAL_DATABASE_DISPLAY_WIDGET_H -#include "../../../filters/filter_tree_model.h" -#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h" -#include "../../key_signals.h" -#include "../cards/card_info_picture_with_text_overlay_widget.h" -#include "../cards/card_size_widget.h" -#include "../general/layout_containers/flow_widget.h" -#include "../general/layout_containers/overlap_control_widget.h" -#include "../utility/custom_line_edit.h" -#include "visual_database_display_color_filter_widget.h" -#include "visual_database_display_filter_toolbar_widget.h" +#include "libcockatrice/card/card_info.h" #include -#include -#include +#include +#include +#include #include #include -#include -#include -#include +#include +#include + +class CardDatabaseDisplayModel; +class CardDatabaseModel; +class CardDatabaseView; +class CardSizeWidget; +class DeckList; +class DeckListModel; +class ExactCard; +class FilterTreeModel; +class FlowWidget; +class OverlapControlWidget; +class QLabel; +class QModelIndex; +class QPushButton; +class QScrollArea; +class QTimer; +class QToolButton; +class QVBoxLayout; +class SearchLineEdit; +class VisualDatabaseDisplayColorFilterWidget; +class VisualDatabaseDisplayFilterToolbarWidget; +template class QList; inline Q_LOGGING_CATEGORY(VisualDatabaseDisplayLog, "visual_database_display"); diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.cpp b/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.cpp index bb5b333d9..0f6ac51ec 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.cpp @@ -2,13 +2,18 @@ #include "../../../client/settings/cache_settings.h" +#include #include #include #include #include #include +#include #include +#include +#include #include +#include FilterDisplayWidget::FilterDisplayWidget(QWidget *parent, const QString &filename, FilterTreeModel *_filterModel) : QWidget(parent), filterFilename(filename), filterModel(_filterModel) diff --git a/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.h b/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.h index 5fe29fa2d..6d051bcf7 100644 --- a/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.h +++ b/cockatrice/src/interface/widgets/visual_database_display/visual_database_filter_display_widget.h @@ -7,12 +7,12 @@ #ifndef VISUAL_DATABASE_FILTER_DISPLAY_WIDGET_H #define VISUAL_DATABASE_FILTER_DISPLAY_WIDGET_H -#include -#include #include #include +#include class FilterTreeModel; +class QPushButton; class FilterDisplayWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.cpp index 28abe480e..25ba41aa9 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.cpp @@ -1,9 +1,27 @@ #include "visual_deck_display_options_widget.h" #include "../../pixel_map_generator.h" +#include "../deck_editor/deck_editor_deck_dock_widget.h" +#include "../quick_settings/settings_button_widget.h" #include "../tabs/visual_deck_editor/tab_deck_editor_visual.h" +#include "../utility/compact_push_button.h" +#include "deck_list_model.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include VisualDeckDisplayOptionsWidget::VisualDeckDisplayOptionsWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.h b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.h index bc11884df..96600c587 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.h @@ -3,12 +3,18 @@ #include "visual_deck_editor_widget.h" -#include -#include -#include -#include -#include +#include +#include +#include #include +#include + +class CompactPushButton; +class QComboBox; +class QHBoxLayout; +class QLabel; +class QListWidget; +class SettingsButtonWidget; /** * @class VisualDeckDisplayOptionsWidget diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp index da4fe09e5..76c3d0908 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp @@ -1,5 +1,9 @@ #include "visual_deck_editor_placeholder_widget.h" +#include +#include +#include + VisualDeckEditorPlaceholderWidget::VisualDeckEditorPlaceholderWidget(QWidget *parent) : QWidget(parent) { mainLayout = new QVBoxLayout(this); diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h index de2362a81..84a3142d8 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h @@ -1,9 +1,11 @@ #ifndef COCKATRICE_VISUAL_DECK_EDITOR_PLACEHOLDER_WIDGET_H #define COCKATRICE_VISUAL_DECK_EDITOR_PLACEHOLDER_WIDGET_H -#include -#include #include +#include + +class QLabel; +class QVBoxLayout; class VisualDeckEditorPlaceholderWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp index cee268228..1554dceb8 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp @@ -1,16 +1,37 @@ #include "visual_deck_editor_sample_hand_widget.h" #include "../../../client/settings/cache_settings.h" -#include "../../deck_loader/deck_loader.h" #include "../cards/card_info_picture_widget.h" +#include "../cards/card_size_widget.h" #include "../deck_analytics/analyzer_modules/draw_probability/draw_probability_widget.h" -#include "../deck_analytics/deck_list_statistics_analyzer.h" +#include "../general/layout_containers/flow_widget.h" +#include "deck_list_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include #include +#include +#include +#include #include +class DeckListStatisticsAnalyzer; + VisualDeckEditorSampleHandWidget::VisualDeckEditorSampleHandWidget(QWidget *parent, DeckListModel *_deckListModel, DeckListStatisticsAnalyzer *_statsAnalyzer) diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h index c6c07dd55..16f343b75 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h @@ -7,16 +7,22 @@ #ifndef VISUAL_DECK_EDITOR_SAMPLE_HAND_WIDGET_H #define VISUAL_DECK_EDITOR_SAMPLE_HAND_WIDGET_H -#include "../cards/card_size_widget.h" -#include "../deck_analytics/deck_list_statistics_analyzer.h" -#include "../general/layout_containers/flow_widget.h" +#include "libcockatrice/card/printing/exact_card.h" -#include -#include +#include #include -#include +#include class DrawProbabilityWidget; +class CardSizeWidget; +class DeckListModel; +class DeckListStatisticsAnalyzer; +class FlowWidget; +class QHBoxLayout; +class QPushButton; +class QSpinBox; +class QVBoxLayout; + class VisualDeckEditorSampleHandWidget : public QWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp index 60e354d6e..74b940586 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp @@ -1,33 +1,48 @@ #include "visual_deck_editor_widget.h" #include "../../../client/settings/cache_settings.h" -#include "../../../main.h" -#include "../../deck_loader/deck_loader.h" -#include "../../layouts/overlap_layout.h" #include "../../pixel_map_generator.h" -#include "../cards/card_info_picture_with_text_overlay_widget.h" +#include "../cards/card_size_widget.h" #include "../cards/deck_card_zone_display_widget.h" #include "../general/layout_containers/flow_widget.h" -#include "../tabs/visual_deck_editor/tab_deck_editor_visual.h" -#include "../tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.h" #include "../utility/compact_push_button.h" #include "../utility/completer_utils.h" +#include "card/card_completer_proxy_model.h" +#include "card_database_display_model.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" #include "visual_deck_display_options_widget.h" +#include "visual_deck_editor_placeholder_widget.h" -#include +#include +#include #include +#include #include +#include +#include +#include +#include #include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include +#include #include #include #include #include -#include +#include VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_deckListModel, diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h index cc045fca2..0b8ff19fb 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h @@ -7,26 +7,35 @@ #ifndef VISUAL_DECK_EDITOR_H #define VISUAL_DECK_EDITOR_H -#include "../cards/card_info_picture_with_text_overlay_widget.h" -#include "../cards/card_size_widget.h" -#include "../general/layout_containers/overlap_control_widget.h" -#include "../quick_settings/settings_button_widget.h" -#include "../utility/compact_push_button.h" -#include "visual_deck_editor_placeholder_widget.h" - -#include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include +#include class VisualDeckDisplayOptionsWidget; class DeckCardZoneDisplayWidget; +class CardCompleterProxyModel; +class CardDatabaseDisplayModel; +class CardDatabaseModel; +class CardSizeWidget; +class CompactPushButton; +class DeckList; +class DeckListModel; +class ExactCard; +class FlowWidget; +class QCompleter; +class QHBoxLayout; +class QItemSelection; +class QItemSelectionModel; +class QLineEdit; +class QModelIndex; +class QScrollArea; +class QVBoxLayout; +class VisualDeckEditorPlaceholderWidget; + enum class DisplayType { Flat, diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.cpp index d1a780c38..1ac4c856c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.cpp @@ -1,8 +1,13 @@ #include "deck_preview_color_identity_filter_widget.h" #include "../../cards/additional_info/mana_symbol_widget.h" +#include "../visual_deck_storage_sort_filter_proxy_model.h" +#include +#include #include +#include +#include DeckPreviewColorIdentityFilterWidget::DeckPreviewColorIdentityFilterWidget(QWidget *parent) : QWidget(parent), layout(new QHBoxLayout(this)) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.h index d54984bcf..e0c90034c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.h @@ -8,11 +8,14 @@ #include "../visual_deck_storage_sort_filter_proxy_model.h" -#include +#include #include -#include #include #include +#include + +class QHBoxLayout; +class QPushButton; class DeckPreviewColorIdentityFilterWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp index 41d87ccb1..dc619e9fa 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp @@ -1,15 +1,23 @@ #include "deck_preview_deck_tags_display_widget.h" #include "../../../../client/settings/cache_settings.h" +#include "../../../deck_loader/deck_file_format.h" #include "../../../deck_loader/deck_loader.h" +#include "../../../deck_loader/loaded_deck.h" #include "../../general/layout_containers/flow_widget.h" #include "deck_preview_tag_addition_widget.h" #include "deck_preview_tag_dialog.h" #include "deck_preview_tag_display_widget.h" +#include "libcockatrice/deck_list/deck_list.h" +#include +#include #include #include +#include #include +#include +#include DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, const QStringList &_tags) : QWidget(_parent), currentTags(_tags) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h index 64bd5aa1a..a12f6ec3c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h @@ -6,9 +6,12 @@ #ifndef DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H #define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H +#include +#include #include #include #include +#include class FlowWidget; diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp index fdf4b2a28..82ed6191c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp @@ -1,12 +1,19 @@ #include "deck_preview_tag_addition_widget.h" -#include "../../../../client/settings/cache_settings.h" -#include "../../../../interface/widgets/tabs/abstract_tab_deck_editor.h" - +#include +#include +#include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include #include DeckPreviewTagAdditionWidget::DeckPreviewTagAdditionWidget(QWidget *_parent, QString _tagName) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h index 7a3a735a2..30ce46249 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.h @@ -7,7 +7,9 @@ #ifndef DECK_PREVIEW_TAG_ADDITION_WIDGET_H #define DECK_PREVIEW_TAG_ADDITION_WIDGET_H -#include "deck_preview_deck_tags_display_widget.h" +#include +#include +#include class DeckPreviewTagAdditionWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.cpp index f27d11d36..2a6a42e9d 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.cpp @@ -8,10 +8,17 @@ #include #include #include +#include +#include #include +#include #include +#include #include +#include +#include #include +#include DeckPreviewTagDialog::DeckPreviewTagDialog(const QStringList &knownTags, const QStringList &_activeTags, diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.h index 4d9040af4..80d5560a0 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.h @@ -9,10 +9,18 @@ #define DECK_PREVIEW_TAG_DIALOG_H #include -#include -#include -#include -#include +#include +#include +#include +#include + +class QHBoxLayout; +class QLabel; +class QLineEdit; +class QListWidget; +class QPushButton; +class QVBoxLayout; +class QWidget; class DeckPreviewTagDialog : public QDialog { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.cpp index a7fef5031..e62570241 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.cpp @@ -1,9 +1,19 @@ #include "deck_preview_tag_display_widget.h" +#include +#include +#include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include DeckPreviewTagDisplayWidget::DeckPreviewTagDisplayWidget(QWidget *parent, const QString &_tagName) : QWidget(parent), tagName(_tagName), state(TagState::NotSelected) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.h index df2a6b404..d3f5e7326 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.h @@ -7,10 +7,12 @@ #ifndef DECK_PREVIEW_TAG_DISPLAY_WIDGET_H #define DECK_PREVIEW_TAG_DISPLAY_WIDGET_H -#include -#include #include #include +#include + +class QLabel; +class QPushButton; enum class TagState { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.cpp index d9ea9fc30..7796f893b 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.cpp @@ -1,5 +1,8 @@ #include "deck_preview_tag_item_widget.h" +#include +#include + DeckPreviewTagItemWidget::DeckPreviewTagItemWidget(const QString &tagName, bool isChecked, QWidget *parent) : QWidget(parent), checkBox_(new QCheckBox(this)) { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.h index a3301799a..a09eb7501 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.h @@ -7,9 +7,11 @@ #ifndef DECK_PREVIEW_TAG_ITEM_WIDGET_H #define DECK_PREVIEW_TAG_ITEM_WIDGET_H -#include -#include +#include #include +#include + +class QCheckBox; class DeckPreviewTagItemWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp index 53fe32314..220c55788 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp @@ -3,26 +3,51 @@ #include "../../../../client/settings/cache_settings.h" #include "../../../../interface/widgets/dialogs/dlg_convert_deck_to_cod_format.h" #include "../../../deck_loader/deck_loader.h" +#include "../../../deck_loader/loaded_deck.h" #include "../../cards/additional_info/color_identity_widget.h" #include "../../cards/deck_preview_card_picture_widget.h" +#include "../visual_deck_storage_model.h" #include "../visual_deck_storage_quick_settings_widget.h" #include "../visual_deck_storage_tag_filter_widget.h" #include "../visual_deck_storage_widget.h" #include "deck_preview_deck_tags_display_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" +#include "libcockatrice/utility/card_ref.h" +#include +#include +#include +#include #include #include #include #include +#include #include #include +#include #include +#include +#include #include +#include +#include +#include #include +#include #include +#include +#include #include +#include +#include #include #include +#include +#include DeckPreviewWidget::DeckPreviewWidget(QWidget *_parent, VisualDeckStorageWidget *_visualDeckStorageWidget, diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h index f4909eda8..cdeed87c7 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h @@ -6,17 +6,18 @@ #ifndef DECK_PREVIEW_WIDGET_H #define DECK_PREVIEW_WIDGET_H -#include "../../cards/deck_preview_card_picture_widget.h" -#include "../visual_deck_storage_model.h" - #include +#include #include #include #include -#include +#include +#include +#include +#include #include +#include -class QEnterEvent; class QFrame; class QLabel; class QMenu; @@ -26,6 +27,8 @@ class DeckPreviewCardPictureWidget; class DeckPreviewDeckTagsDisplayWidget; class VisualDeckStorageModel; class VisualDeckStorageWidget; +class QVBoxLayout; +struct LoadedDeck; class DeckPreviewWidget final : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.cpp index b49d6f9f4..361747423 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.cpp @@ -4,15 +4,19 @@ #include "../../cards/additional_info/color_identity_widget.h" #include "../../cards/deck_preview_card_picture_widget.h" #include "../../general/layout_containers/flow_widget.h" +#include "../remote_public_decks_model.h" #include "deck_preview_tag_display_widget.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/utility/card_ref.h" +#include #include #include -#include -#include #include #include #include +#include PublicDeckPreviewWidget::PublicDeckPreviewWidget(QWidget *parent, const RemotePublicDecksModel::DeckEntry &entry) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.h index a0e5dd43a..103120c7f 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/deck_preview/public_deck_preview_widget.h @@ -9,16 +9,15 @@ #include "../remote_public_decks_model.h" #include +#include #include #include +#include class ColorIdentityWidget; class DeckPreviewCardPictureWidget; class FlowWidget; -class QKeyEvent; class QLabel; -class QMouseEvent; -class QResizeEvent; /** * @brief A preview tile for a public deck published by another user. diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp index a1cabd729..9b8daf87c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.cpp @@ -3,7 +3,10 @@ #include "../../../client/settings/cache_settings.h" #include +#include +#include #include +#include #include #include #include @@ -11,6 +14,9 @@ #include #include #include +#include + +class QObject; RemotePublicDecksModel::RemotePublicDecksModel(AbstractClient *_client, QObject *parent) : QAbstractListModel(parent), client(_client) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h index eeb606442..cb1f786e4 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/remote_public_decks_model.h @@ -9,10 +9,15 @@ #include "visual_deck_storage_sort_filter_proxy_model.h" #include +#include #include #include +#include #include +#include #include +#include +#include class AbstractClient; class CommandContainer; @@ -20,6 +25,7 @@ class QTimer; class Response; class ServerInfo_DeckStorage_Folder; class ServerInfo_DeckStorage_TreeItem; +class QObject; /** * @brief Flat, read-only list of the public decks published by another user. diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp index 53f21d1a1..44b7a1a06 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp @@ -2,6 +2,7 @@ #include "../cards/card_info_picture_widget.h" #include "../cards/card_size_widget.h" +#include "../cards/deck_preview_card_picture_widget.h" #include "../general/display/banner_widget.h" #include "../general/layout_containers/flow_widget.h" #include "deck_preview/deck_preview_widget.h" @@ -10,10 +11,20 @@ #include "visual_deck_storage_sort_filter_proxy_model.h" #include "visual_deck_storage_widget.h" +#include +#include +#include #include +#include +#include +#include +#include #include +#include #include #include +#include +#include VisualDeckStorageFolderDisplayWidget::VisualDeckStorageFolderDisplayWidget( QWidget *parent, diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h index 5a81457b0..998619c0b 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h @@ -17,9 +17,12 @@ #define VISUAL_DECK_STORAGE_FOLDER_DISPLAY_WIDGET_H #include +#include #include #include +#include #include +#include class BannerWidget; class DeckPreviewWidget; diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.cpp index daca55fc8..e84631e52 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.cpp @@ -1,19 +1,32 @@ #include "visual_deck_storage_model.h" +#include "../../deck_loader/deck_file_format.h" #include "../../deck_loader/deck_loader.h" +#include "../../deck_loader/loaded_deck.h" #include "../cards/additional_info/deck_color_identity.h" +#include "libcockatrice/deck_list/deck_list.h" +#include #include #include #include #include #include #include +#include +#include #include +#include +#include #include +#include #include +#include +#include #include +class QObject; + namespace { /** diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.h index 330205356..57eaebacf 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_model.h @@ -14,14 +14,20 @@ #define VISUAL_DECK_STORAGE_MODEL_H #include "../../deck_loader/loaded_deck.h" +#include "libcockatrice/utility/card_ref.h" #include #include #include #include +#include +#include #include -#include -#include +#include +#include +#include + +class QObject; namespace VisualDeckStorageRoles { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp index c19ac0fec..9bb6e0fae 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.cpp @@ -2,14 +2,23 @@ #include "../../../client/settings/cache_settings.h" #include "../cards/card_size_widget.h" -#include "visual_deck_storage_widget.h" +#include "../quick_settings/settings_button_widget.h" +#include "libcockatrice/utility/macros.h" #include #include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include +#include VisualDeckStorageQuickSettingsWidget::VisualDeckStorageQuickSettingsWidget(QWidget *parent) : SettingsButtonWidget(parent) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h index a85e9e654..7bce34d8c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_quick_settings_widget.h @@ -11,11 +11,14 @@ #include "../quick_settings/settings_button_widget.h" +#include + class CardSizeWidget; class QLabel; class QSpinBox; class QCheckBox; class QComboBox; +class QWidget; class VisualDeckStorageQuickSettingsWidget : public SettingsButtonWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp index 406527893..2c03666c1 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp @@ -4,6 +4,10 @@ #include "../../pixel_map_generator.h" #include +#include +#include +#include +#include #include /** diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.h index 7769ea911..87a8dc9f8 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_search_widget.h @@ -6,11 +6,13 @@ #ifndef VISUAL_DECK_STORAGE_SEARCH_WIDGET_H #define VISUAL_DECK_STORAGE_SEARCH_WIDGET_H -#include -#include +#include #include +#include class QTimer; +class QHBoxLayout; +class QLineEdit; class VisualDeckStorageSearchWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.cpp index 0ad6ebcb2..abe3327af 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.cpp @@ -1,10 +1,20 @@ #include "visual_deck_storage_sort_filter_proxy_model.h" #include "../../../client/settings/cache_settings.h" +#include "../../deck_loader/loaded_deck.h" #include "../../filters/deck_filter_string.h" +#include "visual_deck_storage_model.h" +#include +#include #include +#include +#include +#include +#include +#include #include +#include #include #include diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.h index a6c40a2d7..51732adc8 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_filter_proxy_model.h @@ -15,11 +15,15 @@ #ifndef VISUAL_DECK_STORAGE_SORT_FILTER_PROXY_MODEL_H #define VISUAL_DECK_STORAGE_SORT_FILTER_PROXY_MODEL_H -#include "visual_deck_storage_model.h" - +#include +#include #include #include #include +#include + +class QObject; +class VisualDeckStorageModel; class VisualDeckStorageSortFilterProxyModel : public QSortFilterProxyModel { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp index 6289a4941..f798a72a9 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp @@ -3,6 +3,9 @@ #include "../../../client/settings/cache_settings.h" #include "visual_deck_storage_widget.h" +#include +#include +#include #include VisualDeckStorageSortWidget::VisualDeckStorageSortWidget(VisualDeckStorageWidget *parent) : QWidget(parent) diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.h index 633924d84..df3f39eb5 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_sort_widget.h @@ -8,11 +8,13 @@ #include "visual_deck_storage_sort_filter_proxy_model.h" -#include -#include #include +#include class VisualDeckStorageWidget; +class QComboBox; +class QHBoxLayout; + class VisualDeckStorageSortWidget : public QWidget { Q_OBJECT diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp index 6f954b01b..d6b7aedbb 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp @@ -4,6 +4,13 @@ #include "deck_preview/deck_preview_tag_display_widget.h" #include +#include +#include +#include +#include +#include +#include +#include VisualDeckStorageTagFilterWidget::VisualDeckStorageTagFilterWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.h index 5e3cb398c..13a27c10a 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.h @@ -6,13 +6,16 @@ #ifndef VISUAL_DECK_STORAGE_TAG_FILTER_WIDGET_H #define VISUAL_DECK_STORAGE_TAG_FILTER_WIDGET_H -#include +#include #include #include #include +#include class DeckPreviewTagDisplayWidget; class FlowWidget; +class QString; +template class QSet; class VisualDeckStorageTagFilterWidget : public QWidget { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.cpp index c7218f195..51e9c70e7 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.cpp @@ -2,22 +2,38 @@ #include "../../../client/settings/cache_settings.h" #include "../../pixel_map_generator.h" -#include "../quick_settings/settings_button_widget.h" #include "deck_preview/deck_preview_color_identity_filter_widget.h" #include "deck_preview/deck_preview_widget.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_loader.h" #include "visual_deck_storage_folder_display_widget.h" +#include "visual_deck_storage_model.h" #include "visual_deck_storage_quick_settings_widget.h" #include "visual_deck_storage_search_widget.h" +#include "visual_deck_storage_sort_filter_proxy_model.h" #include "visual_deck_storage_sort_widget.h" #include "visual_deck_storage_tag_filter_widget.h" +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include #include +#include +#include #include #include #include #include +#include VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(parent) { diff --git a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h index dfb715bea..b512dd87c 100644 --- a/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_storage/visual_deck_storage_widget.h @@ -6,18 +6,13 @@ #ifndef VISUAL_DECK_STORAGE_WIDGET_H #define VISUAL_DECK_STORAGE_WIDGET_H -#include "visual_deck_storage_model.h" -#include "visual_deck_storage_sort_filter_proxy_model.h" - -#include -#include -#include -#include +#include +#include +#include #include +#include class QLabel; -class QResizeEvent; -class QShowEvent; class QTimer; class DeckPreviewColorIdentityFilterWidget; class VisualDeckStorageFolderDisplayWidget; @@ -25,6 +20,13 @@ class VisualDeckStorageQuickSettingsWidget; class VisualDeckStorageSearchWidget; class VisualDeckStorageSortWidget; class VisualDeckStorageTagFilterWidget; +class QHBoxLayout; +class QScrollArea; +class QToolButton; +class QVBoxLayout; +class VisualDeckStorageModel; +class VisualDeckStorageSortFilterProxyModel; +struct LoadedDeck; class VisualDeckStorageWidget final : public QWidget { diff --git a/cockatrice/src/interface/window_main.cpp b/cockatrice/src/interface/window_main.cpp index 77cc85130..815cec1d2 100644 --- a/cockatrice/src/interface/window_main.cpp +++ b/cockatrice/src/interface/window_main.cpp @@ -21,7 +21,6 @@ #include "../client/latency_status_widget.h" #include "../client/network/update/client/client_update_checker.h" -#include "../client/network/update/client/release_channel.h" #include "../client/settings/cache_settings.h" #include "../client/settings/shortcuts_settings.h" #include "../interface/widgets/dialogs/dlg_edit_tokens.h" @@ -34,50 +33,69 @@ #include "../interface/widgets/dialogs/dlg_view_log.h" #include "../interface/widgets/onboarding/first_run_wizard.h" #include "../interface/widgets/settings_page/general_settings_page.h" -#include "../interface/widgets/tabs/tab_game.h" #include "../interface/widgets/tabs/tab_server.h" #include "../interface/widgets/tabs/tab_supervisor.h" #include "../main.h" +#include "abstract_client.h" +#include "card_database_update/card_database_update_status_bar.h" +#include "card_database_update/card_update_progress.h" #include "intents/contexts/context_connect_to_server.h" #include "intents/contexts/context_join_room.h" +#include "intents/intent.h" #include "intents/intent_connect_to_server.h" #include "intents/intent_login.h" #include "intents/intent_open_server_room_by_name.h" #include "intents/url_parser.h" +#include "latency_tracker.h" #include "logger.h" #include "pixel_map_generator.h" #include "version_string.h" #include "widgets/dialogs/dlg_connect.h" #include "widgets/server/handle_public_servers.h" +#include "widgets/settings_page/abstract_settings_page.h" #include "widgets/tabs/api/commander_spellbook/handle_commander_brackets.h" -#include "widgets/utility/get_text_with_max.h" #include #include #include +#include #include +#include #include +#include #include +#include +#include #include #include -#include +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include #include +#include +#include #include +#include #include -#include #include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include #include #include -#include #include #include #include @@ -91,6 +109,14 @@ #include #include #include +#include +#include +#include +#include +#include +#include + +class LocalServerInterface; #define GITHUB_PAGES_URL "https://cockatrice.github.io" #define GITHUB_CONTRIBUTORS_URL "https://github.com/Cockatrice/Cockatrice/graphs/contributors" @@ -555,6 +581,13 @@ MainWindow::MainWindow(QWidget *parent) connect(connectionController, &ConnectionController::pingStatsUpdated, latencyStatus, &LatencyStatusWidget::updateData); + cardUpdateStatusBar = new CardDatabaseUpdateStatusBar(this); + statusBar()->addPermanentWidget(cardUpdateStatusBar); + connect(this, &MainWindow::cardDatabaseUpdateProgress, cardUpdateStatusBar, + &CardDatabaseUpdateStatusBar::updateProgress); + connect(this, &MainWindow::cardDatabaseUpdateFinished, cardUpdateStatusBar, + &CardDatabaseUpdateStatusBar::updateFinished); + connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this, &MainWindow::refreshShortcuts); refreshShortcuts(); @@ -573,14 +606,45 @@ MainWindow::MainWindow(QWidget *parent) QTimer::singleShot(0, this, &MainWindow::applyStartupDestination); } +void MainWindow::warnAboutDataPathsInProgramDir() +{ + auto &paths = SettingsCache::instance().paths(); + if (SettingsCache::instance().getIsPortableBuild() || paths.getAppDirWarningAcknowledged()) { + return; + } + + const QStringList offenders = paths.pathsInsideDir(QCoreApplication::applicationDirPath()); + if (offenders.isEmpty()) { + return; + } + + QMessageBox box(QMessageBox::Warning, tr("Data paths inside the program directory"), + tr("These paths are configured inside the Cockatrice program directory:\n\n%1\n\n" + "Cockatrice keeps its own data outside the program directory by default. Files " + "stored inside it can be deleted by an update or by uninstalling Cockatrice. " + "Change them in the Settings dialog - most are on the General page - to keep " + "them safe.") + .arg(offenders.join(QLatin1Char('\n'))), + QMessageBox::Ok, this); + box.setTextFormat(Qt::PlainText); + auto *dontShowAgain = new QCheckBox(tr("Don't show this again")); + box.setCheckBox(dontShowAgain); + box.exec(); + if (dontShowAgain->isChecked()) { + paths.setAppDirWarningAcknowledged(true); + } +} + void MainWindow::startupConfigCheck() { + warnAboutDataPathsInProgramDir(); + const bool isCleanInstall = SettingsCache::instance().network().getClientVersion() == CLIENT_INFO_NOT_SET; - // checkUnknownSets() is intentionally deferred from the card database load - // (which runs in main() before MainWindow exists) so that - // cardDatabaseNewSetsFound / cardDatabaseAllNewSetsEnabled have live - // receivers when emitted. + // The loader never runs checkUnknownSets() itself (see main.cpp): the + // front-loaded parse runs before MainWindow exists, so + // cardDatabaseNewSetsFound / cardDatabaseAllNewSetsEnabled would have no + // receivers. MainWindow owns the check after startup. // On a clean install the onboarding wizard owns the first-run experience; // wait until it closes so the legacy "all sets enabled" welcome and the // Manage Sets dialog don't appear first. @@ -877,10 +941,15 @@ void MainWindow::closeEvent(QCloseEvent *event) bClosingDown = true; if (cardUpdateProcess && cardUpdateProcess->state() != QProcess::NotRunning) { - if (QMessageBox::question(this, tr("Are you sure?"), - tr("A card database update is still running. Quitting now will cancel it.\n" - "Are you sure you want to quit?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) { + const QString runningFor = cardUpdateStatusBar ? cardUpdateStatusBar->statusText() : QString(); + const QString message = runningFor.isEmpty() + ? tr("A card database update is still running. Quitting now will cancel it.\n" + "Are you sure you want to quit?") + : tr("A card database update is still running: %1.\nQuitting now will cancel it.\n" + "Are you sure you want to quit?") + .arg(runningFor); + if (QMessageBox::question(this, tr("Are you sure?"), message, QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::No) { event->ignore(); bClosingDown = false; return; @@ -1069,18 +1138,35 @@ void MainWindow::cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknow void MainWindow::cardDatabaseAllNewSetsEnabled() { - if (firstRunWizardActive || CardDatabaseManager::getInstance()->getCardList().isEmpty()) { - // The onboarding wizard owns the first-run messaging on a clean install, - // and with no card data there are no sets to have enabled. + auto *cardDatabase = CardDatabaseManager::getInstance(); + + // With no card data there is nothing to have enabled and nothing to reparse. + if (cardDatabase->getCardList().isEmpty()) { return; } - QMessageBox::information( - this, tr("Welcome"), - tr("Hi! It seems like you're running this version of Cockatrice for the first time.\nAll the sets in the card " - "database have been enabled.\nRead more about changing the set order or disabling specific sets and " - "consequent effects in the \"Manage Sets\" dialog.")); - actManageSets(); + // checkUnknownSets() enabled every set after the database had already been + // parsed under the (empty) first-run enablement, so the parser dropped every + // printing of every set. Reparse now that the sets are enabled, otherwise the + // deck editor's card database display stays empty until the next launch. + auto *watcher = new QFutureWatcher(this); + connect(watcher, &QFutureWatcher::finished, this, [this, watcher] { + watcher->deleteLater(); + if (firstRunWizardActive) { + // The onboarding wizard owns the first-run messaging on a clean install. + return; + } + QMessageBox::information( + this, tr("Welcome"), + tr("Hi! It seems like you're running this version of Cockatrice for the first time.\nAll the sets in the " + "card " + "database have been enabled.\nRead more about changing the set order or disabling specific sets and " + "consequent effects in the \"Manage Sets\" dialog.")); + // The reload above replaces the set instances, so Manage Sets must open + // only after the finished snapshot has been swapped in. + actManageSets(); + }); + watcher->setFuture(QtConcurrent::run([cardDatabase] { cardDatabase->reloadCardDatabasesAndNotify(); })); } /* CARD UPDATER */ @@ -1097,16 +1183,28 @@ void MainWindow::actCheckCardUpdatesBackground() void MainWindow::createCardUpdateProcess(bool background) { if (cardUpdateProcess) { - QMessageBox::information(this, tr("Information"), tr("A card database update is already running.")); + qCDebug(CardDatabaseUpdateLog) << "A card database update is already running; asking it to come to the front"; + if (requestCardUpdateRaise()) { + return; + } + if (background) { + // A hidden run has nothing to raise: keep the user informed without blocking. + announceCardUpdateRunning(); + return; + } + QMessageBox::information(this, tr("Information"), + tr("The card database updater is already open.\n" + "Look for the Oracle window - it may be behind this one.")); return; } cardUpdateProcess = new QProcess(this); connect(cardUpdateProcess, &QProcess::errorOccurred, this, &MainWindow::cardUpdateError); - connect(cardUpdateProcess, qOverload(&QProcess::finished), this, &MainWindow::cardUpdateFinished); + connect(cardUpdateProcess, &QProcess::readyReadStandardOutput, this, &MainWindow::cardUpdateProgressOutput); + connect(cardUpdateProcess, &QProcess::readyReadStandardError, this, &MainWindow::cardUpdateStandardError); // full "run the update" command; leave empty if not present QString updaterCmd; @@ -1151,6 +1249,8 @@ void MainWindow::createCardUpdateProcess(bool background) } if (updaterCmd.isEmpty()) { + qCWarning(CardDatabaseUpdateLog) << "Unable to locate the card database updater; looked for" + << dir.absoluteFilePath(binaryName); QMessageBox::warning(this, tr("Error"), tr("Unable to run the card database updater: ") + dir.absoluteFilePath(binaryName)); exitCardDatabaseUpdate(); @@ -1158,13 +1258,24 @@ void MainWindow::createCardUpdateProcess(bool background) return; } + cardUpdateOutputBuffer.clear(); + cardUpdateErrorOutput.clear(); + cardUpdateErrorPartial.clear(); + cardUpdateLoggedStage = CardUpdateStage::Unknown; + cardUpdateProgressLogTimer.start(); + + qCInfo(CardDatabaseUpdateLog) << "Starting the card database updater" << updaterCmd << "background:" << background; + cardUpdateStatusBar->updateStarted(); + if (!background) { cardUpdateProcess->start(updaterCmd, QStringList()); } else { - cardUpdateOutputBuffer.clear(); - connect(cardUpdateProcess, &QProcess::readyReadStandardOutput, this, &MainWindow::cardUpdateProgressOutput); cardUpdateProcess->start(updaterCmd, QStringList("-b")); statusBar()->showMessage(tr("Card database update running.")); + if (trayIcon && SettingsCache::instance().updates().getCardDatabaseUpdateTrayNotification()) { + trayIcon->showMessage(tr("Card database update started"), + tr("Cockatrice is updating the card database in the background.")); + } } } @@ -1179,24 +1290,43 @@ void MainWindow::cardUpdateProgressOutput() if (newline < 0) { break; } - const QByteArray line = cardUpdateOutputBuffer.left(newline).trimmed(); + const QByteArray line = cardUpdateOutputBuffer.left(newline); cardUpdateOutputBuffer.remove(0, newline + 1); - // Protocol emitted by `oracle -b`: "PROGRESS " - if (!line.startsWith("PROGRESS ")) { + // Protocol emitted by `oracle`: "PROGRESS " + const std::optional progress = CardUpdateProgress::fromProtocolLine(line); + if (!progress.has_value()) { continue; } - const QList parts = line.split(' '); - if (parts.size() != 4) { - continue; + // Log stage changes and, while a stage runs, one line per second at most, so the + // debug log shows liveness without flooding it. + if (progress->stage != cardUpdateLoggedStage || cardUpdateProgressLogTimer.elapsed() >= 1000) { + qCDebug(CardDatabaseUpdateLog) + << "Card database update" << progress->stageToken() << progress->done << "/" << progress->total; + cardUpdateLoggedStage = progress->stage; + cardUpdateProgressLogTimer.restart(); } - bool doneOk = false; - bool totalOk = false; - const qint64 done = parts.at(2).toLongLong(&doneOk); - const qint64 total = parts.at(3).toLongLong(&totalOk); - if (!doneOk || !totalOk || done < 0 || total < 0) { - continue; + emit cardDatabaseUpdateProgress(progress.value()); + } +} + +void MainWindow::cardUpdateStandardError() +{ + if (!cardUpdateProcess) { + return; + } + const QByteArray chunk = cardUpdateProcess->readAllStandardError(); + if (chunk.isEmpty()) { + return; + } + cardUpdateErrorOutput.append(chunk); + cardUpdateErrorPartial.append(chunk); + int newline; + while ((newline = cardUpdateErrorPartial.indexOf('\n')) >= 0) { + const QByteArray line = cardUpdateErrorPartial.left(newline).trimmed(); + cardUpdateErrorPartial.remove(0, newline + 1); + if (!line.isEmpty()) { + qCWarning(CardDatabaseUpdateLog) << "Card database updater:" << line; } - emit cardDatabaseUpdateProgress(QString::fromLatin1(parts.at(1)), done, total); } } @@ -1209,7 +1339,19 @@ void MainWindow::exitCardDatabaseUpdate() cardUpdateProcess = nullptr; statusBar()->clearMessage(); - const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); + // This can be the first successful load of the session (e.g. the onboarding + // download), so it must own the set check for that load. + reloadCardDatabaseAndCheckSets(); +} + +void MainWindow::reloadCardDatabaseAndCheckSets() +{ + auto *watcher = new QFutureWatcher(this); + connect(watcher, &QFutureWatcher::finished, this, [watcher] { + watcher->deleteLater(); + CardDatabaseManager::getInstance()->checkUnknownSets(); + }); + watcher->setFuture(QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); })); } void MainWindow::cardUpdateError(QProcess::ProcessError err) @@ -1221,7 +1363,6 @@ void MainWindow::cardUpdateError(QProcess::ProcessError err) break; case QProcess::Crashed: error = tr("The process crashed some time after starting successfully."); - error += "\n\nError output:\n" + cardUpdateProcess->readAllStandardError(); break; case QProcess::Timedout: error = tr("Timed out. The process took too long to respond. The last waitFor...() function timed out."); @@ -1240,6 +1381,12 @@ void MainWindow::cardUpdateError(QProcess::ProcessError err) break; } + if (!cardUpdateErrorOutput.isEmpty()) { + error += "\n\n" + tr("Error output:") + "\n" + QString::fromUtf8(cardUpdateErrorOutput); + cardUpdateErrorOutput.clear(); + } + + qCWarning(CardDatabaseUpdateLog) << "The card database updater exited with an error:" << error; exitCardDatabaseUpdate(); QMessageBox::warning(this, tr("Error"), tr("The card database updater exited with an error:\n%1").arg(error)); emit cardDatabaseUpdateFinished(false); @@ -1247,16 +1394,56 @@ void MainWindow::cardUpdateError(QProcess::ProcessError err) void MainWindow::cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus) { + if (!cardUpdateProcess) { + return; + } cardUpdateProgressOutput(); // drain any progress lines not yet parsed const bool success = (exitStatus == QProcess::NormalExit) && (exitCode == 0); if (exitStatus == QProcess::NormalExit) { SettingsCache::instance().updates().setLastCardUpdateCheck(QDateTime::currentDateTime().date()); } + qCInfo(CardDatabaseUpdateLog) << "The card database updater finished with exit code" << exitCode << "exit status" + << static_cast(exitStatus) << "success:" << success; exitCardDatabaseUpdate(); + notifyCardUpdateFinishedFromTray(success); emit cardDatabaseUpdateFinished(success); } +bool MainWindow::requestCardUpdateRaise() +{ + const QString serverName = scopedLocalServerName(QStringLiteral("CockatriceOracleRaise")); + QLocalSocket socket; + socket.connectToServer(serverName); + if (!socket.waitForConnected(250)) { + return false; + } + socket.write("RAISE\n"); + const bool acked = socket.waitForBytesWritten(250); + socket.disconnectFromServer(); + return acked; +} + +void MainWindow::announceCardUpdateRunning() +{ + if (SettingsCache::instance().userInterface().getShowStatusBar()) { + statusBar()->showMessage(tr("Card database update running.")); + } else if (trayIcon && SettingsCache::instance().updates().getCardDatabaseUpdateTrayNotification()) { + trayIcon->showMessage(tr("Card database update running"), + tr("Cockatrice is updating the card database in the background.")); + } +} + +void MainWindow::notifyCardUpdateFinishedFromTray(bool success) +{ + if (SettingsCache::instance().userInterface().getShowStatusBar() || !trayIcon || + !SettingsCache::instance().updates().getCardDatabaseUpdateTrayNotification()) { + return; + } + trayIcon->showMessage(tr("Card database update finished"), + success ? tr("The card database is up to date.") : tr("The card database update failed.")); +} + void MainWindow::actCheckServerUpdates() { auto hps = new HandlePublicServers(this); @@ -1366,7 +1553,8 @@ void MainWindow::actAddCustomSet() QMessageBox::information( this, tr("Load sets/cards"), tr("The new sets/cards have been added successfully.\nCockatrice will now reload the card database.")); - const auto reloadOk1 = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); }); + // Imported files can introduce sets the config has never seen. + reloadCardDatabaseAndCheckSets(); } else { QMessageBox::warning(this, tr("Load sets/cards"), tr("Sets/cards failed to import.")); } diff --git a/cockatrice/src/interface/window_main.h b/cockatrice/src/interface/window_main.h index 1c4dde300..ee8873000 100644 --- a/cockatrice/src/interface/window_main.h +++ b/cockatrice/src/interface/window_main.h @@ -26,35 +26,42 @@ #define WINDOW_H #include "../client/lag_monitor.h" +#include "../client/network/update/client/release_channel.h" +#include "card_database_update/card_update_progress.h" #include "connection_controller/remote_connection_controller.h" -#include "widgets/dialogs/dlg_local_game_options.h" +#include +#include +#include #include +#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -#include +#include + +class QAction; +class QWidget; +struct LocalGameOptions; inline Q_LOGGING_CATEGORY(WindowMainLog, "window_main"); inline Q_LOGGING_CATEGORY(WindowMainStartupLog, "window_main.startup"); inline Q_LOGGING_CATEGORY(WindowMainStartupVersionLog, "window_main.startup.version"); inline Q_LOGGING_CATEGORY(WindowMainStartupShortcutsLog, "window_main.startup.shortcuts"); inline Q_LOGGING_CATEGORY(WindowMainStartupAutoconnectLog, "window_main.startup.autoconnect"); +inline Q_LOGGING_CATEGORY(CardDatabaseUpdateLog, "card_database.update"); -class Release; -class DlgConnect; class DlgViewLog; class GameReplay; -class HandlePublicServers; -class LocalClient; class LocalServer; -class QLabel; class LatencyStatusWidget; -class QThread; +class CardDatabaseUpdateStatusBar; class RemoteClient; -class ServerInfo_User; class TabSupervisor; class WndSets; class DlgTipOfTheDay; @@ -65,13 +72,13 @@ class MainWindow : public QMainWindow { Q_OBJECT signals: - /** @brief Emitted after the background card-database update subprocess exits. */ + /** @brief Emitted after the card-database update subprocess exits. */ void cardDatabaseUpdateFinished(bool success); - /** @brief Emitted while the background card-database update subprocess runs. - * @p stage is one of "download", "scan" or "import"; @p done/@p total - * are byte counts for the first two stages and set indices for "import". */ - void cardDatabaseUpdateProgress(const QString &stage, qint64 done, qint64 total); + /** @brief Emitted while the card-database update subprocess runs. + * @p progress.done/@p progress.total are byte counts for the first two stages + * and set indices for "import". */ + void cardDatabaseUpdateProgress(const CardUpdateProgress &progress); public slots: void actCheckCardUpdates(); @@ -103,6 +110,7 @@ private slots: void cardUpdateError(QProcess::ProcessError err); void cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus); void cardUpdateProgressOutput(); + void cardUpdateStandardError(); void refreshShortcuts(); void cardDatabaseLoadingFailed(); void cardDatabaseNewSetsFound(int numUnknownSets, QStringList unknownSetsNames); @@ -141,12 +149,32 @@ private: void runFirstRunWizard(bool firstRun = false); + /** @brief Warns once when a non-portable install keeps its data paths inside the program directory. */ + void warnAboutDataPathsInProgramDir(); + inline QString getCardUpdaterBinaryName() { return "oracle"; } void createCardUpdateProcess(bool background = false); void exitCardDatabaseUpdate(); + /** + * @brief Reloads the card database on a worker thread and runs checkUnknownSets() once the finished + * snapshot has been swapped in. + * + * The loader never runs checkUnknownSets() itself (see main.cpp); post-update loads that can introduce + * new sets must own the check, and it has to run after the queued snapshot swap, not on the worker. + */ + void reloadCardDatabaseAndCheckSets(); + /** + * @brief Tries to bring the open card database updater window to the front. + * @return true when the updater acknowledged the request + */ + bool requestCardUpdateRaise(); + /** @brief Tells the user an update is running without blocking, honoring a hidden status bar. */ + void announceCardUpdateRunning(); + /** @brief Posts a tray notification when the status bar cannot show progress. */ + void notifyCardUpdateFinishedFromTray(bool success); void startLocalGame(const LocalGameOptions &options); @@ -173,6 +201,11 @@ private: bool firstRunWizardActive = false; QProcess *cardUpdateProcess; QByteArray cardUpdateOutputBuffer; + QByteArray cardUpdateErrorOutput; ///< diagnostic output collected from the updater's stderr + QByteArray cardUpdateErrorPartial; ///< incomplete trailing stderr line, kept for line-based logging + CardUpdateStage cardUpdateLoggedStage = CardUpdateStage::Unknown; ///< stage of the last logged progress update + QElapsedTimer cardUpdateProgressLogTimer; ///< throttles progress logging to the running stage + CardDatabaseUpdateStatusBar *cardUpdateStatusBar = nullptr; ///< status bar widget tracking the card database update DlgViewLog *logviewDialog; GameReplay *replay; DlgTipOfTheDay *tip; diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index af519f436..3f63efc3b 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -25,36 +25,55 @@ #include "client/sound_engine.h" #include "client/url_scheme_event_filter.h" #include "database/interface/settings_card_preference_provider.h" +#include "interface/intents/intent.h" #include "interface/intents/intent_open_local_deck.h" #include "interface/logger.h" #include "interface/pixel_map_generator.h" #include "interface/theme_manager.h" -#include "interface/widgets/dialogs/dlg_settings.h" -#include "interface/widgets/tabs/tab_supervisor.h" #include "interface/window_main.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/rng/rng_abstract.h" #include "single_instance_manager.h" #include "version_string.h" #include +#include +#include +#include +#include +#include #include -#include #include +#include +#include +#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include #include #include -#include #include -#include #include #include #include #include #include +#include +#include +#include QTranslator *translator, *qtTranslator; RNG_Abstract *rng; @@ -91,6 +110,7 @@ static void CockatriceLogger(QtMsgType type, const QMessageLogContext &ctx, cons #include #include #include + #pragma comment(lib, "DbgHelp.lib") // Link the DbgHelp library // clang-format on @@ -323,11 +343,12 @@ int main(int argc, char *argv[]) // contention that happens when the load runs alongside window construction. // The CardDatabaseModel populates from the already-loaded data in its // constructor, so the window appears fully populated with no startup lag. - // Note: checkUnknownSets() is deferred from the initial load to - // MainWindow::startupConfigCheck() so that - // cardDatabaseNewSetsFound / cardDatabaseAllNewSetsEnabled have live - // receivers when emitted. Subsequent reloads (e.g. path changes) call - // checkUnknownSets() directly from the loader after the first load. + // Note: checkUnknownSets() is deliberately not run for this front-loaded + // parse. It would run before MainWindow exists, so + // cardDatabaseNewSetsFound / cardDatabaseAllNewSetsEnabled would have no + // receivers, and enabling the sets up-front would suppress the first-run + // experience MainWindow::startupConfigCheck() and the onboarding wizard + // provide. Callers that load after startup own the check. CardDatabaseManager::getInstance()->loadCardDatabases(); MainWindow ui; diff --git a/cockatrice/src/main.h b/cockatrice/src/main.h index eee262d2c..3d772915b 100644 --- a/cockatrice/src/main.h +++ b/cockatrice/src/main.h @@ -15,7 +15,6 @@ class CardDatabase; class QString; class QSystemTrayIcon; class QTranslator; -class SoundEngine; extern CardDatabase *db; diff --git a/cockatrice/src/single_instance_manager.cpp b/cockatrice/src/single_instance_manager.cpp index 8d363ff34..08294d72c 100644 --- a/cockatrice/src/single_instance_manager.cpp +++ b/cockatrice/src/single_instance_manager.cpp @@ -1,7 +1,15 @@ #include "single_instance_manager.h" -#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include namespace { @@ -17,17 +25,9 @@ SingleInstanceManager::SingleInstanceManager(QObject *parent) : QObject(parent) bool SingleInstanceManager::tryRun(const QStringList &filesToSend) { - // Scope the socket name to the current user. On Linux the default abstract - // namespace is system-wide, so a plain name would let one user's instance + // Scope the socket name to the current user so one user's instance cannot // hijack another user's session. - QString userName = qEnvironmentVariable("USER"); - if (userName.isEmpty()) { - userName = qEnvironmentVariable("USERNAME"); - } - if (userName.isEmpty()) { - userName = QDir::home().dirName(); - } - serverName = QStringLiteral("CockatriceSingleInstance-%1").arg(userName); + serverName = scopedLocalServerName(QStringLiteral("CockatriceSingleInstance")); // Hand off to an already-running primary instance if one exists. Never steal // the socket of a busy primary: it is alive and will act on the payload. diff --git a/cockatrice/src/single_instance_manager.h b/cockatrice/src/single_instance_manager.h index d3884a60f..727994208 100644 --- a/cockatrice/src/single_instance_manager.h +++ b/cockatrice/src/single_instance_manager.h @@ -1,10 +1,12 @@ #ifndef COCKATRICE_SINGLE_INSTANCE_MANAGER_H #define COCKATRICE_SINGLE_INSTANCE_MANAGER_H -#include -#include -#include -#include +#include +#include +#include +#include + +class QLocalServer; class SingleInstanceManager : public QObject { diff --git a/doc/carddatabase_v4/cards.xsd b/doc/carddatabase_v4/cards.xsd index 82aed32ab..df52d6327 100644 --- a/doc/carddatabase_v4/cards.xsd +++ b/doc/carddatabase_v4/cards.xsd @@ -29,8 +29,6 @@ - - diff --git a/doc/doxygen/README.md b/doc/doxygen/README.md index 988147159..230422303 100644 --- a/doc/doxygen/README.md +++ b/doc/doxygen/README.md @@ -1,3 +1,17 @@ +## Building Doxygen Documentation + +We use [Doxygen](https://www.doxygen.nl) for our code documentation. +After installing the tool, you can build a HTML webpage into the `/docs` folder according to our [configuration](https://github.com/Cockatrice/Cockatrice/blob/master/Doxyfile): +```bash +doxygen Doxyfile +``` +Open the `index.html` file in the `/docs/html/` folder to browse the result locally. +There is also an online version we host at the Cockatrice webpage: [cockatrice.github.io/docs](https://cockatrice.github.io/docs) + +Doxygen's own documenation can be found at [www.doxygen.nl/manual](https://www.doxygen.nl/manual). + +
+ ## Doxygen Documentation Theme Required changes to the `Doxyfile` config from the [theme docs](https://jothepro.github.io/doxygen-awesome-css/index.html#autotoc_md16) to make [doxygen-awesome-css](https://github.com/jothepro/doxygen-awesome-css) work: diff --git a/doc/doxygen/extra-pages/developer_documentation/network/game_event_handler.md b/doc/doxygen/extra-pages/developer_documentation/network/game_event_handler.md deleted file mode 100644 index fbb298d3a..000000000 --- a/doc/doxygen/extra-pages/developer_documentation/network/game_event_handler.md +++ /dev/null @@ -1,170 +0,0 @@ -@page game_event_handler GameEventHandler - -## Overview - -`GameEventHandler` is the central coordinator for **game-wide commands and events**. -It acts as the bridge between the networking layer (protobuf messages received from -the server) and the local game model and UI. - -Unlike `PlayerEventHandler`, which is responsible for player-scoped state and zones, -`GameEventHandler` handles: - -- Global game flow (turns, phases, host changes) -- Player and spectator lifecycle events -- Chat and logging events -- Dispatching incoming events to the appropriate subsystem -- Sending locally initiated commands to the server - -In short, it is the **top-level event dispatcher** for an active game. - ---- - -## Responsibilities - -`GameEventHandler` has four primary responsibilities: - -### 1. Sending game-wide commands - -UI actions that affect the game as a whole (e.g. advancing the turn, changing phases, -sending chat messages) are translated into protobuf commands and sent to the server -via this class. - -Examples include: - -- Advancing or reversing the turn order -- Conceding or unconceding -- Changing the active phase -- Leaving the game -- Sending chat messages - -These commands are wrapped in `PendingCommand` instances so their lifecycle and -responses can be tracked. - ---- - -### 2. Processing incoming game events - -Incoming server messages arrive as a `GameEventContainer`. -`GameEventHandler` is responsible for: - -- Emitting lifecycle signals before and after processing -- Dispatching each event to the correct handler -- Forwarding player-scoped events to `PlayerEventHandler` instances -- Handling spectator-only and game-global events directly - -This design keeps networking concerns isolated from game logic and UI code. - ---- - -### 3. Managing global game state transitions - -Certain events affect the entire game state and require coordinated updates across -multiple subsystems. Examples include: - -- Full game state synchronization -- Active player or phase changes -- Game host changes -- Game closure -- Turn reversal - -`GameEventHandler` ensures these events are processed in a consistent order and -that all interested systems are notified via Qt signals. - ---- - -### 4. Emitting UI and logging signals - -Rather than directly manipulating UI widgets, `GameEventHandler` emits -high-level signals that are consumed by: - -- Game widgets -- Player and spectator lists -- Message and event logs -- Status indicators (ready state, deck selection, connection state) - -This keeps the handler independent of concrete UI implementations. - ---- - -## Relationship to PlayerEventHandler - -`GameEventHandler` and `PlayerEventHandler` work together but have distinct roles: - -| GameEventHandler | PlayerEventHandler | -|------------------|--------------------| -| Global game state | Per-player state | -| Turn / phase flow | Zones and cards | -| Player join/leave | Player actions | -| Spectator events | Player-specific events | -| Chat dispatch | Card and zone updates | - -When a server event is associated with a specific player, `GameEventHandler` -routes it to the corresponding `PlayerEventHandler`. Events without a player -context are handled directly. - ---- - -## Event Processing Flow - -A typical incoming event flow looks like this: - -1. `AbstractClient` receives a `GameEventContainer` -2. `GameEventHandler::processGameEventContainer()` is called -3. `containerProcessingStarted()` is emitted -4. Each event is: - - Handled directly **or** - - Forwarded to a `PlayerEventHandler` -5. Logging and UI signals are emitted as needed -6. `containerProcessingDone()` is emitted - -This structured flow makes it easy to: - -- Suppress UI updates during replays -- Handle reconnections cleanly -- Detect flood protection or error states - ---- - -## Command Lifecycle - -Outgoing commands follow a similar structured path: - -1. UI action triggers a `handle*()` method -2. A protobuf command is constructed -3. The command is wrapped in a `PendingCommand` -4. `sendGameCommand()` sends it to the server -5. `commandFinished()` receives the response -6. Errors or flood conditions are handled centrally - -This approach avoids duplicated error handling across UI code. - ---- - -## Design Goals - -`GameEventHandler` is designed to be: - -- **Centralized** – one entry point for all game-wide events -- **UI-agnostic** – communicates via signals, not widgets -- **Predictable** – well-defined event ordering and lifecycle -- **Composable** – works in concert with `PlayerEventHandler` -- **Testable** – logic is separated from rendering - ---- - -## Related Classes - -- @ref GameEventHandler -- @ref PlayerEventHandler -- `GameEventContainer` -- `PendingCommand` -- `AbstractClient` -- `AbstractGame` - ---- - -## See Also - -- @ref GameLogic -- @ref PlayerEventHandler -- @ref GameState diff --git a/doc/doxygen/extra-pages/developer_documentation/network/player_event_handler.md b/doc/doxygen/extra-pages/developer_documentation/network/player_event_handler.md deleted file mode 100644 index 6878758da..000000000 --- a/doc/doxygen/extra-pages/developer_documentation/network/player_event_handler.md +++ /dev/null @@ -1,199 +0,0 @@ -@page player_event_handler PlayerEventHandler - -## Overview - -`PlayerEventHandler` is responsible for applying **player-scoped game events** -to a single `Player` instance. These events modify the player’s board state, -zones, cards, counters, arrows, and associated UI and logging output. - -Each `PlayerEventHandler` instance is bound **1:1 to a Player** and is invoked -exclusively by @ref GameEventHandler after basic routing and validation of -incoming server events. - -This class represents the lowest-level authoritative application of game state -changes on the client. - ---- - -## Scope and Authority - -`PlayerEventHandler` operates under the following guarantees: - -- All incoming events are **authoritative** and already validated by the server -- Events refer to valid players, zones, and card identifiers -- Ordering is guaranteed by the server and preserved by `GameEventHandler` - -As a result, the handler does **not** perform rule validation or permission -checks. Its responsibility is to *apply* state, not *decide* legality. - ---- - -## Responsibilities - -### 1. Applying player-specific state changes - -The primary responsibility of `PlayerEventHandler` is to mutate player-owned -state, including: - -- Cards (`CardItem`) -- Zones (`CardZoneLogic`) -- Counters (card-level and player-level) -- Attachments and arrows -- Zone configuration flags (reveal / peek behavior) - -Many handlers update both **logical state** and **visual/UI state** in tandem. - ---- - -### 2. Coordinating complex card movement - -Some events—most notably card movement—require coordinated updates across -multiple systems. For example, `eventMoveCard()`: - -- Removes the card from the source zone -- Updates ownership, visibility, and identity -- Handles attachments and arrow cleanup -- Emits undo-draw or move logs -- Inserts the card into the destination zone -- Updates menus, hover state, and graphics - -This makes `PlayerEventHandler` intentionally stateful and tightly coupled to -the board implementation. - ---- - -### 3. Emitting logging signals - -Rather than writing directly to logs or widgets, `PlayerEventHandler` emits -structured Qt signals describing *what happened*, including: - -- Chat messages -- Card movement -- Shuffles and randomization -- Reveals and peeks -- Counter and attribute changes - -These signals are consumed by logging systems and UI components, keeping -presentation concerns out of the handler. - -Logging signals may be emitted **before or after mutation**, depending on -whether later changes would invalidate log data (e.g. card identity). - ---- - -### 4. Handling cross-player interactions - -Although bound to a single player, some events necessarily affect other -players’ state, including: - -- Moving cards between players -- Attaching cards to another player’s permanents -- Creating arrows targeting other players or cards - -In these cases, `PlayerEventHandler` performs the minimal required mutation -while respecting ownership boundaries enforced elsewhere. - ---- - -## Event Dispatch Model - -`PlayerEventHandler` exposes a single public entry point: - -- `processGameEvent()` - -This method: - -1. Receives a generic `GameEvent` -2. Switches on `GameEventType` -3. Extracts the appropriate protobuf extension -4. Forwards the event to a typed handler - -This keeps the event routing centralized and makes it easy to audit coverage -when new game events are introduced. - -Unhandled events are logged as warnings. - ---- - -## Event Categories - -For clarity, event handlers are grouped conceptually into: - -- **Chat and randomization** - - Chat messages - - Shuffles - - Dice rolls - -- **Arrows and targeting** - - Create / delete arrows - -- **Card and token creation** - - Token generation - - Counter creation - -- **Card attributes and counters** - - Tapped state - - Power/toughness - - Annotations - - Card- and player-level counters - -- **Zone-level operations** - - Card movement - - Zone dumps - - Card destruction - - Attachments - -- **Draw and reveal** - - Drawing cards - - Reveals, peeks, and reveal windows - -- **Zone configuration** - - Always-reveal and always-look-at-top-card flags - -This grouping mirrors the structure of the header file and reflects the -conceptual responsibilities of the class. - ---- - -## Relationship to GameEventHandler - -`PlayerEventHandler` is never instantiated or invoked directly by UI code. -Instead: - -1. `GameEventHandler` receives a `GameEventContainer` -2. Player-scoped events are routed to the appropriate `PlayerEventHandler` -3. Global or spectator events are handled elsewhere - -This separation keeps game-wide logic decoupled from player board state and -makes reconnection and replay handling simpler. - ---- - -## Design Intent - -`PlayerEventHandler` is designed to be: - -- **Authoritative** – applies server state exactly as received -- **Stateful** – maintains consistency across cards, zones, and UI -- **Explicit** – one handler per event type -- **UI-aware** – updates views and menus as part of state mutation -- **Auditable** – easy to trace what code handles which event - ---- - -## Related Classes - -- @ref PlayerEventHandler -- @ref GameEventHandler -- `Player` -- `CardItem` -- `CardZoneLogic` -- `GameEvent` -- `GameEventContext` - ---- - -## See Also - -- @ref GameLogicPlayers -- @ref GameLogic diff --git a/doc/doxygen/images/cockatrice_logo.svg b/doc/doxygen/images/cockatrice_logo.svg new file mode 100644 index 000000000..89ba62dcf --- /dev/null +++ b/doc/doxygen/images/cockatrice_logo.svg @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/doxygen/images/classic_database_display.png b/doc/doxygen/images/screenshots/classic_database_display.png similarity index 100% rename from doc/doxygen/images/classic_database_display.png rename to doc/doxygen/images/screenshots/classic_database_display.png diff --git a/doc/doxygen/images/classic_database_display_add_buttons.png b/doc/doxygen/images/screenshots/classic_database_display_add_buttons.png similarity index 100% rename from doc/doxygen/images/classic_database_display_add_buttons.png rename to doc/doxygen/images/screenshots/classic_database_display_add_buttons.png diff --git a/doc/doxygen/images/classic_deck_editor.png b/doc/doxygen/images/screenshots/classic_deck_editor.png similarity index 100% rename from doc/doxygen/images/classic_deck_editor.png rename to doc/doxygen/images/screenshots/classic_deck_editor.png diff --git a/doc/doxygen/images/deck_dock_deck_list.png b/doc/doxygen/images/screenshots/deck_dock_deck_list.png similarity index 100% rename from doc/doxygen/images/deck_dock_deck_list.png rename to doc/doxygen/images/screenshots/deck_dock_deck_list.png diff --git a/doc/doxygen/images/deck_dock_deck_list_buttons.png b/doc/doxygen/images/screenshots/deck_dock_deck_list_buttons.png similarity index 100% rename from doc/doxygen/images/deck_dock_deck_list_buttons.png rename to doc/doxygen/images/screenshots/deck_dock_deck_list_buttons.png diff --git a/doc/doxygen/images/deck_dock_deck_list_group_by.png b/doc/doxygen/images/screenshots/deck_dock_deck_list_group_by.png similarity index 100% rename from doc/doxygen/images/deck_dock_deck_list_group_by.png rename to doc/doxygen/images/screenshots/deck_dock_deck_list_group_by.png diff --git a/doc/doxygen/images/deckeditordeckdockwidget.png b/doc/doxygen/images/screenshots/deckeditordeckdockwidget.png similarity index 100% rename from doc/doxygen/images/deckeditordeckdockwidget.png rename to doc/doxygen/images/screenshots/deckeditordeckdockwidget.png diff --git a/doc/doxygen/images/printing_selector.png b/doc/doxygen/images/screenshots/printing_selector.png similarity index 100% rename from doc/doxygen/images/printing_selector.png rename to doc/doxygen/images/screenshots/printing_selector.png diff --git a/doc/doxygen/images/printing_selector_disable.png b/doc/doxygen/images/screenshots/printing_selector_disable.png similarity index 100% rename from doc/doxygen/images/printing_selector_disable.png rename to doc/doxygen/images/screenshots/printing_selector_disable.png diff --git a/doc/doxygen/images/printing_selector_enable.png b/doc/doxygen/images/screenshots/printing_selector_enable.png similarity index 100% rename from doc/doxygen/images/printing_selector_enable.png rename to doc/doxygen/images/screenshots/printing_selector_enable.png diff --git a/doc/doxygen/images/printing_selector_navigation.png b/doc/doxygen/images/screenshots/printing_selector_navigation.png similarity index 100% rename from doc/doxygen/images/printing_selector_navigation.png rename to doc/doxygen/images/screenshots/printing_selector_navigation.png diff --git a/doc/doxygen/images/printing_selector_options.png b/doc/doxygen/images/screenshots/printing_selector_options.png similarity index 100% rename from doc/doxygen/images/printing_selector_options.png rename to doc/doxygen/images/screenshots/printing_selector_options.png diff --git a/doc/doxygen/images/printing_selector_pre_providerid.png b/doc/doxygen/images/screenshots/printing_selector_pre_providerid.png similarity index 100% rename from doc/doxygen/images/printing_selector_pre_providerid.png rename to doc/doxygen/images/screenshots/printing_selector_pre_providerid.png diff --git a/doc/doxygen/images/release_channel_beta.png b/doc/doxygen/images/screenshots/release_channel_beta.png similarity index 100% rename from doc/doxygen/images/release_channel_beta.png rename to doc/doxygen/images/screenshots/release_channel_beta.png diff --git a/doc/doxygen/images/vde_deck_analytics.png b/doc/doxygen/images/screenshots/vde_deck_analytics.png similarity index 100% rename from doc/doxygen/images/vde_deck_analytics.png rename to doc/doxygen/images/screenshots/vde_deck_analytics.png diff --git a/doc/doxygen/images/vde_flat_layout_color_grouped.png b/doc/doxygen/images/screenshots/vde_flat_layout_color_grouped.png similarity index 100% rename from doc/doxygen/images/vde_flat_layout_color_grouped.png rename to doc/doxygen/images/screenshots/vde_flat_layout_color_grouped.png diff --git a/doc/doxygen/images/vde_flat_layout_type_grouped.png b/doc/doxygen/images/screenshots/vde_flat_layout_type_grouped.png similarity index 100% rename from doc/doxygen/images/vde_flat_layout_type_grouped.png rename to doc/doxygen/images/screenshots/vde_flat_layout_type_grouped.png diff --git a/doc/doxygen/images/vde_overlap_layout_type_grouped.png b/doc/doxygen/images/screenshots/vde_overlap_layout_type_grouped.png similarity index 100% rename from doc/doxygen/images/vde_overlap_layout_type_grouped.png rename to doc/doxygen/images/screenshots/vde_overlap_layout_type_grouped.png diff --git a/doc/doxygen/images/vde_sample_hand.png b/doc/doxygen/images/screenshots/vde_sample_hand.png similarity index 100% rename from doc/doxygen/images/vde_sample_hand.png rename to doc/doxygen/images/screenshots/vde_sample_hand.png diff --git a/doc/doxygen/extra-pages/developer_documentation/card_database_schema_and_parsing.md b/doc/doxygen/pages/developer_documentation/card_database_schema_and_parsing.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/card_database_schema_and_parsing.md rename to doc/doxygen/pages/developer_documentation/card_database_schema_and_parsing.md diff --git a/doc/doxygen/extra-pages/developer_documentation/displaying_cards.md b/doc/doxygen/pages/developer_documentation/displaying_cards.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/displaying_cards.md rename to doc/doxygen/pages/developer_documentation/displaying_cards.md diff --git a/doc/doxygen/extra-pages/developer_documentation/index.md b/doc/doxygen/pages/developer_documentation/index.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/index.md rename to doc/doxygen/pages/developer_documentation/index.md diff --git a/doc/doxygen/extra-pages/developer_documentation/loading_card_pictures.md b/doc/doxygen/pages/developer_documentation/loading_card_pictures.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/loading_card_pictures.md rename to doc/doxygen/pages/developer_documentation/loading_card_pictures.md diff --git a/doc/doxygen/extra-pages/developer_documentation/logging.md b/doc/doxygen/pages/developer_documentation/logging.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/logging.md rename to doc/doxygen/pages/developer_documentation/logging.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/client/game_event_handler.md b/doc/doxygen/pages/developer_documentation/network/client/game_event_handler.md similarity index 93% rename from doc/doxygen/extra-pages/developer_documentation/network/client/game_event_handler.md rename to doc/doxygen/pages/developer_documentation/network/client/game_event_handler.md index fbb298d3a..051823c6c 100644 --- a/doc/doxygen/extra-pages/developer_documentation/network/client/game_event_handler.md +++ b/doc/doxygen/pages/developer_documentation/network/client/game_event_handler.md @@ -90,13 +90,13 @@ This keeps the handler independent of concrete UI implementations. `GameEventHandler` and `PlayerEventHandler` work together but have distinct roles: -| GameEventHandler | PlayerEventHandler | -|------------------|--------------------| -| Global game state | Per-player state | -| Turn / phase flow | Zones and cards | -| Player join/leave | Player actions | -| Spectator events | Player-specific events | -| Chat dispatch | Card and zone updates | +| GameEventHandler | PlayerEventHandler | +| ----------------- | ---------------------- | +| Global game state | Per-player state | +| Turn / phase flow | Zones and cards | +| Player join/leave | Player actions | +| Spectator events | Player-specific events | +| Chat dispatch | Card and zone updates | When a server event is associated with a specific player, `GameEventHandler` routes it to the corresponding `PlayerEventHandler`. Events without a player diff --git a/doc/doxygen/extra-pages/developer_documentation/network/client/index.md b/doc/doxygen/pages/developer_documentation/network/client/index.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/client/index.md rename to doc/doxygen/pages/developer_documentation/network/client/index.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/client/player_event_handler.md b/doc/doxygen/pages/developer_documentation/network/client/player_event_handler.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/client/player_event_handler.md rename to doc/doxygen/pages/developer_documentation/network/client/player_event_handler.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/index.md b/doc/doxygen/pages/developer_documentation/network/index.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/index.md rename to doc/doxygen/pages/developer_documentation/network/index.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/protocol/index.md b/doc/doxygen/pages/developer_documentation/network/protocol/index.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/protocol/index.md rename to doc/doxygen/pages/developer_documentation/network/protocol/index.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_command_container.md b/doc/doxygen/pages/developer_documentation/network/protocol/protocol_command_container.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_command_container.md rename to doc/doxygen/pages/developer_documentation/network/protocol/protocol_command_container.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_game_command.md b/doc/doxygen/pages/developer_documentation/network/protocol/protocol_game_command.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_game_command.md rename to doc/doxygen/pages/developer_documentation/network/protocol/protocol_game_command.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_overview.md b/doc/doxygen/pages/developer_documentation/network/protocol/protocol_overview.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_overview.md rename to doc/doxygen/pages/developer_documentation/network/protocol/protocol_overview.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_response.md b/doc/doxygen/pages/developer_documentation/network/protocol/protocol_response.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_response.md rename to doc/doxygen/pages/developer_documentation/network/protocol/protocol_response.md diff --git a/doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_server_message.md b/doc/doxygen/pages/developer_documentation/network/protocol/protocol_server_message.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/network/protocol/protocol_server_message.md rename to doc/doxygen/pages/developer_documentation/network/protocol/protocol_server_message.md diff --git a/doc/doxygen/extra-pages/developer_documentation/primer_cards.md b/doc/doxygen/pages/developer_documentation/primer_cards.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/primer_cards.md rename to doc/doxygen/pages/developer_documentation/primer_cards.md diff --git a/doc/doxygen/extra-pages/developer_documentation/querying_the_card_database.md b/doc/doxygen/pages/developer_documentation/querying_the_card_database.md similarity index 100% rename from doc/doxygen/extra-pages/developer_documentation/querying_the_card_database.md rename to doc/doxygen/pages/developer_documentation/querying_the_card_database.md diff --git a/doc/doxygen/extra-pages/index.md b/doc/doxygen/pages/index.md similarity index 77% rename from doc/doxygen/extra-pages/index.md rename to doc/doxygen/pages/index.md index b3363d3f4..9dafe1882 100644 --- a/doc/doxygen/extra-pages/index.md +++ b/doc/doxygen/pages/index.md @@ -1,5 +1,9 @@ @mainpage Documentation +
+ +
+ Welcome to the Cockatrice code documentation. - @subpage user_reference diff --git a/doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md b/doc/doxygen/pages/user_documentation/card_pictures/custom_card_pictures.md similarity index 84% rename from doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md rename to doc/doxygen/pages/user_documentation/card_pictures/custom_card_pictures.md index 3f1079661..bcea6db8b 100644 --- a/doc/doxygen/extra-pages/user_documentation/card_pictures/custom_card_pictures.md +++ b/doc/doxygen/pages/user_documentation/card_pictures/custom_card_pictures.md @@ -69,17 +69,17 @@ the 'Deck Editor' tab, in the 'URL Download Priority' section. The following reference points are available: -| Reference point | Description | Example | -| ------------------------------- | ------------------------------- | -------------- | -| `!name!` | Card name | `Example Card` | -| `!name_lower!` | Card name, lower case | `example card` | -| `!corrected_name!` | Corrected card name | `ExampleCard` (instead of "Example // Card") | -| `!corrected_name_lower!` | Corrected card name, lower case | `examplecard` | -| `!sflang!` | Scryfall language code for the current client language; defaults to English when the language has no localized images | `en`, `zhs` | -| `!setcode!` / `!setcode_lower!` | Set code | `EXM` / `exm` | -| `!setname!` / `!setname_lower!` | Full set name | `Exemplary Set` / `exemplary set` | -| `!set:!` | A property of this printing, e.g. `muid` (Gatherer multiverse ID), `uuid` (Scryfall UUID), `num` (collector number), `rarity` | `373549` | -| `!prop:!` | A property of the card, e.g. `side` (front/back), `colors`, `cmc`, `coloridentity`, `type`, `pt`, and the format legality statuses | `front` | +| Reference point | Description | Example | +| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| `!name!` | Card name | `Example Card` | +| `!name_lower!` | Card name, lower case | `example card` | +| `!corrected_name!` | Corrected card name | `ExampleCard` (instead of "Example // Card") | +| `!corrected_name_lower!` | Corrected card name, lower case | `examplecard` | +| `!sflang!` | Scryfall language code for the current client language; defaults to English when the language has no localized images | `en`, `zhs` | +| `!setcode!` / `!setcode_lower!` | Set code | `EXM` / `exm` | +| `!setname!` / `!setname_lower!` | Full set name | `Exemplary Set` / `exemplary set` | +| `!set:!` | A property of this printing, e.g. `muid` (Gatherer multiverse ID), `uuid` (Scryfall UUID), `num` (collector number), `rarity` | `373549` | +| `!prop:!` | A property of the card, e.g. `side` (front/back), `colors`, `cmc`, `coloridentity`, `type`, `pt`, and the format legality statuses | `front` | The `!set:...!` and `!prop:...!` reference points support two modifiers: diff --git a/doc/doxygen/extra-pages/user_documentation/deck_management/creating_decks.md b/doc/doxygen/pages/user_documentation/deck_management/creating_decks.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/deck_management/creating_decks.md rename to doc/doxygen/pages/user_documentation/deck_management/creating_decks.md diff --git a/doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks.md b/doc/doxygen/pages/user_documentation/deck_management/editing_decks.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks.md rename to doc/doxygen/pages/user_documentation/deck_management/editing_decks.md diff --git a/doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks_classic.md b/doc/doxygen/pages/user_documentation/deck_management/editing_decks_classic.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks_classic.md rename to doc/doxygen/pages/user_documentation/deck_management/editing_decks_classic.md diff --git a/doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks_printings.md b/doc/doxygen/pages/user_documentation/deck_management/editing_decks_printings.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks_printings.md rename to doc/doxygen/pages/user_documentation/deck_management/editing_decks_printings.md diff --git a/doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks_visual.md b/doc/doxygen/pages/user_documentation/deck_management/editing_decks_visual.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/deck_management/editing_decks_visual.md rename to doc/doxygen/pages/user_documentation/deck_management/editing_decks_visual.md diff --git a/doc/doxygen/extra-pages/user_documentation/deck_management/exporting_decks.md b/doc/doxygen/pages/user_documentation/deck_management/exporting_decks.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/deck_management/exporting_decks.md rename to doc/doxygen/pages/user_documentation/deck_management/exporting_decks.md diff --git a/doc/doxygen/extra-pages/user_documentation/deck_management/importing_decks.md b/doc/doxygen/pages/user_documentation/deck_management/importing_decks.md similarity index 77% rename from doc/doxygen/extra-pages/user_documentation/deck_management/importing_decks.md rename to doc/doxygen/pages/user_documentation/deck_management/importing_decks.md index e9626d57f..4aab7ad2c 100644 --- a/doc/doxygen/extra-pages/user_documentation/deck_management/importing_decks.md +++ b/doc/doxygen/pages/user_documentation/deck_management/importing_decks.md @@ -38,7 +38,18 @@ Selecting this action will open a new text editor dialog with the contents of yo The import dialog expects each line to be a card with the following format: -TODO +`[quantity] Card Name [options]` + +- `quantity` is the number of copies and can be written as `2`, `2x` or `2X`. If omitted, a single copy is imported. +- `options` are appended after the card name and are understood on a best-effort basis: + - a set code and collector number, either as `Card Name (SET) 123` or `Card Name (SET) 123-1` + - a foil marker, `Card Name *F*` +- Lines can also carry a `SB:` prefix or a set code prefix (`[SET]`) — Cockatrice tries to stay compatible with the most + common deck formats. + +Tab-separated exports from third-party apps (such as Delver Lens) are also accepted: any line whose first column is a +plain quantity treats the following columns as the card name and printer/set metadata (which is discarded), for example +`2\tCard Name\tSet Name`. Each card should be on a separate line and there should be no empty lines between cards. The first empty line between two blocks of cards will be considered as the divider between mainboard and sideboard. diff --git a/doc/doxygen/extra-pages/user_documentation/index.md b/doc/doxygen/pages/user_documentation/index.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/index.md rename to doc/doxygen/pages/user_documentation/index.md diff --git a/doc/doxygen/extra-pages/user_documentation/settings/beta.md b/doc/doxygen/pages/user_documentation/settings/beta.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/settings/beta.md rename to doc/doxygen/pages/user_documentation/settings/beta.md diff --git a/doc/doxygen/extra-pages/user_documentation/settings/settings_folder.md b/doc/doxygen/pages/user_documentation/settings/settings_folder.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/settings/settings_folder.md rename to doc/doxygen/pages/user_documentation/settings/settings_folder.md diff --git a/doc/doxygen/extra-pages/user_documentation/troubleshooting/enabling_debug_logs.md b/doc/doxygen/pages/user_documentation/troubleshooting/enabling_debug_logs.md similarity index 97% rename from doc/doxygen/extra-pages/user_documentation/troubleshooting/enabling_debug_logs.md rename to doc/doxygen/pages/user_documentation/troubleshooting/enabling_debug_logs.md index 7e4196a50..27c4272f5 100644 --- a/doc/doxygen/extra-pages/user_documentation/troubleshooting/enabling_debug_logs.md +++ b/doc/doxygen/pages/user_documentation/troubleshooting/enabling_debug_logs.md @@ -110,6 +110,7 @@ suffix, e.g. `card_picture_loader.*`, to include all sub categories). | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Card picture loading (URLs, local file hits/misses, downloads, redirects) | `card_picture_loader.*` | | Card database loading and parsing | `card_database`, `card_database.loading`, `card_database.loading.success_or_failure`, `cockatrice_xml.*` | +| Card database update (running Oracle, progress, exit status, errors) | `card_database.update` | | Card, set, and deck information | `card_info`, `card_list`, `deck_loader` | | Startup sequence and update checks | `window_main.startup.*`, `release_channel`, `spoiler_background_updater` | | User interface and themes | `theme_manager`, `sound_engine`, `flow_layout`, `flow_widget.*`, `pixel_map_generator`, `card_info_picture_widget` | @@ -128,6 +129,7 @@ For example, to investigate why a card database update seems to fail, enable the card_database = true card_database.loading = true card_database.loading.success_or_failure = true +card_database.update = true cockatrice_xml.* = true ``` diff --git a/doc/doxygen/extra-pages/user_documentation/troubleshooting/fixing_card_pictures.md b/doc/doxygen/pages/user_documentation/troubleshooting/fixing_card_pictures.md similarity index 100% rename from doc/doxygen/extra-pages/user_documentation/troubleshooting/fixing_card_pictures.md rename to doc/doxygen/pages/user_documentation/troubleshooting/fixing_card_pictures.md diff --git a/gcovr.cfg b/gcovr.cfg new file mode 100644 index 000000000..ac893b6a4 --- /dev/null +++ b/gcovr.cfg @@ -0,0 +1,63 @@ +# gcovr configuration for Cockatrice line coverage. +# +# Used by .ci/compile.sh --coverage and by hand: +# +# cmake -S . -B build/cover -DCMAKE_BUILD_TYPE=Debug -DWITH_SERVER=1 -DTEST=1 -DENABLE_COVERAGE=ON +# cmake --build build/cover -j 24 +# ctest --test-dir build/cover -LE bench -j 24 +# gcovr build/cover --root . --object-directory build/cover --txt --decisions +# +# The point of most of this file is subtraction. A raw report is dominated by code no test can +# reach: vendored third-party trees, build directories left over from earlier experiments, and +# the client's main() and window classes, which have no headless test. Those all dilute the one +# number worth watching, so they are filtered out here rather than in every invocation. + +# root is deliberately not set here. This file is normally invoked from the build directory +# (compile.sh runs there, because it configures with `cmake ..`), so a `root` of `.` would +# resolve to the build tree and every filter below would exclude everything. compile.sh passes +# --root explicitly instead. + +# Our own code only. This keeps generated Qt MOC output, protobuf output and anything CMake +# built under the source tree out of the report. +filter = ^cockatrice/ +filter = ^libcockatrice_[^/]+/ +filter = ^servatrice/ +filter = ^oracle/ + +# The tests are the vehicle, not the subject. They are compiled with the same instrumentation, +# so leaving them in would add their near-perfect coverage to the numerator and quietly report a +# healthier project than we have: test code is only ever executed by the run that is measuring +# it. Helpers under tests/ are excluded on the same grounds. +exclude = ^tests/ + +# Vendored third-party code is not ours to cover and is never going to move the number. +exclude = ^vcpkg/ +exclude = ^doc/doxygen/theme/ +exclude = ^libcockatrice_rng/libcockatrice/rng/sfmt/ +exclude = ^libcockatrice_utility/libcockatrice/utility/peglib\.h$ +exclude = ^oracle/src/lzma/ +exclude = ^oracle/src/qt-json/ +exclude = ^oracle/src/zip/ +exclude = ^servatrice/src/smtp/ + +# Qt's own moc/pch/uic output is generated into the build tree, not the source tree, so the +# filters above already keep it out. These cover CLion's directories, which sit in-tree and are +# picked up by the object-directory walk. +exclude = .*cmake-build-.* +exclude = .*\.cache/ + +# Process entry points and the client's window chrome. Each of these needs a display, an +# interactive terminal, or a live database before it does anything a test could observe, so no +# headless run will ever move them. Left in, they contribute thousands of lines at 0% and drag +# the total down by a fixed amount that hides movement in the code we can actually test. The +# window header is excluded with its .cpp because gcovr attributes its inline template code +# there, which is where most of its line count lives. +exclude = ^cockatrice/src/main\.cpp$ +exclude = ^cockatrice/src/interface/window_main\. +exclude = ^oracle/src/main\.cpp$ +exclude = ^servatrice/src/main\.cpp$ + +exclude-throw-branches = yes +exclude-function-lines = yes + +print-summary = yes diff --git a/iwyu.sh b/iwyu.sh new file mode 100755 index 000000000..279200adf --- /dev/null +++ b/iwyu.sh @@ -0,0 +1,226 @@ +#!/bin/bash + +# This script runs include-what-you-use on the given source files or +# directories, applies its suggestions (forward declarations, minimal and +# canonical #includes), then reformats the touched files with clang-format. +# +# Uses include-what-you-use, iwyu_tool.py, fix_includes.py, clang-format and +# python3. Requires a build directory configured with +# -DCMAKE_EXPORT_COMPILE_COMMANDS=ON to provide compile_commands.json. +# +# The Qt 6 mapping (qt6.imp) makes IWYU prefer capital includes like +# #include over #include and keeps forward declarations +# where possible. Regenerate it with tools/generate_qt_mappings.py whenever the +# installed Qt version changes. +# +# Usage: +# ./iwyu.sh [-b ] [-m ] [-j ] [-n] +# +# Options: +# -b, --build-dir DIR build dir with compile_commands.json (default: build) +# -m, --mapping FILE IWYU mapping file (default: qt6.imp) +# -j, --jobs N IWYU parallel jobs (default: 2) +# -n, --dry-run only print IWYU output, do not modify any file + +set -o pipefail + +# go to the project root directory, this file should be located in the project root directory +cd "${BASH_SOURCE%/*}/" || exit 2 # could not find path, this could happen with special links etc. + +# defaults +build_dir="build" +mapping="qt6.imp" +jobs=2 +dry_run=0 + +# 3rd party code that must not be touched by IWYU or clang-format +excludes=("libcockatrice_rng/libcockatrice/rng/sfmt/" \ +"libcockatrice_utility/libcockatrice/utility/peglib.h" \ +"oracle/src/lzma/" \ +"oracle/src/qt-json/" \ +"oracle/src/zip/" \ +"servatrice/src/smtp/") + +usage() { + cat <] [-m ] [-j ] [-n] + +Runs include-what-you-use on the given files/directories, applies the +suggested include changes in place, and reformats touched files. + +Options: + -b, --build-dir DIR build dir with compile_commands.json (default: build) + -m, --mapping FILE IWYU mapping file (default: qt6.imp) + -j, --jobs N IWYU parallel jobs (default: 2) + -n, --dry-run only print IWYU output, do not modify any file + -h, --help show this help +EOM +} + +# parse options +while [[ $* ]]; do + case "$1" in + '-b'|'--build-dir') + build_dir=$2 + shift 2 + ;; + '-m'|'--mapping') + mapping=$2 + shift 2 + ;; + '-j'|'--jobs') + jobs=$2 + shift 2 + ;; + '-n'|'--dry-run') + dry_run=1 + shift + ;; + '-h'|'--help') + usage + exit 0 + ;; + *) + targets+=("$1") + shift + ;; + esac +done + +# find the IWYU tools, preferring PATH and falling back to the LLVM dir +find_tool() { + local tool=$1 + local path + if path=$(command -v "$tool" 2>/dev/null); then + echo "$path" + elif [ -x "/usr/lib/llvm/22/bin/$tool" ]; then + echo "/usr/lib/llvm/22/bin/$tool" + else + return 1 + fi +} + +find_tool include-what-you-use > /dev/null || { echo "error: include-what-you-use not found"; exit 1; } +IWYU_TOOL=$(find_tool iwyu_tool.py) || { echo "error: iwyu_tool.py not found"; exit 1; } +FIX_INCLUDES=$(find_tool fix_includes.py) || { echo "error: fix_includes.py not found"; exit 1; } +command -v clang-format >/dev/null 2>&1 || { echo "error: clang-format not found"; exit 1; } + +if [ "${#targets[@]}" -eq 0 ]; then + echo "error: specify at least one source file or directory" >&2 + usage + exit 1 +fi + +if [ ! -f "$mapping" ]; then + echo "error: mapping file '$mapping' not found" >&2 + exit 1 +fi + +if [ ! -f "$build_dir/compile_commands.json" ]; then + echo "error: '$build_dir/compile_commands.json' not found" >&2 + echo "configure the build with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON first" >&2 + exit 1 +fi + +tmpdir=$(mktemp -d /tmp/iwyu.XXXXXX) +trap 'rm -rf "$tmpdir"' EXIT + +# filter the compilation database: drop excluded 3rd party code and strip the +# GCC-only flags that clang/include-what-you-use rejects +root="$PWD" +python3 - "$build_dir/compile_commands.json" "$root" "${excludes[@]}" <<'PYEOF' > "$tmpdir/compile_commands.json" +import json +import os +import re +import sys + +cc_path, root = sys.argv[1], sys.argv[2] +excludes = sys.argv[3:] +root = os.path.normpath(root) +excl_norm = [os.path.normpath(os.path.join(root, e)) for e in excludes] + +out = [] +for entry in json.load(open(cc_path)): + path = os.path.normpath(entry['file']) + if not path.startswith(root + os.sep): + continue + # skip generated code: protobuf output and moc autogen files + if re.search(r'\.pb\.(h|cc)$', path) or '_autogen/' in path: + continue + if any(path.startswith(e + os.sep) or path == e for e in excl_norm): + continue + command = entry.get('command', '') + command = re.sub(r'-mno-direct-extern-access', '', command) + command = re.sub(r'--coverage', '', command) + out.append(dict(entry, command=command)) + +json.dump(out, sys.stdout) +PYEOF + +mapping_abs="$PWD/$mapping" +if [ "$dry_run" = 1 ]; then + python3 "$IWYU_TOOL" -p "$tmpdir" -o iwyu -j "$jobs" "${targets[@]}" \ + -- -Xiwyu "--mapping_file=$mapping_abs" +else + before=$(git diff --name-only 2>/dev/null | sort -u) + + python3 "$IWYU_TOOL" -p "$tmpdir" -o iwyu -j "$jobs" "${targets[@]}" \ + -- -Xiwyu "--mapping_file=$mapping_abs" | + python3 "$FIX_INCLUDES" --nosafe_headers --nocomments --noreorder --basedir="$root" + + # fix_includes can emit absolute paths for headers that the compiler resolved + # through an absolute -I entry. Those are machine-specific and break every + # other checkout and CI, so rewrite them into the project-relative quoted + # form the codebase uses. Must run before clang-format so the regroup/sort + # pass sees the final paths. + python3 - "$root" <<'PYEOF' +import os +import re +import subprocess +import sys + +root = os.path.normpath(sys.argv[1]) +pattern = re.compile(r'^(\s*#\s*include\s*)"(/)') + +# Collect from git so untracked scratch files are left alone. +changed = subprocess.run( + ['git', 'diff', '--name-only', '--diff-filter=ACMR'], + capture_output=True, text=True, check=True).stdout.split() + +for rel in changed: + if not rel.endswith(('.h', '.cpp', '.cc', '.cxx')): + continue + path = os.path.join(root, rel) + if not os.path.isfile(path): + continue + src = open(path, encoding='utf-8').read() + if '"' + os.sep not in src: + continue + out = [] + for line in src.split('\n'): + m = pattern.match(line) + if not m: + out.append(line) + continue + target = os.path.normpath(line[m.end(1) + 1:].rstrip('"')) + if not target.startswith(root + os.sep): + out.append(line) + continue + spelled = os.path.relpath(target, os.path.dirname(path)) + out.append(f'{m.group(1)}"{spelled}"') + new = '\n'.join(out) + if new != src: + open(path, 'w', encoding='utf-8').write(new) +PYEOF + + # reformat every file this IWYU pass modified (fix_includes also touches + # headers pulled in by the requested files) + touched=$(comm -13 <(printf '%s\n' "$before") <(git diff --name-only 2>/dev/null | sort -u)) + for file in $touched; do + case "$file" in + *.h|*.cpp) + clang-format -i "$file" + ;; + esac + done +fi diff --git a/libcockatrice_card/CMakeLists.txt b/libcockatrice_card/CMakeLists.txt index 15388ecfc..b3583522c 100644 --- a/libcockatrice_card/CMakeLists.txt +++ b/libcockatrice_card/CMakeLists.txt @@ -60,3 +60,5 @@ target_link_libraries( PUBLIC libcockatrice_utility PUBLIC ${QT_CORE_MODULE} ) + +target_precompile_headers(libcockatrice_card PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_card/libcockatrice/card/card_info.cpp b/libcockatrice_card/libcockatrice/card/card_info.cpp index 56c737793..bd33f18e7 100644 --- a/libcockatrice_card/libcockatrice/card/card_info.cpp +++ b/libcockatrice_card/libcockatrice/card/card_info.cpp @@ -1,21 +1,17 @@ #include "card_info.h" #include "game_specific_terms.h" +#include "libcockatrice/card/lazy_properties_hash.h" #include "printing/printing_info.h" #include "relation/card_relation.h" #include "set/card_set.h" -#include +#include #include #include #include -#include #include -class CardRelation; -class CardSet; -class CardInfo; - using CardInfoPtr = QSharedPointer; const QHash &CardInfo::getPropertiesHash() const diff --git a/libcockatrice_card/libcockatrice/card/card_info.h b/libcockatrice_card/libcockatrice/card/card_info.h index 17894cec5..356da0546 100644 --- a/libcockatrice_card/libcockatrice/card/card_info.h +++ b/libcockatrice_card/libcockatrice/card/card_info.h @@ -5,15 +5,19 @@ #include "lazy_properties_hash.h" #include "printing/printing_info.h" -#include +#include +#include #include #include #include #include #include -#include +#include +#include #include -#include +#include +#include +#include #include inline Q_LOGGING_CATEGORY(CardInfoLog, "card_info"); @@ -21,7 +25,6 @@ inline Q_LOGGING_CATEGORY(CardInfoLog, "card_info"); class CardInfo; class CardSet; class CardRelation; -class ICardDatabaseParser; typedef QSharedPointer CardInfoPtr; typedef QSharedPointer CardSetPtr; diff --git a/libcockatrice_card/libcockatrice/card/card_info_comparator.cpp b/libcockatrice_card/libcockatrice/card/card_info_comparator.cpp index cc0314e21..d0800e596 100644 --- a/libcockatrice_card/libcockatrice/card/card_info_comparator.cpp +++ b/libcockatrice_card/libcockatrice/card/card_info_comparator.cpp @@ -1,5 +1,11 @@ #include "card_info_comparator.h" +#include "libcockatrice/card/card_info.h" + +#include +#include +#include + CardInfoComparator::CardInfoComparator(const QStringList &properties, Qt::SortOrder order) : m_properties(properties), m_order(order) { diff --git a/libcockatrice_card/libcockatrice/card/card_info_comparator.h b/libcockatrice_card/libcockatrice/card/card_info_comparator.h index b6df8c7a3..b184f5d55 100644 --- a/libcockatrice_card/libcockatrice/card/card_info_comparator.h +++ b/libcockatrice_card/libcockatrice/card/card_info_comparator.h @@ -9,6 +9,9 @@ #include "card_info.h" +#include +#include +#include #include #include diff --git a/libcockatrice_card/libcockatrice/card/card_localization.cpp b/libcockatrice_card/libcockatrice/card/card_localization.cpp index 03c6c659b..4f91bac78 100644 --- a/libcockatrice_card/libcockatrice/card/card_localization.cpp +++ b/libcockatrice_card/libcockatrice/card/card_localization.cpp @@ -1,8 +1,10 @@ #include "card_localization.h" #include +#include #include #include +#include namespace CardLocalization { diff --git a/libcockatrice_card/libcockatrice/card/card_localization.h b/libcockatrice_card/libcockatrice/card/card_localization.h index 1bde506cb..ee2aaa9b7 100644 --- a/libcockatrice_card/libcockatrice/card/card_localization.h +++ b/libcockatrice_card/libcockatrice/card/card_localization.h @@ -1,6 +1,8 @@ #ifndef CARD_LOCALIZATION_H #define CARD_LOCALIZATION_H +#include +#include #include #include diff --git a/libcockatrice_card/libcockatrice/card/database/card_database.cpp b/libcockatrice_card/libcockatrice/card/database/card_database.cpp index 209b9d2c2..7b0d5b2f9 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database.cpp +++ b/libcockatrice_card/libcockatrice/card/database/card_database.cpp @@ -1,17 +1,28 @@ #include "card_database.h" #include "../relation/card_relation.h" -#include "card_database_manager.h" -#include "parser/cockatrice_xml_4.h" +#include "libcockatrice/card/database/card_database_data.h" +#include "libcockatrice/card/database/card_database_loader.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/database/parser/card_database_parser.h" +#include "libcockatrice/card/format/format_legality_rules.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/card/set/card_set_list.h" -#include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include +class ICardDatabasePathProvider; +class ICardPreferenceProvider; +class ICardSetPriorityController; + CardDatabase::CardDatabase(QObject *parent, ICardPreferenceProvider *prefs, ICardDatabasePathProvider *pathProvider, @@ -23,7 +34,7 @@ CardDatabase::CardDatabase(QObject *parent, qRegisterMetaType("CardDatabaseData"); // create loader and wire it up - loader = new CardDatabaseLoader(this, this, pathProvider, prefs, setPriorityController); + loader = new CardDatabaseLoader(this, this, pathProvider, setPriorityController); // 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); @@ -68,15 +79,19 @@ void CardDatabase::loadCardDatabases() void CardDatabase::reloadCardDatabasesAndNotify() { - loadCardDatabases(); + // An explicit reload bypasses the binary cache so the files on disk are + // always re-read, even when their size/mtime hash still matches the cache. + // Models refresh from the swap's cardDatabaseReset in a single batch, so + // no cardDatabaseEnabledSetsChanged is emitted here: that rebuilt the + // 36k-card models a second time on the GUI thread, which froze startup + // after enabling new/custom sets. The follow-up unknown-sets check is + // queued to the GUI thread so it sees the swapped-in data (this may run + // on a worker via QtConcurrent::run); it is silent unless new sets + // appeared mid-reload. + loadStatus = loader->loadCardDatabases(/* ignoreCache */ true); if (loadStatus == Ok) { - checkUnknownSets(); - // A reload reconstructs the exact same enabled-set state, so the cached - // set-name / alt-name data computed during construction is still valid. - // Skipping the per-card refresh avoids a full 36k-card recompute that - // would otherwise duplicate the work already done while building cards. - notifyEnabledSetsChanged(false); + QMetaObject::invokeMethod(this, &CardDatabase::checkUnknownSets, Qt::AutoConnection); } } @@ -195,15 +210,19 @@ void CardDatabase::checkUnknownSets() if (numUnknownSets > 0) { emit cardDatabaseNewSetsFound(numUnknownSets, unknownSetNames); } else { - _sets.markAllAsKnown(); + _sets.markAllAsKnownBatched(setPriorityController); } } else { // No set enabled. Probably this is the first time running trice - _sets.guessSortKeys(); + _sets.enableAllBatched(setPriorityController); _sets.sortByKey(); - _sets.enableAll(); - notifyEnabledSetsChanged(); + // No cardDatabaseEnabledSetsChanged here: the reload chained off + // cardDatabaseAllNewSetsEnabled re-parses with the sets enabled and its + // swap's cardDatabaseReset rebuilds the models in one batch. Emitting + // both back-to-back rebuilt the 36k-card models twice on the GUI thread, + // stalling startup. (When the card list is empty the slot returns early + // without reloading, but there is nothing to display either.) emit cardDatabaseAllNewSetsEnabled(); } } @@ -211,13 +230,13 @@ void CardDatabase::checkUnknownSets() void CardDatabase::enableAllUnknownSets() { auto _sets = getSetList(); - _sets.enableAllUnknown(); + _sets.enableAllUnknownBatched(setPriorityController); } void CardDatabase::markAllSetsAsKnown() { auto _sets = getSetList(); - _sets.markAllAsKnown(); + _sets.markAllAsKnownBatched(setPriorityController); } void CardDatabase::notifyEnabledSetsChanged(bool recomputeCachedSets) diff --git a/libcockatrice_card/libcockatrice/card/database/card_database.h b/libcockatrice_card/libcockatrice/card/database/card_database.h index b10e3c726..9f0d67b67 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database.h +++ b/libcockatrice_card/libcockatrice/card/database/card_database.h @@ -2,18 +2,26 @@ #define CARDDATABASE_H #include "../set/card_set_list.h" -#include "card_database_data.h" #include "card_database_loader.h" -#include "card_database_querier.h" + +// IWYU pragma: keep +// CardDatabaseData is passed by value to the swapInDatabaseData() slot, and +// CardInfoPtr is passed by value to the cardAdded()/cardRemoved() signals, so +// the moc-generated code needs the complete types. +#include "card_database_data.h" +#include "libcockatrice/card/card_info.h" #include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include +#include + +class CardDatabaseQuerier; +class ICardDatabasePathProvider; +class ICardPreferenceProvider; +class ICardSetPriorityController; inline Q_LOGGING_CATEGORY(CardDatabaseLog, "card_database"); @@ -169,8 +177,12 @@ public slots: void addFormat(const FormatRulesPtr &format); - /** @brief Loads card databases from configured paths. */ + /** @brief Loads card databases from configured paths, using the binary cache when valid. */ void loadCardDatabases(); + /** + * @brief Reloads card databases from disk, bypassing the binary cache, + * and notifies observers of the fresh state. + */ void reloadCardDatabasesAndNotify(); /** @brief Saves custom tokens to file. diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_cache.cpp b/libcockatrice_card/libcockatrice/card/database/card_database_cache.cpp index 3165ff871..4ab4d1fca 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_cache.cpp +++ b/libcockatrice_card/libcockatrice/card/database/card_database_cache.cpp @@ -4,15 +4,32 @@ #include "../format/format_legality_rules.h" #include "../printing/printing_info.h" #include "../relation/card_relation.h" -#include "../relation/card_relation_type.h" #include "../set/card_set.h" #include "card_database_loader.h" +#include "libcockatrice/card/database/card_database_data.h" +#include "libcockatrice/card/lazy_properties_hash.h" #include +#include #include +#include +#include #include #include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include + +class ICardSetPriorityController; +enum class CardRelationType; +template class QHash; namespace { diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_cache.h b/libcockatrice_card/libcockatrice/card/database/card_database_cache.h index 40ff96541..178b3ac6e 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_cache.h +++ b/libcockatrice_card/libcockatrice/card/database/card_database_cache.h @@ -1,10 +1,11 @@ #ifndef CARDDATABASE_CACHE_H #define CARDDATABASE_CACHE_H -#include "card_database_data.h" +#include -#include -#include +class ICardSetPriorityController; +class QByteArray; +struct CardDatabaseData; namespace CardDatabaseCache { diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_loader.cpp b/libcockatrice_card/libcockatrice/card/database/card_database_loader.cpp index 47f7eee6d..00b21f88e 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_loader.cpp +++ b/libcockatrice_card/libcockatrice/card/database/card_database_loader.cpp @@ -2,6 +2,11 @@ #include "card_database.h" #include "card_database_cache.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_data.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/interfaces/interface_card_database_path_provider.h" +#include "libcockatrice/interfaces/interface_card_set_priority_controller.h" #include "parser/card_database_parser.h" #include "parser/cockatrice_xml_3.h" #include "parser/cockatrice_xml_4.h" @@ -9,29 +14,43 @@ #include #include #include +#include #include +#include #include #include #include +#include +#include +#include +#include #include +#include +#include + +class ICardPreferenceProvider; CardDatabaseLoader::CardDatabaseLoader(QObject *parent, CardDatabase *db, ICardDatabasePathProvider *_pathProvider, - ICardPreferenceProvider *_preferenceProvider, ICardSetPriorityController *_priorityController) : QObject(parent), database(db), pathProvider(_pathProvider), priorityController(_priorityController) { // instantiate available parsers here - availableParsers << new CockatriceXml4Parser(_preferenceProvider, _priorityController); + availableParsers << new CockatriceXml4Parser(_priorityController); availableParsers << new CockatriceXml3Parser(_priorityController); // The load path parses into a snapshot and never emits per-card signals; // the finished snapshot is swapped into the live database on the GUI thread. // when SettingsCache's path changes, trigger reloads - connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this, - &CardDatabaseLoader::loadCardDatabases); + connect(pathProvider, &ICardDatabasePathProvider::cardDatabasePathChanged, this, [this] { + loadCardDatabases(); + // This reload runs synchronously on the emitting (GUI) thread, so the + // finished snapshot is already swapped in when it returns: enable any + // sets the newly pointed-at database introduced. + database->checkUnknownSets(); + }); } CardDatabaseLoader::~CardDatabaseLoader() @@ -76,12 +95,12 @@ LoadStatus CardDatabaseLoader::loadCardDatabase(const QString &path, CardDatabas return tempLoadStatus; } -LoadStatus CardDatabaseLoader::loadCardDatabases() +LoadStatus CardDatabaseLoader::loadCardDatabases(bool ignoreCache) { - return doLoadCardDatabases(); + return doLoadCardDatabases(ignoreCache); } -LoadStatus CardDatabaseLoader::doLoadCardDatabases() +LoadStatus CardDatabaseLoader::doLoadCardDatabases(bool ignoreCache) { QMutexLocker locker(reloadDatabaseMutex); @@ -99,9 +118,14 @@ LoadStatus CardDatabaseLoader::doLoadCardDatabases() LoadStatus loadStatus = NotLoaded; // Try the binary cache first: a cache hit avoids re-parsing the (large) XML. + // An explicit reload skips the lookup so the files on disk are always + // re-read, even when their size/mtime hash still matches the cache. const QStringList customPaths = collectCustomDatabasePaths(); const QByteArray sourceHash = computeSourceHash(customPaths); - if (loadFromCache(data, sourceHash)) { + if (ignoreCache) { + qCInfo(CardDatabaseLoadingLog) << "Ignoring binary cache, re-parsing source files"; + } + if (!ignoreCache && loadFromCache(data, sourceHash)) { qCInfo(CardDatabaseLoadingLog) << "Loaded card database from binary cache"; loadStatus = Ok; } else { @@ -118,7 +142,23 @@ LoadStatus CardDatabaseLoader::doLoadCardDatabases() loadCardDatabase(p, data); } - if (!saveToCache(data, sourceHash)) { + // A snapshot parsed while no set is enabled has had every printing + // stripped by the parsers, and the cache reader re-derives enablement + // from the priority controller, so such an entry can never be reused + // meaningfully. Skip writing it so a first-run (blank config) load + // cannot poison the cache with an empty snapshot. The check mirrors + // what the parsers saw: any set still reporting enabled means the + // snapshot is complete for the current enablement. + bool anySetEnabled = false; + for (const CardSetPtr &set : data.sets) { + if (set && set->getEnabled()) { + anySetEnabled = true; + break; + } + } + if (!data.sets.isEmpty() && !anySetEnabled) { + qCInfo(CardDatabaseLoadingLog) << "Skipping binary cache: no set is enabled yet, snapshot was stripped"; + } else if (!saveToCache(data, sourceHash)) { qCWarning(CardDatabaseLoadingLog) << "Failed to write binary cache to" << cachePath(); } } @@ -130,18 +170,15 @@ LoadStatus CardDatabaseLoader::doLoadCardDatabases() database->refreshCachedReverseRelatedCards(data.cards); qCInfo(CardDatabaseLoadingSuccessOrFailureLog) << "Card Database Loading Success"; + // NOTE: checkUnknownSets() is intentionally NOT called here. During the + // front-loaded parse in main() MainWindow does not exist yet, so + // cardDatabaseNewSetsFound / cardDatabaseAllNewSetsEnabled would be + // emitted with no receivers, and enabling the sets up-front would + // suppress the first-run experience MainWindow::startupConfigCheck() + // and the onboarding wizard are designed around. Callers that load + // after startup own the check (and any reload it triggers). emit databaseDataReady(std::move(data)); emit loadingFinished(); - // During the front-loaded parse in main() this runs before MainWindow - // exists, so cardDatabaseNewSetsFound / cardDatabaseAllNewSetsEnabled - // would be emitted with no receivers. Skip the check on the first load; - // MainWindow::startupConfigCheck() calls checkUnknownSets() once its - // signal connections are live. On subsequent reloads (e.g. path change) - // MainWindow exists and signals have live receivers. - if (initialLoadComplete) { - database->checkUnknownSets(); - } - initialLoadComplete = true; } else { qCInfo(CardDatabaseLoadingSuccessOrFailureLog) << "Card Database Loading Failed"; emit loadingFailed(); // bring up the settings dialog @@ -166,6 +203,12 @@ QByteArray CardDatabaseLoader::computeSourceHash(const QStringList &customPaths) hash.addData(QCoreApplication::applicationVersion().toUtf8()); hash.addData(QByteArray(1, '\0')); + // Include parser schema version to invalidate caches when parser behavior changes. + // Increment this if the parser logic changes in a way that affects cached data. + static const char SCHEMA_VERSION[] = "carddb-parse-schema-v1"; + hash.addData(QByteArray(SCHEMA_VERSION, sizeof(SCHEMA_VERSION) - 1)); + hash.addData(QByteArray(1, '\0')); + const QStringList inputs = QStringList() << pathProvider->getCardDatabasePath() << pathProvider->getTokenDatabasePath() << pathProvider->getSpoilerCardDatabasePath() << customPaths; @@ -180,6 +223,17 @@ QByteArray CardDatabaseLoader::computeSourceHash(const QStringList &customPaths) hash.addData(QByteArray(1, '\0')); } } + + // The parsers drop printings of disabled sets at parse time, so the cached + // snapshot depends on enablement: fold the enabled set names in so that + // toggling a set invalidates the cache and forces a re-parse. + if (priorityController) { + const QStringList enabledSets = priorityController->getEnabledSetNames(); + for (const QString &setName : enabledSets) { + hash.addData(setName.toUtf8()); + hash.addData(QByteArray(1, '\0')); + } + } return hash.result(); } diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_loader.h b/libcockatrice_card/libcockatrice/card/database/card_database_loader.h index 6dcb06bf2..bfbaa0f51 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_loader.h +++ b/libcockatrice_card/libcockatrice/card/database/card_database_loader.h @@ -2,12 +2,21 @@ #define COCKATRICE_CARD_DATABASE_LOADER_H #include +#include #include #include -#include -#include -#include -#include +#include +#include +#include +#include + +class ICardDatabasePathProvider; +class ICardSetPriorityController; + +// IWYU pragma: keep +// CardDatabaseData is passed by value to the databaseDataReady() signal, so the +// moc-generated code needs the complete type. +#include "card_database_data.h" inline Q_LOGGING_CATEGORY(CardDatabaseLoadingLog, "card_database.loading"); inline Q_LOGGING_CATEGORY(CardDatabaseLoadingSuccessOrFailureLog, "card_database.loading.success_or_failure"); @@ -49,12 +58,10 @@ public: * @param parent QObject parent. * @param db Pointer to the CardDatabase to populate (non-owning). * @param pathProvider Provider for card database file paths. - * @param preferenceProvider Optional card preference provider for pinned printings. */ explicit CardDatabaseLoader(QObject *parent, CardDatabase *db, ICardDatabasePathProvider *pathProvider, - ICardPreferenceProvider *preferenceProvider, ICardSetPriorityController *_priorityController); /** @brief Destructor cleans up allocated parsers. */ @@ -66,9 +73,13 @@ public slots: * * Runs synchronously on the calling thread. The caller should ensure * that any signal receivers are already connected before invoking this. + * @param ignoreCache Skip the binary cache lookup and re-parse the source + * files from disk, refreshing the cache afterwards. Used for + * explicit reloads so that edits the source hash cannot see are + * still picked up. * @return Status of the main database load. */ - LoadStatus loadCardDatabases(); + LoadStatus loadCardDatabases(bool ignoreCache = false); /** * @brief Loads a single card database file into the given snapshot. @@ -121,9 +132,10 @@ private: /** * @brief Performs the actual load work synchronously on the calling thread. + * @param ignoreCache Skip the binary cache lookup and re-parse from disk. * @return Status of the main database load. */ - LoadStatus doLoadCardDatabases(); + LoadStatus doLoadCardDatabases(bool ignoreCache); /** * @brief Collects custom card database paths recursively. @@ -167,7 +179,6 @@ private: QBasicMutex *loadFromFileMutex = new QBasicMutex(); /**< Mutex for single-file loading. */ QBasicMutex *reloadDatabaseMutex = new QBasicMutex(); /**< Mutex for reloading entire database. */ - bool initialLoadComplete = false; /**< Set after the first successful load. */ }; #endif // COCKATRICE_CARD_DATABASE_LOADER_H diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_manager.cpp b/libcockatrice_card/libcockatrice/card/database/card_database_manager.cpp index 614b4a7f8..b06c258fa 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_manager.cpp +++ b/libcockatrice_card/libcockatrice/card/database/card_database_manager.cpp @@ -1,9 +1,16 @@ #include "card_database_manager.h" +#include "libcockatrice/card/database/card_database.h" + #include #include #include +class CardDatabaseQuerier; +class ICardDatabasePathProvider; +class ICardPreferenceProvider; +class ICardSetPriorityController; + ICardPreferenceProvider *CardDatabaseManager::cardPreferenceProvider = new NoopCardPreferenceProvider(); ICardDatabasePathProvider *CardDatabaseManager::pathProvider = new NoopCardDatabasePathProvider(); ICardSetPriorityController *CardDatabaseManager::setPriorityController = new NoopCardSetPriorityController(); diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_manager.h b/libcockatrice_card/libcockatrice/card/database/card_database_manager.h index c7de66a25..074154a41 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_manager.h +++ b/libcockatrice_card/libcockatrice/card/database/card_database_manager.h @@ -2,7 +2,12 @@ #define CARD_DATABASE_ACCESSOR_H #pragma once -#include "card_database.h" + +class CardDatabase; +class CardDatabaseQuerier; +class ICardDatabasePathProvider; +class ICardPreferenceProvider; +class ICardSetPriorityController; /** * @class CardDatabaseManager diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_querier.cpp b/libcockatrice_card/libcockatrice/card/database/card_database_querier.cpp index 5b9c5a4b5..2fad5212d 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_querier.cpp +++ b/libcockatrice_card/libcockatrice/card/database/card_database_querier.cpp @@ -4,8 +4,15 @@ #include "../printing/exact_card.h" #include "../set/card_set_comparator.h" #include "card_database.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/interfaces/interface_card_preference_provider.h" +#include "libcockatrice/utility/card_ref.h" -#include +#include +#include +#include +#include +#include CardDatabaseQuerier::CardDatabaseQuerier(QObject *_parent, const CardDatabase *_db, diff --git a/libcockatrice_card/libcockatrice/card/database/card_database_querier.h b/libcockatrice_card/libcockatrice/card/database/card_database_querier.h index f195a8170..a1409b3cc 100644 --- a/libcockatrice_card/libcockatrice/card/database/card_database_querier.h +++ b/libcockatrice_card/libcockatrice/card/database/card_database_querier.h @@ -3,12 +3,18 @@ #include "../card_info.h" #include "../printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include +#include #include -#include -#include +#include +#include +#include class CardDatabase; +class ICardPreferenceProvider; +struct CardRef; /** * @class CardDatabaseQuerier diff --git a/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.cpp b/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.cpp index 00ed9377d..1374533ca 100644 --- a/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.cpp +++ b/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.cpp @@ -1,6 +1,11 @@ #include "card_database_parser.h" -#include +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_data.h" + +#include + +class ICardSetPriorityController; SetNameMap ICardDatabaseParser::sets; diff --git a/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.h b/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.h index 6d9c91260..b82d9aed7 100644 --- a/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.h +++ b/libcockatrice_card/libcockatrice/card/database/parser/card_database_parser.h @@ -2,10 +2,17 @@ #define CARDDATABASE_PARSER_H #include "../../card_info.h" -#include "../card_database_data.h" +#include "libcockatrice/card/database/parser/card_database_parser.h" +#include "libcockatrice/card/set/card_set.h" -#include +#include +#include #include +#include + +class ICardSetPriorityController; +class QIODevice; +struct CardDatabaseData; #define COCKATRICE_XML_XSI_NAMESPACE "http://www.w3.org/2001/XMLSchema-instance" diff --git a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.cpp b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.cpp index 64202ab21..b17eb8b5e 100644 --- a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.cpp +++ b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.cpp @@ -2,13 +2,33 @@ #include "../../relation/card_relation.h" #include "../../relation/card_relation_type.h" +#include "libcockatrice/card/database/card_database_data.h" +#include "libcockatrice/card/database/parser/card_database_parser.h" +#include "libcockatrice/card/lazy_properties_hash.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +class ICardSetPriorityController; + #define COCKATRICE_XML3_TAGNAME "cockatrice_carddatabase" #define COCKATRICE_XML3_TAGVER 3 #define COCKATRICE_XML3_SCHEMALOCATION \ diff --git a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.h b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.h index 83b736257..cb76e960d 100644 --- a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.h +++ b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_3.h @@ -2,9 +2,14 @@ #define COCKATRICE_XML3_H #include "card_database_parser.h" +#include "libcockatrice/card/card_info.h" #include -#include +#include +#include + +class ICardSetPriorityController; +class QXmlStreamReader; inline Q_LOGGING_CATEGORY(CockatriceXml3Log, "cockatrice_xml.xml_3_parser"); diff --git a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.cpp b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.cpp index 19e972a7a..4d975e533 100644 --- a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.cpp +++ b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.cpp @@ -1,22 +1,44 @@ #include "cockatrice_xml_4.h" #include "../../relation/card_relation.h" +#include "libcockatrice/card/database/card_database_data.h" +#include "libcockatrice/card/database/parser/card_database_parser.h" +#include "libcockatrice/card/lazy_properties_hash.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/relation/card_relation_type.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/interfaces/interface_card_preference_provider.h" #include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include #include +class ICardSetPriorityController; + #define COCKATRICE_XML4_TAGNAME "cockatrice_carddatabase" #define COCKATRICE_XML4_TAGVER 4 #define COCKATRICE_XML4_SCHEMALOCATION \ "https://raw.githubusercontent.com/Cockatrice/Cockatrice/master/doc/carddatabase_v4/cards.xsd" -CockatriceXml4Parser::CockatriceXml4Parser(ICardPreferenceProvider *_cardPreferenceProvider, - ICardSetPriorityController *_cardSetPriorityController) - : ICardDatabaseParser(_cardSetPriorityController), cardPreferenceProvider(_cardPreferenceProvider) +CockatriceXml4Parser::CockatriceXml4Parser(ICardSetPriorityController *_cardSetPriorityController) + : ICardDatabaseParser(_cardSetPriorityController) { } @@ -261,7 +283,6 @@ QHash CockatriceXml4Parser::loadCardPropertiesFromXml(QXmlStre void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml) { - bool includeRebalancedCards = cardPreferenceProvider->getIncludeRebalancedCards(); while (!xml.atEnd()) { if (xml.readNext() == QXmlStreamReader::EndElement) { break; @@ -363,17 +384,7 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml) printingProps.insert(attrName, attr.value().toString()); } PrintingInfo printingInfo(set, LazyPropertiesHash(printingProps)); - - // This is very much a hack and not the right place to - // put this check, as it requires a reload of Cockatrice - // to be apply. - // - // However, this is also true of the `set->getEnabled()` - // check above (which is currently bugged as well), so - // we'll fix both at the same time. - if (includeRebalancedCards || printingInfo.getProperty("isRebalanced") != "true") { - _sets[setName].append(printingInfo); - } + _sets[setName].append(printingInfo); } // related cards } else if (xmlName == "related" || xmlName == "reverse-related") { diff --git a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.h b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.h index 55f7c5a3b..390282796 100644 --- a/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.h +++ b/libcockatrice_card/libcockatrice/card/database/parser/cockatrice_xml_4.h @@ -2,10 +2,15 @@ #define COCKATRICE_XML4_H #include "card_database_parser.h" +#include "libcockatrice/card/card_info.h" +#include #include -#include -#include +#include +#include + +class ICardSetPriorityController; +class QXmlStreamReader; inline Q_LOGGING_CATEGORY(CockatriceXml4Log, "cockatrice_xml.xml_4_parser"); @@ -21,7 +26,6 @@ inline Q_LOGGING_CATEGORY(CockatriceXml4Log, "cockatrice_xml.xml_4_parser"); * @note Differences from v3: * - Card properties are stored in blocks as a QHash. * - Sets can include a element. - * - Supports user preferences via ICardPreferenceProvider (e.g., skipping rebalanced cards). * - Related cards support persistent relations and multiple attach types (e.g., transform). * - More robust serialization; easier to extend schema in the future. */ @@ -29,8 +33,7 @@ class CockatriceXml4Parser : public ICardDatabaseParser { Q_OBJECT public: - explicit CockatriceXml4Parser(ICardPreferenceProvider *cardPreferenceProvider, - ICardSetPriorityController *cardSetPriorityController); + explicit CockatriceXml4Parser(ICardSetPriorityController *cardSetPriorityController); ~CockatriceXml4Parser() override = default; /** @@ -65,8 +68,6 @@ public: const QString &sourceVersion = "unknown") override; private: - ICardPreferenceProvider *cardPreferenceProvider; ///< Interface to handle user preferences - /** * @brief Loads a generic block from a element. * @param xml The open QXmlStreamReader positioned at a element. @@ -77,7 +78,6 @@ private: /** * @brief Load all elements from the XML stream. * @param xml The open QXmlStreamReader positioned at the element. - * Honors the user's preference regarding rebalanced cards. */ void loadCardsFromXml(QXmlStreamReader &xml); diff --git a/libcockatrice_card/libcockatrice/card/format/format_legality_rules.cpp b/libcockatrice_card/libcockatrice/card/format/format_legality_rules.cpp index a6b3bb038..64785759e 100644 --- a/libcockatrice_card/libcockatrice/card/format/format_legality_rules.cpp +++ b/libcockatrice_card/libcockatrice/card/format/format_legality_rules.cpp @@ -1,6 +1,9 @@ #include "format_legality_rules.h" +#include +#include #include +#include bool cardMatchesCondition(const CardInfo &card, const CardCondition &cond) { diff --git a/libcockatrice_card/libcockatrice/card/format/format_legality_rules.h b/libcockatrice_card/libcockatrice/card/format/format_legality_rules.h index 8778ab17e..15ba46728 100644 --- a/libcockatrice_card/libcockatrice/card/format/format_legality_rules.h +++ b/libcockatrice_card/libcockatrice/card/format/format_legality_rules.h @@ -1,11 +1,12 @@ #ifndef COCKATRICE_FORMAT_LEGALITY_RULES_H #define COCKATRICE_FORMAT_LEGALITY_RULES_H -#include +#include #include #include class CardInfo; + using CardInfoPtr = QSharedPointer; struct CardCondition diff --git a/libcockatrice_card/libcockatrice/card/import/card_name_normalizer.cpp b/libcockatrice_card/libcockatrice/card/import/card_name_normalizer.cpp index 91ebd6647..975f7f2d6 100644 --- a/libcockatrice_card/libcockatrice/card/import/card_name_normalizer.cpp +++ b/libcockatrice_card/libcockatrice/card/import/card_name_normalizer.cpp @@ -2,8 +2,14 @@ #include "../database/card_database_manager.h" #include "../printing/exact_card.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include +#include #include +#include +#include +#include /** * @brief Resolves the complete display name of a card. diff --git a/libcockatrice_card/libcockatrice/card/lazy_properties_hash.cpp b/libcockatrice_card/libcockatrice/card/lazy_properties_hash.cpp index 4d903a3bd..a12de469b 100644 --- a/libcockatrice_card/libcockatrice/card/lazy_properties_hash.cpp +++ b/libcockatrice_card/libcockatrice/card/lazy_properties_hash.cpp @@ -1,6 +1,8 @@ #include "lazy_properties_hash.h" -#include +#include +#include +#include LazyPropertiesHash::LazyPropertiesHash() : isMaterialized(true) { diff --git a/libcockatrice_card/libcockatrice/card/lazy_properties_hash.h b/libcockatrice_card/libcockatrice/card/lazy_properties_hash.h index 0ed8c215b..04f5d0251 100644 --- a/libcockatrice_card/libcockatrice/card/lazy_properties_hash.h +++ b/libcockatrice_card/libcockatrice/card/lazy_properties_hash.h @@ -1,8 +1,10 @@ #ifndef COCKATRICE_LAZY_PROPERTIES_HASH_H #define COCKATRICE_LAZY_PROPERTIES_HASH_H +#include #include #include +#include /** * @brief A property map that can lazily deserialize blobs to avoid loading overhead. diff --git a/libcockatrice_card/libcockatrice/card/printing/exact_card.cpp b/libcockatrice_card/libcockatrice/card/printing/exact_card.cpp index 993b5b96e..19e902b27 100644 --- a/libcockatrice_card/libcockatrice/card/printing/exact_card.cpp +++ b/libcockatrice_card/libcockatrice/card/printing/exact_card.cpp @@ -3,6 +3,10 @@ #include "../card_info.h" #include "printing_info.h" +#include +#include +#include + /** * Default constructor. * This will set the CardInfoPtr to null. diff --git a/libcockatrice_card/libcockatrice/card/printing/exact_card.h b/libcockatrice_card/libcockatrice/card/printing/exact_card.h index 74fc75da3..ea49072fb 100644 --- a/libcockatrice_card/libcockatrice/card/printing/exact_card.h +++ b/libcockatrice_card/libcockatrice/card/printing/exact_card.h @@ -2,6 +2,11 @@ #define EXACT_CARD_H #include "../card_info.h" +#include "libcockatrice/card/printing/printing_info.h" + +#include +#include +#include /** * @class ExactCard diff --git a/libcockatrice_card/libcockatrice/card/printing/printing_info.cpp b/libcockatrice_card/libcockatrice/card/printing/printing_info.cpp index 3d185583a..654efac5e 100644 --- a/libcockatrice_card/libcockatrice/card/printing/printing_info.cpp +++ b/libcockatrice_card/libcockatrice/card/printing/printing_info.cpp @@ -2,9 +2,6 @@ #include "../set/card_set.h" -#include -#include - PrintingInfo::PrintingInfo(const CardSetPtr &_set, const LazyPropertiesHash &_properties) : set(_set), properties(_properties) { diff --git a/libcockatrice_card/libcockatrice/card/printing/printing_info.h b/libcockatrice_card/libcockatrice/card/printing/printing_info.h index 974c7bb95..038960e86 100644 --- a/libcockatrice_card/libcockatrice/card/printing/printing_info.h +++ b/libcockatrice_card/libcockatrice/card/printing/printing_info.h @@ -4,9 +4,12 @@ #include "../set/card_set.h" #include "libcockatrice/card/lazy_properties_hash.h" +#include #include #include #include +#include +#include class PrintingInfo; diff --git a/libcockatrice_card/libcockatrice/card/relation/card_relation.cpp b/libcockatrice_card/libcockatrice/card/relation/card_relation.cpp index 8903c892d..410b25682 100644 --- a/libcockatrice_card/libcockatrice/card/relation/card_relation.cpp +++ b/libcockatrice_card/libcockatrice/card/relation/card_relation.cpp @@ -1,7 +1,5 @@ #include "card_relation.h" -#include "card_relation_type.h" - CardRelation::CardRelation(const QString &_name, CardRelationType _attachType, bool _isCreateAllExclusion, diff --git a/libcockatrice_card/libcockatrice/card/relation/card_relation.h b/libcockatrice_card/libcockatrice/card/relation/card_relation.h index a1864f5b2..3a1366f2b 100644 --- a/libcockatrice_card/libcockatrice/card/relation/card_relation.h +++ b/libcockatrice_card/libcockatrice/card/relation/card_relation.h @@ -5,6 +5,7 @@ #include #include +#include /** * @class CardRelation diff --git a/libcockatrice_card/libcockatrice/card/set/card_set.cpp b/libcockatrice_card/libcockatrice/card/set/card_set.cpp index 92060f6c4..e873eeeab 100644 --- a/libcockatrice_card/libcockatrice/card/set/card_set.cpp +++ b/libcockatrice_card/libcockatrice/card/set/card_set.cpp @@ -1,5 +1,7 @@ #include "card_set.h" +#include "libcockatrice/interfaces/interface_card_set_priority_controller.h" + #include #include diff --git a/libcockatrice_card/libcockatrice/card/set/card_set.h b/libcockatrice_card/libcockatrice/card/set/card_set.h index 8e16e01df..b9ac74e2d 100644 --- a/libcockatrice_card/libcockatrice/card/set/card_set.h +++ b/libcockatrice_card/libcockatrice/card/set/card_set.h @@ -5,12 +5,14 @@ #include #include #include -#include class CardInfo; +class ICardSetPriorityController; + using CardInfoPtr = QSharedPointer; class CardSet; + using CardSetPtr = QSharedPointer; /** @@ -225,6 +227,10 @@ public: * @param _isknown True if known, false if unknown. */ void setIsKnown(bool _isknown); + void setIsKnownInMemory(bool _isknown) + { + isknown = _isknown; + } /** * @brief Determines whether the set has incomplete metadata and should be ignored. diff --git a/libcockatrice_card/libcockatrice/card/set/card_set_list.cpp b/libcockatrice_card/libcockatrice/card/set/card_set_list.cpp index 8d6aa7365..c4faf1c4c 100644 --- a/libcockatrice_card/libcockatrice/card/set/card_set_list.cpp +++ b/libcockatrice_card/libcockatrice/card/set/card_set_list.cpp @@ -1,5 +1,14 @@ #include "card_set_list.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/interfaces/interface_card_set_priority_controller.h" + +#include +#include +#include +#include +#include + class CardSetList::KeyCompareFunctor { public: @@ -55,60 +64,87 @@ QStringList CardSetList::getUnknownSetsNames() return sets; } -void CardSetList::enableAllUnknown() +void CardSetList::enableAllUnknownBatched(ICardSetPriorityController *controller) { - for (int i = 0; i < size(); ++i) { - CardSetPtr set = at(i); - if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) { - set->setIsKnown(true); - set->setEnabled(true); - } else if (set && set->getIsKnownIgnored() && !set->getEnabled()) { - set->setEnabled(true); - } - } -} - -void CardSetList::enableAll() -{ - for (int i = 0; i < size(); ++i) { - CardSetPtr set = at(i); - - if (set == nullptr) { - // qCWarning(CardInfoLog) << "enabledAll has null"; - continue; - } - - if (!set->getIsKnownIgnored()) { - set->setIsKnown(true); - } - - set->setEnabled(true); - } -} - -void CardSetList::markAllAsKnown() -{ - for (int i = 0; i < size(); ++i) { - CardSetPtr set = at(i); - if (set && !set->getIsKnown() && !set->getIsKnownIgnored()) { - set->setIsKnown(true); - set->setEnabled(false); - } else if (set && set->getIsKnownIgnored() && !set->getEnabled()) { - set->setEnabled(true); - } - } -} - -void CardSetList::guessSortKeys() -{ - defaultSort(); + QVector saveData; for (int i = 0; i < size(); ++i) { CardSetPtr set = at(i); if (set.isNull()) { - // qCWarning(CardInfoLog) << "guessSortKeys set is null"; continue; } - set->setSortKey(i); + + bool changed = false; + if (!set->getIsKnown() && !set->getIsKnownIgnored()) { + set->setIsKnownInMemory(true); + set->setEnabledInMemory(true); + changed = true; + } else if (set->getIsKnownIgnored() && !set->getEnabled()) { + set->setEnabledInMemory(true); + changed = true; + } + if (changed) { + saveData.append( + {set->getShortName(), static_cast(set->getSortKey()), true, set->getIsKnown()}); + } + } + + if (!saveData.isEmpty()) { + controller->saveSets(saveData); + } +} + +void CardSetList::enableAllBatched(ICardSetPriorityController *controller) +{ + defaultSort(); + + QVector saveData; + saveData.reserve(size()); + for (int i = 0; i < size(); ++i) { + CardSetPtr set = at(i); + if (set.isNull()) { + continue; + } + + const auto sortKey = static_cast(i); + set->setSortKeyInMemory(sortKey); + if (!set->getIsKnownIgnored()) { + set->setIsKnownInMemory(true); + } + set->setEnabledInMemory(true); + saveData.append({set->getShortName(), sortKey, true, set->getIsKnown()}); + } + + if (!saveData.isEmpty()) { + controller->saveSets(saveData); + } +} + +void CardSetList::markAllAsKnownBatched(ICardSetPriorityController *controller) +{ + QVector saveData; + for (int i = 0; i < size(); ++i) { + CardSetPtr set = at(i); + if (set.isNull()) { + continue; + } + + bool changed = false; + if (!set->getIsKnown() && !set->getIsKnownIgnored()) { + set->setIsKnownInMemory(true); + set->setEnabledInMemory(false); + changed = true; + } else if (set->getIsKnownIgnored() && !set->getEnabled()) { + set->setEnabledInMemory(true); + changed = true; + } + if (changed) { + saveData.append({set->getShortName(), static_cast(set->getSortKey()), set->getEnabled(), + set->getIsKnown()}); + } + } + + if (!saveData.isEmpty()) { + controller->saveSets(saveData); } } diff --git a/libcockatrice_card/libcockatrice/card/set/card_set_list.h b/libcockatrice_card/libcockatrice/card/set/card_set_list.h index 81d605374..f31710b33 100644 --- a/libcockatrice_card/libcockatrice/card/set/card_set_list.h +++ b/libcockatrice_card/libcockatrice/card/set/card_set_list.h @@ -4,6 +4,8 @@ #include "card_set.h" #include +#include +#include /** * @class CardSetList @@ -38,36 +40,37 @@ public: void sortByKey(); /** - * @brief Reassigns sort keys based on the current order. + * @brief Enables every set with fresh sort keys, persisting in one flush. * - * Calls defaultSort() and then assigns sequential sort keys - * to all sets according to their resulting positions, replacing - * any existing sort keys to ensure consistent ordering. + * Assigns sequential sort keys in default-sorted order and marks every set + * known and enabled, writing all records through the controller's batched + * saveSets() in a single settings flush instead of ~3 QSettings rewrite + * cycles per set, which froze the GUI thread for seconds on a first run + * with a full database. + * @param controller The set priority controller to persist the records with. */ - void guessSortKeys(); + void enableAllBatched(ICardSetPriorityController *controller); /** - * @brief Enables all sets that are unknown or ignored. + * @brief Enables all sets that are unknown or ignored, persisting in one flush. * * Sets that are not marked as known and not ignored are marked as known * and enabled. Ignored-known sets are also enabled, but remain ignored. + * Only changed sets are written, so the common case of a few new sets costs + * a single settings flush no matter how large the database is. + * @param controller The set priority controller to persist the records with. */ - void enableAllUnknown(); + void enableAllUnknownBatched(ICardSetPriorityController *controller); /** - * @brief Enables all sets in the list. - * - * Equivalent to calling `setEnabled(true)` on each entry. - */ - void enableAll(); - - /** - * @brief Marks all sets as known and adjusts their enabled state. + * @brief Marks all sets as known and adjusts their enabled state, persisting in one flush. * * Unknown, non-ignored sets become known and disabled. * Ignored-known sets are enabled if they were previously disabled. + * Only changed sets are written; when nothing is unknown no flush happens at all. + * @param controller The set priority controller to persist the records with. */ - void markAllAsKnown(); + void markAllAsKnownBatched(ICardSetPriorityController *controller); /** * @brief Counts the number of sets that are currently enabled. diff --git a/libcockatrice_deck_list/CMakeLists.txt b/libcockatrice_deck_list/CMakeLists.txt index 0c487466c..e61a5702c 100644 --- a/libcockatrice_deck_list/CMakeLists.txt +++ b/libcockatrice_deck_list/CMakeLists.txt @@ -41,3 +41,5 @@ target_link_libraries( libcockatrice_deck_list PUBLIC libcockatrice_interfaces libcockatrice_protocol libcockatrice_utility ${QT_CORE_MODULE} ) + +target_precompile_headers(libcockatrice_deck_list PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp index 90f63c09d..821b53dff 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.cpp @@ -2,16 +2,26 @@ #include "deck_list_memento.h" #include "deck_list_plain_text_parser.h" -#include "tree/abstract_deck_list_node.h" +#include "libcockatrice/deck_list/deck_list_node_tree.h" +#include "libcockatrice/deck_list/sideboard_plan.h" +#include "libcockatrice/utility/playmat_params.h" #include "tree/deck_list_card_node.h" #include "tree/inner_deck_list_node.h" -#include +#include #include -#include #include +#include +#include #include +#include +#include +#include +#include #include +#include +#include +#include static const QString CURRENT_SIDEBOARD_PLAN_KEY = ""; diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h index 199d3a9a8..6796e9c33 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list.h @@ -12,20 +12,24 @@ #include "deck_list_memento.h" #include "deck_list_node_tree.h" +#include "libcockatrice/protocol/pb/move_card_to_zone.pb.h" +#include "libcockatrice/utility/card_ref.h" #include "sideboard_plan.h" #include "tree/inner_deck_list_node.h" +#include #include -#include -#include +#include +#include +#include +#include #include -class AbstractDecklistNode; class DecklistCardNode; -class CardDatabase; class QIODevice; class QTextStream; -class InnerDecklistNode; +class QXmlStreamReader; +class QXmlStreamWriter; /** * @class DeckList diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.cpp index b6d0687b4..cba926fd5 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.cpp @@ -1,5 +1,10 @@ #include "deck_list_history_manager.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/deck_list_memento.h" + +#include + void DeckListHistoryManager::save(const DeckListMemento &memento) { undoStack.push(memento); diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.h b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.h index 6acdb199e..dce9e0af8 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_history_manager.h @@ -1,11 +1,13 @@ #ifndef COCKATRICE_DECK_LIST_HISTORY_MANAGER_H #define COCKATRICE_DECK_LIST_HISTORY_MANAGER_H -#include "deck_list.h" #include "deck_list_memento.h" #include #include +#include + +class DeckList; class DeckListHistoryManager : public QObject { diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp index 66f228d19..5c26030bf 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.cpp @@ -1,9 +1,19 @@ #include "deck_list_node_tree.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" #include "tree/deck_list_card_node.h" +#include +#include #include #include +#include +#include +#include +#include +#include +#include static constexpr int MAX_DECK_SIZE = 1e5; diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h index 2c66b34ff..08b4b0d73 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_node_tree.h @@ -1,11 +1,17 @@ #ifndef COCKATRICE_DECKLIST_NODE_TREE_H #define COCKATRICE_DECKLIST_NODE_TREE_H -#include "libcockatrice/utility/card_ref.h" #include "tree/deck_list_card_node.h" #include "tree/inner_deck_list_node.h" +#include #include +#include +#include + +class AbstractDecklistNode; +class QXmlStreamReader; +class QXmlStreamWriter; class DecklistNodeTree { diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.cpp index de50d743b..fb6a61769 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.cpp @@ -1,10 +1,17 @@ #include "deck_list_plain_text_parser.h" #include "deck_list_node_tree.h" +#include "libcockatrice/deck_list/deck_list.h" #include "tree/inner_deck_list_node.h" +#include +#include #include +#include +#include #include +#include +#include namespace DeckListPlainText { @@ -26,6 +33,7 @@ bool parse(QTextStream &in, // Regex for advanced card parsing static const QRegularExpression reMultiplier(R"(^[xX\(\[]*(\d+)[xX\*\)\]]* ?(.+))"); + static const QRegularExpression reTabQuantity(R"(^\d+[xX]?$)"); // Regex for extracting set code and collector number with attached symbols static const QRegularExpression reHyphenFormat(R"(\((\w{3,})\)\s+(\w{3,})-(\d+[^\w\s]*))"); @@ -103,8 +111,34 @@ bool parse(QTextStream &in, continue; } - QString cardName = match.captured().simplified(); + const QString rawLine = match.captured(); + QString cardName = rawLine.simplified(); bool sideboard = false; + int amount = 1; + + // Card names never contain tab characters, so a leading numeric field + // marks a tabular record emitted by third-party deck tools (e.g. Delver + // Lens "2\tCard Name\tSet Name"). The first two columns are the quantity + // and the card name; any further columns are printer/set metadata and + // are discarded. + bool hasTabQuantity = false; + const auto tabFields = rawLine.split('\t'); + int firstField = 0; + while (firstField < tabFields.size() && tabFields.at(firstField).trimmed().isEmpty()) { + ++firstField; + } + if (firstField + 1 < tabFields.size()) { + const QString quantity = tabFields.at(firstField).trimmed(); + if (reTabQuantity.match(quantity).hasMatch()) { + hasTabQuantity = true; + QString digits = quantity; + if (digits.endsWith('x') || digits.endsWith('X')) { + digits.chop(1); + } + amount = digits.toInt(); + cardName = tabFields.at(firstField + 1).simplified(); + } + } // Sideboard detection if (sBStart < 0) { @@ -149,11 +183,12 @@ bool parse(QTextStream &in, } // check if a specific amount is mentioned - int amount = 1; - match = reMultiplier.match(cardName); - if (match.hasMatch()) { - amount = match.captured(1).toInt(); - cardName = match.captured(2); + if (!hasTabQuantity) { + match = reMultiplier.match(cardName); + if (match.hasMatch()) { + amount = match.captured(1).toInt(); + cardName = match.captured(2); + } } // Normalize the card name diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.h b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.h index e0f456a18..0845f7935 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/deck_list_plain_text_parser.h @@ -3,10 +3,11 @@ #include "deck_list.h" -#include #include class QTextStream; +class DecklistNodeTree; +class QString; namespace DeckListPlainText { diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.cpp index fd72fea0b..d1d44cca5 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.cpp @@ -1,6 +1,12 @@ #include "playmat_resolver.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/interfaces/interface_interface_settings_provider.h" +#include "libcockatrice/utility/card_ref.h" + +#include #include +#include PlaymatInfo resolveEffectivePlaymat(const DeckList &deck, const PlaymatInfo &force, diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.h b/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.h index 59bc449c8..411ca81fd 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/playmat_resolver.h @@ -1,10 +1,13 @@ #ifndef COCKATRICE_PLAYMAT_RESOLVER_H #define COCKATRICE_PLAYMAT_RESOLVER_H -#include "deck_list.h" +#include "libcockatrice/utility/playmat_params.h" #include +class DeckList; +template class QList; + /** * @brief Resolves the effective playmat for a deck per the resolution chain: * force override > deck-configured playmat > fallback list > none. diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.cpp index 855062c18..3a47bf1a5 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.cpp @@ -1,6 +1,12 @@ #include "sideboard_plan.h" +#include "libcockatrice/protocol/pb/move_card_to_zone.pb.h" + +#include +#include #include +#include +#include namespace { diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.h b/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.h index fff4ff2f3..ee29991d6 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/sideboard_plan.h @@ -2,6 +2,7 @@ #define COCKATRICE_SIDEBOARD_PLAN_H #include +#include #include class QXmlStreamWriter; diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.cpp index 685238d53..5c7b4bf84 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.cpp @@ -1,5 +1,10 @@ #include "abstract_deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" + +#include +#include + bool AbstractDecklistCardNode::compare(AbstractDecklistNode *other) const { switch (sortMethod) { diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.h b/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.h index 0942a4601..ebfd9a0b6 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_card_node.h @@ -13,6 +13,10 @@ #include "abstract_deck_list_node.h" +#include + +class InnerDecklistNode; + /** * @class AbstractDecklistCardNode * @ingroup DeckModels diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_node.h b/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_node.h index 38d1d44b8..406c6fb4d 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_node.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/tree/abstract_deck_list_node.h @@ -17,7 +17,9 @@ #ifndef COCKATRICE_ABSTRACT_DECK_LIST_NODE_H #define COCKATRICE_ABSTRACT_DECK_LIST_NODE_H -#include +#include + +class QXmlStreamWriter; /** * @enum DeckSortMethod diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.cpp index 1791c09a6..803737f1e 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.cpp @@ -1,5 +1,9 @@ #include "deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_card_node.h" + +class InnerDecklistNode; + DecklistCardNode::DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent) : AbstractDecklistCardNode(_parent), name(other->getName()), number(other->getNumber()), cardSetShortName(other->getCardSetShortName()), cardSetNumber(other->getCardCollectorNumber()), diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.h b/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.h index 3bab5405a..c96a764af 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.h @@ -14,7 +14,11 @@ #include "abstract_deck_list_card_node.h" +#include #include +#include + +class InnerDecklistNode; /** * @class DecklistCardNode diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.cpp b/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.cpp index 86f7f5363..b7b1e0b8f 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.cpp +++ b/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.cpp @@ -1,6 +1,18 @@ #include "inner_deck_list_node.h" #include "deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_card_node.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include InnerDecklistNode::InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent) : AbstractDecklistNode(_parent), name(other->getName()) diff --git a/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.h b/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.h index 8404d7116..6086f9efa 100644 --- a/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.h +++ b/libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.h @@ -19,7 +19,13 @@ #include "abstract_deck_list_node.h" #include +#include #include +#include +#include +#include + +class QXmlStreamReader; /** @brief Constant for the "main" deck zone name. */ #define DECK_ZONE_MAIN "main" diff --git a/libcockatrice_filters/CMakeLists.txt b/libcockatrice_filters/CMakeLists.txt index 905533df8..2d45b8e5b 100644 --- a/libcockatrice_filters/CMakeLists.txt +++ b/libcockatrice_filters/CMakeLists.txt @@ -18,3 +18,5 @@ add_dependencies(libcockatrice_filters libcockatrice_card) target_include_directories(libcockatrice_filters PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(libcockatrice_filters PUBLIC libcockatrice_card ${QT_CORE_MODULE}) + +target_precompile_headers(libcockatrice_filters PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_filters/libcockatrice/filters/filter_card.cpp b/libcockatrice_filters/libcockatrice/filters/filter_card.cpp index 5fdce7ae0..26cddd53c 100644 --- a/libcockatrice_filters/libcockatrice/filters/filter_card.cpp +++ b/libcockatrice_filters/libcockatrice/filters/filter_card.cpp @@ -1,6 +1,9 @@ #include "filter_card.h" #include +#include +#include +#include QJsonObject CardFilter::toJson() const { diff --git a/libcockatrice_filters/libcockatrice/filters/filter_card.h b/libcockatrice_filters/libcockatrice/filters/filter_card.h index bb1e0ef53..e6a37ee40 100644 --- a/libcockatrice_filters/libcockatrice/filters/filter_card.h +++ b/libcockatrice_filters/libcockatrice/filters/filter_card.h @@ -7,8 +7,10 @@ #ifndef CARDFILTER_H #define CARDFILTER_H +#include #include #include +#include class CardFilter : public QObject { diff --git a/libcockatrice_filters/libcockatrice/filters/filter_string.cpp b/libcockatrice_filters/libcockatrice/filters/filter_string.cpp index df0c70ae7..bc137b0f6 100644 --- a/libcockatrice_filters/libcockatrice/filters/filter_string.cpp +++ b/libcockatrice_filters/libcockatrice/filters/filter_string.cpp @@ -1,12 +1,35 @@ #include "filter_string.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/card_localization.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/card/set/card_set_list.h" + #include +#include +#include #include +#include +#include #include +#include +#include #include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include static peg::parser search(R"( Start <- QueryPartList diff --git a/libcockatrice_filters/libcockatrice/filters/filter_string.h b/libcockatrice_filters/libcockatrice/filters/filter_string.h index 015df0cf4..2abe95201 100644 --- a/libcockatrice_filters/libcockatrice/filters/filter_string.h +++ b/libcockatrice_filters/libcockatrice/filters/filter_string.h @@ -7,15 +7,13 @@ #ifndef FILTER_STRING_H #define FILTER_STRING_H -#include "filter_tree.h" - #include -#include #include #include #include #include -#include + +struct CardSearchLanguage; inline Q_LOGGING_CATEGORY(FilterStringLog, "filter_string"); @@ -29,6 +27,7 @@ namespace peg { template struct AstBase; struct EmptyType; + typedef AstBase Ast; } // namespace peg diff --git a/libcockatrice_filters/libcockatrice/filters/filter_tree.cpp b/libcockatrice_filters/libcockatrice/filters/filter_tree.cpp index a5d91d9d3..742b44e97 100644 --- a/libcockatrice_filters/libcockatrice/filters/filter_tree.cpp +++ b/libcockatrice_filters/libcockatrice/filters/filter_tree.cpp @@ -1,8 +1,16 @@ #include "filter_tree.h" #include "filter_card.h" +#include "libcockatrice/card/card_localization.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include #include +#include +#include +#include +#include template FilterTreeNode *FilterTreeBranch::nodeAt(int i) const { diff --git a/libcockatrice_filters/libcockatrice/filters/filter_tree.h b/libcockatrice_filters/libcockatrice/filters/filter_tree.h index dd47a1ebc..0defd466b 100644 --- a/libcockatrice_filters/libcockatrice/filters/filter_tree.h +++ b/libcockatrice_filters/libcockatrice/filters/filter_tree.h @@ -8,13 +8,16 @@ #define FILTERTREE_H #include "filter_card.h" +#include "libcockatrice/card/card_info.h" #include #include -#include -#include +#include +#include #include +struct CardSearchLanguage; + class FilterTreeNode { private: @@ -120,6 +123,7 @@ public: class FilterItemList; class FilterTree; + class LogicMap : public FilterTreeBranch { @@ -142,6 +146,7 @@ public: }; class FilterItem; + class FilterItemList : public FilterTreeBranch { private: diff --git a/libcockatrice_interfaces/CMakeLists.txt b/libcockatrice_interfaces/CMakeLists.txt index f53c41807..3b17569b1 100644 --- a/libcockatrice_interfaces/CMakeLists.txt +++ b/libcockatrice_interfaces/CMakeLists.txt @@ -31,3 +31,5 @@ add_library(libcockatrice_interfaces STATIC ${MOC_SOURCES}) target_include_directories(libcockatrice_interfaces PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(libcockatrice_interfaces PUBLIC libcockatrice_utility ${QT_CORE_MODULE}) + +target_precompile_headers(libcockatrice_interfaces PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_preference_provider.h b/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_preference_provider.h index a6cf941fb..2510919ca 100644 --- a/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_preference_provider.h +++ b/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_preference_provider.h @@ -8,7 +8,6 @@ class ICardPreferenceProvider public: virtual ~ICardPreferenceProvider() = default; [[nodiscard]] virtual QString getCardPreferenceOverride(const QString &cardName) const = 0; - [[nodiscard]] virtual bool getIncludeRebalancedCards() const = 0; }; #endif // COCKATRICE_INTERFACE_CARD_PREFERENCE_PROVIDER_H diff --git a/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h b/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h index 36e748006..746ac9490 100644 --- a/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h +++ b/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h @@ -2,6 +2,7 @@ #define COCKATRICE_INTERFACE_CARD_SET_PRIORITY_CONTROLLER_H #include +#include class ICardSetPriorityController { @@ -11,6 +12,7 @@ public: QString shortName; unsigned int sortKey; bool enabled; + bool isKnown = false; }; /** @@ -46,6 +48,24 @@ public: */ virtual SetOptions getSetOptions(QString shortName) const = 0; + /** + * @brief Returns the short names of every set currently marked as enabled. + * + * Callers fold this into the card database cache source hash so that + * toggling set enablement invalidates the cache. + * + * @return The enabled set short names, sorted alphabetically. + */ + virtual QStringList getEnabledSetNames() const = 0; + + /** + * @brief Persists per-set options for every entry in a single settings flush. + * + * Each individual setSortKey/setEnabled/setIsKnown call re-opens and re-syncs + * the whole .ini when backed by QSettings, so persisting hundreds of sets + * one option at a time freezes the GUI thread for seconds. Callers that touch + * more than a handful of sets must bundle the records and call this once. + */ virtual void saveSets(const QVector &data) = 0; }; diff --git a/libcockatrice_interfaces/libcockatrice/interfaces/interface_cards_display_settings_provider.h b/libcockatrice_interfaces/libcockatrice/interfaces/interface_cards_display_settings_provider.h index 2821fb96e..a5ab4fc37 100644 --- a/libcockatrice_interfaces/libcockatrice/interfaces/interface_cards_display_settings_provider.h +++ b/libcockatrice_interfaces/libcockatrice/interfaces/interface_cards_display_settings_provider.h @@ -14,7 +14,6 @@ public: [[nodiscard]] virtual bool getBumpSetsWithCardsInDeckToTop() const = 0; [[nodiscard]] virtual int getPrintingSelectorSortOrder() const = 0; [[nodiscard]] virtual int getPrintingSelectorCardSize() const = 0; - [[nodiscard]] virtual bool getIncludeRebalancedCards() const = 0; [[nodiscard]] virtual bool getPrintingSelectorNavigationButtonsVisible() const = 0; [[nodiscard]] virtual bool getTapAnimation() const = 0; [[nodiscard]] virtual bool getArrowDrawAnimation() const = 0; diff --git a/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_preference_provider.h b/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_preference_provider.h index 3781f4b63..f846d51e8 100644 --- a/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_preference_provider.h +++ b/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_preference_provider.h @@ -9,11 +9,6 @@ public: { return {}; } - - [[nodiscard]] bool getIncludeRebalancedCards() const override - { - return true; - } }; #endif // COCKATRICE_NOOP_CARD_PREFERENCE_PROVIDER_H diff --git a/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h b/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h index 8cc2011bd..94e1f0c9a 100644 --- a/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h +++ b/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h @@ -34,6 +34,11 @@ public: return {0, true, true}; } + QStringList getEnabledSetNames() const override + { + return {}; + } + void saveSets(const QVector & /* data */) override { } diff --git a/libcockatrice_models/libcockatrice/models/database/CMakeLists.txt b/libcockatrice_models/libcockatrice/models/database/CMakeLists.txt index 840f14b08..a73e36dbb 100644 --- a/libcockatrice_models/libcockatrice/models/database/CMakeLists.txt +++ b/libcockatrice_models/libcockatrice/models/database/CMakeLists.txt @@ -29,3 +29,5 @@ add_library( target_include_directories(libcockatrice_models_database PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(libcockatrice_models_database PUBLIC libcockatrice_card libcockatrice_filters ${QT_CORE_MODULE}) + +target_precompile_headers(libcockatrice_models_database PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.cpp b/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.cpp index f31463b50..b99b8b0f7 100644 --- a/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.cpp @@ -1,5 +1,14 @@ #include "card_completer_proxy_model.h" +#include +#include +#include +#include +#include +#include + +class QObject; + CardCompleterProxyModel::CardCompleterProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { } diff --git a/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.h b/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.h index 91dc06335..8aa671af7 100644 --- a/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.h +++ b/libcockatrice_models/libcockatrice/models/database/card/card_completer_proxy_model.h @@ -8,6 +8,9 @@ #define CARD_COMPLETER_PROXY_MODEL_H #include +#include + +class QObject; class CardCompleterProxyModel : public QSortFilterProxyModel { diff --git a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp index 3a734ed37..5bde6e3fc 100644 --- a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp @@ -3,6 +3,10 @@ #include "../card_database_display_model.h" #include "../card_database_model.h" +#include +#include +#include +#include #include #include diff --git a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h index b877a9385..08d0e8636 100644 --- a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h +++ b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h @@ -7,9 +7,20 @@ #ifndef CARD_SEARCH_MODEL_H #define CARD_SEARCH_MODEL_H -#include "../card_database_display_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/card_localization.h" #include +#include +#include +#include +#include +#include +#include +#include + +class CardDatabaseDisplayModel; +class QObject; class CardSearchModel : public QAbstractListModel { diff --git a/libcockatrice_models/libcockatrice/models/database/card_database_display_model.cpp b/libcockatrice_models/libcockatrice/models/database/card_database_display_model.cpp index 7f89677c8..39bb8314c 100644 --- a/libcockatrice_models/libcockatrice/models/database/card_database_display_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/card_database_display_model.cpp @@ -1,6 +1,23 @@ #include "card_database_display_model.h" #include "card_database_model.h" +#include "libcockatrice/card/card_localization.h" +#include "libcockatrice/filters/filter_string.h" +#include "libcockatrice/filters/filter_tree.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QObject; CardDatabaseDisplayModel::CardDatabaseDisplayModel(QObject *parent) : QSortFilterProxyModel(parent), isToken(ShowAll), filterString(nullptr) diff --git a/libcockatrice_models/libcockatrice/models/database/card_database_display_model.h b/libcockatrice_models/libcockatrice/models/database/card_database_display_model.h index e6aadd8c6..d12dd1fb4 100644 --- a/libcockatrice_models/libcockatrice/models/database/card_database_display_model.h +++ b/libcockatrice_models/libcockatrice/models/database/card_database_display_model.h @@ -8,12 +8,21 @@ #ifndef COCKATRICE_CARD_DATABASE_DISPLAY_MODEL_H #define COCKATRICE_CARD_DATABASE_DISPLAY_MODEL_H +#include "libcockatrice/card/card_info.h" + +#include +#include #include +#include #include #include #include +#include class FilterTree; +class QObject; +template class QMap; + class CardDatabaseDisplayModel : public QSortFilterProxyModel { Q_OBJECT diff --git a/libcockatrice_models/libcockatrice/models/database/card_database_model.cpp b/libcockatrice_models/libcockatrice/models/database/card_database_model.cpp index ecd26a9f8..1ede554f8 100644 --- a/libcockatrice_models/libcockatrice/models/database/card_database_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/card_database_model.cpp @@ -1,8 +1,16 @@ #include "card_database_model.h" -#include +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" + +#include +#include +#include +#include #include +class QObject; + #define CARDDBMODEL_COLUMNS 6 CardDatabaseModel::CardDatabaseModel(CardDatabase *_db, bool _showOnlyCardsFromEnabledSets, QObject *parent) diff --git a/libcockatrice_models/libcockatrice/models/database/card_database_model.h b/libcockatrice_models/libcockatrice/models/database/card_database_model.h index ad84de6f4..208240109 100644 --- a/libcockatrice_models/libcockatrice/models/database/card_database_model.h +++ b/libcockatrice_models/libcockatrice/models/database/card_database_model.h @@ -7,10 +7,17 @@ #ifndef CARDDATABASEMODEL_H #define CARDDATABASEMODEL_H +#include "libcockatrice/card/card_info.h" + #include #include +#include #include -#include +#include +#include + +class CardDatabase; +class QObject; class CardDatabaseModel : public QAbstractListModel { diff --git a/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.cpp b/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.cpp index 8fd5311f2..a0b9c1061 100644 --- a/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.cpp @@ -1,6 +1,19 @@ #include "card_sets_model.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/interfaces/interface_card_set_priority_controller.h" + +#include +#include +#include +#include +#include +#include +#include #include +#include +#include SetsModel::SetsModel(CardDatabase *_db, QObject *parent) : QAbstractTableModel(parent), sets(_db->getSetList()) { @@ -253,7 +266,7 @@ void SetsModel::save(CardDatabase *db) const bool enabled = enabledSets.contains(sets[i]); sets[i]->setSortKeyInMemory(sortKey); sets[i]->setEnabledInMemory(enabled); - saveData.append({sets[i]->getShortName(), sortKey, enabled}); + saveData.append({sets[i]->getShortName(), sortKey, enabled, sets[i]->getIsKnown()}); } db->getPriorityController()->saveSets(saveData); diff --git a/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.h b/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.h index 2adf71def..354414dc8 100644 --- a/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.h +++ b/libcockatrice_models/libcockatrice/models/database/card_set/card_sets_model.h @@ -7,13 +7,24 @@ #ifndef SETSMODEL_H #define SETSMODEL_H +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/set/card_set_list.h" + #include +#include #include +#include +#include #include #include -#include +#include +#include +#include +#include +#include -class SetsProxyModel; +class CardDatabase; +class QObject; class SetsMimeData : public QMimeData { diff --git a/libcockatrice_models/libcockatrice/models/database/token/token_display_model.cpp b/libcockatrice_models/libcockatrice/models/database/token/token_display_model.cpp index 4282c6dc8..e08183576 100644 --- a/libcockatrice_models/libcockatrice/models/database/token/token_display_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/token/token_display_model.cpp @@ -1,6 +1,12 @@ #include "token_display_model.h" #include "../card_database_model.h" +#include "card_database_display_model.h" +#include "libcockatrice/card/card_info.h" + +#include + +class QObject; TokenDisplayModel::TokenDisplayModel(QObject *parent) : CardDatabaseDisplayModel(parent) { diff --git a/libcockatrice_models/libcockatrice/models/database/token/token_display_model.h b/libcockatrice_models/libcockatrice/models/database/token/token_display_model.h index c8f767189..a8625368f 100644 --- a/libcockatrice_models/libcockatrice/models/database/token/token_display_model.h +++ b/libcockatrice_models/libcockatrice/models/database/token/token_display_model.h @@ -9,6 +9,11 @@ #include "../card_database_display_model.h" +#include +#include + +class QObject; + class TokenDisplayModel : public CardDatabaseDisplayModel { Q_OBJECT diff --git a/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.cpp b/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.cpp index 89a1f71b1..9636ed665 100644 --- a/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.cpp @@ -2,9 +2,13 @@ #include "../card_database_display_model.h" #include "../card_database_model.h" +#include "libcockatrice/card/set/card_set.h" +#include #include +class QObject; + TokenEditModel::TokenEditModel(QObject *parent) : CardDatabaseDisplayModel(parent) { } diff --git a/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.h b/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.h index 92dfaadd7..2f3398899 100644 --- a/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.h +++ b/libcockatrice_models/libcockatrice/models/database/token/token_edit_model.h @@ -9,6 +9,11 @@ #include "../card_database_display_model.h" +#include +#include + +class QObject; + class TokenEditModel : public CardDatabaseDisplayModel { Q_OBJECT diff --git a/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt b/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt index a6ab2a204..324bed102 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt +++ b/libcockatrice_models/libcockatrice/models/deck_list/CMakeLists.txt @@ -16,3 +16,5 @@ target_include_directories(libcockatrice_models_deck_list PUBLIC ${CMAKE_CURRENT target_link_libraries( libcockatrice_models_deck_list PUBLIC libcockatrice_card libcockatrice_deck_list ${QT_CORE_MODULE} ) + +target_precompile_headers(libcockatrice_models_deck_list PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp index a5628a844..4b4088972 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.cpp @@ -1,6 +1,27 @@ #include "deck_list_model.h" +#include "deck_list_model_custom_zones.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/format/format_legality_rules.h" +#include "libcockatrice/card/printing/exact_card.h" +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/deck_list_node_tree.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" +#include "libcockatrice/deck_list/tree/deck_list_card_node.h" + +#include +#include +#include +#include +#include +#include #include +#include +#include + +class QObject; DeckListModel::DeckListModel(QObject *parent) : QAbstractItemModel(parent), lastKnownColumn(1), lastKnownOrder(Qt::AscendingOrder) diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h index ce6d7f8cb..7334d48ef 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model.h @@ -1,18 +1,26 @@ #ifndef DECKLISTMODEL_H #define DECKLISTMODEL_H -#include "deck_list_model_custom_zones.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include "libcockatrice/utility/card_ref.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 #include -#include -#include +#include +#include +#include +#include +#include +#include +#include -class CardDatabase; -class QPrinter; -class QTextCursor; +class AbstractDecklistNode; +class DeckList; +class ExactCard; +class QObject; /** * @namespace DeckRoles diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.cpp b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.cpp index 1dc745e63..419c38b04 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.cpp +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.cpp @@ -1,10 +1,14 @@ #include "deck_list_model_custom_zones.h" #include "deck_list_model.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" #include <../../../../libcockatrice_deck_list/libcockatrice/deck_list/tree/deck_list_card_node.h> #include +#include #include +#include namespace DeckListModelCustomZones { diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.h b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.h index 518a9e1d2..53bdeaa1e 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.h +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_model_custom_zones.h @@ -4,7 +4,10 @@ #include <../../../../libcockatrice_deck_list/libcockatrice/deck_list/tree/inner_deck_list_node.h> #include #include -#include +#include +#include + +class AbstractDecklistNode; /** * @class DecklistModelSubZoneNode diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.cpp b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.cpp index 3d433153a..dcb294ec8 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.cpp +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.cpp @@ -1,6 +1,16 @@ #include "deck_list_sort_filter_proxy_model.h" #include "deck_list_model.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_manager.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/printing/exact_card.h" + +#include +#include +#include +#include +#include bool DeckListSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { diff --git a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.h b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.h index 1565417f0..522ed1e23 100644 --- a/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.h +++ b/libcockatrice_models/libcockatrice/models/deck_list/deck_list_sort_filter_proxy_model.h @@ -7,8 +7,13 @@ #ifndef COCKATRICE_DECK_LIST_SORT_FILTER_PROXY_MODEL_H #define COCKATRICE_DECK_LIST_SORT_FILTER_PROXY_MODEL_H +#include #include -#include +#include +#include +#include + +class QObject; class DeckListSortFilterProxyModel : public QSortFilterProxyModel { diff --git a/libcockatrice_network/libcockatrice/network/client/abstract/CMakeLists.txt b/libcockatrice_network/libcockatrice/network/client/abstract/CMakeLists.txt index 6fba8d629..53ad524b4 100644 --- a/libcockatrice_network/libcockatrice/network/client/abstract/CMakeLists.txt +++ b/libcockatrice_network/libcockatrice/network/client/abstract/CMakeLists.txt @@ -19,3 +19,5 @@ target_link_libraries( PUBLIC ${COCKATRICE_QT_VERSION_NAME}::Network ${COCKATRICE_QT_VERSION_NAME}::WebSockets libcockatrice_protocol libcockatrice_network_server_remote ) + +target_precompile_headers(libcockatrice_network_client_abstract PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.cpp b/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.cpp index 687d93666..d66653fb1 100644 --- a/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.cpp +++ b/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.cpp @@ -1,6 +1,25 @@ #include "abstract_client.h" +#include "libcockatrice/protocol/pb/admin_commands.pb.h" +#include "libcockatrice/protocol/pb/developer_commands.pb.h" +#include "libcockatrice/protocol/pb/game_event_container.pb.h" +#include "libcockatrice/protocol/pb/moderator_commands.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/room_commands.pb.h" +#include "libcockatrice/protocol/pb/room_event.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" +#include "libcockatrice/protocol/pb/session_event.pb.h" + +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include #include diff --git a/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.h b/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.h index af22a5c9d..442e96eb2 100644 --- a/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.h +++ b/libcockatrice_network/libcockatrice/network/client/abstract/abstract_client.h @@ -11,10 +11,27 @@ #include #include +#include #include -#include -#include +#include +#include +#include + +// IWYU pragma: keep +// ServerInfo_User appears in signal signatures, including inside QList, so the +// moc-generated code needs the complete type. +#include #include +#include + +namespace google +{ +namespace protobuf +{ +class Message; +} // namespace protobuf +} // namespace google +template class QList; inline Q_LOGGING_CATEGORY(AbstractClientLog, "abstract_client"); @@ -36,7 +53,6 @@ class Event_NotifyUser; class Event_ConnectionClosed; class Event_ServerShutdown; class Event_ReplayAdded; -class FeatureSet; enum ClientStatus { diff --git a/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.cpp b/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.cpp index 98b353fdf..bc6230621 100644 --- a/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.cpp +++ b/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.cpp @@ -1,7 +1,10 @@ #include "latency_tracker.h" +#include +#include #include #include +#include void LatencyTracker::addSample(qint64 ms) { diff --git a/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.h b/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.h index 75f18ac0c..cae11ea4d 100644 --- a/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.h +++ b/libcockatrice_network/libcockatrice/network/client/abstract/latency_tracker.h @@ -6,8 +6,10 @@ #ifndef LATENCY_TRACKER_H #define LATENCY_TRACKER_H +#include #include #include +#include #include /** diff --git a/libcockatrice_network/libcockatrice/network/client/local/CMakeLists.txt b/libcockatrice_network/libcockatrice/network/client/local/CMakeLists.txt index 2ac12e1fe..08c12b7f8 100644 --- a/libcockatrice_network/libcockatrice/network/client/local/CMakeLists.txt +++ b/libcockatrice_network/libcockatrice/network/client/local/CMakeLists.txt @@ -19,3 +19,5 @@ target_link_libraries( PUBLIC ${COCKATRICE_QT_VERSION_NAME}::Network ${COCKATRICE_QT_VERSION_NAME}::WebSockets libcockatrice_network_client_abstract ) + +target_precompile_headers(libcockatrice_network_client_local PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_network/libcockatrice/network/client/local/local_client.cpp b/libcockatrice_network/libcockatrice/network/client/local/local_client.cpp index eefa3a2f3..c1c1cc976 100644 --- a/libcockatrice_network/libcockatrice/network/client/local/local_client.cpp +++ b/libcockatrice_network/libcockatrice/network/client/local/local_client.cpp @@ -1,9 +1,17 @@ #include "local_client.h" #include "../../server/local/local_server_interface.h" +#include "abstract_client.h" +#include "libcockatrice/protocol/pb/commands.pb.h" +#include "libcockatrice/protocol/pb/server_message.pb.h" +#include +#include #include #include +#include + +class QObject; LocalClient::LocalClient(LocalServerInterface *_lsi, const QString &_playerName, diff --git a/libcockatrice_network/libcockatrice/network/client/local/local_client.h b/libcockatrice_network/libcockatrice/network/client/local/local_client.h index 9e1c89ddd..3ae570255 100644 --- a/libcockatrice_network/libcockatrice/network/client/local/local_client.h +++ b/libcockatrice_network/libcockatrice/network/client/local/local_client.h @@ -10,6 +10,11 @@ #include "../abstract/abstract_client.h" #include +#include +#include + +class QObject; +class ServerMessage; inline Q_LOGGING_CATEGORY(LocalClientLog, "local_client"); diff --git a/libcockatrice_network/libcockatrice/network/client/remote/CMakeLists.txt b/libcockatrice_network/libcockatrice/network/client/remote/CMakeLists.txt index cb68d0c37..c32ca0aa8 100644 --- a/libcockatrice_network/libcockatrice/network/client/remote/CMakeLists.txt +++ b/libcockatrice_network/libcockatrice/network/client/remote/CMakeLists.txt @@ -19,3 +19,5 @@ target_link_libraries( PUBLIC ${COCKATRICE_QT_VERSION_NAME}::Network ${COCKATRICE_QT_VERSION_NAME}::WebSockets libcockatrice_network_client_abstract libcockatrice_interfaces libcockatrice_utility libcockatrice_protocol ) + +target_precompile_headers(libcockatrice_network_client_remote PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp index de2cc720f..feda9e3f4 100644 --- a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp +++ b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.cpp @@ -1,5 +1,8 @@ #include "remote_client.h" +#include "abstract_client.h" +#include "libcockatrice/protocol/pb/commands.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include "version_string.h" #include @@ -7,13 +10,21 @@ #include #include #include +#include +#include +#include +#include +#include #include #include +#include #include +#include +#include +#include #include #include #include -#include #include #include #include @@ -22,6 +33,10 @@ #include #include #include +#include + +class Event_ConnectionClosed; +class QObject; static const unsigned int protocolVersion = 14; diff --git a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h index 862dac06e..4d8c24fd2 100644 --- a/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h +++ b/libcockatrice_network/libcockatrice/network/client/remote/remote_client.h @@ -8,11 +8,23 @@ #define REMOTECLIENT_H #include "../abstract/abstract_client.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" +#include +#include #include +#include +#include #include -#include -#include +#include +#include + +class Event_ConnectionClosed; +class Event_ServerIdentification; +class INetworkSettingsProvider; +class QObject; +template class QList; inline Q_LOGGING_CATEGORY(RemoteClientLog, "remote_client"); diff --git a/libcockatrice_network/libcockatrice/network/server/local/CMakeLists.txt b/libcockatrice_network/libcockatrice/network/server/local/CMakeLists.txt index 494ae1294..020753d7f 100644 --- a/libcockatrice_network/libcockatrice/network/server/local/CMakeLists.txt +++ b/libcockatrice_network/libcockatrice/network/server/local/CMakeLists.txt @@ -15,3 +15,5 @@ add_dependencies(libcockatrice_network_server_local libcockatrice_protocol) target_include_directories(libcockatrice_network_server_local PUBLIC .) target_link_libraries(libcockatrice_network_server_local PUBLIC ${COCKATRICE_QT_MODULES} libcockatrice_protocol) + +target_precompile_headers(libcockatrice_network_server_local PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_network/libcockatrice/network/server/local/local_server.cpp b/libcockatrice_network/libcockatrice/network/server/local/local_server.cpp index 8f9d82aa4..ebfc9bdeb 100644 --- a/libcockatrice_network/libcockatrice/network/server/local/local_server.cpp +++ b/libcockatrice_network/libcockatrice/network/server/local/local_server.cpp @@ -1,8 +1,17 @@ #include "local_server.h" +#include "../remote/server.h" +#include "../remote/server_database_interface.h" +#include "../remote/server_protocolhandler.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include "local_server_interface.h" #include <../remote/server_room.h> +#include +#include +#include + +class QObject; LocalServer::LocalServer(QObject *parent) : Server(parent) { diff --git a/libcockatrice_network/libcockatrice/network/server/local/local_server.h b/libcockatrice_network/libcockatrice/network/server/local/local_server.h index 0112afa72..ee8d487d2 100644 --- a/libcockatrice_network/libcockatrice/network/server/local/local_server.h +++ b/libcockatrice_network/libcockatrice/network/server/local/local_server.h @@ -9,8 +9,11 @@ #include <../remote/server.h> #include <../remote/server_database_interface.h> +#include +#include class LocalServerInterface; +class QObject; class LocalServer : public Server { diff --git a/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.cpp b/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.cpp index bb86198af..b7c8d4bfa 100644 --- a/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.cpp +++ b/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.cpp @@ -1,8 +1,10 @@ #include "local_server_interface.h" +#include "../remote/server_protocolhandler.h" #include "local_server.h" -#include +class CommandContainer; +class Server_DatabaseInterface; LocalServerInterface::LocalServerInterface(LocalServer *_server, Server_DatabaseInterface *_databaseInterface) : Server_ProtocolHandler(_server, _databaseInterface, _server) diff --git a/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.h b/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.h index 44e3b3e53..8aadb40ca 100644 --- a/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.h +++ b/libcockatrice_network/libcockatrice/network/server/local/local_server_interface.h @@ -8,8 +8,13 @@ #define LOCALSERVERINTERFACE_H #include <../remote/server_protocolhandler.h> +#include +#include class LocalServer; +class CommandContainer; +class ServerMessage; +class Server_DatabaseInterface; class LocalServerInterface : public Server_ProtocolHandler { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt b/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt index e11a962d1..2127487d2 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt +++ b/libcockatrice_network/libcockatrice/network/server/remote/CMakeLists.txt @@ -3,6 +3,7 @@ set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) set(HEADERS + game/dump_zone_range.h game/server_abstract_participant.h game/server_abstract_player.h game/server_arrow.h @@ -33,6 +34,7 @@ qt6_wrap_cpp(MOC_SOURCES ${HEADERS}) add_library( libcockatrice_network_server_remote STATIC ${MOC_SOURCES} + game/dump_zone_range.cpp game/server_abstract_participant.cpp game/server_abstract_player.cpp game/server_arrow.cpp @@ -62,3 +64,5 @@ target_link_libraries( libcockatrice_network_server_remote PUBLIC libcockatrice_protocol libcockatrice_utility libcockatrice_rng libcockatrice_deck_list ${COCKATRICE_QT_MODULES} ) + +target_precompile_headers(libcockatrice_network_server_remote PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/dump_zone_range.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/dump_zone_range.cpp new file mode 100644 index 000000000..4ecca95cb --- /dev/null +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/dump_zone_range.cpp @@ -0,0 +1,17 @@ +#include "dump_zone_range.h" + +#include + +std::pair dumpZoneCardRange(qsizetype cardCount, int numberCards, bool isReversed) +{ + qsizetype count = 0; + if (numberCards == -1) { + count = cardCount; + } else if (numberCards > 0) { + count = std::min(numberCards, cardCount); + } + count = std::max(count, 0); + + const qsizetype begin = isReversed ? cardCount - count : 0; + return {begin, begin + count}; +} diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/dump_zone_range.h b/libcockatrice_network/libcockatrice/network/server/remote/game/dump_zone_range.h new file mode 100644 index 000000000..a688b09d0 --- /dev/null +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/dump_zone_range.h @@ -0,0 +1,29 @@ +#ifndef DUMP_ZONE_RANGE_H +#define DUMP_ZONE_RANGE_H + +#include +#include + +/** + * @brief Resolve a client's zone dump request against a zone's real card count. + * + * @c number_cards arrives from the client unvalidated. -1 means "the whole zone", which + * is the convention the client uses when sizing its own view of one. Every other negative + * value, and every value larger than the zone, has to be brought into range rather than + * used as an index: with a reversed request the zone offset is + * @c cardCount - @c numberCards, which runs off the front of the list when the request + * exceeds the zone and off the back when @c numberCards is -1. + * + * Kept in its own translation unit so it can be exercised without the rest of + * server_abstract_player.cpp, which refers to the RNG global that only the servatrice + * binary defines. + * + * @param cardCount number of cards the zone actually holds + * @param numberCards the requested count, -1 for the whole zone + * @param isReversed take the trailing cards instead of the leading ones + * @return the half-open index range [begin, end) into the zone's card list, always + * contained in [0, cardCount) + */ +std::pair dumpZoneCardRange(qsizetype cardCount, int numberCards, bool isReversed); + +#endif // DUMP_ZONE_RANGE_H diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp index a6280ffa1..5b8d901bb 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.cpp @@ -4,10 +4,16 @@ #include "../server_abstractuserinterface.h" #include "../server_database_interface.h" #include "../server_room.h" -#include "server_card.h" +#include "game/server_abstract_player.h" +#include "libcockatrice/protocol/pb/event_leave.pb.h" +#include "libcockatrice/protocol/pb/game_commands.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" #include "server_game.h" -#include "server_player.h" +#include "server_response_containers.h" +#include "serverinfo_user_container.h" +#include +#include #include #include #include @@ -50,6 +56,7 @@ #include #include #include +#include Server_AbstractParticipant::Server_AbstractParticipant(Server_Game *_game, int _playerId, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h index c78ae78c1..195da9b7f 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_participant.h @@ -5,8 +5,8 @@ #include "server_arrowtarget.h" #include -#include #include +#include class Server_Game; class Server_AbstractUserInterface; @@ -17,7 +17,6 @@ class GameEventContainer; class GameEventStorage; class ResponseContainer; class GameCommand; - class Command_KickFromGame; class Command_LeaveGame; class Command_GameSay; diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp index 6b4101a99..c03f1e966 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.cpp @@ -1,14 +1,34 @@ #include "server_abstract_player.h" +#include "dump_zone_range.h" +#include "game/server_abstract_participant.h" +#include "game/server_arrowtarget.h" +#include "libcockatrice/protocol/pb/card_attributes.pb.h" +#include "libcockatrice/protocol/pb/color.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_arrow.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_card.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_cardcounter.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_zone.pb.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" #include "server_arrow.h" #include "server_card.h" #include "server_cardzone.h" #include "server_game.h" #include "server_move_card_struct.h" +#include "server_response_containers.h" -#include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include @@ -50,8 +70,11 @@ #include #include #include -#include #include +#include +#include + +class Server_AbstractUserInterface; Server_AbstractPlayer::Server_AbstractPlayer(Server_Game *_game, int _playerId, @@ -1413,23 +1436,23 @@ Server_AbstractPlayer::cmdDumpZone(const Command_DumpZone &cmd, ResponseContaine int numberCards = cmd.number_cards(); const QList &cards = zone->getCards(); + const auto cardRange = dumpZoneCardRange(cards.size(), numberCards, cmd.is_reversed()); auto *re = new Response_DumpZone; ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); zoneInfo->set_name(zone->getName().toStdString()); zoneInfo->set_type(zone->getType()); zoneInfo->set_with_coords(zone->hasCoords()); - zoneInfo->set_card_count(numberCards < cards.size() ? cards.size() : numberCards); + zoneInfo->set_card_count(cards.size()); - for (int i = 0; (i < cards.size()) && (i < numberCards || numberCards == -1); ++i) { - const auto &findId = cmd.is_reversed() ? cards.size() - numberCards + i : i; - Server_Card *card = cards[findId]; + for (qsizetype findId = cardRange.first; findId < cardRange.second; ++findId) { + Server_Card *card = cards.at(findId); QString displayedName = card->getFaceDown() ? QString() : card->getName(); ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); cardInfo->set_provider_id(card->getProviderId().toStdString()); cardInfo->set_name(displayedName.toStdString()); if (zone->getType() == ServerInfo_Zone::HiddenZone) { - cardInfo->set_id(findId); + cardInfo->set_id(static_cast(findId)); } else { cardInfo->set_id(card->getId()); cardInfo->set_x(card->getX()); diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h index 4cc79c5fe..ae20955bf 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_abstract_player.h @@ -1,25 +1,32 @@ #ifndef ABSTRACT_PLAYER_H #define ABSTRACT_PLAYER_H -#include "../serverinfo_user_container.h" +#include "libcockatrice/protocol/pb/response.pb.h" #include "server_abstract_participant.h" #include #include +#include class CardToMove; class DeckList; class Server_Arrow; class Server_Card; class Server_CardZone; -class Server_Counter; struct MoveCardStruct; +class GameEventStorage; +class ServerInfo_User; +class Server_AbstractUserInterface; +class Server_Game; +enum CardAttribute : int; +template class QList; class Server_AbstractPlayer : public Server_AbstractParticipant { Q_OBJECT private: class MoveCardCompareFunctor; + QMap arrows; void sendCreateTokenEvents(Server_CardZone *zone, Server_Card *card, int xCoord, int yCoord, GameEventStorage &ges); @@ -49,6 +56,10 @@ public: { return deck; } + bool getSideboardLocked() const + { + return sideboardLocked; + } bool getReadyStart() const { return readyStart; diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrow.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrow.cpp index 2ad38b977..b5ccff8fe 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrow.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrow.cpp @@ -1,10 +1,16 @@ #include "server_arrow.h" +#include "game/server_abstract_player.h" +#include "game/server_arrowtarget.h" +#include "libcockatrice/protocol/pb/color.pb.h" #include "server_card.h" #include "server_cardzone.h" #include "server_player.h" +#include +#include #include +#include Server_Arrow::Server_Arrow(int _id, Server_Card *_startCard, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrowtarget.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrowtarget.h index 5a080018d..c4da725c2 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrowtarget.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_arrowtarget.h @@ -2,6 +2,7 @@ #define SERVER_ARROWTARGET_H #include +#include class Server_ArrowTarget : public QObject { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.cpp index 8c7feadba..c79f13634 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.cpp @@ -19,16 +19,22 @@ ***************************************************************************/ #include "server_card.h" +#include "game/server_abstract_player.h" +#include "libcockatrice/protocol/pb/card_attributes.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_cardcounter.pb.h" +#include "libcockatrice/utility/card_ref.h" #include "server_cardzone.h" -#include "server_player.h" +#include +#include #include +#include #include #include #include #include #include -#include +#include Server_Card::Server_Card(const CardRef &cardRef, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone) : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), cardRef(cardRef), tapped(false), attacking(false), diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.h index a2698ad61..cffd9eb40 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_card.h @@ -22,15 +22,18 @@ #include "server_arrowtarget.h" +#include #include #include -#include -#include +#include #include +#include class Server_CardZone; class Event_SetCardCounter; class Event_SetCardAttr; +class ServerInfo_Card; +enum CardAttribute : int; class Server_Card : public Server_ArrowTarget { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.cpp index 1db4f9c4c..5f40aa480 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.cpp @@ -19,13 +19,21 @@ ***************************************************************************/ #include "server_cardzone.h" +#include "libcockatrice/protocol/pb/serverinfo_zone.pb.h" #include "server_abstract_player.h" #include "server_card.h" #include +#include +#include +#include #include +#include +#include #include #include +#include +#include Server_CardZone::Server_CardZone(Server_AbstractPlayer *_player, const QString &_name, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.h index 77fea54ca..9ed39a159 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_cardzone.h @@ -20,15 +20,16 @@ #ifndef SERVER_CARDZONE_H #define SERVER_CARDZONE_H +#include #include #include #include +#include #include class Server_Card; class Server_AbstractPlayer; class Server_AbstractParticipant; -class Server_Game; class GameEventStorage; class Server_CardZone diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_counter.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_counter.cpp index b18e11c2b..f3dcb0fb1 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_counter.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_counter.cpp @@ -1,6 +1,9 @@ #include "server_counter.h" +#include "libcockatrice/protocol/pb/color.pb.h" + #include +#include Server_Counter::Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count) : id(_id), name(_name), counterColor(_counterColor), radius(_radius), count(_count) diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp index 131ff1077..b1863c91e 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.cpp @@ -23,21 +23,46 @@ #include "../server_database_interface.h" #include "../server_protocolhandler.h" #include "../server_room.h" +#include "game/game_config.h" +#include "game/server_abstract_participant.h" +#include "game/server_arrowtarget.h" +#include "game/server_deck_validation_strategy.h" +#include "game/server_game_lifecycle_strategy.h" +#include "game/server_match_result_strategy.h" #include "libcockatrice/protocol/pb/command_move_card.pb.h" +#include "libcockatrice/protocol/pb/game_event.pb.h" +#include "libcockatrice/protocol/pb/game_event_container.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/server_message.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_gametype.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_replay.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_replay_match.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_event.pb.h" #include "server_abstract_player.h" +#include "server_abstractuserinterface.h" #include "server_arrow.h" #include "server_card.h" #include "server_cardzone.h" #include "server_player.h" +#include "server_response_containers.h" #include "server_spectator.h" #include #include +#include +#include #include +#include +#include +#include #include #include +#include #include -#include +#include #include #include #include @@ -53,6 +78,9 @@ #include #include #include +#include +#include +#include Server_Game::Server_Game(const GameConfig &config, Server_Room *_room) : QObject(), room(_room), nextPlayerId(0), hostId(0), creatorInfo(new ServerInfo_User(config.creatorInfo)), @@ -799,6 +827,48 @@ void Server_Game::createGameJoinedEvent(Server_AbstractParticipant *joiningParti } rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); + + // A newly joined player never saw the "Player X has loaded a deck" messages + // (they are only broadcast when a deck is selected), so replay a deck-select + // context for every player that already has a deck loaded. It is delivered + // privately to the joining participant, whose client renders it as a log + // entry in the same way as a fresh deck selection. Skipped on reconnect + // (resuming) — the player already saw these — and once the game has started, + // when the message is no longer useful and would only spam the log. + if (!resuming && !gameStarted) { + for (auto *participant : participants.values()) { + if (participant == joiningParticipant) { + continue; + } + auto *deckOwner = qobject_cast(participant); + if (deckOwner == nullptr) { + continue; + } + const DeckList *deckList = deckOwner->getDeckList(); + if (deckList == nullptr) { + continue; + } + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_sideboard_locked(deckOwner->getSideboardLocked()); + event.mutable_player_properties()->set_deck_hash(deckList->getDeckHash().toStdString()); + + Context_DeckSelect deckSelect; + deckSelect.set_deck_hash(deckList->getDeckHash().toStdString()); + deckSelect.set_sideboard_size(deckList->getSideboardSize()); + if (getShareDecklistsOnLoad()) { + deckSelect.set_deck_list(deckList->writeToString_Native().toStdString()); + } + + GameEventContext context; + context.GetReflection() + ->MutableMessage(&context, deckSelect.GetDescriptor()->FindExtensionByName("ext")) + ->CopyFrom(deckSelect); + + rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, + prepareGameEvent(event, deckOwner->getPlayerId(), &context)); + } + } } void Server_Game::sendGameEventContainer(GameEventContainer *cont, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h index 1ed4fe4ca..c7f8d0929 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_game.h @@ -21,21 +21,25 @@ #define SERVERGAME_H #include "../server_response_containers.h" -#include "game_config.h" -#include "server_deck_validation_strategy.h" -#include "server_game_lifecycle_strategy.h" -#include "server_match_result_strategy.h" +#include "libcockatrice/protocol/pb/game_event_context.pb.h" +// IWYU pragma: keep +// ServerInfo_Game is passed by value to the gameInfoChanged() signal, so the +// moc-generated code needs the complete type. #include +#include #include -#include #include +#include #include #include -#include +#include +#include +#include #include #include #include +#include class QTimer; class GameEventContainer; @@ -47,6 +51,17 @@ class ServerInfo_User; class ServerInfo_Game; class Server_AbstractUserInterface; class Event_GameStateChanged; +class Server_DeckValidationStrategy; +class Server_GameLifecycleStrategy; +class Server_MatchResultStrategy; +namespace google +{ +namespace protobuf +{ +class Message; +} // namespace protobuf +} // namespace google +struct GameConfig; class Server_Game : public QObject { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.cpp index cafa33c07..a4c904c01 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.cpp @@ -1,23 +1,34 @@ #include "server_player.h" #include "../server.h" -#include "../server_abstractuserinterface.h" #include "../server_database_interface.h" #include "../server_room.h" +#include "game/server_abstract_participant.h" +#include "game/server_abstract_player.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" +#include "libcockatrice/protocol/pb/color.pb.h" +#include "libcockatrice/protocol/pb/move_card_to_zone.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_card.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_counter.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_playerproperties.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_zone.pb.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" #include "server_card.h" #include "server_cardzone.h" #include "server_counter.h" #include "server_game.h" #include "server_move_card_struct.h" +#include "server_response_containers.h" -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include #include #include #include @@ -43,13 +54,15 @@ #include #include #include -#include #include #include -#include #include #include #include +#include +#include + +class Server_AbstractUserInterface; Server_Player::Server_Player(Server_Game *_game, int _playerId, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.h index c35428480..5d514a344 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_player.h @@ -1,8 +1,19 @@ #ifndef PLAYER_H #define PLAYER_H +#include "libcockatrice/protocol/pb/response.pb.h" #include "server_abstract_player.h" +#include +#include +#include + +class GameEventStorage; +class ServerInfo_User; +class Server_AbstractUserInterface; +class Server_Counter; +class Server_Game; + class Server_Player : public Server_AbstractPlayer { Q_OBJECT diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.cpp b/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.cpp index bc873e386..d1c369949 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.cpp @@ -1,5 +1,11 @@ #include "server_spectator.h" +#include "game/server_abstract_participant.h" + +class ServerInfo_User; +class Server_AbstractUserInterface; +class Server_Game; + Server_Spectator::Server_Spectator(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.h b/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.h index 4d3928a63..2a8995ec3 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/game/server_spectator.h @@ -3,6 +3,12 @@ #include "server_abstract_participant.h" +#include + +class ServerInfo_User; +class Server_AbstractUserInterface; +class Server_Game; + class Server_Spectator : public Server_AbstractParticipant { Q_OBJECT diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server.cpp b/libcockatrice_network/libcockatrice/network/server/remote/server.cpp index 7abccfca8..73b13e23e 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/server.cpp @@ -19,16 +19,36 @@ ***************************************************************************/ #include "server.h" +#include "game/server_abstract_participant.h" #include "game/server_game.h" -#include "game/server_player.h" +#include "libcockatrice/protocol/pb/commands.pb.h" +#include "libcockatrice/protocol/pb/game_commands.pb.h" +#include "libcockatrice/protocol/pb/game_event_container.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/room_commands.pb.h" +#include "libcockatrice/protocol/pb/room_event.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_ban.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_room.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "server_abstractuserinterface.h" #include "server_database_interface.h" #include "server_protocolhandler.h" #include "server_remoteuserinterface.h" +#include "server_response_containers.h" #include "server_room.h" +#include "serverinfo_user_container.h" -#include +#include #include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include @@ -36,6 +56,10 @@ #include #include #include +#include +#include +#include +#include Server::Server(QObject *parent) : QObject(parent), nextLocalGameId(0), tcpUserCount(0), webSocketUserCount(0) { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server.h b/libcockatrice_network/libcockatrice/network/server/remote/server.h index 3d27f4210..99247bb67 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server.h @@ -3,30 +3,32 @@ #include "server_player_reference.h" +#include +#include #include #include +#include #include #include -#include -#include -#include +#include +#include +#include class Server_DatabaseInterface; -class Server_Game; class Server_Room; class Server_ProtocolHandler; class Server_AbstractUserInterface; -class GameReplay; class IslMessage; class SessionEvent; class RoomEvent; -class DeckList; class ServerInfo_Game; class ServerInfo_Room; class Response; class GameEventContainer; class CommandContainer; class Command_JoinGame; +class QThread; +class ServerInfo_User; enum AuthenticationResult { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.cpp b/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.cpp index 31fa13d81..25aa415fc 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.cpp @@ -1,7 +1,13 @@ #include "server_abstractuserinterface.h" +#include "game/server_abstract_participant.h" #include "game/server_game.h" -#include "game/server_player.h" +#include "libcockatrice/protocol/pb/game_event_container.pb.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/room_event.pb.h" +#include "libcockatrice/protocol/pb/server_message.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_event.pb.h" #include "server.h" #include "server_player_reference.h" #include "server_response_containers.h" @@ -9,8 +15,13 @@ #include #include +#include +#include +#include #include -#include +#include +#include +#include void Server_AbstractUserInterface::sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item) diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.h b/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.h index 2da72c01d..a19475e34 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_abstractuserinterface.h @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include @@ -12,9 +14,15 @@ class SessionEvent; class GameEventContainer; class RoomEvent; class ResponseContainer; - class Server; class Server_Game; +namespace google +{ +namespace protobuf +{ +class Message; +} // namespace protobuf +} // namespace google class Server_AbstractUserInterface : public ServerInfo_User_Container { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h b/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h index 1e4fc990b..e0be7990b 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_database_interface.h @@ -1,9 +1,22 @@ #ifndef SERVER_DATABASE_INTERFACE_H #define SERVER_DATABASE_INTERFACE_H +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" #include "server.h" +#include #include +#include +#include +#include +#include + +class DeckList; +class GameReplay; +class ServerInfo_Game; +class Server_ProtocolHandler; +template class QList; +template class QSet; class Server_DatabaseInterface : public QObject { diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp b/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp index 8422d703d..fc5cfa148 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.cpp @@ -1,20 +1,43 @@ #include "server_protocolhandler.h" #include "game/game_config.h" +#include "game/server_abstract_participant.h" #include "game/server_game.h" -#include "game/server_player.h" +#include "libcockatrice/protocol/pb/admin_commands.pb.h" +#include "libcockatrice/protocol/pb/developer_commands.pb.h" +#include "libcockatrice/protocol/pb/game_commands.pb.h" +#include "libcockatrice/protocol/pb/game_event_container.pb.h" +#include "libcockatrice/protocol/pb/moderator_commands.pb.h" +#include "libcockatrice/protocol/pb/room_commands.pb.h" +#include "libcockatrice/protocol/pb/room_event.pb.h" +#include "libcockatrice/protocol/pb/server_message.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_chat_message.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" +#include "libcockatrice/protocol/pb/session_event.pb.h" #include "server_database_interface.h" +#include "server_response_containers.h" #include "server_room.h" +#include "serverinfo_user_container.h" +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include #include #include #include #include -#include #include #include #include @@ -28,6 +51,9 @@ #include #include #include +#include +#include +#include Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.h b/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.h index 2c8efe50e..a12706757 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_protocolhandler.h @@ -4,34 +4,24 @@ #include "server.h" #include "server_abstractuserinterface.h" +#include +#include #include +#include #include -#include +#include -class Features; class Server_DatabaseInterface; -class Server_Player; -class ServerInfo_User; class Server_Room; -class QTimer; -class FeatureSet; - class ServerMessage; -class Response; -class SessionEvent; -class GameEventContainer; -class RoomEvent; class ResponseContainer; - class CommandContainer; class SessionCommand; class ModeratorCommand; class AdminCommand; class DeveloperCommand; - class Command_Ping; class Command_Login; -class Command_Register; class Command_Message; class Command_ListUsers; class Command_GetGamesOfUser; diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_remoteuserinterface.h b/libcockatrice_network/libcockatrice/network/server/remote/server_remoteuserinterface.h index d68656b9d..3bdf04220 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_remoteuserinterface.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_remoteuserinterface.h @@ -3,6 +3,9 @@ #include "server_abstractuserinterface.h" +class Server; +class ServerInfo_User_Container; + class Server_RemoteUserInterface : public Server_AbstractUserInterface { public: diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.cpp b/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.cpp index 22fb199fb..4c4f351c9 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.cpp @@ -1,8 +1,13 @@ #include "server_response_containers.h" #include "game/server_game.h" +#include "libcockatrice/protocol/pb/game_event.pb.h" +#include "libcockatrice/protocol/pb/game_event_container.pb.h" +#include "libcockatrice/protocol/pb/game_event_context.pb.h" #include +#include +#include GameEventStorageItem::GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.h b/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.h index 118b32d38..32b7a80a2 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_response_containers.h @@ -1,10 +1,14 @@ #ifndef SERVER_RESPONSE_CONTAINERS_H #define SERVER_RESPONSE_CONTAINERS_H +#include #include #include +#include #include +class GameEvent; + namespace google { namespace protobuf diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp b/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp index 1f29e62fb..614de8d63 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_room.cpp @@ -1,11 +1,26 @@ #include "server_room.h" #include "game/server_game.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/room_event.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_gametype.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "server.h" +#include "server_abstractuserinterface.h" #include "server_protocolhandler.h" +#include "server_response_containers.h" +#include "serverinfo_user_container.h" #include -#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include @@ -16,6 +31,10 @@ #include #include #include +#include +#include +#include +#include Server_Room::Server_Room(int _id, int _chatHistorySize, diff --git a/libcockatrice_network/libcockatrice/network/server/remote/server_room.h b/libcockatrice_network/libcockatrice/network/server/remote/server_room.h index 3d9988f20..5933894d5 100644 --- a/libcockatrice_network/libcockatrice/network/server/remote/server_room.h +++ b/libcockatrice_network/libcockatrice/network/server/remote/server_room.h @@ -1,16 +1,16 @@ #ifndef SERVER_ROOM_H #define SERVER_ROOM_H -#include "serverinfo_user_container.h" - +#include #include -#include #include #include +#include +#include #include #include +#include -class Server_DatabaseInterface; class Server_ProtocolHandler; class RoomEvent; class ServerInfo_User; @@ -18,10 +18,17 @@ class ServerInfo_Room; class ServerInfo_Game; class Server_Game; class Server; - class Command_JoinGame; class ResponseContainer; class Server_AbstractUserInterface; +class ServerInfo_User_Container; +namespace google +{ +namespace protobuf +{ +class Message; +} // namespace protobuf +} // namespace google class Server_Room : public QObject { diff --git a/libcockatrice_protocol/CMakeLists.txt b/libcockatrice_protocol/CMakeLists.txt index 7dc0a0360..55184045a 100644 --- a/libcockatrice_protocol/CMakeLists.txt +++ b/libcockatrice_protocol/CMakeLists.txt @@ -24,3 +24,5 @@ target_include_directories( libcockatrice_protocol PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} # points to the generated headers ) + +target_precompile_headers(libcockatrice_protocol PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp b/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp index 4d4889323..f892c3f15 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp +++ b/libcockatrice_protocol/libcockatrice/protocol/debug_pb_message.cpp @@ -1,11 +1,13 @@ #include "debug_pb_message.h" -#include #include #include #include +#include #include #include +#include +#include // FastFieldValuePrinter is added in protobuf 3.4, going out of our way to add the old FieldValuePrinter is not worth it #if GOOGLE_PROTOBUF_VERSION > 3004000 diff --git a/libcockatrice_protocol/libcockatrice/protocol/featureset.cpp b/libcockatrice_protocol/libcockatrice/protocol/featureset.cpp index 3e687ef56..0f8fd4210 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/featureset.cpp +++ b/libcockatrice_protocol/libcockatrice/protocol/featureset.cpp @@ -1,6 +1,7 @@ #include "featureset.h" #include +#include FeatureSet::FeatureSet() { diff --git a/libcockatrice_protocol/libcockatrice/protocol/get_pb_extension.cpp b/libcockatrice_protocol/libcockatrice/protocol/get_pb_extension.cpp index a693ea5a7..b9d2f18d0 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/get_pb_extension.cpp +++ b/libcockatrice_protocol/libcockatrice/protocol/get_pb_extension.cpp @@ -2,6 +2,7 @@ #include #include +#include int getPbExtension(const ::google::protobuf::Message &message) { diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt b/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt index bc4814d5e..4e4f0e190 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/CMakeLists.txt @@ -55,6 +55,7 @@ set(PROTO_FILES command_report_details.proto command_report_list.proto command_report_my_list.proto + command_report_reopen.proto command_report_resolve.proto command_report_stats.proto command_report_user_info.proto diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/command_report_reopen.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/command_report_reopen.proto new file mode 100644 index 000000000..1f9c707e8 --- /dev/null +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/command_report_reopen.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; +import "moderator_commands.proto"; + +message Command_ReportReopen { + extend ModeratorCommand { + optional Command_ReportReopen ext = 1206; + } + required int32 report_id = 1; + optional string reopen_note = 2; +} diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/moderator_commands.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/moderator_commands.proto index 4f1e80c27..5298d3dad 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/moderator_commands.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/moderator_commands.proto @@ -26,6 +26,7 @@ message ModeratorCommand { REPLAY_DOWNLOAD_BY_GAME_ID = 1203; REPORT_USER_INFO = 1204; REPORT_STATS = 1205; + REPORT_REOPEN = 1206; } extensions 100 to max; } diff --git a/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_report.proto b/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_report.proto index a145fd855..3b624cc6d 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_report.proto +++ b/libcockatrice_protocol/libcockatrice/protocol/pb/serverinfo_report.proto @@ -33,4 +33,7 @@ message ServerInfo_Report { optional string chat_log = 14; optional string resolution_note = 15; + optional string resolved_by_name = 16; + + optional int32 reported_user_level = 17; } diff --git a/libcockatrice_protocol/libcockatrice/protocol/pending_command.cpp b/libcockatrice_protocol/libcockatrice/protocol/pending_command.cpp index 62d35313e..4a23fb6ef 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pending_command.cpp +++ b/libcockatrice_protocol/libcockatrice/protocol/pending_command.cpp @@ -1,5 +1,8 @@ #include "pending_command.h" +class CommandContainer; +class Response; + PendingCommand::PendingCommand(const CommandContainer &_commandContainer, QVariant _extraData) : commandContainer(_commandContainer), extraData(_extraData), ticks(0) { diff --git a/libcockatrice_protocol/libcockatrice/protocol/pending_command.h b/libcockatrice_protocol/libcockatrice/protocol/pending_command.h index b8f861d08..9ed8a863c 100644 --- a/libcockatrice_protocol/libcockatrice/protocol/pending_command.h +++ b/libcockatrice_protocol/libcockatrice/protocol/pending_command.h @@ -8,9 +8,13 @@ #define PENDING_COMMAND_H #include +#include #include +#include #include -#include +#include + +class Response; class PendingCommand : public QObject { diff --git a/libcockatrice_rng/CMakeLists.txt b/libcockatrice_rng/CMakeLists.txt index b988c9d2f..6128e3f6e 100644 --- a/libcockatrice_rng/CMakeLists.txt +++ b/libcockatrice_rng/CMakeLists.txt @@ -11,6 +11,10 @@ add_library( libcockatrice/rng/sfmt/SFMT.c ) +# SFMT is vendored and its own headers trip UBSan's alignment and vptr checks. +cockatrice_disable_sanitizers_for(libcockatrice/rng/sfmt/SFMT.c) +cockatrice_disable_coverage_for(libcockatrice/rng/sfmt/SFMT.c) + target_include_directories(libcockatrice_rng PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(libcockatrice_rng PUBLIC ${QT_CORE_MODULE}) diff --git a/libcockatrice_rng/libcockatrice/rng/rng_abstract.cpp b/libcockatrice_rng/libcockatrice/rng/rng_abstract.cpp index 82404d351..34a778ca9 100644 --- a/libcockatrice_rng/libcockatrice/rng/rng_abstract.cpp +++ b/libcockatrice_rng/libcockatrice/rng/rng_abstract.cpp @@ -1,6 +1,8 @@ #include "rng_abstract.h" #include +#include +#include QVector RNG_Abstract::makeNumbersVector(int n, int min, int max) { diff --git a/libcockatrice_rng/libcockatrice/rng/rng_abstract.h b/libcockatrice_rng/libcockatrice/rng/rng_abstract.h index 903e6ef1a..49fb89612 100644 --- a/libcockatrice_rng/libcockatrice/rng/rng_abstract.h +++ b/libcockatrice_rng/libcockatrice/rng/rng_abstract.h @@ -3,6 +3,7 @@ #include #include +#include class RNG_Abstract : public QObject { diff --git a/libcockatrice_rng/libcockatrice/rng/rng_sfmt.cpp b/libcockatrice_rng/libcockatrice/rng/rng_sfmt.cpp index 4c578b4e4..13e6fe680 100644 --- a/libcockatrice_rng/libcockatrice/rng/rng_sfmt.cpp +++ b/libcockatrice_rng/libcockatrice/rng/rng_sfmt.cpp @@ -1,8 +1,13 @@ #include "rng_sfmt.h" -#include -#include +#include "libcockatrice/rng/rng_abstract.h" +#include "libcockatrice/rng/sfmt/SFMT.h" + +#include #include +#include + +class QObject; // This is from gcc sources, namely from fixincludes/inclhack.def // On C++11 systems, could be included instead. diff --git a/libcockatrice_rng/libcockatrice/rng/rng_sfmt.h b/libcockatrice_rng/libcockatrice/rng/rng_sfmt.h index a180dad99..e178812ab 100644 --- a/libcockatrice_rng/libcockatrice/rng/rng_sfmt.h +++ b/libcockatrice_rng/libcockatrice/rng/rng_sfmt.h @@ -5,7 +5,10 @@ #include "sfmt/SFMT.h" #include -#include +#include +#include + +class QObject; /** * This class encapsulates a state of the art PRNG and can be used diff --git a/libcockatrice_settings/CMakeLists.txt b/libcockatrice_settings/CMakeLists.txt index 80a465b6d..5a2fa42a9 100644 --- a/libcockatrice_settings/CMakeLists.txt +++ b/libcockatrice_settings/CMakeLists.txt @@ -71,3 +71,5 @@ target_include_directories( ) target_link_libraries(libcockatrice_settings PUBLIC libcockatrice_card libcockatrice_utility ${QT_CORE_MODULE}) + +target_precompile_headers(libcockatrice_settings PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp b/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp index 839e33be4..14969dae6 100644 --- a/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/appearance_settings.cpp @@ -1,5 +1,11 @@ #include "appearance_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + AppearanceSettings::AppearanceSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "appearance.ini", "appearance", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/appearance_settings.h b/libcockatrice_settings/libcockatrice/settings/appearance_settings.h index a4504798e..9d15caddd 100644 --- a/libcockatrice_settings/libcockatrice/settings/appearance_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/appearance_settings.h @@ -9,6 +9,11 @@ #include "settings_manager.h" +#include +#include + +class QObject; + class AppearanceSettings : public SettingsManager { Q_OBJECT diff --git a/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.cpp b/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.cpp index c800cc024..aaea87791 100644 --- a/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.cpp @@ -1,5 +1,11 @@ #include "cache_storage_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + CacheStorageSettings::CacheStorageSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "cache_storage.ini", "cache_storage", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.h b/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.h index 4a4e73461..a4c8a197d 100644 --- a/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/cache_storage_settings.h @@ -3,7 +3,11 @@ #include "settings_manager.h" +#include #include +#include + +class QObject; // In MB (Increments of 64) #define PIXMAPCACHE_SIZE_DEFAULT 2048 diff --git a/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp b/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp index b55c97909..49bcb042b 100644 --- a/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp @@ -1,6 +1,16 @@ #include "card_database_settings.h" +#include "libcockatrice/interfaces/interface_card_set_priority_controller.h" +#include "libcockatrice/settings/settings_manager.h" + +#include #include +#include +#include +#include +#include + +class QObject; CardDatabaseSettings::CardDatabaseSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "cardDatabase.ini", QString(), QString(), parent) @@ -78,6 +88,20 @@ ICardSetPriorityController::SetOptions CardDatabaseSettings::getSetOptions(QStri return setOptionsCache.value(shortName); } +QStringList CardDatabaseSettings::getEnabledSetNames() const +{ + QMutexLocker lock(&setOptionsMutex); + ensureSetOptionsLoaded(); + QStringList names; + for (auto it = setOptionsCache.constBegin(); it != setOptionsCache.constEnd(); ++it) { + if (it.value().enabled) { + names << it.key(); + } + } + names.sort(); + return names; +} + void CardDatabaseSettings::saveSets(const QVector &data) { batchWrite([&](QSettings &s) { @@ -86,6 +110,7 @@ void CardDatabaseSettings::saveSets(const QVector #include +#include +#include #include +#include + +class QObject; class CardDatabaseSettings : public SettingsManager, public ICardSetPriorityController { @@ -30,6 +35,8 @@ public: SetOptions getSetOptions(QString shortName) const override; + QStringList getEnabledSetNames() const override; + void saveSets(const QVector &data) override; private: diff --git a/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp b/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp index a61a4693b..5a853a927 100644 --- a/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp @@ -1,5 +1,12 @@ #include "card_override_settings.h" +#include "libcockatrice/settings/settings_manager.h" +#include "libcockatrice/utility/card_ref.h" + +#include + +class QObject; + CardOverrideSettings::CardOverrideSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "cardPreferenceOverrides.ini", "cards", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/card_override_settings.h b/libcockatrice_settings/libcockatrice/settings/card_override_settings.h index cd515d4da..a9e8b2d69 100644 --- a/libcockatrice_settings/libcockatrice/settings/card_override_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/card_override_settings.h @@ -9,8 +9,11 @@ #include "settings_manager.h" -#include -#include +#include +#include + +class QObject; +struct CardRef; class CardOverrideSettings : public SettingsManager { diff --git a/libcockatrice_settings/libcockatrice/settings/cards_display_settings.cpp b/libcockatrice_settings/libcockatrice/settings/cards_display_settings.cpp index 3af607198..f047973f0 100644 --- a/libcockatrice_settings/libcockatrice/settings/cards_display_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/cards_display_settings.cpp @@ -1,5 +1,13 @@ #include "cards_display_settings.h" +#include "libcockatrice/card/card_localization.h" +#include "libcockatrice/settings/settings_manager.h" + +#include +#include + +class QObject; + CardsDisplaySettings::CardsDisplaySettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "cards_display.ini", "cards", QString(), parent) { @@ -35,11 +43,6 @@ int CardsDisplaySettings::getPrintingSelectorCardSize() const return getValue("printingSelector", "cards", "cardSize", 100).toInt(); } -bool CardsDisplaySettings::getIncludeRebalancedCards() const -{ - return getValue("includerebalancedcards", QString(), QString(), true).toBool(); -} - bool CardsDisplaySettings::getPrintingSelectorNavigationButtonsVisible() const { return getValue("navigationButtonsVisible", "cards", "printingSelector", true).toBool(); @@ -159,15 +162,6 @@ void CardsDisplaySettings::setPrintingSelectorCardSize(int _printingSelectorCard emit printingSelectorCardSizeChanged(); } -void CardsDisplaySettings::setIncludeRebalancedCards(bool _includeRebalancedCards) -{ - if (_includeRebalancedCards == getIncludeRebalancedCards()) { - return; - } - setValue(_includeRebalancedCards, "includerebalancedcards"); - emit includeRebalancedCardsChanged(_includeRebalancedCards); -} - void CardsDisplaySettings::setPrintingSelectorNavigationButtonsVisible(bool _navigationButtonsVisible) { setValue(_navigationButtonsVisible, "navigationButtonsVisible", "cards", "printingSelector"); diff --git a/libcockatrice_settings/libcockatrice/settings/cards_display_settings.h b/libcockatrice_settings/libcockatrice/settings/cards_display_settings.h index 77924d14c..961550d3c 100644 --- a/libcockatrice_settings/libcockatrice/settings/cards_display_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/cards_display_settings.h @@ -3,8 +3,11 @@ #include "settings_manager.h" -#include +#include #include +#include + +class QObject; class CardsDisplaySettings : public SettingsManager, public ICardsDisplaySettingsProvider { @@ -18,7 +21,6 @@ public: [[nodiscard]] bool getBumpSetsWithCardsInDeckToTop() const override; [[nodiscard]] int getPrintingSelectorSortOrder() const override; [[nodiscard]] int getPrintingSelectorCardSize() const override; - [[nodiscard]] bool getIncludeRebalancedCards() const override; [[nodiscard]] bool getPrintingSelectorNavigationButtonsVisible() const override; [[nodiscard]] bool getTapAnimation() const override; [[nodiscard]] bool getArrowDrawAnimation() const override; @@ -42,7 +44,6 @@ public: void setBumpSetsWithCardsInDeckToTop(bool _bumpSetsWithCardsInDeckToTop); void setPrintingSelectorSortOrder(int _printingSelectorSortOrder); void setPrintingSelectorCardSize(int _printingSelectorCardSize); - void setIncludeRebalancedCards(bool _includeRebalancedCards); void setPrintingSelectorNavigationButtonsVisible(bool _navigationButtonsVisible); void setTapAnimation(bool _tapAnimation); void setArrowDrawAnimation(bool _arrowDrawAnimation); @@ -67,7 +68,6 @@ signals: void bumpSetsWithCardsInDeckToTopChanged(); void printingSelectorSortOrderChanged(); void printingSelectorCardSizeChanged(); - void includeRebalancedCardsChanged(bool _includeRebalancedCards); void printingSelectorNavigationButtonsVisibleChanged(); void visualDeckStorageCardSizeChanged(); void visualDatabaseDisplayCardSizeChanged(); diff --git a/libcockatrice_settings/libcockatrice/settings/chat_settings.cpp b/libcockatrice_settings/libcockatrice/settings/chat_settings.cpp index 0ee29b4f5..d9ae0ddac 100644 --- a/libcockatrice_settings/libcockatrice/settings/chat_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/chat_settings.cpp @@ -1,5 +1,11 @@ #include "chat_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + ChatSettings::ChatSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "chat.ini", "chat", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/chat_settings.h b/libcockatrice_settings/libcockatrice/settings/chat_settings.h index d928b23b7..e00da4527 100644 --- a/libcockatrice_settings/libcockatrice/settings/chat_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/chat_settings.h @@ -3,7 +3,11 @@ #include "settings_manager.h" +#include #include +#include + +class QObject; class ChatSettings : public SettingsManager, public IChatSettingsProvider { diff --git a/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.cpp b/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.cpp index 0c5f5521e..eb692fe81 100644 --- a/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.cpp @@ -1,6 +1,16 @@ #include "commander_bracket_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include +#include #include +#include +#include +#include +#include + +class QObject; QVariantList CommanderBracketSettings::defaultDefinitions() { diff --git a/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.h b/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.h index 5a29f5dc7..ad012fc30 100644 --- a/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/commander_bracket_settings.h @@ -4,9 +4,11 @@ #include "settings_manager.h" #include -#include #include #include +#include + +class QObject; struct CommanderBracketDefinition { diff --git a/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp b/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp index 5bf6eca30..c36e7187e 100644 --- a/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp @@ -1,6 +1,11 @@ #include "debug_settings.h" -#include +#include "libcockatrice/settings/settings_manager.h" + +#include +#include + +class QObject; DebugSettings::DebugSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "debug.ini", "debug", QString(), parent) diff --git a/libcockatrice_settings/libcockatrice/settings/debug_settings.h b/libcockatrice_settings/libcockatrice/settings/debug_settings.h index acb5cf313..9521a7738 100644 --- a/libcockatrice_settings/libcockatrice/settings/debug_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/debug_settings.h @@ -8,6 +8,11 @@ #define DEBUG_SETTINGS_H #include "settings_manager.h" +#include +#include + +class QObject; + class DebugSettings : public SettingsManager { Q_OBJECT diff --git a/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.cpp b/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.cpp index 44cdcd86f..ee570ed67 100644 --- a/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.cpp @@ -1,5 +1,11 @@ #include "deck_editor_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + DeckEditorSettings::DeckEditorSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "deck_editor.ini", "deckeditor", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.h b/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.h index 0c87a270a..aa024910d 100644 --- a/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/deck_editor_settings.h @@ -3,7 +3,11 @@ #include "settings_manager.h" +#include #include +#include + +class QObject; enum commanderSpellbookIntegrationEnabledIndex { diff --git a/libcockatrice_settings/libcockatrice/settings/download_settings.cpp b/libcockatrice_settings/libcockatrice/settings/download_settings.cpp index 6e22a84f4..84a6a7509 100644 --- a/libcockatrice_settings/libcockatrice/settings/download_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/download_settings.cpp @@ -2,6 +2,14 @@ #include "settings_manager.h" +#include +#include +#include +#include +#include + +class QObject; + const QStringList DownloadSettings::DEFAULT_DOWNLOAD_URLS = { "https://cards.scryfall.io/large/!prop:side!/!set:uuid_substr_0_1!/!set:uuid_substr_1_1!/!set:uuid!.jpg", "https://api.scryfall.com/cards/!set:uuid!?format=image&face=!prop:side!&lang=!sflang!", diff --git a/libcockatrice_settings/libcockatrice/settings/download_settings.h b/libcockatrice_settings/libcockatrice/settings/download_settings.h index 7eca77df6..f7cf482e1 100644 --- a/libcockatrice_settings/libcockatrice/settings/download_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/download_settings.h @@ -10,6 +10,11 @@ #include "settings_manager.h" #include +#include +#include +#include + +class QObject; class DownloadSettings : public SettingsManager { diff --git a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp index 0edba44dd..79d1bc9e2 100644 --- a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp @@ -1,7 +1,15 @@ #include "game_filters_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include #include +#include +#include #include +#include + +class QObject; GameFiltersSettings::GameFiltersSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "gamefilters.ini", "filter_games", QString(), parent) diff --git a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h index 11480d483..ec5e3fdc2 100644 --- a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h @@ -10,6 +10,13 @@ #include "settings_manager.h" +#include +#include +#include +#include + +class QObject; + class GameFiltersSettings : public SettingsManager { Q_OBJECT diff --git a/libcockatrice_settings/libcockatrice/settings/game_settings.cpp b/libcockatrice_settings/libcockatrice/settings/game_settings.cpp index dfd67c98a..c8c6463e3 100644 --- a/libcockatrice_settings/libcockatrice/settings/game_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/game_settings.cpp @@ -1,5 +1,11 @@ #include "game_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + GameSettings::GameSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "game.ini", QString(), QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/game_settings.h b/libcockatrice_settings/libcockatrice/settings/game_settings.h index e0a484bac..3e64234fc 100644 --- a/libcockatrice_settings/libcockatrice/settings/game_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/game_settings.h @@ -3,7 +3,11 @@ #include "settings_manager.h" +#include #include +#include + +class QObject; class GameSettings : public SettingsManager, public IGameSettingsProvider { diff --git a/libcockatrice_settings/libcockatrice/settings/interface_settings.cpp b/libcockatrice_settings/libcockatrice/settings/interface_settings.cpp index b92a5fdec..256d9eb26 100644 --- a/libcockatrice_settings/libcockatrice/settings/interface_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/interface_settings.cpp @@ -1,5 +1,16 @@ #include "interface_settings.h" +#include "libcockatrice/settings/settings_manager.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" + +#include +#include +#include +#include + +class QObject; + namespace { const QChar PLAYMAT_FIELD_SEP = QChar(0x1F); ///< Separator between PlaymatInfo fields. @@ -37,7 +48,7 @@ InterfaceSettings::InterfaceSettings(const QString &settingPath, QObject *parent bool InterfaceSettings::getUseTearOffMenus() const { - return getValue("useTearOffMenus", QString(), QString(), true).toBool(); + return getValue("useTearOffMenus", QString(), QString(), false).toBool(); } int InterfaceSettings::getCardViewInitialRowsMax() const diff --git a/libcockatrice_settings/libcockatrice/settings/interface_settings.h b/libcockatrice_settings/libcockatrice/settings/interface_settings.h index 6b226f307..41bb6ee17 100644 --- a/libcockatrice_settings/libcockatrice/settings/interface_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/interface_settings.h @@ -3,7 +3,15 @@ #include "settings_manager.h" +#include +#include +#include #include +#include + +class QObject; +struct PlaymatInfo; +template class QList; class InterfaceSettings : public SettingsManager, public IInterfaceSettingsProvider { diff --git a/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp b/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp index e914dc2d8..aba620026 100644 --- a/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp @@ -1,5 +1,11 @@ #include "layouts_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + const static QString STATE_PROP = "state"; const static QString GEOMETRY_PROP = "geometry"; const static QString SIZE_PROP = "widgetSize"; diff --git a/libcockatrice_settings/libcockatrice/settings/layouts_settings.h b/libcockatrice_settings/libcockatrice/settings/layouts_settings.h index d5f26b61b..91b0a2ea6 100644 --- a/libcockatrice_settings/libcockatrice/settings/layouts_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/layouts_settings.h @@ -9,7 +9,11 @@ #include "settings_manager.h" -#include +#include +#include +#include + +class QObject; class LayoutsSettings : public SettingsManager { diff --git a/libcockatrice_settings/libcockatrice/settings/message_settings.cpp b/libcockatrice_settings/libcockatrice/settings/message_settings.cpp index 50da39df6..ca77246ef 100644 --- a/libcockatrice_settings/libcockatrice/settings/message_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/message_settings.cpp @@ -1,5 +1,11 @@ #include "message_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + MessageSettings::MessageSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "messages.ini", "messages", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/message_settings.h b/libcockatrice_settings/libcockatrice/settings/message_settings.h index 8276aa39d..83513d562 100644 --- a/libcockatrice_settings/libcockatrice/settings/message_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/message_settings.h @@ -9,6 +9,11 @@ #include "settings_manager.h" +#include +#include + +class QObject; + class MessageSettings : public SettingsManager { Q_OBJECT diff --git a/libcockatrice_settings/libcockatrice/settings/network_settings.cpp b/libcockatrice_settings/libcockatrice/settings/network_settings.cpp index 2d34d47ad..6d0fa9d1c 100644 --- a/libcockatrice_settings/libcockatrice/settings/network_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/network_settings.cpp @@ -1,5 +1,11 @@ #include "network_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + NetworkSettings::NetworkSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "network.ini", "network", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/network_settings.h b/libcockatrice_settings/libcockatrice/settings/network_settings.h index 446bb51d3..4367f9cb3 100644 --- a/libcockatrice_settings/libcockatrice/settings/network_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/network_settings.h @@ -9,6 +9,11 @@ #include "settings_manager.h" +#include +#include + +class QObject; + class NetworkSettings : public SettingsManager { Q_OBJECT diff --git a/libcockatrice_settings/libcockatrice/settings/paths_settings.cpp b/libcockatrice_settings/libcockatrice/settings/paths_settings.cpp index 67032e38f..41ccf6460 100644 --- a/libcockatrice_settings/libcockatrice/settings/paths_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/paths_settings.cpp @@ -1,7 +1,12 @@ #include "paths_settings.h" +#include "libcockatrice/settings/settings_manager.h" + #include -#include +#include +#include + +class QObject; PathsSettings::PathsSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "paths.ini", "paths", QString(), parent) @@ -118,3 +123,52 @@ void PathsSettings::setSpoilerDatabasePath(const QString &_spoilerDatabasePath) setValue(_spoilerDatabasePath, "spoilerDatabase"); emit cardDatabasePathChanged(); } + +QStringList PathsSettings::pathsInsideDir(const QString &baseDir) const +{ + QStringList offenders; + const auto check = [&offenders, &baseDir](const QString &path) { + if (!path.isEmpty() && isInsideDir(path, baseDir)) { + offenders.append(QDir::cleanPath(path)); + } + }; + + check(getDeckPath()); + check(getFiltersPath()); + check(getReplaysPath()); + check(getPicsPath()); + check(getCustomPicsPath()); + check(getThemesPath()); + check(getCardDatabasePath()); + check(getCustomCardDatabasePath()); + check(getTokenDatabasePath()); + check(getSpoilerCardDatabasePath()); + check(getRedirectCachePath()); + + offenders.removeDuplicates(); + return offenders; +} + +bool PathsSettings::isInsideDir(const QString &path, const QString &baseDir) +{ +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) + // Windows and default macOS volumes are case-insensitive filesystems. + constexpr Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; +#else + constexpr Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive; +#endif + const QString base = QDir::cleanPath(baseDir); + const QString cleaned = QDir::cleanPath(path); + const QString prefix = base.endsWith(QLatin1Char('/')) ? base : base + QLatin1Char('/'); + return cleaned == base || cleaned.startsWith(prefix, caseSensitivity); +} + +bool PathsSettings::getAppDirWarningAcknowledged() const +{ + return getValue("appDirWarningAcknowledged").toBool(); +} + +void PathsSettings::setAppDirWarningAcknowledged(bool _appDirWarningAcknowledged) +{ + setValue(_appDirWarningAcknowledged, "appDirWarningAcknowledged"); +} diff --git a/libcockatrice_settings/libcockatrice/settings/paths_settings.h b/libcockatrice_settings/libcockatrice/settings/paths_settings.h index ab1ea05c8..fa00428e3 100644 --- a/libcockatrice_settings/libcockatrice/settings/paths_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/paths_settings.h @@ -3,7 +3,12 @@ #include "settings_manager.h" +#include +#include #include +#include + +class QObject; class PathsSettings : public SettingsManager, public IPathsSettingsProvider { @@ -23,6 +28,24 @@ public: [[nodiscard]] QString getSpoilerCardDatabasePath() const override; [[nodiscard]] QString getRedirectCachePath() const override; + /** + * @brief Returns the configured paths that resolve inside baseDir. + * + * Comparison is lexical (QDir::cleanPath); symlinks are not resolved, so a + * path that only reaches baseDir through a symlink is not reported. + */ + [[nodiscard]] QStringList pathsInsideDir(const QString &baseDir) const; + + /** + * @brief Whether path resolves inside baseDir, as a single-path check. + * + * A path counts as inside when it equals baseDir or is nested below it; + * a sibling sharing the name prefix (baseDir + "2") does not. + */ + [[nodiscard]] static bool isInsideDir(const QString &path, const QString &baseDir); + + [[nodiscard]] bool getAppDirWarningAcknowledged() const; + void setDeckPath(const QString &_deckPath); void setFiltersPath(const QString &_filtersPath); void setReplaysPath(const QString &_replaysPath); @@ -33,14 +56,17 @@ public: void setCustomCardDatabasePath(const QString &_customCardDatabasePath); void setTokenDatabasePath(const QString &_tokenDatabasePath); void setSpoilerDatabasePath(const QString &_spoilerDatabasePath); + void setAppDirWarningAcknowledged(bool _appDirWarningAcknowledged); signals: void cardDatabasePathChanged(); void picsPathChanged(); void themeChanged(); -private: +public: explicit PathsSettings(const QString &settingPath, QObject *parent = nullptr); + +private: PathsSettings(const PathsSettings & /*other*/); }; diff --git a/libcockatrice_settings/libcockatrice/settings/personal_settings.cpp b/libcockatrice_settings/libcockatrice/settings/personal_settings.cpp index d1cb74d09..682144485 100644 --- a/libcockatrice_settings/libcockatrice/settings/personal_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/personal_settings.cpp @@ -1,5 +1,12 @@ #include "personal_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include +#include + +class QObject; + PersonalSettings::PersonalSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "personal.ini", "personal", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/personal_settings.h b/libcockatrice_settings/libcockatrice/settings/personal_settings.h index 04eab2a8a..0819af41b 100644 --- a/libcockatrice_settings/libcockatrice/settings/personal_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/personal_settings.h @@ -3,9 +3,12 @@ #include "settings_manager.h" -#include -#include +#include #include +#include + +class QObject; +template class QList; class PersonalSettings : public SettingsManager, public IPersonalSettingsProvider { diff --git a/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp b/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp index 5f16af179..4f2c06c88 100644 --- a/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp @@ -1,5 +1,12 @@ #include "recents_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include +#include + +class QObject; + #define MAX_RECENT_DECK_COUNT 10 RecentsSettings::RecentsSettings(const QString &settingPath, QObject *parent) diff --git a/libcockatrice_settings/libcockatrice/settings/recents_settings.h b/libcockatrice_settings/libcockatrice/settings/recents_settings.h index 01b2a37bc..dc5853908 100644 --- a/libcockatrice_settings/libcockatrice/settings/recents_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/recents_settings.h @@ -9,6 +9,12 @@ #include "settings_manager.h" +#include +#include +#include + +class QObject; + class RecentsSettings : public SettingsManager { Q_OBJECT diff --git a/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp b/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp index 436e260c5..c5c4b2592 100644 --- a/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp @@ -1,8 +1,17 @@ #include "servers_settings.h" +#include "libcockatrice/settings/settings_manager.h" + #include +#include +#include +#include +#include +#include #include +class QObject; + ServersSettings::ServersSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "servers.ini", "server", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/servers_settings.h b/libcockatrice_settings/libcockatrice/settings/servers_settings.h index 93651c813..40648baa9 100644 --- a/libcockatrice_settings/libcockatrice/settings/servers_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/servers_settings.h @@ -10,7 +10,12 @@ #include "settings_manager.h" #include -#include +#include +#include +#include + +class QObject; + #define SERVERSETTINGS_DEFAULT_HOST "server.cockatrice.us" #define SERVERSETTINGS_DEFAULT_PORT "4748" diff --git a/libcockatrice_settings/libcockatrice/settings/settings_manager.h b/libcockatrice_settings/libcockatrice/settings/settings_manager.h index 3d3c95d3e..8d3110106 100644 --- a/libcockatrice_settings/libcockatrice/settings/settings_manager.h +++ b/libcockatrice_settings/libcockatrice/settings/settings_manager.h @@ -7,9 +7,12 @@ #ifndef SETTINGSMANAGER_H #define SETTINGSMANAGER_H +#include #include -#include +#include #include +#include +#include class SettingsManager : public QObject { diff --git a/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp b/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp index c22bd3c02..d9652cde3 100644 --- a/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp +++ b/libcockatrice_settings/libcockatrice/settings/settings_migration.cpp @@ -1,15 +1,25 @@ #include "settings_migration.h" +#include #include +#include #include #include #include #include +#include +#include +#include #include #include +#include #include +#include #include +#include +#include #include +#include inline Q_LOGGING_CATEGORY(SettingsMigrationLog, "settings_migration"); @@ -249,7 +259,6 @@ static void migrateCardsDisplaySettings(const QString &settingsPath, QSettings & {"cards/roundcardcorners", "cards/roundCardCorners"}, {"cards/overrideallcardartwithpersonalpreference", "cards/overrideAllCardArtWithPersonalPreference"}, {"cards/bumpsetswithcardsindecktotop", "cards/bumpSetsWithCardsInDeckToTop"}, - {"cards/includerebalancedcards", "cards/includerebalancedcards"}, {"cards/tapanimation", "cards/tapAnimation"}, {"cards/autorotatesidewayslayoutcards", "cards/autoRotateSidewaysLayoutCards"}, {"cards/scaleCards", "cards/scaleCards"}, @@ -561,9 +570,15 @@ static void migrateLegacySets(const QString &settingsPath) QSettings cardDbIni(settingsPath + "cardDatabase.ini", QSettings::IniFormat); for (const auto &shortName : groups) { legacySetting.beginGroup(shortName); - cardDbIni.setValue("sets/" + shortName + "/sortKey", legacySetting.value("sortkey")); - cardDbIni.setValue("sets/" + shortName + "/enabled", legacySetting.value("enabled")); - cardDbIni.setValue("sets/" + shortName + "/isKnown", legacySetting.value("isknown")); + if (legacySetting.contains("sortkey")) { + cardDbIni.setValue("sets/" + shortName + "/sortKey", legacySetting.value("sortkey")); + } + if (legacySetting.contains("enabled")) { + cardDbIni.setValue("sets/" + shortName + "/enabled", legacySetting.value("enabled")); + } + if (legacySetting.contains("isknown")) { + cardDbIni.setValue("sets/" + shortName + "/isKnown", legacySetting.value("isknown")); + } legacySetting.endGroup(); } legacySetting.endGroup(); @@ -627,6 +642,34 @@ static void migrateLegacyMessages(const QString &settingsPath) legacySetting.endGroup(); } +/** + * gamefilters.ini keys renamed to camelCase by #7084. Profiles that migrated from the legacy + * native store before that rename still hold the old snake_case keys, which nothing reads + * anymore, so their saved filters silently stopped loading. + */ +static const QMap &renamedGameFilterKeys() +{ + static const QMap keyMap = { + {"hide_buddies_only_games", "hideBuddiesOnlyGames"}, + {"hide_full_games", "hideFullGames"}, + {"hide_games_that_started", "hideGamesThatStarted"}, + {"hide_password_protected_games", "hidePasswordProtectedGames"}, + {"hide_ignored_user_games", "hideIgnoredUserGames"}, + {"hide_not_buddy_created_games", "hideNotBuddyCreatedGames"}, + {"hide_open_decklist_games", "hideOpenDecklistGames"}, + {"game_name_filter", "gameNameFilter"}, + {"creator_name_filter", "hostNameFilter"}, + {"min_players", "minPlayers"}, + {"max_players", "maxPlayers"}, + {"max_game_age_time", "maxGameAgeTime"}, + {"show_only_if_spectators_can_watch", "showOnlyIfSpectatorsCanWatch"}, + {"show_spectator_password_protected", "showSpectatorPasswordProtected"}, + {"show_only_if_spectators_can_chat", "showOnlyIfSpectatorsCanChat"}, + {"show_only_if_spectators_can_see_hands", "showOnlyIfSpectatorsCanSeeHands"}, + }; + return keyMap; +} + static void migrateLegacyGameFilters(const QString &settingsPath) { QSettings legacySetting; @@ -637,24 +680,7 @@ static void migrateLegacyGameFilters(const QString &settingsPath) return; } - const QMap filterKeyMap = { - {"hide_buddies_only_games", "hideBuddiesOnlyGames"}, - {"hide_full_games", "hideFullGames"}, - {"hide_games_that_started", "hideGamesThatStarted"}, - {"hide_password_protected_games", "hidePasswordProtectedGames"}, - {"hide_ignored_user_games", "hideIgnoredUserGames"}, - {"hide_not_buddy_created_games", "hideNotBuddyCreatedGames"}, - {"hide_open_decklist_games", "hideOpenDecklistGames"}, - {"game_name_filter", "gameNameFilter"}, - {"creator_name_filter", "creatorNameFilter"}, - {"min_players", "minPlayers"}, - {"max_players", "maxPlayers"}, - {"max_game_age_time", "maxGameAgeTime"}, - {"show_only_if_spectators_can_watch", "showOnlyIfSpectatorsCanWatch"}, - {"show_spectator_password_protected", "showSpectatorPasswordProtected"}, - {"show_only_if_spectators_can_chat", "showOnlyIfSpectatorsCanChat"}, - {"show_only_if_spectators_can_see_hands", "showOnlyIfSpectatorsCanSeeHands"}, - }; + const QMap &filterKeyMap = renamedGameFilterKeys(); QSettings filtersIni(settingsPath + "gamefilters.ini", QSettings::IniFormat); for (auto it = filterKeyMap.constBegin(); it != filterKeyMap.constEnd(); ++it) { @@ -671,6 +697,68 @@ static void migrateLegacyGameFilters(const QString &settingsPath) legacySetting.endGroup(); } +static const QString LEGACY_GAME_FILTERS_GAME_TYPE_PREFIX = QStringLiteral("filter_games/game_type/"); +static const QString GAME_FILTERS_GAME_TYPE_PREFIX = QStringLiteral("filter_games/gameType/"); + +static bool gameFiltersCamelCaseMigrationPending(const QString &settingsPath) +{ + if (!QFile::exists(settingsPath + "gamefilters.ini")) { + return false; + } + + QSettings filtersIni(settingsPath + "gamefilters.ini", QSettings::IniFormat); + const QMap &keyMap = renamedGameFilterKeys(); + for (auto it = keyMap.constBegin(); it != keyMap.constEnd(); ++it) { + if (filtersIni.contains("filter_games/" + it.key()) && !filtersIni.contains("filter_games/" + it.value())) { + return true; + } + } + // Orphaned by #7084, which migrated the legacy host-name filter to a key nothing reads. + if (filtersIni.contains("filter_games/creatorNameFilter") && !filtersIni.contains("filter_games/hostNameFilter")) { + return true; + } + for (const auto &key : filtersIni.allKeys()) { + if (key.startsWith(LEGACY_GAME_FILTERS_GAME_TYPE_PREFIX) && + !filtersIni.contains(GAME_FILTERS_GAME_TYPE_PREFIX + + key.mid(LEGACY_GAME_FILTERS_GAME_TYPE_PREFIX.size()))) { + return true; + } + } + return false; +} + +bool SettingsMigration::migrateGameFiltersToCamelCase(const QString &settingsPath) +{ + if (!gameFiltersCamelCaseMigrationPending(settingsPath)) { + return false; + } + + QSettings filtersIni(settingsPath + "gamefilters.ini", QSettings::IniFormat); + const QMap &keyMap = renamedGameFilterKeys(); + for (auto it = keyMap.constBegin(); it != keyMap.constEnd(); ++it) { + const QString oldKey = "filter_games/" + it.key(); + const QString newKey = "filter_games/" + it.value(); + if (filtersIni.contains(oldKey) && !filtersIni.contains(newKey)) { + filtersIni.setValue(newKey, filtersIni.value(oldKey)); + } + } + if (filtersIni.contains("filter_games/creatorNameFilter") && !filtersIni.contains("filter_games/hostNameFilter")) { + filtersIni.setValue("filter_games/hostNameFilter", filtersIni.value("filter_games/creatorNameFilter")); + } + for (const auto &key : filtersIni.allKeys()) { + if (key.startsWith(LEGACY_GAME_FILTERS_GAME_TYPE_PREFIX)) { + const QString newKey = GAME_FILTERS_GAME_TYPE_PREFIX + key.mid(LEGACY_GAME_FILTERS_GAME_TYPE_PREFIX.size()); + if (!filtersIni.contains(newKey)) { + filtersIni.setValue(newKey, filtersIni.value(key)); + } + } + } + // The old keys are deliberately kept: pre-#7084 builds still read them, so removing them + // would break downgrades, and nothing in the current code reads them anymore. + filtersIni.sync(); + return true; +} + bool SettingsMigration::migrateLegacySettings(const QString &settingsPath) { QSettings personalIni(settingsPath + "personal.ini", QSettings::IniFormat); @@ -729,6 +817,10 @@ bool SettingsMigration::isMigrationPending(const QString &settingsPath) return true; } + if (gameFiltersCamelCaseMigrationPending(settingsPath)) { + return true; + } + QSettings personalIni(settingsPath + "personal.ini", QSettings::IniFormat); if (personalIni.value("migration/legacy_complete", false).toBool()) { return false; diff --git a/libcockatrice_settings/libcockatrice/settings/settings_migration.h b/libcockatrice_settings/libcockatrice/settings/settings_migration.h index 78f9c8a3f..0a706af98 100644 --- a/libcockatrice_settings/libcockatrice/settings/settings_migration.h +++ b/libcockatrice_settings/libcockatrice/settings/settings_migration.h @@ -9,6 +9,15 @@ public: static bool migrateSettingsFromGlobalIni(const QString &settingsPath); static bool migrateLegacySettings(const QString &settingsPath); + /** + * Moves pre-camelCase gamefilters.ini keys (snake_case, game_type/) to the camelCase + * keys used since #7084, for profiles that already migrated before that rename and therefore + * never pass through migrateLegacySettings again. Copies values only where the new key is + * absent, never deletes the old keys, and returns true when anything was copied. Idempotent, + * so it runs on every startup. + */ + static bool migrateGameFiltersToCamelCase(const QString &settingsPath); + /** * Returns true when at least one of the two migrations would still do work, i.e. when a * backup of the settings directory is worth taking before they run. diff --git a/libcockatrice_settings/libcockatrice/settings/sound_settings.cpp b/libcockatrice_settings/libcockatrice/settings/sound_settings.cpp index 82b724a07..5de7f9105 100644 --- a/libcockatrice_settings/libcockatrice/settings/sound_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/sound_settings.cpp @@ -1,5 +1,11 @@ #include "sound_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include + +class QObject; + SoundSettings::SoundSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "sound.ini", "sound", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/sound_settings.h b/libcockatrice_settings/libcockatrice/settings/sound_settings.h index ffaed2a7c..df6332cae 100644 --- a/libcockatrice_settings/libcockatrice/settings/sound_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/sound_settings.h @@ -3,7 +3,11 @@ #include "settings_manager.h" +#include #include +#include + +class QObject; class SoundSettings : public SettingsManager, public ISoundSettingsProvider { diff --git a/libcockatrice_settings/libcockatrice/settings/tabs_settings.cpp b/libcockatrice_settings/libcockatrice/settings/tabs_settings.cpp index cf5bfd81a..7ed6c4433 100644 --- a/libcockatrice_settings/libcockatrice/settings/tabs_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/tabs_settings.cpp @@ -1,5 +1,12 @@ #include "tabs_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include +#include + +class QObject; + TabsSettings::TabsSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "tabs.ini", "tabs", QString(), parent) { diff --git a/libcockatrice_settings/libcockatrice/settings/tabs_settings.h b/libcockatrice_settings/libcockatrice/settings/tabs_settings.h index eb78d311b..5411a6721 100644 --- a/libcockatrice_settings/libcockatrice/settings/tabs_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/tabs_settings.h @@ -3,7 +3,11 @@ #include "settings_manager.h" +#include #include +#include + +class QObject; /** * @brief The tab the application selects after launch. diff --git a/libcockatrice_settings/libcockatrice/settings/updates_settings.cpp b/libcockatrice_settings/libcockatrice/settings/updates_settings.cpp index 166bc0aa8..9ea22ed7c 100644 --- a/libcockatrice_settings/libcockatrice/settings/updates_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/updates_settings.cpp @@ -1,6 +1,13 @@ #include "updates_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include #include +#include +#include + +class QObject; UpdatesSettings::UpdatesSettings(const QString &settingPath, QObject *parent) : SettingsManager(settingPath + "updates.ini", "updates", QString(), parent) @@ -53,6 +60,11 @@ bool UpdatesSettings::getNotifyAboutNewVersion() const return getValue("newVersionNotification", QString(), QString(), true).toBool(); } +bool UpdatesSettings::getCardDatabaseUpdateTrayNotification() const +{ + return getValue("cardDatabaseUpdateTrayNotification", QString(), QString(), true).toBool(); +} + int UpdatesSettings::getUpdateReleaseChannelIndex() const { return getValue("updateReleaseChannel", QString(), QString(), 0).toInt(); @@ -98,6 +110,11 @@ void UpdatesSettings::setNotifyAboutNewVersion(bool _notifyaboutnewversion) setValue(_notifyaboutnewversion, "newVersionNotification"); } +void UpdatesSettings::setCardDatabaseUpdateTrayNotification(bool value) +{ + setValue(value, "cardDatabaseUpdateTrayNotification"); +} + void UpdatesSettings::setUpdateReleaseChannelIndex(int value) { setValue(value, "updateReleaseChannel"); diff --git a/libcockatrice_settings/libcockatrice/settings/updates_settings.h b/libcockatrice_settings/libcockatrice/settings/updates_settings.h index 6df0f8ce4..490dca14e 100644 --- a/libcockatrice_settings/libcockatrice/settings/updates_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/updates_settings.h @@ -3,8 +3,12 @@ #include "settings_manager.h" -#include +#include #include +#include + +class QDate; +class QObject; class UpdatesSettings : public SettingsManager, public IUpdatesSettingsProvider { @@ -21,6 +25,7 @@ public: [[nodiscard]] bool getAlwaysEnableNewSets() const override; [[nodiscard]] bool getNotifyAboutUpdates() const override; [[nodiscard]] bool getNotifyAboutNewVersion() const override; + [[nodiscard]] bool getCardDatabaseUpdateTrayNotification() const; [[nodiscard]] int getUpdateReleaseChannelIndex() const override; void setCheckUpdatesOnStartup(bool value); @@ -31,6 +36,7 @@ public: void setAlwaysEnableNewSets(bool value); void setNotifyAboutUpdates(bool _notifyaboutupdate); void setNotifyAboutNewVersion(bool _notifyaboutnewversion); + void setCardDatabaseUpdateTrayNotification(bool value); void setUpdateReleaseChannelIndex(int value); public: diff --git a/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.cpp b/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.cpp index 3320598d8..4667a278c 100644 --- a/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.cpp +++ b/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.cpp @@ -1,5 +1,12 @@ #include "visual_deck_storage_settings.h" +#include "libcockatrice/settings/settings_manager.h" + +#include +#include + +class QObject; + namespace { QStringList defaultTags = { diff --git a/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.h b/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.h index 9bc9d4172..12b96fd8b 100644 --- a/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.h +++ b/libcockatrice_settings/libcockatrice/settings/visual_deck_storage_settings.h @@ -3,8 +3,12 @@ #include "settings_manager.h" +#include #include #include +#include + +class QObject; class VisualDeckStorageSettings : public SettingsManager, public IVisualDeckStorageSettingsProvider { diff --git a/libcockatrice_utility/CMakeLists.txt b/libcockatrice_utility/CMakeLists.txt index 41f1bfa0f..5e6fa986d 100644 --- a/libcockatrice_utility/CMakeLists.txt +++ b/libcockatrice_utility/CMakeLists.txt @@ -22,6 +22,7 @@ set(UTILITY_HEADERS libcockatrice/utility/cryptoutil.h libcockatrice/utility/expression.h libcockatrice/utility/levenshtein.h + libcockatrice/utility/local_server_name.h libcockatrice/utility/macros.h libcockatrice/utility/passwordhasher.h libcockatrice/utility/playmat_params.h @@ -48,3 +49,5 @@ target_link_libraries(libcockatrice_utility PUBLIC libcockatrice_rng OpenSSL::Cr set(ORACLE_LIBS) include_directories(${${COCKATRICE_QT_VERSION_NAME}Core_INCLUDE_DIRS}) + +target_precompile_headers(libcockatrice_utility PRIVATE "${CMAKE_SOURCE_DIR}/cmake/pch/qtcore_pch.h") diff --git a/libcockatrice_utility/libcockatrice/utility/cryptoutil.cpp b/libcockatrice_utility/libcockatrice/utility/cryptoutil.cpp index 416ef261b..fb59022de 100644 --- a/libcockatrice_utility/libcockatrice/utility/cryptoutil.cpp +++ b/libcockatrice_utility/libcockatrice/utility/cryptoutil.cpp @@ -1,6 +1,7 @@ #include "cryptoutil.h" #include +#include namespace CryptoUtil { diff --git a/libcockatrice_utility/libcockatrice/utility/expression.cpp b/libcockatrice_utility/libcockatrice/utility/expression.cpp index 718b0fe18..85d1cdddc 100644 --- a/libcockatrice_utility/libcockatrice/utility/expression.cpp +++ b/libcockatrice_utility/libcockatrice/utility/expression.cpp @@ -5,7 +5,12 @@ #include #include #include +#include #include +#include +#include +#include +#include peg::parser math(R"( EXPRESSION <- P0 diff --git a/libcockatrice_utility/libcockatrice/utility/levenshtein.cpp b/libcockatrice_utility/libcockatrice/utility/levenshtein.cpp index f39d325fb..f7d8459cb 100644 --- a/libcockatrice_utility/libcockatrice/utility/levenshtein.cpp +++ b/libcockatrice_utility/libcockatrice/utility/levenshtein.cpp @@ -1,5 +1,7 @@ #include "levenshtein.h" +#include +#include #include #include diff --git a/libcockatrice_utility/libcockatrice/utility/local_server_name.h b/libcockatrice_utility/libcockatrice/utility/local_server_name.h new file mode 100644 index 000000000..a5797fba1 --- /dev/null +++ b/libcockatrice_utility/libcockatrice/utility/local_server_name.h @@ -0,0 +1,28 @@ +#ifndef COCKATRICE_LOCAL_SERVER_NAME_H +#define COCKATRICE_LOCAL_SERVER_NAME_H + +#include +#include +#include + +/** + * @brief Builds a QLocalServer/QLocalSocket name scoped to the current user. + * + * On Linux the default local socket namespace is system-wide, so an unscoped name + * would let one user's process talk to — or hijack — another user's session. + * @param prefix application specific socket name prefix + * @return the scoped socket name + */ +inline QString scopedLocalServerName(const QString &prefix) +{ + QString userName = qEnvironmentVariable("USER"); + if (userName.isEmpty()) { + userName = qEnvironmentVariable("USERNAME"); + } + if (userName.isEmpty()) { + userName = QDir::home().dirName(); + } + return prefix + QLatin1Char('-') + userName; +} + +#endif // COCKATRICE_LOCAL_SERVER_NAME_H diff --git a/libcockatrice_utility/libcockatrice/utility/passwordhasher.cpp b/libcockatrice_utility/libcockatrice/utility/passwordhasher.cpp index 1c22fdcfa..b4a412fa6 100644 --- a/libcockatrice_utility/libcockatrice/utility/passwordhasher.cpp +++ b/libcockatrice_utility/libcockatrice/utility/passwordhasher.cpp @@ -1,5 +1,7 @@ #include "passwordhasher.h" +#include +#include #include #include diff --git a/libcockatrice_utility/libcockatrice/utility/passwordhasher.h b/libcockatrice_utility/libcockatrice/utility/passwordhasher.h index 811ecef15..8ad83f089 100644 --- a/libcockatrice_utility/libcockatrice/utility/passwordhasher.h +++ b/libcockatrice_utility/libcockatrice/utility/passwordhasher.h @@ -1,7 +1,7 @@ #ifndef PASSWORDHASHER_H #define PASSWORDHASHER_H -#include +#include class PasswordHasher { diff --git a/libcockatrice_utility/libcockatrice/utility/report_categories.cpp b/libcockatrice_utility/libcockatrice/utility/report_categories.cpp index 8551c1ca1..f3576d7fd 100644 --- a/libcockatrice_utility/libcockatrice/utility/report_categories.cpp +++ b/libcockatrice_utility/libcockatrice/utility/report_categories.cpp @@ -1,5 +1,8 @@ #include "report_categories.h" +#include +#include + namespace ReportCategories { const QStringList &keys() diff --git a/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.cpp b/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.cpp index 2a1e3b283..50340c350 100644 --- a/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.cpp +++ b/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.cpp @@ -1,5 +1,9 @@ #include "server_rate_limiter.h" +#include +#include +#include + bool ServerRateLimiter::isRateLimited(const QString &host, const QDateTime &now) const { auto it = backoffUntil.constFind(host); diff --git a/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.h b/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.h index e071b9189..cae26983d 100644 --- a/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.h +++ b/libcockatrice_utility/libcockatrice/utility/server_rate_limiter.h @@ -4,6 +4,7 @@ #include #include #include +#include /** * @class ServerRateLimiter diff --git a/libcockatrice_utility/libcockatrice/utility/translation_loader.cpp b/libcockatrice_utility/libcockatrice/utility/translation_loader.cpp index b06bcffc6..41c6107b3 100644 --- a/libcockatrice_utility/libcockatrice/utility/translation_loader.cpp +++ b/libcockatrice_utility/libcockatrice/utility/translation_loader.cpp @@ -1,13 +1,23 @@ #include "translation_loader.h" +#include #include +#include #include #include +#include #include +#include #include +#include #include +#include +#include +#include #include +#include #include +#include // Kept under the historical category name so existing QT_LOGGING_RULES filters keep working. Q_LOGGING_CATEGORY(TranslationLoaderLog, "qt_translator") diff --git a/libcockatrice_utility/libcockatrice/utility/warning_categories.cpp b/libcockatrice_utility/libcockatrice/utility/warning_categories.cpp index b5ca563ff..ad0fc86f0 100644 --- a/libcockatrice_utility/libcockatrice/utility/warning_categories.cpp +++ b/libcockatrice_utility/libcockatrice/utility/warning_categories.cpp @@ -1,5 +1,9 @@ #include "warning_categories.h" +#include +#include +#include + QList parseWarningCategories(const QString &value) { QList categories; diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 0003b77ac..0df345812 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -79,6 +79,9 @@ if(ZLIB_FOUND) include_directories(${ZLIB_INCLUDE_DIRS}) add_definitions("-DHAS_ZLIB") list(APPEND oracle_SOURCES src/zip/unzip.cpp src/zip/zipglobal.cpp) + # minizip and zlib are vendored. + cockatrice_disable_sanitizers_for(src/zip/unzip.cpp src/zip/zipglobal.cpp) + cockatrice_disable_coverage_for(src/zip/unzip.cpp src/zip/zipglobal.cpp) else() message(STATUS "Oracle: zlib not found; ZIP support disabled") endif() @@ -89,6 +92,9 @@ if(LIBLZMA_FOUND) include_directories(${LIBLZMA_INCLUDE_DIRS}) add_definitions("-DHAS_LZMA") list(APPEND oracle_SOURCES src/lzma/decompress.cpp) + # The LZMA SDK is vendored. + cockatrice_disable_sanitizers_for(src/lzma/decompress.cpp) + cockatrice_disable_coverage_for(src/lzma/decompress.cpp) else() message(STATUS "Oracle: LibLZMA not found; xz support disabled") endif() diff --git a/oracle/oracle_en@source.ts b/oracle/oracle_en@source.ts index b3263f861..09020f02c 100644 --- a/oracle/oracle_en@source.ts +++ b/oracle/oracle_en@source.ts @@ -4,22 +4,22 @@ IntroPage - + Introduction - + This wizard will import the list of sets, cards, and tokens that will be used by Cockatrice. - + Interface language: - + Version: @@ -27,192 +27,206 @@ LoadSetsPage - + Source selection - + Please specify a compatible source for the list of sets and cards. You can specify a URL address that will be downloaded or use an existing file from your computer. - + Download URL: - + Local file: - + Restore default URL - + Choose file... - + Load sets file - + Sets file (%1) Sets JSON file (%1) - - - - - - - + + + + + Error - + The provided URL is not valid. - - Downloading (0MB) - - - - + Please choose a file. - + Cannot open file '%1'. - - Downloading (%1MB) - - - - + Network error: %1. - + Parsing file - + Xz extraction failed. - + Sorry, this version of Oracle does not support xz compressed files. - + Failed to open Zip archive: %1. - + Zip extraction failed: the Zip archive doesn't contain exactly one file. - + Zip extraction failed: %1. - + Sorry, this version of Oracle does not support zipped files. - + Failed to interpret downloaded data. - + + Downloading (0 MB) + + + + + Downloading (%1 MB) + + + + + Parsing file (%1%) + + + + + Extracting file... + + + + Do you want to download the uncompressed file instead? - + + The file was retrieved successfully, but it does not contain any sets data. + + + Parsing file (100%) + + LoadSpoilersPage - + Save spoiler database - + XML; spoiler database (*.xml) - + spoiler - + Spoilers import - + Please specify a compatible source for spoiler data. - + Download URL: - + Local file: - + Restore default URL - + Choose file... - + The spoiler database will be saved at the following location: - + Save to a custom path (not recommended) @@ -220,57 +234,57 @@ LoadTokensPage - + Save token database - + XML; token database (*.xml) - + tokens - + Tokens import - + Please specify a compatible source for token data. - + Download URL: - + Local file: - + Restore default URL - + Choose file... - + The token database will be saved at the following location: - + Save to a custom path (not recommended) @@ -278,7 +292,7 @@ OracleImporter - + Dummy set containing tokens @@ -286,7 +300,7 @@ OracleWizard - + Oracle Importer @@ -294,22 +308,22 @@ OutroPage - + Finished - + The wizard has finished. - + You can now start using Cockatrice with the newly updated cards. - + If the card databases don't reload automatically, restart the Cockatrice client. @@ -317,73 +331,76 @@ SaveSetsPage - - + + Error - + + No set has been imported. - + Sets imported - - A cockatrice database file of %1 MB has been downloaded. + + A Cockatrice card database file of %1 MB has been downloaded. - + The following sets have been found: - + Press "Save" to store the imported cards in the Cockatrice database. - + The card database will be saved at the following location: - + Save to a custom path (not recommended) - + &Save - + + Import finished: %1 cards. - + + %1: %2 cards imported - + Save card database - + XML; card database (*.xml) - + The file could not be saved to %1 @@ -416,7 +433,8 @@
- Downloading (0MB) + Downloading (0 MB) + Downloading (0MB) @@ -589,7 +607,7 @@ i18n - + English @@ -597,12 +615,12 @@ main - + Only run in spoiler mode - + Run in no-confirm background mode diff --git a/oracle/src/main.cpp b/oracle/src/main.cpp index 103c72784..cae2ee37d 100644 --- a/oracle/src/main.cpp +++ b/oracle/src/main.cpp @@ -5,8 +5,12 @@ #include <../../cockatrice/src/client/settings/cache_settings.h> #include +#include #include +#include +#include #include +#include #include #include #include diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 88b522197..3382e36d6 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -1,20 +1,35 @@ #include "oracleimporter.h" -#include "libcockatrice/interfaces/noop_card_preference_provider.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/format/format_legality_rules.h" +#include "libcockatrice/card/lazy_properties_hash.h" +#include "libcockatrice/card/relation/card_relation_type.h" #include "libcockatrice/interfaces/noop_card_set_priority_controller.h" #include "parsehelpers.h" +#include #include #include #include #include +#include +#include +#include +#include #include +#include #include +#include +#include +#include #include #include #include #include #include +#include + +class ICardSetPriorityController; static const QList kConstructedCounts = {{4, "legal"}, {0, "banned"}}; @@ -286,9 +301,9 @@ CardInfoPtr OracleImporter::addCard(QString name, static QString getJsonString(const QJsonObject &obj, const QString &key) { - // QVariant coerces numbers and booleans to text, while QJsonValue::toString() - // returns a null string for them — some MTGJSON fields (manaValue, - // convertedManaCost, isOnlineOnly, isRebalanced) carry those types. + // QVariant coerces numbers to text, while QJsonValue::toString() returns a + // null string for them — MTGJSON fields like manaValue and convertedManaCost + // carry those types. return obj.value(key).toVariant().toString(); } @@ -397,11 +412,8 @@ int OracleImporter::importCardsFromSet(const CardSetPtr ¤tSet, const QJson }; // mtgjson name => xml name - static const QMap setInfoProperties{{"number", "num"}, - {"rarity", "rarity"}, - {"isOnlineOnly", "isOnlineOnly"}, - {"isRebalanced", "isRebalanced"}, - {"artist", "artist"}}; + static const QMap setInfoProperties{ + {"number", "num"}, {"rarity", "rarity"}, {"artist", "artist"}}; // mtgjson name => xml name static const QMap identifierProperties{{"multiverseId", "muid"}, {"scryfallId", "uuid"}}; @@ -836,7 +848,7 @@ int OracleImporter::startImport() bool OracleImporter::saveToFile(const QString &fileName, const QString &sourceUrl, const QString &sourceVersion) { - CockatriceXml4Parser parser(new NoopCardPreferenceProvider(), new NoopCardSetPriorityController()); + CockatriceXml4Parser parser(new NoopCardSetPriorityController()); return parser.saveToFile(createDefaultMagicFormats(), sets, cards, fileName, sourceUrl, sourceVersion); } diff --git a/oracle/src/oracleimporter.h b/oracle/src/oracleimporter.h index c8d3a19bf..d872e184e 100644 --- a/oracle/src/oracleimporter.h +++ b/oracle/src/oracleimporter.h @@ -1,18 +1,29 @@ #ifndef ORACLEIMPORTER_H #define ORACLEIMPORTER_H +#include "libcockatrice/card/printing/printing_info.h" +#include "libcockatrice/card/set/card_set.h" #include "raw_json_scanner.h" #include #include +#include +#include #include #include +#include #include -#include -#include +#include +#include +#include #include +#include +#include #include +class CardRelation; +class QRegularExpression; + // many users prefer not to see these sets with non english arts // they will given priority PriorityLowest const QStringList nonEnglishSets = {"4BB", "FBB", "PS11", "PSAL", "REN", "RIN"}; @@ -174,9 +185,10 @@ private: /** * Whether readSetsFromByteArray() should report scan progress via - * dataReadProgress. A background run routes that signal to stdout (for the - * hosting Cockatrice client to parse); the flag exists to skip the scanner - * instrumentation entirely when no consumer needs it. + * dataReadProgress. The wizard streams that signal to stdout (for the + * hosting Cockatrice client to parse) in both interactive and background + * runs; the flag exists to skip the scanner instrumentation entirely when + * no consumer needs it. */ bool progressReporting = true; @@ -244,9 +256,9 @@ public: * @brief Controls whether readSetsFromByteArray() instruments the raw scan. * * When enabled (the default) the raw scanner reports progress via - * dataReadProgress(), which an interactive wizard shows on its progress bar - * and a background run routes to stdout for the hosting client. Switch it - * off only when nothing will consume scan progress. + * dataReadProgress(), which the wizard streams to stdout (so the hosting + * Cockatrice client can show it) and also displays on its own progress bar. + * Switch it off only when nothing will consume scan progress. */ void setProgressReporting(bool enabled) { diff --git a/oracle/src/oraclewizard.cpp b/oracle/src/oraclewizard.cpp index 9ce0d7b51..05f08ce64 100644 --- a/oracle/src/oraclewizard.cpp +++ b/oracle/src/oraclewizard.cpp @@ -6,17 +6,28 @@ #include "pages.h" #include "pagetemplates.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include + +class QWidget; OracleWizard::OracleWizard(QWidget *parent) : QWizard(parent) { @@ -64,6 +75,7 @@ OracleWizard::OracleWizard(QWidget *parent) : QWizard(parent) } retranslateUi(); + startRaiseServer(); } /** @@ -132,6 +144,54 @@ void OracleWizard::runInBackground() currentPage()->initializePage(); } +void OracleWizard::startRaiseServer() +{ + // Scope the socket name to the current user, mirroring the hosting client. + raiseServer = new QLocalServer(this); + connect(raiseServer, &QLocalServer::newConnection, this, &OracleWizard::handleRaiseRequest); + const QString serverName = scopedLocalServerName(QStringLiteral("CockatriceOracleRaise")); + if (raiseServer->listen(serverName)) { + return; + } + // A stale socket left behind by a crashed run holds the name: take it back. + QLocalServer::removeServer(serverName); + if (!raiseServer->listen(serverName)) { + qWarning() << "Oracle: could not listen for raise requests on" << serverName; + delete raiseServer; + raiseServer = nullptr; + } +} + +void OracleWizard::handleRaiseRequest() +{ + while (raiseServer && raiseServer->hasPendingConnections()) { + QLocalSocket *socket = raiseServer->nextPendingConnection(); + connect(socket, &QLocalSocket::readyRead, this, [this, socket]() { + socket->readAll(); + socket->deleteLater(); + raiseWizard(); + }); + connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater); + } + raiseWizard(); +} + +void OracleWizard::raiseWizard() +{ + // An ongoing background run is hidden; the user asked to see it, so promote it to a window. + if (backgroundMode && !isVisible()) { + show(); + } + if (isMinimized()) { + showNormal(); + } + raise(); + activateWindow(); + if (windowHandle()) { + windowHandle()->requestActivate(); + } +} + void OracleWizard::enableButtons() { button(QWizard::NextButton)->setDisabled(false); diff --git a/oracle/src/oraclewizard.h b/oracle/src/oraclewizard.h index 9a509ce5e..ea652bdc5 100644 --- a/oracle/src/oraclewizard.h +++ b/oracle/src/oraclewizard.h @@ -1,21 +1,17 @@ #ifndef ORACLEWIZARD_H #define ORACLEWIZARD_H +#include +#include #include +#include #include -class QCheckBox; -class QGroupBox; -class QComboBox; -class QLabel; -class QLineEdit; -class QRadioButton; -class QProgressBar; class QNetworkAccessManager; -class QTextEdit; -class QVBoxLayout; class OracleImporter; +class QLocalServer; class QSettings; +class QWidget; class OracleWizard : public QWizard { @@ -65,6 +61,7 @@ public: private slots: void updateLanguage(); + void handleRaiseRequest(); private: QByteArray tokensData; @@ -72,6 +69,13 @@ private: QString cardSourceVersion; void migrateOracleSettings(); + /** + * @brief Starts the local socket the hosting Cockatrice client uses to bring this wizard forward. + */ + void startRaiseServer(); + /** @brief Shows, raises and activates the wizard window. */ + void raiseWizard(); + QLocalServer *raiseServer = nullptr; ///< listens for raise requests from the hosting client protected: void changeEvent(QEvent *event) override; diff --git a/oracle/src/pages.cpp b/oracle/src/pages.cpp index 566c88520..8c286fb46 100644 --- a/oracle/src/pages.cpp +++ b/oracle/src/pages.cpp @@ -4,36 +4,59 @@ #include "main.h" #include "oracleimporter.h" #include "oraclewizard.h" -#include "pages.h" #include "pagetemplates.h" #include "version_string.h" -#include #include #include #include +#include #include #include +#include #include +#include #include +#include +#include +#include #include #include +#include +#include #include #include #include +#include +#include #include #include #include #include #include -#include +#include +#include #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include +#include +#include +#include +#include +#include +#include + +class QWidget; #ifdef HAS_LZMA #include "lzma/decompress.h" @@ -59,13 +82,12 @@ #endif /** - * @brief Emits one machine-readable background-run progress line to stdout. + * @brief Emits one machine-readable progress line to stdout. * - * Used only in background mode, so the hosting Cockatrice client can parse these - * lines to drive a determinate progress bar. stderr stays reserved for - * human-readable log output. + * The hosting Cockatrice client parses these lines to drive a determinate + * progress bar. stderr stays reserved for human-readable log output. */ -static void emitBackgroundProgress(const char *stage, qint64 done, qint64 total) +static void emitProgress(const char *stage, qint64 done, qint64 total) { QTextStream out(stdout); out << "PROGRESS " << stage << ' ' << done << ' ' << total << '\n'; @@ -450,9 +472,7 @@ void LoadSetsPage::downloadSetsFile(const QUrl &url) void LoadSetsPage::actDownloadProgressSetsFile(qint64 received, qint64 total) { - if (wizard()->backgroundMode) { - emitBackgroundProgress("download", received, total); - } + emitProgress("download", received, total); if (total > 0) { progressBar->setMaximum(static_cast(total)); progressBar->setValue(static_cast(received)); @@ -511,7 +531,7 @@ void LoadSetsPage::updateParsingProgress(int bytesRead, int totalBytes) void LoadSetsPage::scanProgressToStdout(int bytesRead, int totalBytes) { - emitBackgroundProgress("scan", bytesRead, totalBytes); + emitProgress("scan", bytesRead, totalBytes); } void LoadSetsPage::beginLoadSets(bool compressedFile) @@ -818,18 +838,18 @@ void SaveSetsPage::updateTotalProgress(int cardsImported, int setIndex, const QS const int cardCount = wizard()->importer->getCardList().size(); if (wizard()->backgroundMode) { qInfo() << tr("Import finished: %1 cards.").arg(cardCount); - emitBackgroundProgress("import", totalSets, totalSets); } else { messageLog->append("" + tr("Import finished: %1 cards.").arg(cardCount) + ""); } + emitProgress("import", totalSets, totalSets); } else { progressBar->setValue(setIndex); if (wizard()->backgroundMode) { qInfo() << tr("%1: %2 cards imported").arg(setName).arg(cardsImported); - emitBackgroundProgress("import", setIndex, totalSets); } else { messageLog->append(tr("%1: %2 cards imported").arg(setName).arg(cardsImported)); } + emitProgress("import", setIndex, totalSets); } messageLog->verticalScrollBar()->setValue(messageLog->verticalScrollBar()->maximum()); diff --git a/oracle/src/pages.h b/oracle/src/pages.h index d0a9fcd43..221f032d3 100644 --- a/oracle/src/pages.h +++ b/oracle/src/pages.h @@ -7,22 +7,20 @@ #include #include #include -#include -#include -#include +#include +#include +#include class QCheckBox; -class QGroupBox; class QComboBox; class QLabel; class QLineEdit; class QRadioButton; class QProgressBar; -class QNetworkAccessManager; class QTextEdit; -class QVBoxLayout; -class OracleImporter; -class QSettings; +class QPushButton; +class QUrl; +class QWidget; class IntroPage : public OracleWizardPage { diff --git a/oracle/src/pagetemplates.cpp b/oracle/src/pagetemplates.cpp index 0ffeabbb3..d37818dcb 100644 --- a/oracle/src/pagetemplates.cpp +++ b/oracle/src/pagetemplates.cpp @@ -3,17 +3,32 @@ #include "oraclewizard.h" #include +#include #include +#include #include +#include #include +#include #include #include +#include #include +#include #include +#include +#include #include #include #include -#include +#include +#include +#include +#include +#include +#include + +class QWidget; SimpleDownloadFilePage::SimpleDownloadFilePage(QWidget *parent) : OracleWizardPage(parent) { diff --git a/oracle/src/pagetemplates.h b/oracle/src/pagetemplates.h index ccad7ec62..2a996801d 100644 --- a/oracle/src/pagetemplates.h +++ b/oracle/src/pagetemplates.h @@ -1,15 +1,21 @@ #ifndef PAGETEMPLATES_H #define PAGETEMPLATES_H +#include +#include #include +#include +#include -class QFile; class QRadioButton; class OracleWizard; class QCheckBox; class QLabel; class QLineEdit; class QProgressBar; +class QPushButton; +class QUrl; +class QWidget; class OracleWizardPage : public QWizardPage { diff --git a/oracle/src/parsehelpers.cpp b/oracle/src/parsehelpers.cpp index ee7c4eb2e..2c897031f 100644 --- a/oracle/src/parsehelpers.cpp +++ b/oracle/src/parsehelpers.cpp @@ -1,7 +1,11 @@ #include "parsehelpers.h" #include +#include #include +#include +#include +#include /** * Parses the card text to determine if the card should have the cipt tag diff --git a/oracle/src/raw_json_scanner.cpp b/oracle/src/raw_json_scanner.cpp index 8c4633598..2396b59ae 100644 --- a/oracle/src/raw_json_scanner.cpp +++ b/oracle/src/raw_json_scanner.cpp @@ -1,5 +1,9 @@ #include "raw_json_scanner.h" +#include +#include +#include +#include #include #include diff --git a/oracle/src/raw_json_scanner.h b/oracle/src/raw_json_scanner.h index 04fcc52e4..18030d834 100644 --- a/oracle/src/raw_json_scanner.h +++ b/oracle/src/raw_json_scanner.h @@ -1,11 +1,13 @@ #ifndef RAW_JSON_SCANNER_H #define RAW_JSON_SCANNER_H -#include #include #include +#include #include +class QByteArray; + namespace RawJson { diff --git a/qt6.imp b/qt6.imp new file mode 100644 index 000000000..4f09d6406 --- /dev/null +++ b/qt6.imp @@ -0,0 +1,2471 @@ +# Do not edit! Generated by generate_qt_mappings.py from +# /usr/include/qt6 +[ + { "symbol": [ "QAbstractAnimation", "private", "", "public"] }, + { "symbol": [ "QAbstractButton", "private", "", "public"] }, + { "symbol": [ "QAbstractEventDispatcher", "private", "", "public"] }, + { "symbol": [ "QAbstractEventDispatcherV2", "private", "", "public"] }, + { "symbol": [ "QAbstractFileIconProvider", "private", "", "public"] }, + { "symbol": [ "QAbstractGraphicsShapeItem", "private", "", "public"] }, + { "symbol": [ "QAbstractItemDelegate", "private", "", "public"] }, + { "symbol": [ "QAbstractItemModel", "private", "", "public"] }, + { "symbol": [ "QAbstractItemModelTester", "private", "", "public"] }, + { "symbol": [ "QAbstractItemView", "private", "", "public"] }, + { "symbol": [ "QAbstractListModel", "private", "", "public"] }, + { "symbol": [ "QAbstractNativeEventFilter", "private", "", "public"] }, + { "symbol": [ "QAbstractNetworkCache", "private", "", "public"] }, + { "symbol": [ "QAbstractOAuth", "private", "", "public"] }, + { "symbol": [ "QAbstractOAuth2", "private", "", "public"] }, + { "symbol": [ "QAbstractOAuthReplyHandler", "private", "", "public"] }, + { "symbol": [ "QAbstractPrintDialog", "private", "", "public"] }, + { "symbol": [ "QAbstractProxyModel", "private", "", "public"] }, + { "symbol": [ "QAbstractScrollArea", "private", "", "public"] }, + { "symbol": [ "QAbstractSlider", "private", "", "public"] }, + { "symbol": [ "QAbstractSocket", "private", "", "public"] }, + { "symbol": [ "QAbstractSpinBox", "private", "", "public"] }, + { "symbol": [ "QAbstractState", "private", "", "public"] }, + { "symbol": [ "QAbstractTableModel", "private", "", "public"] }, + { "symbol": [ "QAbstractTextDocumentLayout", "private", "", "public"] }, + { "symbol": [ "QAbstractTransition", "private", "", "public"] }, + { "symbol": [ "QAbstractUndoItem", "private", "", "public"] }, + { "symbol": [ "QAbstractVideoBuffer", "private", "", "public"] }, + { "symbol": [ "QAccessibilityHints", "private", "", "public"] }, + { "symbol": [ "QAccessible", "private", "", "public"] }, + { "symbol": [ "QAccessibleActionInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleAnnouncementEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleApplication", "private", "", "public"] }, + { "symbol": [ "QAccessibleAttributesInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleBridge", "private", "", "public"] }, + { "symbol": [ "QAccessibleBridgePlugin", "private", "", "public"] }, + { "symbol": [ "QAccessibleEditableTextInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleHyperlinkInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleImageInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleObject", "private", "", "public"] }, + { "symbol": [ "QAccessiblePlugin", "private", "", "public"] }, + { "symbol": [ "QAccessibleSelectionInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleStateChangeEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleTableCellInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleTableInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleTableModelChangeEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleTextCursorEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleTextInsertEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleTextInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleTextRemoveEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleTextSelectionEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleTextUpdateEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleValueChangeEvent", "private", "", "public"] }, + { "symbol": [ "QAccessibleValueInterface", "private", "", "public"] }, + { "symbol": [ "QAccessibleWidget", "private", "", "public"] }, + { "symbol": [ "QAccessibleWidgetV2", "private", "", "public"] }, + { "symbol": [ "QAction", "private", "", "public"] }, + { "symbol": [ "QActionEvent", "private", "", "public"] }, + { "symbol": [ "QActionGroup", "private", "", "public"] }, + { "symbol": [ "QAmbientSound", "private", "", "public"] }, + { "symbol": [ "QAnimationDriver", "private", "", "public"] }, + { "symbol": [ "QAnimationGroup", "private", "", "public"] }, + { "symbol": [ "QAnyStringView", "private", "", "public"] }, + { "symbol": [ "QApplication", "private", "", "public"] }, + { "symbol": [ "QApplicationStateChangeEvent", "private", "", "public"] }, + { "symbol": [ "QApplicationStatic", "private", "", "public"] }, + { "symbol": [ "QArgument", "private", "", "public"] }, + { "symbol": [ "QArrayData", "private", "", "public"] }, + { "symbol": [ "QArrayDataOps", "private", "", "public"] }, + { "symbol": [ "QArrayDataPointer", "private", "", "public"] }, + { "symbol": [ "QAssociativeConstIterator", "private", "", "public"] }, + { "symbol": [ "QAssociativeIterable", "private", "", "public"] }, + { "symbol": [ "QAssociativeIterator", "private", "", "public"] }, + { "symbol": [ "QAtomicInt", "private", "", "public"] }, + { "symbol": [ "QAtomicInteger", "private", "", "public"] }, + { "symbol": [ "QAtomicPointer", "private", "", "public"] }, + { "symbol": [ "QAtomicScopedValueRollback", "private", "", "public"] }, + { "symbol": [ "QAudio", "private", "", "public"] }, + { "symbol": [ "QAudioBuffer", "private", "", "public"] }, + { "symbol": [ "QAudioBufferInput", "private", "", "public"] }, + { "symbol": [ "QAudioBufferOutput", "private", "", "public"] }, + { "symbol": [ "QAudioDecoder", "private", "", "public"] }, + { "symbol": [ "QAudioDevice", "private", "", "public"] }, + { "symbol": [ "QAudioEngine", "private", "", "public"] }, + { "symbol": [ "QAudioFormat", "private", "", "public"] }, + { "symbol": [ "QAudioFrame", "private", "", "public"] }, + { "symbol": [ "QAudioInput", "private", "", "public"] }, + { "symbol": [ "QAudioListener", "private", "", "public"] }, + { "symbol": [ "QAudioOutput", "private", "", "public"] }, + { "symbol": [ "QAudioRoom", "private", "", "public"] }, + { "symbol": [ "QAudioSink", "private", "", "public"] }, + { "symbol": [ "QAudioSource", "private", "", "public"] }, + { "symbol": [ "QAuthenticator", "private", "", "public"] }, + { "symbol": [ "QBEInteger", "private", "", "public"] }, + { "symbol": [ "QBackingStore", "private", "", "public"] }, + { "symbol": [ "QBaseIterator", "private", "", "public"] }, + { "symbol": [ "QBasicMutex", "private", "", "public"] }, + { "symbol": [ "QBasicReadWriteLock", "private", "", "public"] }, + { "symbol": [ "QBasicTimer", "private", "", "public"] }, + { "symbol": [ "QBasicUtf8StringView", "private", "", "public"] }, + { "symbol": [ "QBigEndianStorageType", "private", "", "public"] }, + { "symbol": [ "QBinaryJson", "private", "", "public"] }, + { "symbol": [ "QBindable", "private", "", "public"] }, + { "symbol": [ "QBindingStatus", "private", "", "public"] }, + { "symbol": [ "QBindingStorage", "private", "", "public"] }, + { "symbol": [ "QBitArray", "private", "", "public"] }, + { "symbol": [ "QBitRef", "private", "", "public"] }, + { "symbol": [ "QBitmap", "private", "", "public"] }, + { "symbol": [ "QBluetoothAddress", "private", "", "public"] }, + { "symbol": [ "QBluetoothDeviceDiscoveryAgent", "private", "", "public"] }, + { "symbol": [ "QBluetoothDeviceInfo", "private", "", "public"] }, + { "symbol": [ "QBluetoothHostInfo", "private", "", "public"] }, + { "symbol": [ "QBluetoothLocalDevice", "private", "", "public"] }, + { "symbol": [ "QBluetoothPermission", "private", "", "public"] }, + { "symbol": [ "QBluetoothServer", "private", "", "public"] }, + { "symbol": [ "QBluetoothServiceDiscoveryAgent", "private", "", "public"] }, + { "symbol": [ "QBluetoothServiceInfo", "private", "", "public"] }, + { "symbol": [ "QBluetoothSocket", "private", "", "public"] }, + { "symbol": [ "QBluetoothUuid", "private", "", "public"] }, + { "symbol": [ "QBoxLayout", "private", "", "public"] }, + { "symbol": [ "QBrush", "private", "", "public"] }, + { "symbol": [ "QBrushData", "private", "", "public"] }, + { "symbol": [ "QBrushDataPointerDeleter", "private", "", "public"] }, + { "symbol": [ "QBuffer", "private", "", "public"] }, + { "symbol": [ "QButtonGroup", "private", "", "public"] }, + { "symbol": [ "QByteArray", "private", "", "public"] }, + { "symbol": [ "QByteArrayAlgorithms", "private", "", "public"] }, + { "symbol": [ "QByteArrayList", "private", "", "public"] }, + { "symbol": [ "QByteArrayListIterator", "private", "", "public"] }, + { "symbol": [ "QByteArrayMatcher", "private", "", "public"] }, + { "symbol": [ "QByteArrayView", "private", "", "public"] }, + { "symbol": [ "QCache", "private", "", "public"] }, + { "symbol": [ "QCalendar", "private", "", "public"] }, + { "symbol": [ "QCalendarPermission", "private", "", "public"] }, + { "symbol": [ "QCalendarWidget", "private", "", "public"] }, + { "symbol": [ "QCamera", "private", "", "public"] }, + { "symbol": [ "QCameraDevice", "private", "", "public"] }, + { "symbol": [ "QCameraFormat", "private", "", "public"] }, + { "symbol": [ "QCapturableWindow", "private", "", "public"] }, + { "symbol": [ "QCborArray", "private", "", "public"] }, + { "symbol": [ "QCborError", "private", "", "public"] }, + { "symbol": [ "QCborMap", "private", "", "public"] }, + { "symbol": [ "QCborParserError", "private", "", "public"] }, + { "symbol": [ "QCborStreamReader", "private", "", "public"] }, + { "symbol": [ "QCborStreamWriter", "private", "", "public"] }, + { "symbol": [ "QCborValue", "private", "", "public"] }, + { "symbol": [ "QCborValueConstRef", "private", "", "public"] }, + { "symbol": [ "QCborValueRef", "private", "", "public"] }, + { "symbol": [ "QChar", "private", "", "public"] }, + { "symbol": [ "QCheckBox", "private", "", "public"] }, + { "symbol": [ "QChildEvent", "private", "", "public"] }, + { "symbol": [ "QChildWindowEvent", "private", "", "public"] }, + { "symbol": [ "QChronoTimer", "private", "", "public"] }, + { "symbol": [ "QClipboard", "private", "", "public"] }, + { "symbol": [ "QCloseEvent", "private", "", "public"] }, + { "symbol": [ "QCollator", "private", "", "public"] }, + { "symbol": [ "QCollatorSortKey", "private", "", "public"] }, + { "symbol": [ "QColor", "private", "", "public"] }, + { "symbol": [ "QColorDialog", "private", "", "public"] }, + { "symbol": [ "QColorSpace", "private", "", "public"] }, + { "symbol": [ "QColorTransform", "private", "", "public"] }, + { "symbol": [ "QColormap", "private", "", "public"] }, + { "symbol": [ "QColumnView", "private", "", "public"] }, + { "symbol": [ "QComboBox", "private", "", "public"] }, + { "symbol": [ "QCommandLineOption", "private", "", "public"] }, + { "symbol": [ "QCommandLineParser", "private", "", "public"] }, + { "symbol": [ "QCommandLinkButton", "private", "", "public"] }, + { "symbol": [ "QCommonStyle", "private", "", "public"] }, + { "symbol": [ "QCompleter", "private", "", "public"] }, + { "symbol": [ "QCompressedHelpInfo", "private", "", "public"] }, + { "symbol": [ "QConcatenateTablesProxyModel", "private", "", "public"] }, + { "symbol": [ "QConicalGradient", "private", "", "public"] }, + { "symbol": [ "QConstIterator", "private", "", "public"] }, + { "symbol": [ "QContactsPermission", "private", "", "public"] }, + { "symbol": [ "QContextMenuEvent", "private", "", "public"] }, + { "symbol": [ "QContiguousCache", "private", "", "public"] }, + { "symbol": [ "QContiguousCacheData", "private", "", "public"] }, + { "symbol": [ "QContiguousCacheTypedData", "private", "", "public"] }, + { "symbol": [ "QCoreApplication", "private", "", "public"] }, + { "symbol": [ "QCryptographicHash", "private", "", "public"] }, + { "symbol": [ "QCursor", "private", "", "public"] }, + { "symbol": [ "QDBusAbstractAdaptor", "private", "", "public"] }, + { "symbol": [ "QDBusAbstractInterface", "private", "", "public"] }, + { "symbol": [ "QDBusAbstractInterfaceBase", "private", "", "public"] }, + { "symbol": [ "QDBusArgument", "private", "", "public"] }, + { "symbol": [ "QDBusConnection", "private", "", "public"] }, + { "symbol": [ "QDBusConnectionInterface", "private", "", "public"] }, + { "symbol": [ "QDBusContext", "private", "", "public"] }, + { "symbol": [ "QDBusError", "private", "", "public"] }, + { "symbol": [ "QDBusInterface", "private", "", "public"] }, + { "symbol": [ "QDBusMessage", "private", "", "public"] }, + { "symbol": [ "QDBusMetaType", "private", "", "public"] }, + { "symbol": [ "QDBusObjectPath", "private", "", "public"] }, + { "symbol": [ "QDBusPendingCall", "private", "", "public"] }, + { "symbol": [ "QDBusPendingCallWatcher", "private", "", "public"] }, + { "symbol": [ "QDBusPendingReply", "private", "", "public"] }, + { "symbol": [ "QDBusPendingReplyBase", "private", "", "public"] }, + { "symbol": [ "QDBusReply", "private", "", "public"] }, + { "symbol": [ "QDBusServer", "private", "", "public"] }, + { "symbol": [ "QDBusServiceWatcher", "private", "", "public"] }, + { "symbol": [ "QDBusSignature", "private", "", "public"] }, + { "symbol": [ "QDBusUnixFileDescriptor", "private", "", "public"] }, + { "symbol": [ "QDBusVariant", "private", "", "public"] }, + { "symbol": [ "QDBusVirtualObject", "private", "", "public"] }, + { "symbol": [ "QDataStream", "private", "", "public"] }, + { "symbol": [ "QDataWidgetMapper", "private", "", "public"] }, + { "symbol": [ "QDate", "private", "", "public"] }, + { "symbol": [ "QDateEdit", "private", "", "public"] }, + { "symbol": [ "QDateTime", "private", "", "public"] }, + { "symbol": [ "QDateTimeEdit", "private", "", "public"] }, + { "symbol": [ "QDeadlineTimer", "private", "", "public"] }, + { "symbol": [ "QDebug", "private", "", "public"] }, + { "symbol": [ "QDebugStateSaver", "private", "", "public"] }, + { "symbol": [ "QDesignerExportWidget", "private", "", "public"] }, + { "symbol": [ "QDesktopServices", "private", "", "public"] }, + { "symbol": [ "QDial", "private", "", "public"] }, + { "symbol": [ "QDialog", "private", "", "public"] }, + { "symbol": [ "QDialogButtonBox", "private", "", "public"] }, + { "symbol": [ "QDir", "private", "", "public"] }, + { "symbol": [ "QDirIterator", "private", "", "public"] }, + { "symbol": [ "QDirListing", "private", "", "public"] }, + { "symbol": [ "QDnsDomainNameRecord", "private", "", "public"] }, + { "symbol": [ "QDnsHostAddressRecord", "private", "", "public"] }, + { "symbol": [ "QDnsLookup", "private", "", "public"] }, + { "symbol": [ "QDnsMailExchangeRecord", "private", "", "public"] }, + { "symbol": [ "QDnsServiceRecord", "private", "", "public"] }, + { "symbol": [ "QDnsTextRecord", "private", "", "public"] }, + { "symbol": [ "QDnsTlsAssociationRecord", "private", "", "public"] }, + { "symbol": [ "QDockWidget", "private", "", "public"] }, + { "symbol": [ "QDomAttr", "private", "", "public"] }, + { "symbol": [ "QDomCDATASection", "private", "", "public"] }, + { "symbol": [ "QDomCharacterData", "private", "", "public"] }, + { "symbol": [ "QDomComment", "private", "", "public"] }, + { "symbol": [ "QDomDocument", "private", "", "public"] }, + { "symbol": [ "QDomDocumentFragment", "private", "", "public"] }, + { "symbol": [ "QDomDocumentType", "private", "", "public"] }, + { "symbol": [ "QDomElement", "private", "", "public"] }, + { "symbol": [ "QDomEntity", "private", "", "public"] }, + { "symbol": [ "QDomEntityReference", "private", "", "public"] }, + { "symbol": [ "QDomImplementation", "private", "", "public"] }, + { "symbol": [ "QDomNamedNodeMap", "private", "", "public"] }, + { "symbol": [ "QDomNode", "private", "", "public"] }, + { "symbol": [ "QDomNodeList", "private", "", "public"] }, + { "symbol": [ "QDomNotation", "private", "", "public"] }, + { "symbol": [ "QDomProcessingInstruction", "private", "", "public"] }, + { "symbol": [ "QDomText", "private", "", "public"] }, + { "symbol": [ "QDoubleSpinBox", "private", "", "public"] }, + { "symbol": [ "QDoubleValidator", "private", "", "public"] }, + { "symbol": [ "QDrag", "private", "", "public"] }, + { "symbol": [ "QDragEnterEvent", "private", "", "public"] }, + { "symbol": [ "QDragLeaveEvent", "private", "", "public"] }, + { "symbol": [ "QDragMoveEvent", "private", "", "public"] }, + { "symbol": [ "QDropEvent", "private", "", "public"] }, + { "symbol": [ "QDtls", "private", "", "public"] }, + { "symbol": [ "QDtlsClientVerifier", "private", "", "public"] }, + { "symbol": [ "QDynamicPropertyChangeEvent", "private", "", "public"] }, + { "symbol": [ "QEasingCurve", "private", "", "public"] }, + { "symbol": [ "QElapsedTimer", "private", "", "public"] }, + { "symbol": [ "QEnableSharedFromThis", "private", "", "public"] }, + { "symbol": [ "QEnterEvent", "private", "", "public"] }, + { "symbol": [ "QErrorMessage", "private", "", "public"] }, + { "symbol": [ "QEvent", "private", "", "public"] }, + { "symbol": [ "QEventLoop", "private", "", "public"] }, + { "symbol": [ "QEventLoopLocker", "private", "", "public"] }, + { "symbol": [ "QEventPoint", "private", "", "public"] }, + { "symbol": [ "QEventTransition", "private", "", "public"] }, + { "symbol": [ "QException", "private", "", "public"] }, + { "symbol": [ "QExplicitlySharedDataPointer", "private", "", "public"] }, + { "symbol": [ "QExposeEvent", "private", "", "public"] }, + { "symbol": [ "QFactoryInterface", "private", "", "public"] }, + { "symbol": [ "QFile", "private", "", "public"] }, + { "symbol": [ "QFileDevice", "private", "", "public"] }, + { "symbol": [ "QFileDialog", "private", "", "public"] }, + { "symbol": [ "QFileIconProvider", "private", "", "public"] }, + { "symbol": [ "QFileInfo", "private", "", "public"] }, + { "symbol": [ "QFileInfoList", "private", "", "public"] }, + { "symbol": [ "QFileOpenEvent", "private", "", "public"] }, + { "symbol": [ "QFileSelector", "private", "", "public"] }, + { "symbol": [ "QFileSystemModel", "private", "", "public"] }, + { "symbol": [ "QFileSystemWatcher", "private", "", "public"] }, + { "symbol": [ "QFinalState", "private", "", "public"] }, + { "symbol": [ "QFlag", "private", "", "public"] }, + { "symbol": [ "QFlags", "private", "", "public"] }, + { "symbol": [ "QFloat16", "private", "", "public"] }, + { "symbol": [ "QFocusEvent", "private", "", "public"] }, + { "symbol": [ "QFocusFrame", "private", "", "public"] }, + { "symbol": [ "QFont", "private", "", "public"] }, + { "symbol": [ "QFontComboBox", "private", "", "public"] }, + { "symbol": [ "QFontDatabase", "private", "", "public"] }, + { "symbol": [ "QFontDialog", "private", "", "public"] }, + { "symbol": [ "QFontInfo", "private", "", "public"] }, + { "symbol": [ "QFontMetrics", "private", "", "public"] }, + { "symbol": [ "QFontMetricsF", "private", "", "public"] }, + { "symbol": [ "QFontVariableAxis", "private", "", "public"] }, + { "symbol": [ "QForeach", "private", "", "public"] }, + { "symbol": [ "QFormDataBuilder", "private", "", "public"] }, + { "symbol": [ "QFormDataPartBuilder", "private", "", "public"] }, + { "symbol": [ "QFormLayout", "private", "", "public"] }, + { "symbol": [ "QFrame", "private", "", "public"] }, + { "symbol": [ "QFunctionPointer", "private", "", "public"] }, + { "symbol": [ "QFuture", "private", "", "public"] }, + { "symbol": [ "QFutureInterface", "private", "", "public"] }, + { "symbol": [ "QFutureInterfaceBase", "private", "", "public"] }, + { "symbol": [ "QFutureIterator", "private", "", "public"] }, + { "symbol": [ "QFutureSynchronizer", "private", "", "public"] }, + { "symbol": [ "QFutureWatcher", "private", "", "public"] }, + { "symbol": [ "QFutureWatcherBase", "private", "", "public"] }, + { "symbol": [ "QGenericArgument", "private", "", "public"] }, + { "symbol": [ "QGenericMatrix", "private", "", "public"] }, + { "symbol": [ "QGenericPlugin", "private", "", "public"] }, + { "symbol": [ "QGenericPluginFactory", "private", "", "public"] }, + { "symbol": [ "QGenericReturnArgument", "private", "", "public"] }, + { "symbol": [ "QGesture", "private", "", "public"] }, + { "symbol": [ "QGestureEvent", "private", "", "public"] }, + { "symbol": [ "QGestureRecognizer", "private", "", "public"] }, + { "symbol": [ "QGlobalStatic", "private", "", "public"] }, + { "symbol": [ "QGlyphRun", "private", "", "public"] }, + { "symbol": [ "QGradient", "private", "", "public"] }, + { "symbol": [ "QGradientStop", "private", "", "public"] }, + { "symbol": [ "QGradientStops", "private", "", "public"] }, + { "symbol": [ "QGraphicsAnchor", "private", "", "public"] }, + { "symbol": [ "QGraphicsAnchorLayout", "private", "", "public"] }, + { "symbol": [ "QGraphicsBlurEffect", "private", "", "public"] }, + { "symbol": [ "QGraphicsColorizeEffect", "private", "", "public"] }, + { "symbol": [ "QGraphicsDropShadowEffect", "private", "", "public"] }, + { "symbol": [ "QGraphicsEffect", "private", "", "public"] }, + { "symbol": [ "QGraphicsEllipseItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsGridLayout", "private", "", "public"] }, + { "symbol": [ "QGraphicsItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsItemAnimation", "private", "", "public"] }, + { "symbol": [ "QGraphicsItemGroup", "private", "", "public"] }, + { "symbol": [ "QGraphicsLayout", "private", "", "public"] }, + { "symbol": [ "QGraphicsLayoutItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsLineItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsLinearLayout", "private", "", "public"] }, + { "symbol": [ "QGraphicsObject", "private", "", "public"] }, + { "symbol": [ "QGraphicsOpacityEffect", "private", "", "public"] }, + { "symbol": [ "QGraphicsPathItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsPixmapItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsPolygonItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsProxyWidget", "private", "", "public"] }, + { "symbol": [ "QGraphicsRectItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsRotation", "private", "", "public"] }, + { "symbol": [ "QGraphicsScale", "private", "", "public"] }, + { "symbol": [ "QGraphicsScene", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneContextMenuEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneDragDropEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneHelpEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneHoverEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneMouseEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneMoveEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneResizeEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSceneWheelEvent", "private", "", "public"] }, + { "symbol": [ "QGraphicsSimpleTextItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsSvgItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsTextItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsTransform", "private", "", "public"] }, + { "symbol": [ "QGraphicsVideoItem", "private", "", "public"] }, + { "symbol": [ "QGraphicsView", "private", "", "public"] }, + { "symbol": [ "QGraphicsWidget", "private", "", "public"] }, + { "symbol": [ "QGridLayout", "private", "", "public"] }, + { "symbol": [ "QGroupBox", "private", "", "public"] }, + { "symbol": [ "QGuiApplication", "private", "", "public"] }, + { "symbol": [ "QHBoxLayout", "private", "", "public"] }, + { "symbol": [ "QHash", "private", "", "public"] }, + { "symbol": [ "QHashDummyValue", "private", "", "public"] }, + { "symbol": [ "QHashFunctions", "private", "", "public"] }, + { "symbol": [ "QHashHeterogeneousSearch", "private", "", "public"] }, + { "symbol": [ "QHashIterator", "private", "", "public"] }, + { "symbol": [ "QHashSeed", "private", "", "public"] }, + { "symbol": [ "QHeaderView", "private", "", "public"] }, + { "symbol": [ "QHelpContentItem", "private", "", "public"] }, + { "symbol": [ "QHelpContentModel", "private", "", "public"] }, + { "symbol": [ "QHelpContentWidget", "private", "", "public"] }, + { "symbol": [ "QHelpEngine", "private", "", "public"] }, + { "symbol": [ "QHelpEngineCore", "private", "", "public"] }, + { "symbol": [ "QHelpEvent", "private", "", "public"] }, + { "symbol": [ "QHelpFilterData", "private", "", "public"] }, + { "symbol": [ "QHelpFilterEngine", "private", "", "public"] }, + { "symbol": [ "QHelpFilterSettingsWidget", "private", "", "public"] }, + { "symbol": [ "QHelpGlobal", "private", "", "public"] }, + { "symbol": [ "QHelpIndexModel", "private", "", "public"] }, + { "symbol": [ "QHelpIndexWidget", "private", "", "public"] }, + { "symbol": [ "QHelpLink", "private", "", "public"] }, + { "symbol": [ "QHelpSearchEngine", "private", "", "public"] }, + { "symbol": [ "QHelpSearchEngineCore", "private", "", "public"] }, + { "symbol": [ "QHelpSearchQuery", "private", "", "public"] }, + { "symbol": [ "QHelpSearchQueryWidget", "private", "", "public"] }, + { "symbol": [ "QHelpSearchResult", "private", "", "public"] }, + { "symbol": [ "QHelpSearchResultWidget", "private", "", "public"] }, + { "symbol": [ "QHideEvent", "private", "", "public"] }, + { "symbol": [ "QHistoryState", "private", "", "public"] }, + { "symbol": [ "QHostAddress", "private", "", "public"] }, + { "symbol": [ "QHostInfo", "private", "", "public"] }, + { "symbol": [ "QHoverEvent", "private", "", "public"] }, + { "symbol": [ "QHstsPolicy", "private", "", "public"] }, + { "symbol": [ "QHttp1Configuration", "private", "", "public"] }, + { "symbol": [ "QHttp2Configuration", "private", "", "public"] }, + { "symbol": [ "QHttpHeaders", "private", "", "public"] }, + { "symbol": [ "QHttpMultiPart", "private", "", "public"] }, + { "symbol": [ "QHttpPart", "private", "", "public"] }, + { "symbol": [ "QIODevice", "private", "", "public"] }, + { "symbol": [ "QIODeviceBase", "private", "", "public"] }, + { "symbol": [ "QIPv6Address", "private", "", "public"] }, + { "symbol": [ "QIcon", "private", "", "public"] }, + { "symbol": [ "QIconDragEvent", "private", "", "public"] }, + { "symbol": [ "QIconEngine", "private", "", "public"] }, + { "symbol": [ "QIconEnginePlugin", "private", "", "public"] }, + { "symbol": [ "QIdentityProxyModel", "private", "", "public"] }, + { "symbol": [ "QImage", "private", "", "public"] }, + { "symbol": [ "QImageCapture", "private", "", "public"] }, + { "symbol": [ "QImageCleanupFunction", "private", "", "public"] }, + { "symbol": [ "QImageIOHandler", "private", "", "public"] }, + { "symbol": [ "QImageIOPlugin", "private", "", "public"] }, + { "symbol": [ "QImageReader", "private", "", "public"] }, + { "symbol": [ "QImageWriter", "private", "", "public"] }, + { "symbol": [ "QIncompatibleFlag", "private", "", "public"] }, + { "symbol": [ "QInputDevice", "private", "", "public"] }, + { "symbol": [ "QInputDialog", "private", "", "public"] }, + { "symbol": [ "QInputEvent", "private", "", "public"] }, + { "symbol": [ "QInputMethod", "private", "", "public"] }, + { "symbol": [ "QInputMethodEvent", "private", "", "public"] }, + { "symbol": [ "QInputMethodQueryEvent", "private", "", "public"] }, + { "symbol": [ "QIntValidator", "private", "", "public"] }, + { "symbol": [ "QInternal", "private", "", "public"] }, + { "symbol": [ "QItemDelegate", "private", "", "public"] }, + { "symbol": [ "QItemEditorCreator", "private", "", "public"] }, + { "symbol": [ "QItemEditorCreatorBase", "private", "", "public"] }, + { "symbol": [ "QItemEditorFactory", "private", "", "public"] }, + { "symbol": [ "QItemSelection", "private", "", "public"] }, + { "symbol": [ "QItemSelectionModel", "private", "", "public"] }, + { "symbol": [ "QItemSelectionRange", "private", "", "public"] }, + { "symbol": [ "QIterable", "private", "", "public"] }, + { "symbol": [ "QIterator", "private", "", "public"] }, + { "symbol": [ "QJSEngine", "private", "", "public"] }, + { "symbol": [ "QJSList", "private", "", "public"] }, + { "symbol": [ "QJSListForInIterator", "private", "", "public"] }, + { "symbol": [ "QJSListForOfIterator", "private", "", "public"] }, + { "symbol": [ "QJSListIndexClamp", "private", "", "public"] }, + { "symbol": [ "QJSManagedValue", "private", "", "public"] }, + { "symbol": [ "QJSNumberCoercion", "private", "", "public"] }, + { "symbol": [ "QJSPrimitiveValue", "private", "", "public"] }, + { "symbol": [ "QJSValue", "private", "", "public"] }, + { "symbol": [ "QJSValueIterator", "private", "", "public"] }, + { "symbol": [ "QJSValueList", "private", "", "public"] }, + { "symbol": [ "QJsonArray", "private", "", "public"] }, + { "symbol": [ "QJsonDocument", "private", "", "public"] }, + { "symbol": [ "QJsonObject", "private", "", "public"] }, + { "symbol": [ "QJsonParseError", "private", "", "public"] }, + { "symbol": [ "QJsonValue", "private", "", "public"] }, + { "symbol": [ "QJsonValueConstRef", "private", "", "public"] }, + { "symbol": [ "QJsonValueRef", "private", "", "public"] }, + { "symbol": [ "QKeyCombination", "private", "", "public"] }, + { "symbol": [ "QKeyEvent", "private", "", "public"] }, + { "symbol": [ "QKeyEventTransition", "private", "", "public"] }, + { "symbol": [ "QKeySequence", "private", "", "public"] }, + { "symbol": [ "QKeySequenceEdit", "private", "", "public"] }, + { "symbol": [ "QKeyValueIterator", "private", "", "public"] }, + { "symbol": [ "QLCDNumber", "private", "", "public"] }, + { "symbol": [ "QLEInteger", "private", "", "public"] }, + { "symbol": [ "QLabel", "private", "", "public"] }, + { "symbol": [ "QLatin1Char", "private", "", "public"] }, + { "symbol": [ "QLatin1String", "private", "", "public"] }, + { "symbol": [ "QLatin1StringMatcher", "private", "", "public"] }, + { "symbol": [ "QLatin1StringView", "private", "", "public"] }, + { "symbol": [ "QLayout", "private", "", "public"] }, + { "symbol": [ "QLayoutItem", "private", "", "public"] }, + { "symbol": [ "QLibrary", "private", "", "public"] }, + { "symbol": [ "QLibraryInfo", "private", "", "public"] }, + { "symbol": [ "QLine", "private", "", "public"] }, + { "symbol": [ "QLineEdit", "private", "", "public"] }, + { "symbol": [ "QLineF", "private", "", "public"] }, + { "symbol": [ "QLinearGradient", "private", "", "public"] }, + { "symbol": [ "QLinkedList", "private", "", "public"] }, + { "symbol": [ "QLinkedListData", "private", "", "public"] }, + { "symbol": [ "QLinkedListIterator", "private", "", "public"] }, + { "symbol": [ "QLinkedListNode", "private", "", "public"] }, + { "symbol": [ "QList", "private", "", "public"] }, + { "symbol": [ "QListIterator", "private", "", "public"] }, + { "symbol": [ "QListSpecialMethods", "private", "", "public"] }, + { "symbol": [ "QListSpecialMethodsBase", "private", "", "public"] }, + { "symbol": [ "QListView", "private", "", "public"] }, + { "symbol": [ "QListWidget", "private", "", "public"] }, + { "symbol": [ "QListWidgetItem", "private", "", "public"] }, + { "symbol": [ "QLittleEndianStorageType", "private", "", "public"] }, + { "symbol": [ "QLocalServer", "private", "", "public"] }, + { "symbol": [ "QLocalSocket", "private", "", "public"] }, + { "symbol": [ "QLocale", "private", "", "public"] }, + { "symbol": [ "QLocationPermission", "private", "", "public"] }, + { "symbol": [ "QLockFile", "private", "", "public"] }, + { "symbol": [ "QLoggingCategory", "private", "", "public"] }, + { "symbol": [ "QLowEnergyAdvertisingData", "private", "", "public"] }, + { "symbol": [ "QLowEnergyAdvertisingParameters", "private", "", "public"] }, + { "symbol": [ "QLowEnergyCharacteristic", "private", "", "public"] }, + { "symbol": [ "QLowEnergyCharacteristicData", "private", "", "public"] }, + { "symbol": [ "QLowEnergyConnectionParameters", "private", "", "public"] }, + { "symbol": [ "QLowEnergyController", "private", "", "public"] }, + { "symbol": [ "QLowEnergyDescriptor", "private", "", "public"] }, + { "symbol": [ "QLowEnergyDescriptorData", "private", "", "public"] }, + { "symbol": [ "QLowEnergyHandle", "private", "", "public"] }, + { "symbol": [ "QLowEnergyService", "private", "", "public"] }, + { "symbol": [ "QLowEnergyServiceData", "private", "", "public"] }, + { "symbol": [ "QMainWindow", "private", "", "public"] }, + { "symbol": [ "QMap", "private", "", "public"] }, + { "symbol": [ "QMapData", "private", "", "public"] }, + { "symbol": [ "QMapIterator", "private", "", "public"] }, + { "symbol": [ "QMargins", "private", "", "public"] }, + { "symbol": [ "QMarginsF", "private", "", "public"] }, + { "symbol": [ "QMaskGenerator", "private", "", "public"] }, + { "symbol": [ "QMatrix2x2", "private", "", "public"] }, + { "symbol": [ "QMatrix2x3", "private", "", "public"] }, + { "symbol": [ "QMatrix2x4", "private", "", "public"] }, + { "symbol": [ "QMatrix3x2", "private", "", "public"] }, + { "symbol": [ "QMatrix3x3", "private", "", "public"] }, + { "symbol": [ "QMatrix3x4", "private", "", "public"] }, + { "symbol": [ "QMatrix4x2", "private", "", "public"] }, + { "symbol": [ "QMatrix4x3", "private", "", "public"] }, + { "symbol": [ "QMatrix4x4", "private", "", "public"] }, + { "symbol": [ "QMdiArea", "private", "", "public"] }, + { "symbol": [ "QMdiSubWindow", "private", "", "public"] }, + { "symbol": [ "QMediaCaptureSession", "private", "", "public"] }, + { "symbol": [ "QMediaDevices", "private", "", "public"] }, + { "symbol": [ "QMediaFormat", "private", "", "public"] }, + { "symbol": [ "QMediaMetaData", "private", "", "public"] }, + { "symbol": [ "QMediaPlayer", "private", "", "public"] }, + { "symbol": [ "QMediaRecorder", "private", "", "public"] }, + { "symbol": [ "QMediaTimeRange", "private", "", "public"] }, + { "symbol": [ "QMenu", "private", "", "public"] }, + { "symbol": [ "QMenuBar", "private", "", "public"] }, + { "symbol": [ "QMessageAuthenticationCode", "private", "", "public"] }, + { "symbol": [ "QMessageBox", "private", "", "public"] }, + { "symbol": [ "QMessageLogContext", "private", "", "public"] }, + { "symbol": [ "QMessageLogger", "private", "", "public"] }, + { "symbol": [ "QMetaAssociation", "private", "", "public"] }, + { "symbol": [ "QMetaClassInfo", "private", "", "public"] }, + { "symbol": [ "QMetaContainer", "private", "", "public"] }, + { "symbol": [ "QMetaEnum", "private", "", "public"] }, + { "symbol": [ "QMetaMethod", "private", "", "public"] }, + { "symbol": [ "QMetaMethodArgument", "private", "", "public"] }, + { "symbol": [ "QMetaMethodReturnArgument", "private", "", "public"] }, + { "symbol": [ "QMetaObject", "private", "", "public"] }, + { "symbol": [ "QMetaProperty", "private", "", "public"] }, + { "symbol": [ "QMetaSequence", "private", "", "public"] }, + { "symbol": [ "QMetaType", "private", "", "public"] }, + { "symbol": [ "QMetaTypeId", "private", "", "public"] }, + { "symbol": [ "QMetaTypeId2", "private", "", "public"] }, + { "symbol": [ "QMetaTypeIdQObject", "private", "", "public"] }, + { "symbol": [ "QMethodRawArguments", "private", "", "public"] }, + { "symbol": [ "QMimeData", "private", "", "public"] }, + { "symbol": [ "QMimeDatabase", "private", "", "public"] }, + { "symbol": [ "QMimeType", "private", "", "public"] }, + { "symbol": [ "QModelIndex", "private", "", "public"] }, + { "symbol": [ "QModelIndexList", "private", "", "public"] }, + { "symbol": [ "QModelRoleData", "private", "", "public"] }, + { "symbol": [ "QModelRoleDataSpan", "private", "", "public"] }, + { "symbol": [ "QMouseEvent", "private", "", "public"] }, + { "symbol": [ "QMouseEventTransition", "private", "", "public"] }, + { "symbol": [ "QMoveEvent", "private", "", "public"] }, + { "symbol": [ "QMovie", "private", "", "public"] }, + { "symbol": [ "QMultiHash", "private", "", "public"] }, + { "symbol": [ "QMultiHashIterator", "private", "", "public"] }, + { "symbol": [ "QMultiMap", "private", "", "public"] }, + { "symbol": [ "QMultiMapIterator", "private", "", "public"] }, + { "symbol": [ "QMutableByteArrayListIterator", "private", "", "public"] }, + { "symbol": [ "QMutableFutureIterator", "private", "", "public"] }, + { "symbol": [ "QMutableHashIterator", "private", "", "public"] }, + { "symbol": [ "QMutableLinkedListIterator", "private", "", "public"] }, + { "symbol": [ "QMutableListIterator", "private", "", "public"] }, + { "symbol": [ "QMutableMapIterator", "private", "", "public"] }, + { "symbol": [ "QMutableMultiHashIterator", "private", "", "public"] }, + { "symbol": [ "QMutableMultiMapIterator", "private", "", "public"] }, + { "symbol": [ "QMutableSetIterator", "private", "", "public"] }, + { "symbol": [ "QMutableVectorIterator", "private", "", "public"] }, + { "symbol": [ "QMutex", "private", "", "public"] }, + { "symbol": [ "QMutexLocker", "private", "", "public"] }, + { "symbol": [ "QNativeGestureEvent", "private", "", "public"] }, + { "symbol": [ "QNativeIpcKey", "private", "", "public"] }, + { "symbol": [ "QNetworkAccessManager", "private", "", "public"] }, + { "symbol": [ "QNetworkAddressEntry", "private", "", "public"] }, + { "symbol": [ "QNetworkCacheMetaData", "private", "", "public"] }, + { "symbol": [ "QNetworkCookie", "private", "", "public"] }, + { "symbol": [ "QNetworkCookieJar", "private", "", "public"] }, + { "symbol": [ "QNetworkDatagram", "private", "", "public"] }, + { "symbol": [ "QNetworkDiskCache", "private", "", "public"] }, + { "symbol": [ "QNetworkInformation", "private", "", "public"] }, + { "symbol": [ "QNetworkInterface", "private", "", "public"] }, + { "symbol": [ "QNetworkProxy", "private", "", "public"] }, + { "symbol": [ "QNetworkProxyFactory", "private", "", "public"] }, + { "symbol": [ "QNetworkProxyQuery", "private", "", "public"] }, + { "symbol": [ "QNetworkReply", "private", "", "public"] }, + { "symbol": [ "QNetworkRequest", "private", "", "public"] }, + { "symbol": [ "QNetworkRequestFactory", "private", "", "public"] }, + { "symbol": [ "QNoDebug", "private", "", "public"] }, + { "symbol": [ "QNtfsPermissionCheckGuard", "private", "", "public"] }, + { "symbol": [ "QOAuth1", "private", "", "public"] }, + { "symbol": [ "QOAuth1Signature", "private", "", "public"] }, + { "symbol": [ "QOAuth2AuthorizationCodeFlow", "private", "", "public"] }, + { "symbol": [ "QOAuth2DeviceAuthorizationFlow", "private", "", "public"] }, + { "symbol": [ "QOAuthHttpServerReplyHandler", "private", "", "public"] }, + { "symbol": [ "QOAuthOobReplyHandler", "private", "", "public"] }, + { "symbol": [ "QOAuthUriSchemeReplyHandler", "private", "", "public"] }, + { "symbol": [ "QObject", "private", "", "public"] }, + { "symbol": [ "QObjectBindableProperty", "private", "", "public"] }, + { "symbol": [ "QObjectCleanupHandler", "private", "", "public"] }, + { "symbol": [ "QObjectComputedProperty", "private", "", "public"] }, + { "symbol": [ "QObjectData", "private", "", "public"] }, + { "symbol": [ "QObjectList", "private", "", "public"] }, + { "symbol": [ "QOcspResponse", "private", "", "public"] }, + { "symbol": [ "QOffscreenSurface", "private", "", "public"] }, + { "symbol": [ "QOpenGLBuffer", "private", "", "public"] }, + { "symbol": [ "QOpenGLContext", "private", "", "public"] }, + { "symbol": [ "QOpenGLContextGroup", "private", "", "public"] }, + { "symbol": [ "QOpenGLDebugLogger", "private", "", "public"] }, + { "symbol": [ "QOpenGLDebugMessage", "private", "", "public"] }, + { "symbol": [ "QOpenGLExtraFunctions", "private", "", "public"] }, + { "symbol": [ "QOpenGLExtraFunctionsPrivate", "private", "", "public"] }, + { "symbol": [ "QOpenGLFramebufferObject", "private", "", "public"] }, + { "symbol": [ "QOpenGLFramebufferObjectFormat", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctionsPrivate", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_1_0", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_1_1", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_1_2", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_1_3", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_1_4", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_1_5", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_2_0", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_2_1", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_3_0", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_3_1", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_3_2_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_3_2_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_3_3_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_3_3_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_0_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_0_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_1_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_1_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_2_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_2_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_3_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_3_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_4_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_4_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_5_Compatibility", "private", "", "public"] }, + { "symbol": [ "QOpenGLFunctions_4_5_Core", "private", "", "public"] }, + { "symbol": [ "QOpenGLPaintDevice", "private", "", "public"] }, + { "symbol": [ "QOpenGLPixelTransferOptions", "private", "", "public"] }, + { "symbol": [ "QOpenGLShader", "private", "", "public"] }, + { "symbol": [ "QOpenGLShaderProgram", "private", "", "public"] }, + { "symbol": [ "QOpenGLTexture", "private", "", "public"] }, + { "symbol": [ "QOpenGLTextureBlitter", "private", "", "public"] }, + { "symbol": [ "QOpenGLTimeMonitor", "private", "", "public"] }, + { "symbol": [ "QOpenGLTimerQuery", "private", "", "public"] }, + { "symbol": [ "QOpenGLVersionFunctions", "private", "", "public"] }, + { "symbol": [ "QOpenGLVersionFunctionsFactory", "private", "", "public"] }, + { "symbol": [ "QOpenGLVersionProfile", "private", "", "public"] }, + { "symbol": [ "QOpenGLVertexArrayObject", "private", "", "public"] }, + { "symbol": [ "QOpenGLWidget", "private", "", "public"] }, + { "symbol": [ "QOpenGLWindow", "private", "", "public"] }, + { "symbol": [ "QOperatingSystemVersion", "private", "", "public"] }, + { "symbol": [ "QOperatingSystemVersionBase", "private", "", "public"] }, + { "symbol": [ "QOperatingSystemVersionUnexported", "private", "", "public"] }, + { "symbol": [ "QPageLayout", "private", "", "public"] }, + { "symbol": [ "QPageRanges", "private", "", "public"] }, + { "symbol": [ "QPageSetupDialog", "private", "", "public"] }, + { "symbol": [ "QPageSize", "private", "", "public"] }, + { "symbol": [ "QPagedPaintDevice", "private", "", "public"] }, + { "symbol": [ "QPaintDevice", "private", "", "public"] }, + { "symbol": [ "QPaintDeviceWindow", "private", "", "public"] }, + { "symbol": [ "QPaintEngine", "private", "", "public"] }, + { "symbol": [ "QPaintEngineState", "private", "", "public"] }, + { "symbol": [ "QPaintEvent", "private", "", "public"] }, + { "symbol": [ "QPainter", "private", "", "public"] }, + { "symbol": [ "QPainterPath", "private", "", "public"] }, + { "symbol": [ "QPainterPathStroker", "private", "", "public"] }, + { "symbol": [ "QPainterStateGuard", "private", "", "public"] }, + { "symbol": [ "QPair", "private", "", "public"] }, + { "symbol": [ "QPalette", "private", "", "public"] }, + { "symbol": [ "QPanGesture", "private", "", "public"] }, + { "symbol": [ "QParallelAnimationGroup", "private", "", "public"] }, + { "symbol": [ "QPartialOrdering", "private", "", "public"] }, + { "symbol": [ "QPasswordDigestor", "private", "", "public"] }, + { "symbol": [ "QPauseAnimation", "private", "", "public"] }, + { "symbol": [ "QPdfBookmarkModel", "private", "", "public"] }, + { "symbol": [ "QPdfDocument", "private", "", "public"] }, + { "symbol": [ "QPdfDocumentRenderOptions", "private", "", "public"] }, + { "symbol": [ "QPdfLink", "private", "", "public"] }, + { "symbol": [ "QPdfLinkModel", "private", "", "public"] }, + { "symbol": [ "QPdfOutputIntent", "private", "", "public"] }, + { "symbol": [ "QPdfPageNavigator", "private", "", "public"] }, + { "symbol": [ "QPdfPageRenderer", "private", "", "public"] }, + { "symbol": [ "QPdfPageSelector", "private", "", "public"] }, + { "symbol": [ "QPdfSearchModel", "private", "", "public"] }, + { "symbol": [ "QPdfSelection", "private", "", "public"] }, + { "symbol": [ "QPdfView", "private", "", "public"] }, + { "symbol": [ "QPdfWriter", "private", "", "public"] }, + { "symbol": [ "QPen", "private", "", "public"] }, + { "symbol": [ "QPermission", "private", "", "public"] }, + { "symbol": [ "QPermissions", "private", "", "public"] }, + { "symbol": [ "QPersistentModelIndex", "private", "", "public"] }, + { "symbol": [ "QPicture", "private", "", "public"] }, + { "symbol": [ "QPinchGesture", "private", "", "public"] }, + { "symbol": [ "QPixelFormat", "private", "", "public"] }, + { "symbol": [ "QPixmap", "private", "", "public"] }, + { "symbol": [ "QPixmapCache", "private", "", "public"] }, + { "symbol": [ "QPlainTextDocumentLayout", "private", "", "public"] }, + { "symbol": [ "QPlainTextEdit", "private", "", "public"] }, + { "symbol": [ "QPlatformSurfaceEvent", "private", "", "public"] }, + { "symbol": [ "QPlaybackOptions", "private", "", "public"] }, + { "symbol": [ "QPluginLoader", "private", "", "public"] }, + { "symbol": [ "QPluginMetaData", "private", "", "public"] }, + { "symbol": [ "QPluginMetaDataV2", "private", "", "public"] }, + { "symbol": [ "QPoint", "private", "", "public"] }, + { "symbol": [ "QPointF", "private", "", "public"] }, + { "symbol": [ "QPointer", "private", "", "public"] }, + { "symbol": [ "QPointerEvent", "private", "", "public"] }, + { "symbol": [ "QPointingDevice", "private", "", "public"] }, + { "symbol": [ "QPointingDeviceUniqueId", "private", "", "public"] }, + { "symbol": [ "QPolygon", "private", "", "public"] }, + { "symbol": [ "QPolygonF", "private", "", "public"] }, + { "symbol": [ "QPrintDialog", "private", "", "public"] }, + { "symbol": [ "QPrintEngine", "private", "", "public"] }, + { "symbol": [ "QPrintPreviewDialog", "private", "", "public"] }, + { "symbol": [ "QPrintPreviewWidget", "private", "", "public"] }, + { "symbol": [ "QPrinter", "private", "", "public"] }, + { "symbol": [ "QPrinterInfo", "private", "", "public"] }, + { "symbol": [ "QProcess", "private", "", "public"] }, + { "symbol": [ "QProcessEnvironment", "private", "", "public"] }, + { "symbol": [ "QProgressBar", "private", "", "public"] }, + { "symbol": [ "QProgressDialog", "private", "", "public"] }, + { "symbol": [ "QPromise", "private", "", "public"] }, + { "symbol": [ "QProperty", "private", "", "public"] }, + { "symbol": [ "QPropertyAnimation", "private", "", "public"] }, + { "symbol": [ "QPropertyBinding", "private", "", "public"] }, + { "symbol": [ "QPropertyBindingError", "private", "", "public"] }, + { "symbol": [ "QPropertyBindingPrivatePtr", "private", "", "public"] }, + { "symbol": [ "QPropertyBindingSourceLocation", "private", "", "public"] }, + { "symbol": [ "QPropertyChangeHandler", "private", "", "public"] }, + { "symbol": [ "QPropertyData", "private", "", "public"] }, + { "symbol": [ "QPropertyNotifier", "private", "", "public"] }, + { "symbol": [ "QPropertyObserver", "private", "", "public"] }, + { "symbol": [ "QPropertyObserverBase", "private", "", "public"] }, + { "symbol": [ "QPropertyProxyBindingData", "private", "", "public"] }, + { "symbol": [ "QProxyStyle", "private", "", "public"] }, + { "symbol": [ "QPushButton", "private", "", "public"] }, + { "symbol": [ "QQmlAbstractUrlInterceptor", "private", "", "public"] }, + { "symbol": [ "QQmlApplicationEngine", "private", "", "public"] }, + { "symbol": [ "QQmlComponent", "private", "", "public"] }, + { "symbol": [ "QQmlContext", "private", "", "public"] }, + { "symbol": [ "QQmlDebuggingEnabler", "private", "", "public"] }, + { "symbol": [ "QQmlEngine", "private", "", "public"] }, + { "symbol": [ "QQmlEngineExtensionInterface", "private", "", "public"] }, + { "symbol": [ "QQmlEngineExtensionPlugin", "private", "", "public"] }, + { "symbol": [ "QQmlError", "private", "", "public"] }, + { "symbol": [ "QQmlExpression", "private", "", "public"] }, + { "symbol": [ "QQmlExtensionInterface", "private", "", "public"] }, + { "symbol": [ "QQmlExtensionPlugin", "private", "", "public"] }, + { "symbol": [ "QQmlFile", "private", "", "public"] }, + { "symbol": [ "QQmlFileSelector", "private", "", "public"] }, + { "symbol": [ "QQmlImageProviderBase", "private", "", "public"] }, + { "symbol": [ "QQmlIncubationController", "private", "", "public"] }, + { "symbol": [ "QQmlIncubator", "private", "", "public"] }, + { "symbol": [ "QQmlInfo", "private", "", "public"] }, + { "symbol": [ "QQmlListProperty", "private", "", "public"] }, + { "symbol": [ "QQmlListReference", "private", "", "public"] }, + { "symbol": [ "QQmlModuleRegistration", "private", "", "public"] }, + { "symbol": [ "QQmlNetworkAccessManagerFactory", "private", "", "public"] }, + { "symbol": [ "QQmlParserStatus", "private", "", "public"] }, + { "symbol": [ "QQmlProperties", "private", "", "public"] }, + { "symbol": [ "QQmlProperty", "private", "", "public"] }, + { "symbol": [ "QQmlPropertyMap", "private", "", "public"] }, + { "symbol": [ "QQmlPropertyValueSource", "private", "", "public"] }, + { "symbol": [ "QQmlScriptString", "private", "", "public"] }, + { "symbol": [ "QQmlTypeInfo", "private", "", "public"] }, + { "symbol": [ "QQmlTypeNotAvailable", "private", "", "public"] }, + { "symbol": [ "QQmlTypesExtensionInterface", "private", "", "public"] }, + { "symbol": [ "QQmlWebChannel", "private", "", "public"] }, + { "symbol": [ "QQuaternion", "private", "", "public"] }, + { "symbol": [ "QQueue", "private", "", "public"] }, + { "symbol": [ "QQuick3D", "private", "", "public"] }, + { "symbol": [ "QQuick3DGeometry", "private", "", "public"] }, + { "symbol": [ "QQuick3DInstancing", "private", "", "public"] }, + { "symbol": [ "QQuick3DObject", "private", "", "public"] }, + { "symbol": [ "QQuick3DRenderExtension", "private", "", "public"] }, + { "symbol": [ "QQuick3DTextureData", "private", "", "public"] }, + { "symbol": [ "QQuick3DTextureProviderExtension", "private", "", "public"] }, + { "symbol": [ "QQuickAsyncImageProvider", "private", "", "public"] }, + { "symbol": [ "QQuickAttachedPropertyPropagator", "private", "", "public"] }, + { "symbol": [ "QQuickFramebufferObject", "private", "", "public"] }, + { "symbol": [ "QQuickGraphicsConfiguration", "private", "", "public"] }, + { "symbol": [ "QQuickGraphicsDevice", "private", "", "public"] }, + { "symbol": [ "QQuickImageProvider", "private", "", "public"] }, + { "symbol": [ "QQuickImageResponse", "private", "", "public"] }, + { "symbol": [ "QQuickItem", "private", "", "public"] }, + { "symbol": [ "QQuickItemGrabResult", "private", "", "public"] }, + { "symbol": [ "QQuickOpenGLUtils", "private", "", "public"] }, + { "symbol": [ "QQuickPaintedItem", "private", "", "public"] }, + { "symbol": [ "QQuickRenderControl", "private", "", "public"] }, + { "symbol": [ "QQuickRenderTarget", "private", "", "public"] }, + { "symbol": [ "QQuickRhiItem", "private", "", "public"] }, + { "symbol": [ "QQuickRhiItemRenderer", "private", "", "public"] }, + { "symbol": [ "QQuickStyle", "private", "", "public"] }, + { "symbol": [ "QQuickTextDocument", "private", "", "public"] }, + { "symbol": [ "QQuickTextureFactory", "private", "", "public"] }, + { "symbol": [ "QQuickTransform", "private", "", "public"] }, + { "symbol": [ "QQuickView", "private", "", "public"] }, + { "symbol": [ "QQuickWebEngineDownloadRequest", "private", "", "public"] }, + { "symbol": [ "QQuickWebEngineProfile", "private", "", "public"] }, + { "symbol": [ "QQuickWidget", "private", "", "public"] }, + { "symbol": [ "QQuickWindow", "private", "", "public"] }, + { "symbol": [ "QRadialGradient", "private", "", "public"] }, + { "symbol": [ "QRadioButton", "private", "", "public"] }, + { "symbol": [ "QRandomGenerator", "private", "", "public"] }, + { "symbol": [ "QRandomGenerator64", "private", "", "public"] }, + { "symbol": [ "QRangeModel", "private", "", "public"] }, + { "symbol": [ "QRangeModelAdapter", "private", "", "public"] }, + { "symbol": [ "QRasterWindow", "private", "", "public"] }, + { "symbol": [ "QRawFont", "private", "", "public"] }, + { "symbol": [ "QReadLocker", "private", "", "public"] }, + { "symbol": [ "QReadWriteLock", "private", "", "public"] }, + { "symbol": [ "QRect", "private", "", "public"] }, + { "symbol": [ "QRectF", "private", "", "public"] }, + { "symbol": [ "QRecursiveMutex", "private", "", "public"] }, + { "symbol": [ "QRegExp", "private", "", "public"] }, + { "symbol": [ "QRegion", "private", "", "public"] }, + { "symbol": [ "QRegularExpression", "private", "", "public"] }, + { "symbol": [ "QRegularExpressionMatch", "private", "", "public"] }, + { "symbol": [ "QRegularExpressionMatchIterator", "private", "", "public"] }, + { "symbol": [ "QRegularExpressionValidator", "private", "", "public"] }, + { "symbol": [ "QResizeEvent", "private", "", "public"] }, + { "symbol": [ "QResource", "private", "", "public"] }, + { "symbol": [ "QRestAccessManager", "private", "", "public"] }, + { "symbol": [ "QRestReply", "private", "", "public"] }, + { "symbol": [ "QReturnArgument", "private", "", "public"] }, + { "symbol": [ "QRgb", "private", "", "public"] }, + { "symbol": [ "QRgba64", "private", "", "public"] }, + { "symbol": [ "QRgbaFloat", "private", "", "public"] }, + { "symbol": [ "QRgbaFloat16", "private", "", "public"] }, + { "symbol": [ "QRgbaFloat32", "private", "", "public"] }, + { "symbol": [ "QRhiWidget", "private", "", "public"] }, + { "symbol": [ "QRubberBand", "private", "", "public"] }, + { "symbol": [ "QRunnable", "private", "", "public"] }, + { "symbol": [ "QSGBasicGeometryNode", "private", "", "public"] }, + { "symbol": [ "QSGClipNode", "private", "", "public"] }, + { "symbol": [ "QSGDynamicTexture", "private", "", "public"] }, + { "symbol": [ "QSGFlatColorMaterial", "private", "", "public"] }, + { "symbol": [ "QSGGeometry", "private", "", "public"] }, + { "symbol": [ "QSGGeometryNode", "private", "", "public"] }, + { "symbol": [ "QSGImageNode", "private", "", "public"] }, + { "symbol": [ "QSGMaterial", "private", "", "public"] }, + { "symbol": [ "QSGMaterialShader", "private", "", "public"] }, + { "symbol": [ "QSGNinePatchNode", "private", "", "public"] }, + { "symbol": [ "QSGNode", "private", "", "public"] }, + { "symbol": [ "QSGNodeVisitor", "private", "", "public"] }, + { "symbol": [ "QSGOpacityNode", "private", "", "public"] }, + { "symbol": [ "QSGOpaqueTextureMaterial", "private", "", "public"] }, + { "symbol": [ "QSGRectangleNode", "private", "", "public"] }, + { "symbol": [ "QSGRenderNode", "private", "", "public"] }, + { "symbol": [ "QSGRendererInterface", "private", "", "public"] }, + { "symbol": [ "QSGRootNode", "private", "", "public"] }, + { "symbol": [ "QSGSimpleRectNode", "private", "", "public"] }, + { "symbol": [ "QSGSimpleTextureNode", "private", "", "public"] }, + { "symbol": [ "QSGTextNode", "private", "", "public"] }, + { "symbol": [ "QSGTexture", "private", "", "public"] }, + { "symbol": [ "QSGTextureMaterial", "private", "", "public"] }, + { "symbol": [ "QSGTextureProvider", "private", "", "public"] }, + { "symbol": [ "QSGTransformNode", "private", "", "public"] }, + { "symbol": [ "QSGVertexColorMaterial", "private", "", "public"] }, + { "symbol": [ "QSaveFile", "private", "", "public"] }, + { "symbol": [ "QScopeGuard", "private", "", "public"] }, + { "symbol": [ "QScopedArrayPointer", "private", "", "public"] }, + { "symbol": [ "QScopedPointer", "private", "", "public"] }, + { "symbol": [ "QScopedPointerArrayDeleter", "private", "", "public"] }, + { "symbol": [ "QScopedPointerDeleteLater", "private", "", "public"] }, + { "symbol": [ "QScopedPointerDeleter", "private", "", "public"] }, + { "symbol": [ "QScopedPointerObjectDeleteLater", "private", "", "public"] }, + { "symbol": [ "QScopedPointerPodDeleter", "private", "", "public"] }, + { "symbol": [ "QScopedPropertyUpdateGroup", "private", "", "public"] }, + { "symbol": [ "QScopedValueRollback", "private", "", "public"] }, + { "symbol": [ "QScreen", "private", "", "public"] }, + { "symbol": [ "QScreenCapture", "private", "", "public"] }, + { "symbol": [ "QScreenOrientationChangeEvent", "private", "", "public"] }, + { "symbol": [ "QScrollArea", "private", "", "public"] }, + { "symbol": [ "QScrollBar", "private", "", "public"] }, + { "symbol": [ "QScrollEvent", "private", "", "public"] }, + { "symbol": [ "QScrollPrepareEvent", "private", "", "public"] }, + { "symbol": [ "QScroller", "private", "", "public"] }, + { "symbol": [ "QScrollerProperties", "private", "", "public"] }, + { "symbol": [ "QScxmlCompiler", "private", "", "public"] }, + { "symbol": [ "QScxmlCppDataModel", "private", "", "public"] }, + { "symbol": [ "QScxmlDataModel", "private", "", "public"] }, + { "symbol": [ "QScxmlDynamicScxmlServiceFactory", "private", "", "public"] }, + { "symbol": [ "QScxmlError", "private", "", "public"] }, + { "symbol": [ "QScxmlEvent", "private", "", "public"] }, + { "symbol": [ "QScxmlInvokableService", "private", "", "public"] }, + { "symbol": [ "QScxmlInvokableServiceFactory", "private", "", "public"] }, + { "symbol": [ "QScxmlNullDataModel", "private", "", "public"] }, + { "symbol": [ "QScxmlStateMachine", "private", "", "public"] }, + { "symbol": [ "QScxmlStaticScxmlServiceFactory", "private", "", "public"] }, + { "symbol": [ "QScxmlTableData", "private", "", "public"] }, + { "symbol": [ "QSemaphore", "private", "", "public"] }, + { "symbol": [ "QSemaphoreReleaser", "private", "", "public"] }, + { "symbol": [ "QSequentialAnimationGroup", "private", "", "public"] }, + { "symbol": [ "QSequentialConstIterator", "private", "", "public"] }, + { "symbol": [ "QSequentialIterable", "private", "", "public"] }, + { "symbol": [ "QSequentialIterator", "private", "", "public"] }, + { "symbol": [ "QSessionManager", "private", "", "public"] }, + { "symbol": [ "QSet", "private", "", "public"] }, + { "symbol": [ "QSetIterator", "private", "", "public"] }, + { "symbol": [ "QSettings", "private", "", "public"] }, + { "symbol": [ "QSharedData", "private", "", "public"] }, + { "symbol": [ "QSharedDataPointer", "private", "", "public"] }, + { "symbol": [ "QSharedDataPointerBase", "private", "", "public"] }, + { "symbol": [ "QSharedMemory", "private", "", "public"] }, + { "symbol": [ "QSharedPointer", "private", "", "public"] }, + { "symbol": [ "QShortcut", "private", "", "public"] }, + { "symbol": [ "QShortcutEvent", "private", "", "public"] }, + { "symbol": [ "QShowEvent", "private", "", "public"] }, + { "symbol": [ "QSignalBlocker", "private", "", "public"] }, + { "symbol": [ "QSignalMapper", "private", "", "public"] }, + { "symbol": [ "QSignalSpy", "private", "", "public"] }, + { "symbol": [ "QSignalTransition", "private", "", "public"] }, + { "symbol": [ "QSinglePointEvent", "private", "", "public"] }, + { "symbol": [ "QSize", "private", "", "public"] }, + { "symbol": [ "QSizeF", "private", "", "public"] }, + { "symbol": [ "QSizeGrip", "private", "", "public"] }, + { "symbol": [ "QSizePolicy", "private", "", "public"] }, + { "symbol": [ "QSlider", "private", "", "public"] }, + { "symbol": [ "QSocketDescriptor", "private", "", "public"] }, + { "symbol": [ "QSocketNotifier", "private", "", "public"] }, + { "symbol": [ "QSortFilterProxyModel", "private", "", "public"] }, + { "symbol": [ "QSoundEffect", "private", "", "public"] }, + { "symbol": [ "QSpacerItem", "private", "", "public"] }, + { "symbol": [ "QSpan", "private", "", "public"] }, + { "symbol": [ "QSpatialSound", "private", "", "public"] }, + { "symbol": [ "QSpecialInteger", "private", "", "public"] }, + { "symbol": [ "QSpinBox", "private", "", "public"] }, + { "symbol": [ "QSplashScreen", "private", "", "public"] }, + { "symbol": [ "QSplitter", "private", "", "public"] }, + { "symbol": [ "QSplitterHandle", "private", "", "public"] }, + { "symbol": [ "QSpontaneKeyEvent", "private", "", "public"] }, + { "symbol": [ "QSql", "private", "", "public"] }, + { "symbol": [ "QSqlDatabase", "private", "", "public"] }, + { "symbol": [ "QSqlDatabaseDefaultConnectionName", "private", "", "public"] }, + { "symbol": [ "QSqlDriver", "private", "", "public"] }, + { "symbol": [ "QSqlDriverCreator", "private", "", "public"] }, + { "symbol": [ "QSqlDriverCreatorBase", "private", "", "public"] }, + { "symbol": [ "QSqlDriverPlugin", "private", "", "public"] }, + { "symbol": [ "QSqlError", "private", "", "public"] }, + { "symbol": [ "QSqlField", "private", "", "public"] }, + { "symbol": [ "QSqlIndex", "private", "", "public"] }, + { "symbol": [ "QSqlQuery", "private", "", "public"] }, + { "symbol": [ "QSqlQueryModel", "private", "", "public"] }, + { "symbol": [ "QSqlRecord", "private", "", "public"] }, + { "symbol": [ "QSqlRelation", "private", "", "public"] }, + { "symbol": [ "QSqlRelationalDelegate", "private", "", "public"] }, + { "symbol": [ "QSqlRelationalTableModel", "private", "", "public"] }, + { "symbol": [ "QSqlResult", "private", "", "public"] }, + { "symbol": [ "QSqlTableModel", "private", "", "public"] }, + { "symbol": [ "QSsl", "private", "", "public"] }, + { "symbol": [ "QSslCertificate", "private", "", "public"] }, + { "symbol": [ "QSslCertificateExtension", "private", "", "public"] }, + { "symbol": [ "QSslCipher", "private", "", "public"] }, + { "symbol": [ "QSslConfiguration", "private", "", "public"] }, + { "symbol": [ "QSslDiffieHellmanParameters", "private", "", "public"] }, + { "symbol": [ "QSslEllipticCurve", "private", "", "public"] }, + { "symbol": [ "QSslError", "private", "", "public"] }, + { "symbol": [ "QSslKey", "private", "", "public"] }, + { "symbol": [ "QSslPreSharedKeyAuthenticator", "private", "", "public"] }, + { "symbol": [ "QSslServer", "private", "", "public"] }, + { "symbol": [ "QSslSocket", "private", "", "public"] }, + { "symbol": [ "QStack", "private", "", "public"] }, + { "symbol": [ "QStackedLayout", "private", "", "public"] }, + { "symbol": [ "QStackedWidget", "private", "", "public"] }, + { "symbol": [ "QStandardItem", "private", "", "public"] }, + { "symbol": [ "QStandardItemEditorCreator", "private", "", "public"] }, + { "symbol": [ "QStandardItemModel", "private", "", "public"] }, + { "symbol": [ "QStandardPaths", "private", "", "public"] }, + { "symbol": [ "QState", "private", "", "public"] }, + { "symbol": [ "QStateMachine", "private", "", "public"] }, + { "symbol": [ "QStaticByteArrayMatcher", "private", "", "public"] }, + { "symbol": [ "QStaticByteArrayMatcherBase", "private", "", "public"] }, + { "symbol": [ "QStaticLatin1StringMatcher", "private", "", "public"] }, + { "symbol": [ "QStaticPlugin", "private", "", "public"] }, + { "symbol": [ "QStaticText", "private", "", "public"] }, + { "symbol": [ "QStatusBar", "private", "", "public"] }, + { "symbol": [ "QStatusTipEvent", "private", "", "public"] }, + { "symbol": [ "QStorageInfo", "private", "", "public"] }, + { "symbol": [ "QString", "private", "", "public"] }, + { "symbol": [ "QStringAlgorithms", "private", "", "public"] }, + { "symbol": [ "QStringBuilder", "private", "", "public"] }, + { "symbol": [ "QStringConverter", "private", "", "public"] }, + { "symbol": [ "QStringConverterBase", "private", "", "public"] }, + { "symbol": [ "QStringDecoder", "private", "", "public"] }, + { "symbol": [ "QStringEncoder", "private", "", "public"] }, + { "symbol": [ "QStringList", "private", "", "public"] }, + { "symbol": [ "QStringListModel", "private", "", "public"] }, + { "symbol": [ "QStringLiteral", "private", "", "public"] }, + { "symbol": [ "QStringMatcher", "private", "", "public"] }, + { "symbol": [ "QStringRef", "private", "", "public"] }, + { "symbol": [ "QStringTokenizer", "private", "", "public"] }, + { "symbol": [ "QStringTokenizerBase", "private", "", "public"] }, + { "symbol": [ "QStringTokenizerBaseBase", "private", "", "public"] }, + { "symbol": [ "QStringView", "private", "", "public"] }, + { "symbol": [ "QStyle", "private", "", "public"] }, + { "symbol": [ "QStyleFactory", "private", "", "public"] }, + { "symbol": [ "QStyleHintReturn", "private", "", "public"] }, + { "symbol": [ "QStyleHintReturnMask", "private", "", "public"] }, + { "symbol": [ "QStyleHintReturnVariant", "private", "", "public"] }, + { "symbol": [ "QStyleHints", "private", "", "public"] }, + { "symbol": [ "QStyleOption", "private", "", "public"] }, + { "symbol": [ "QStyleOptionButton", "private", "", "public"] }, + { "symbol": [ "QStyleOptionComboBox", "private", "", "public"] }, + { "symbol": [ "QStyleOptionComplex", "private", "", "public"] }, + { "symbol": [ "QStyleOptionDockWidget", "private", "", "public"] }, + { "symbol": [ "QStyleOptionFocusRect", "private", "", "public"] }, + { "symbol": [ "QStyleOptionFrame", "private", "", "public"] }, + { "symbol": [ "QStyleOptionGraphicsItem", "private", "", "public"] }, + { "symbol": [ "QStyleOptionGroupBox", "private", "", "public"] }, + { "symbol": [ "QStyleOptionHeader", "private", "", "public"] }, + { "symbol": [ "QStyleOptionHeaderV2", "private", "", "public"] }, + { "symbol": [ "QStyleOptionMenuItem", "private", "", "public"] }, + { "symbol": [ "QStyleOptionMenuItemV2", "private", "", "public"] }, + { "symbol": [ "QStyleOptionProgressBar", "private", "", "public"] }, + { "symbol": [ "QStyleOptionRubberBand", "private", "", "public"] }, + { "symbol": [ "QStyleOptionSizeGrip", "private", "", "public"] }, + { "symbol": [ "QStyleOptionSlider", "private", "", "public"] }, + { "symbol": [ "QStyleOptionSpinBox", "private", "", "public"] }, + { "symbol": [ "QStyleOptionTab", "private", "", "public"] }, + { "symbol": [ "QStyleOptionTabBarBase", "private", "", "public"] }, + { "symbol": [ "QStyleOptionTabWidgetFrame", "private", "", "public"] }, + { "symbol": [ "QStyleOptionTitleBar", "private", "", "public"] }, + { "symbol": [ "QStyleOptionToolBar", "private", "", "public"] }, + { "symbol": [ "QStyleOptionToolBox", "private", "", "public"] }, + { "symbol": [ "QStyleOptionToolButton", "private", "", "public"] }, + { "symbol": [ "QStyleOptionViewItem", "private", "", "public"] }, + { "symbol": [ "QStylePainter", "private", "", "public"] }, + { "symbol": [ "QStylePlugin", "private", "", "public"] }, + { "symbol": [ "QStyledItemDelegate", "private", "", "public"] }, + { "symbol": [ "QSurface", "private", "", "public"] }, + { "symbol": [ "QSurfaceFormat", "private", "", "public"] }, + { "symbol": [ "QSvgGenerator", "private", "", "public"] }, + { "symbol": [ "QSvgRenderer", "private", "", "public"] }, + { "symbol": [ "QSvgWidget", "private", "", "public"] }, + { "symbol": [ "QSwipeGesture", "private", "", "public"] }, + { "symbol": [ "QSyntaxHighlighter", "private", "", "public"] }, + { "symbol": [ "QSysInfo", "private", "", "public"] }, + { "symbol": [ "QSystemSemaphore", "private", "", "public"] }, + { "symbol": [ "QSystemTrayIcon", "private", "", "public"] }, + { "symbol": [ "QTabBar", "private", "", "public"] }, + { "symbol": [ "QTabWidget", "private", "", "public"] }, + { "symbol": [ "QTableView", "private", "", "public"] }, + { "symbol": [ "QTableWidget", "private", "", "public"] }, + { "symbol": [ "QTableWidgetItem", "private", "", "public"] }, + { "symbol": [ "QTableWidgetSelectionRange", "private", "", "public"] }, + { "symbol": [ "QTabletEvent", "private", "", "public"] }, + { "symbol": [ "QTaggedIterator", "private", "", "public"] }, + { "symbol": [ "QTaggedPointer", "private", "", "public"] }, + { "symbol": [ "QTapAndHoldGesture", "private", "", "public"] }, + { "symbol": [ "QTapGesture", "private", "", "public"] }, + { "symbol": [ "QTcpServer", "private", "", "public"] }, + { "symbol": [ "QTcpSocket", "private", "", "public"] }, + { "symbol": [ "QTemplatedMetaMethodReturnArgument", "private", "", "public"] }, + { "symbol": [ "QTemporaryDir", "private", "", "public"] }, + { "symbol": [ "QTemporaryFile", "private", "", "public"] }, + { "symbol": [ "QTest", "private", "", "public"] }, + { "symbol": [ "QTestAccessibility", "private", "", "public"] }, + { "symbol": [ "QTestData", "private", "", "public"] }, + { "symbol": [ "QTestDelayEvent", "private", "", "public"] }, + { "symbol": [ "QTestEvent", "private", "", "public"] }, + { "symbol": [ "QTestEventList", "private", "", "public"] }, + { "symbol": [ "QTestEventLoop", "private", "", "public"] }, + { "symbol": [ "QTestKeyClicksEvent", "private", "", "public"] }, + { "symbol": [ "QTestKeyEvent", "private", "", "public"] }, + { "symbol": [ "QTestMouseEvent", "private", "", "public"] }, + { "symbol": [ "QTextBlock", "private", "", "public"] }, + { "symbol": [ "QTextBlockFormat", "private", "", "public"] }, + { "symbol": [ "QTextBlockGroup", "private", "", "public"] }, + { "symbol": [ "QTextBlockUserData", "private", "", "public"] }, + { "symbol": [ "QTextBoundaryFinder", "private", "", "public"] }, + { "symbol": [ "QTextBrowser", "private", "", "public"] }, + { "symbol": [ "QTextCharFormat", "private", "", "public"] }, + { "symbol": [ "QTextCodec", "private", "", "public"] }, + { "symbol": [ "QTextCursor", "private", "", "public"] }, + { "symbol": [ "QTextDecoder", "private", "", "public"] }, + { "symbol": [ "QTextDocument", "private", "", "public"] }, + { "symbol": [ "QTextDocumentFragment", "private", "", "public"] }, + { "symbol": [ "QTextDocumentWriter", "private", "", "public"] }, + { "symbol": [ "QTextEdit", "private", "", "public"] }, + { "symbol": [ "QTextEncoder", "private", "", "public"] }, + { "symbol": [ "QTextFormat", "private", "", "public"] }, + { "symbol": [ "QTextFragment", "private", "", "public"] }, + { "symbol": [ "QTextFrame", "private", "", "public"] }, + { "symbol": [ "QTextFrameFormat", "private", "", "public"] }, + { "symbol": [ "QTextFrameLayoutData", "private", "", "public"] }, + { "symbol": [ "QTextImageFormat", "private", "", "public"] }, + { "symbol": [ "QTextInlineObject", "private", "", "public"] }, + { "symbol": [ "QTextItem", "private", "", "public"] }, + { "symbol": [ "QTextLayout", "private", "", "public"] }, + { "symbol": [ "QTextLength", "private", "", "public"] }, + { "symbol": [ "QTextLine", "private", "", "public"] }, + { "symbol": [ "QTextList", "private", "", "public"] }, + { "symbol": [ "QTextListFormat", "private", "", "public"] }, + { "symbol": [ "QTextObject", "private", "", "public"] }, + { "symbol": [ "QTextObjectInterface", "private", "", "public"] }, + { "symbol": [ "QTextOption", "private", "", "public"] }, + { "symbol": [ "QTextStream", "private", "", "public"] }, + { "symbol": [ "QTextStreamFunction", "private", "", "public"] }, + { "symbol": [ "QTextStreamManipulator", "private", "", "public"] }, + { "symbol": [ "QTextTable", "private", "", "public"] }, + { "symbol": [ "QTextTableCell", "private", "", "public"] }, + { "symbol": [ "QTextTableCellFormat", "private", "", "public"] }, + { "symbol": [ "QTextTableFormat", "private", "", "public"] }, + { "symbol": [ "QThread", "private", "", "public"] }, + { "symbol": [ "QThreadPool", "private", "", "public"] }, + { "symbol": [ "QThreadStorage", "private", "", "public"] }, + { "symbol": [ "QThreadStorageData", "private", "", "public"] }, + { "symbol": [ "QThreadStorageTraits", "private", "", "public"] }, + { "symbol": [ "QTileRules", "private", "", "public"] }, + { "symbol": [ "QTime", "private", "", "public"] }, + { "symbol": [ "QTimeEdit", "private", "", "public"] }, + { "symbol": [ "QTimeLine", "private", "", "public"] }, + { "symbol": [ "QTimeZone", "private", "", "public"] }, + { "symbol": [ "QTimer", "private", "", "public"] }, + { "symbol": [ "QTimerEvent", "private", "", "public"] }, + { "symbol": [ "QToolBar", "private", "", "public"] }, + { "symbol": [ "QToolBarChangeEvent", "private", "", "public"] }, + { "symbol": [ "QToolBox", "private", "", "public"] }, + { "symbol": [ "QToolButton", "private", "", "public"] }, + { "symbol": [ "QToolTip", "private", "", "public"] }, + { "symbol": [ "QTouchEvent", "private", "", "public"] }, + { "symbol": [ "QTransform", "private", "", "public"] }, + { "symbol": [ "QTranslator", "private", "", "public"] }, + { "symbol": [ "QTransposeProxyModel", "private", "", "public"] }, + { "symbol": [ "QTreeView", "private", "", "public"] }, + { "symbol": [ "QTreeWidget", "private", "", "public"] }, + { "symbol": [ "QTreeWidgetItem", "private", "", "public"] }, + { "symbol": [ "QTreeWidgetItemIterator", "private", "", "public"] }, + { "symbol": [ "QTypeInfo", "private", "", "public"] }, + { "symbol": [ "QTypeInfoMerger", "private", "", "public"] }, + { "symbol": [ "QTypeRevision", "private", "", "public"] }, + { "symbol": [ "QTypedArrayAllocationResult", "private", "", "public"] }, + { "symbol": [ "QTypedArrayData", "private", "", "public"] }, + { "symbol": [ "QUdpSocket", "private", "", "public"] }, + { "symbol": [ "QUiLoader", "private", "", "public"] }, + { "symbol": [ "QUndoCommand", "private", "", "public"] }, + { "symbol": [ "QUndoGroup", "private", "", "public"] }, + { "symbol": [ "QUndoStack", "private", "", "public"] }, + { "symbol": [ "QUndoView", "private", "", "public"] }, + { "symbol": [ "QUnhandledException", "private", "", "public"] }, + { "symbol": [ "QUntypedBindable", "private", "", "public"] }, + { "symbol": [ "QUntypedPropertyBinding", "private", "", "public"] }, + { "symbol": [ "QUntypedPropertyData", "private", "", "public"] }, + { "symbol": [ "QUrl", "private", "", "public"] }, + { "symbol": [ "QUrlQuery", "private", "", "public"] }, + { "symbol": [ "QUrlTwoFlags", "private", "", "public"] }, + { "symbol": [ "QUtf8StringView", "private", "", "public"] }, + { "symbol": [ "QUuid", "private", "", "public"] }, + { "symbol": [ "QVBoxLayout", "private", "", "public"] }, + { "symbol": [ "QValidator", "private", "", "public"] }, + { "symbol": [ "QVarLengthArray", "private", "", "public"] }, + { "symbol": [ "QVariant", "private", "", "public"] }, + { "symbol": [ "QVariantAnimation", "private", "", "public"] }, + { "symbol": [ "QVariantHash", "private", "", "public"] }, + { "symbol": [ "QVariantList", "private", "", "public"] }, + { "symbol": [ "QVariantMap", "private", "", "public"] }, + { "symbol": [ "QVector", "private", "", "public"] }, + { "symbol": [ "QVector2D", "private", "", "public"] }, + { "symbol": [ "QVector3D", "private", "", "public"] }, + { "symbol": [ "QVector4D", "private", "", "public"] }, + { "symbol": [ "QVectorIterator", "private", "", "public"] }, + { "symbol": [ "QVersionNumber", "private", "", "public"] }, + { "symbol": [ "QVideoFrame", "private", "", "public"] }, + { "symbol": [ "QVideoFrameFormat", "private", "", "public"] }, + { "symbol": [ "QVideoFrameInput", "private", "", "public"] }, + { "symbol": [ "QVideoSink", "private", "", "public"] }, + { "symbol": [ "QVideoWidget", "private", "", "public"] }, + { "symbol": [ "QVulkanDeviceFunctions", "private", "", "public"] }, + { "symbol": [ "QVulkanExtension", "private", "", "public"] }, + { "symbol": [ "QVulkanFunctions", "private", "", "public"] }, + { "symbol": [ "QVulkanInfoVector", "private", "", "public"] }, + { "symbol": [ "QVulkanInstance", "private", "", "public"] }, + { "symbol": [ "QVulkanLayer", "private", "", "public"] }, + { "symbol": [ "QVulkanWindow", "private", "", "public"] }, + { "symbol": [ "QVulkanWindowRenderer", "private", "", "public"] }, + { "symbol": [ "QWaitCondition", "private", "", "public"] }, + { "symbol": [ "QWaveDecoder", "private", "", "public"] }, + { "symbol": [ "QWaylandBufferRef", "private", "", "public"] }, + { "symbol": [ "QWaylandClient", "private", "", "public"] }, + { "symbol": [ "QWaylandClientExtension", "private", "", "public"] }, + { "symbol": [ "QWaylandClientExtensionTemplate", "private", "", "public"] }, + { "symbol": [ "QWaylandCompositor", "private", "", "public"] }, + { "symbol": [ "QWaylandCompositorExtension", "private", "", "public"] }, + { "symbol": [ "QWaylandCompositorExtensionTemplate", "private", "", "public"] }, + { "symbol": [ "QWaylandDestroyListener", "private", "", "public"] }, + { "symbol": [ "QWaylandDrag", "private", "", "public"] }, + { "symbol": [ "QWaylandIdleInhibitManagerV1", "private", "", "public"] }, + { "symbol": [ "QWaylandInputMethodControl", "private", "", "public"] }, + { "symbol": [ "QWaylandIviApplication", "private", "", "public"] }, + { "symbol": [ "QWaylandIviSurface", "private", "", "public"] }, + { "symbol": [ "QWaylandKeyboard", "private", "", "public"] }, + { "symbol": [ "QWaylandKeymap", "private", "", "public"] }, + { "symbol": [ "QWaylandObject", "private", "", "public"] }, + { "symbol": [ "QWaylandOutput", "private", "", "public"] }, + { "symbol": [ "QWaylandOutputMode", "private", "", "public"] }, + { "symbol": [ "QWaylandPointer", "private", "", "public"] }, + { "symbol": [ "QWaylandQtTextInputMethod", "private", "", "public"] }, + { "symbol": [ "QWaylandQtTextInputMethodManager", "private", "", "public"] }, + { "symbol": [ "QWaylandQtWindowManager", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickCompositor", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickExtension", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickItem", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickOutput", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickShellIntegration", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickShellSurfaceItem", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickSurface", "private", "", "public"] }, + { "symbol": [ "QWaylandQuickXdgOutputV1", "private", "", "public"] }, + { "symbol": [ "QWaylandResource", "private", "", "public"] }, + { "symbol": [ "QWaylandSeat", "private", "", "public"] }, + { "symbol": [ "QWaylandShell", "private", "", "public"] }, + { "symbol": [ "QWaylandShellSurface", "private", "", "public"] }, + { "symbol": [ "QWaylandShellSurfaceTemplate", "private", "", "public"] }, + { "symbol": [ "QWaylandShellTemplate", "private", "", "public"] }, + { "symbol": [ "QWaylandSurface", "private", "", "public"] }, + { "symbol": [ "QWaylandSurfaceGrabber", "private", "", "public"] }, + { "symbol": [ "QWaylandSurfaceRole", "private", "", "public"] }, + { "symbol": [ "QWaylandTextInput", "private", "", "public"] }, + { "symbol": [ "QWaylandTextInputManager", "private", "", "public"] }, + { "symbol": [ "QWaylandTextInputManagerV3", "private", "", "public"] }, + { "symbol": [ "QWaylandTextInputV3", "private", "", "public"] }, + { "symbol": [ "QWaylandTouch", "private", "", "public"] }, + { "symbol": [ "QWaylandView", "private", "", "public"] }, + { "symbol": [ "QWaylandViewporter", "private", "", "public"] }, + { "symbol": [ "QWaylandWlShell", "private", "", "public"] }, + { "symbol": [ "QWaylandWlShellSurface", "private", "", "public"] }, + { "symbol": [ "QWaylandXdgDecorationManagerV1", "private", "", "public"] }, + { "symbol": [ "QWaylandXdgOutputManagerV1", "private", "", "public"] }, + { "symbol": [ "QWaylandXdgOutputV1", "private", "", "public"] }, + { "symbol": [ "QWaylandXdgPopup", "private", "", "public"] }, + { "symbol": [ "QWaylandXdgShell", "private", "", "public"] }, + { "symbol": [ "QWaylandXdgSurface", "private", "", "public"] }, + { "symbol": [ "QWaylandXdgToplevel", "private", "", "public"] }, + { "symbol": [ "QWeakPointer", "private", "", "public"] }, + { "symbol": [ "QWebChannel", "private", "", "public"] }, + { "symbol": [ "QWebChannelAbstractTransport", "private", "", "public"] }, + { "symbol": [ "QWebEngineCertificateError", "private", "", "public"] }, + { "symbol": [ "QWebEngineClientCertificateSelection", "private", "", "public"] }, + { "symbol": [ "QWebEngineClientCertificateStore", "private", "", "public"] }, + { "symbol": [ "QWebEngineClientHints", "private", "", "public"] }, + { "symbol": [ "QWebEngineContextMenuRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineCookieStore", "private", "", "public"] }, + { "symbol": [ "QWebEngineDesktopMediaRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineDownloadRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineExtensionInfo", "private", "", "public"] }, + { "symbol": [ "QWebEngineExtensionManager", "private", "", "public"] }, + { "symbol": [ "QWebEngineFileSystemAccessRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineFindTextResult", "private", "", "public"] }, + { "symbol": [ "QWebEngineFrame", "private", "", "public"] }, + { "symbol": [ "QWebEngineFullScreenRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineGlobalSettings", "private", "", "public"] }, + { "symbol": [ "QWebEngineHistory", "private", "", "public"] }, + { "symbol": [ "QWebEngineHistoryItem", "private", "", "public"] }, + { "symbol": [ "QWebEngineHistoryModel", "private", "", "public"] }, + { "symbol": [ "QWebEngineHttpRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineLoadingInfo", "private", "", "public"] }, + { "symbol": [ "QWebEngineNavigationRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineNewWindowRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineNotification", "private", "", "public"] }, + { "symbol": [ "QWebEnginePage", "private", "", "public"] }, + { "symbol": [ "QWebEnginePermission", "private", "", "public"] }, + { "symbol": [ "QWebEngineProfile", "private", "", "public"] }, + { "symbol": [ "QWebEngineProfileBuilder", "private", "", "public"] }, + { "symbol": [ "QWebEngineQuotaRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineRegisterProtocolHandlerRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineScript", "private", "", "public"] }, + { "symbol": [ "QWebEngineScriptCollection", "private", "", "public"] }, + { "symbol": [ "QWebEngineSettings", "private", "", "public"] }, + { "symbol": [ "QWebEngineUrlRequestInfo", "private", "", "public"] }, + { "symbol": [ "QWebEngineUrlRequestInterceptor", "private", "", "public"] }, + { "symbol": [ "QWebEngineUrlRequestJob", "private", "", "public"] }, + { "symbol": [ "QWebEngineUrlScheme", "private", "", "public"] }, + { "symbol": [ "QWebEngineUrlSchemeHandler", "private", "", "public"] }, + { "symbol": [ "QWebEngineView", "private", "", "public"] }, + { "symbol": [ "QWebEngineWebAuthPinRequest", "private", "", "public"] }, + { "symbol": [ "QWebEngineWebAuthUxRequest", "private", "", "public"] }, + { "symbol": [ "QWebSocket", "private", "", "public"] }, + { "symbol": [ "QWebSocketCorsAuthenticator", "private", "", "public"] }, + { "symbol": [ "QWebSocketHandshakeOptions", "private", "", "public"] }, + { "symbol": [ "QWebSocketProtocol", "private", "", "public"] }, + { "symbol": [ "QWebSocketServer", "private", "", "public"] }, + { "symbol": [ "QWhatsThis", "private", "", "public"] }, + { "symbol": [ "QWhatsThisClickedEvent", "private", "", "public"] }, + { "symbol": [ "QWheelEvent", "private", "", "public"] }, + { "symbol": [ "QWidget", "private", "", "public"] }, + { "symbol": [ "QWidgetAction", "private", "", "public"] }, + { "symbol": [ "QWidgetData", "private", "", "public"] }, + { "symbol": [ "QWidgetItem", "private", "", "public"] }, + { "symbol": [ "QWidgetItemV2", "private", "", "public"] }, + { "symbol": [ "QWidgetList", "private", "", "public"] }, + { "symbol": [ "QWidgetMapper", "private", "", "public"] }, + { "symbol": [ "QWidgetSet", "private", "", "public"] }, + { "symbol": [ "QWinEventNotifier", "private", "", "public"] }, + { "symbol": [ "QWindow", "private", "", "public"] }, + { "symbol": [ "QWindowCapture", "private", "", "public"] }, + { "symbol": [ "QWindowList", "private", "", "public"] }, + { "symbol": [ "QWindowStateChangeEvent", "private", "", "public"] }, + { "symbol": [ "QWizard", "private", "", "public"] }, + { "symbol": [ "QWizardPage", "private", "", "public"] }, + { "symbol": [ "QWriteLocker", "private", "", "public"] }, + { "symbol": [ "QXmlAttributes", "private", "", "public"] }, + { "symbol": [ "QXmlContentHandler", "private", "", "public"] }, + { "symbol": [ "QXmlDTDHandler", "private", "", "public"] }, + { "symbol": [ "QXmlDeclHandler", "private", "", "public"] }, + { "symbol": [ "QXmlDefaultHandler", "private", "", "public"] }, + { "symbol": [ "QXmlEntityResolver", "private", "", "public"] }, + { "symbol": [ "QXmlErrorHandler", "private", "", "public"] }, + { "symbol": [ "QXmlInputSource", "private", "", "public"] }, + { "symbol": [ "QXmlLexicalHandler", "private", "", "public"] }, + { "symbol": [ "QXmlLocator", "private", "", "public"] }, + { "symbol": [ "QXmlNamespaceSupport", "private", "", "public"] }, + { "symbol": [ "QXmlParseException", "private", "", "public"] }, + { "symbol": [ "QXmlReader", "private", "", "public"] }, + { "symbol": [ "QXmlSimpleReader", "private", "", "public"] }, + { "symbol": [ "QXmlStreamAttribute", "private", "", "public"] }, + { "symbol": [ "QXmlStreamAttributes", "private", "", "public"] }, + { "symbol": [ "QXmlStreamEntityDeclaration", "private", "", "public"] }, + { "symbol": [ "QXmlStreamEntityDeclarations", "private", "", "public"] }, + { "symbol": [ "QXmlStreamEntityResolver", "private", "", "public"] }, + { "symbol": [ "QXmlStreamNamespaceDeclaration", "private", "", "public"] }, + { "symbol": [ "QXmlStreamNamespaceDeclarations", "private", "", "public"] }, + { "symbol": [ "QXmlStreamNotationDeclaration", "private", "", "public"] }, + { "symbol": [ "QXmlStreamNotationDeclarations", "private", "", "public"] }, + { "symbol": [ "QXmlStreamReader", "private", "", "public"] }, + { "symbol": [ "QXmlStreamWriter", "private", "", "public"] }, + { "symbol": [ "Q_IPV6ADDR", "private", "", "public"] }, + { "symbol": [ "Qt", "private", "", "public"] }, + { "symbol": [ "QtAlgorithms", "private", "", "public"] }, + { "symbol": [ "QtAudio", "private", "", "public"] }, + { "symbol": [ "QtBluetoothVersion", "private", "", "public"] }, + { "symbol": [ "QtCborCommon", "private", "", "public"] }, + { "symbol": [ "QtCleanUpFunction", "private", "", "public"] }, + { "symbol": [ "QtCompare", "private", "", "public"] }, + { "symbol": [ "QtCompilerDetection", "private", "", "public"] }, + { "symbol": [ "QtConcurrentFilter", "private", "", "public"] }, + { "symbol": [ "QtConcurrentMap", "private", "", "public"] }, + { "symbol": [ "QtConcurrentRun", "private", "", "public"] }, + { "symbol": [ "QtConcurrentTask", "private", "", "public"] }, + { "symbol": [ "QtConcurrentVersion", "private", "", "public"] }, + { "symbol": [ "QtConfig", "private", "", "public"] }, + { "symbol": [ "QtConnectivityVersion", "private", "", "public"] }, + { "symbol": [ "QtConstructorMacros", "private", "", "public"] }, + { "symbol": [ "QtContainerFwd", "private", "", "public"] }, + { "symbol": [ "QtCore5CompatVersion", "private", "", "public"] }, + { "symbol": [ "QtCoreGlobal", "private", "", "public"] }, + { "symbol": [ "QtCoreVersion", "private", "", "public"] }, + { "symbol": [ "QtCoverageScanner", "private", "", "public"] }, + { "symbol": [ "QtDBusVersion", "private", "", "public"] }, + { "symbol": [ "QtDarwinHelpers", "private", "", "public"] }, + { "symbol": [ "QtDebug", "private", "", "public"] }, + { "symbol": [ "QtDeprecationMarkers", "private", "", "public"] }, + { "symbol": [ "QtDeviceDiscoverySupportVersion", "private", "", "public"] }, + { "symbol": [ "QtEndian", "private", "", "public"] }, + { "symbol": [ "QtEvents", "private", "", "public"] }, + { "symbol": [ "QtExceptionHandling", "private", "", "public"] }, + { "symbol": [ "QtFFmpegMediaPluginImplVersion", "private", "", "public"] }, + { "symbol": [ "QtFbSupportVersion", "private", "", "public"] }, + { "symbol": [ "QtGlobal", "private", "", "public"] }, + { "symbol": [ "QtGuiVersion", "private", "", "public"] }, + { "symbol": [ "QtHelpVersion", "private", "", "public"] }, + { "symbol": [ "QtInputSupportVersion", "private", "", "public"] }, + { "symbol": [ "QtKmsSupportVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsAnimationVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsFolderListModelVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsPlatformVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsQmlModelsVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsSettingsVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsSharedImageVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsStyleKitImplVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsStyleKitVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsSynchronizerVersion", "private", "", "public"] }, + { "symbol": [ "QtLabsWavefrontMeshVersion", "private", "", "public"] }, + { "symbol": [ "QtLogging", "private", "", "public"] }, + { "symbol": [ "QtMalloc", "private", "", "public"] }, + { "symbol": [ "QtMath", "private", "", "public"] }, + { "symbol": [ "QtMessageHandler", "private", "", "public"] }, + { "symbol": [ "QtMultimediaQuickVersion", "private", "", "public"] }, + { "symbol": [ "QtMultimediaTestLibVersion", "private", "", "public"] }, + { "symbol": [ "QtMultimediaVersion", "private", "", "public"] }, + { "symbol": [ "QtMultimediaWidgetsVersion", "private", "", "public"] }, + { "symbol": [ "QtNetworkAuthVersion", "private", "", "public"] }, + { "symbol": [ "QtNetworkVersion", "private", "", "public"] }, + { "symbol": [ "QtNumeric", "private", "", "public"] }, + { "symbol": [ "QtOpenGLVersion", "private", "", "public"] }, + { "symbol": [ "QtOpenGLWidgetsVersion", "private", "", "public"] }, + { "symbol": [ "QtPacketProtocolVersion", "private", "", "public"] }, + { "symbol": [ "QtPdfQuickVersion", "private", "", "public"] }, + { "symbol": [ "QtPdfVersion", "private", "", "public"] }, + { "symbol": [ "QtPdfWidgetsVersion", "private", "", "public"] }, + { "symbol": [ "QtPlugin", "private", "", "public"] }, + { "symbol": [ "QtPluginInstanceFunction", "private", "", "public"] }, + { "symbol": [ "QtPluginMetaDataFunction", "private", "", "public"] }, + { "symbol": [ "QtPrintSupportVersion", "private", "", "public"] }, + { "symbol": [ "QtPrivate", "private", "", "public"] }, + { "symbol": [ "QtProcessorDetection", "private", "", "public"] }, + { "symbol": [ "QtQmlCompilerVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlCoreVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlDebugVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlDomVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlFormatVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlIntegrationVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlLocalStorageVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlMetaVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlModelsVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlNetworkVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlToolingSettingsVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlTypeRegistrarVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlWorkerScriptVersion", "private", "", "public"] }, + { "symbol": [ "QtQmlXmlListModelVersion", "private", "", "public"] }, + { "symbol": [ "QtQmltcVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DAssetImportVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DAssetUtilsVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DGlslParserVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DHelpersImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DHelpersVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DIblBakerVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DParticlesVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DRuntimeRenderVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DSpatialAudioVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DUtilsVersion", "private", "", "public"] }, + { "symbol": [ "QtQuick3DVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2BasicStyleImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2BasicVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2FluentWinUI3StyleImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2FusionStyleImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2FusionVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2ImagineStyleImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2ImagineVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2ImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2MaterialStyleImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2MaterialVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2UniversalStyleImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2UniversalVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickControls2Version", "private", "", "public"] }, + { "symbol": [ "QtQuickControlsTestUtilsVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickDialogs2QuickImplVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickDialogs2UtilsVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickDialogs2Version", "private", "", "public"] }, + { "symbol": [ "QtQuickEffectsVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickLayoutsVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickParticlesVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickShapesDesignHelpersVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickShapesVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickTemplates2Version", "private", "", "public"] }, + { "symbol": [ "QtQuickTestUtilsVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickTestVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickTimelineBlendTreesVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickTimelineVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickVectorImageGeneratorVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickVectorImageHelpersVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickVectorImageVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickVersion", "private", "", "public"] }, + { "symbol": [ "QtQuickWidgetsVersion", "private", "", "public"] }, + { "symbol": [ "QtResource", "private", "", "public"] }, + { "symbol": [ "QtScxmlGlobalVersion", "private", "", "public"] }, + { "symbol": [ "QtScxmlQmlVersion", "private", "", "public"] }, + { "symbol": [ "QtScxmlVersion", "private", "", "public"] }, + { "symbol": [ "QtShaderToolsVersion", "private", "", "public"] }, + { "symbol": [ "QtSpatialAudioVersion", "private", "", "public"] }, + { "symbol": [ "QtSqlVersion", "private", "", "public"] }, + { "symbol": [ "QtStartUpFunction", "private", "", "public"] }, + { "symbol": [ "QtStateMachineQmlVersion", "private", "", "public"] }, + { "symbol": [ "QtStateMachineVersion", "private", "", "public"] }, + { "symbol": [ "QtStdLibDetection", "private", "", "public"] }, + { "symbol": [ "QtSvgVersion", "private", "", "public"] }, + { "symbol": [ "QtSvgWidgetsVersion", "private", "", "public"] }, + { "symbol": [ "QtSwap", "private", "", "public"] }, + { "symbol": [ "QtSystemDetection", "private", "", "public"] }, + { "symbol": [ "QtTestGui", "private", "", "public"] }, + { "symbol": [ "QtTestNetwork", "private", "", "public"] }, + { "symbol": [ "QtTestVersion", "private", "", "public"] }, + { "symbol": [ "QtTestWidgets", "private", "", "public"] }, + { "symbol": [ "QtToolsVersion", "private", "", "public"] }, + { "symbol": [ "QtTypeTraits", "private", "", "public"] }, + { "symbol": [ "QtUiPluginVersion", "private", "", "public"] }, + { "symbol": [ "QtUiToolsVersion", "private", "", "public"] }, + { "symbol": [ "QtVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandClientVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandCompositorIviapplicationVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandCompositorPresentationTimeVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandCompositorVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandCompositorWLShellVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandCompositorXdgShellVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandEglCompositorHwIntegrationVersion", "private", "", "public"] }, + { "symbol": [ "QtWaylandGlobalVersion", "private", "", "public"] }, + { "symbol": [ "QtWebChannelQuickVersion", "private", "", "public"] }, + { "symbol": [ "QtWebChannelVersion", "private", "", "public"] }, + { "symbol": [ "QtWebEngineCoreVersion", "private", "", "public"] }, + { "symbol": [ "QtWebEngineQuickVersion", "private", "", "public"] }, + { "symbol": [ "QtWebEngineWidgetsVersion", "private", "", "public"] }, + { "symbol": [ "QtWebSocketsVersion", "private", "", "public"] }, + { "symbol": [ "QtWidgetsVersion", "private", "", "public"] }, + { "symbol": [ "QtWlShellIntegrationVersion", "private", "", "public"] }, + { "symbol": [ "QtXmlVersion", "private", "", "public"] }, + { "symbol": [ "operator==", "private", "", "public"] }, + { "symbol": [ "operator!=", "private", "", "public"] }, + { "symbol": [ "operator<", "private", "", "public"] }, + { "symbol": [ "operator<=", "private", "", "public"] }, + { "symbol": [ "operator>", "private", "", "public"] }, + { "symbol": [ "operator>=", "private", "", "public"] }, + { "symbol": [ "comparesEqual", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothaddress\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothdevicediscoveryagent\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothdeviceinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothhostinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothlocaldevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothserver\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothservicediscoveryagent\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothserviceinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothsocket\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qbluetoothuuid\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergyadvertisingdata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergyadvertisingparameters\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergycharacteristic\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergycharacteristicdata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergyconnectionparameters\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergycontroller\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergydescriptor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergydescriptordata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergyservice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qlowenergyservicedata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtBluetooth/)?qtbluetoothversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtConcurrent/)?qtconcurrentfilter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtConcurrent/)?qtconcurrentmap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtConcurrent/)?qtconcurrentrun\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtConcurrent/)?qtconcurrenttask\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtConcurrent/)?qtconcurrentversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtConnectivity/)?qtconnectivityversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qabstractanimation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qabstracteventdispatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qabstractitemmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qabstractnativeeventfilter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qabstractproxymodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qanimationgroup\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qanystringview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qapplicationstatic\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qarraydata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qarraydataops\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qarraydatapointer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qassert\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qassociativeiterable\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qatomicscopedvaluerollback\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbasictimer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbindingstorage\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbitarray\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbuffer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbytearray\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbytearrayalgorithms\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbytearraylist\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbytearraymatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qbytearrayview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcache\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcalendar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcborarray\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcbormap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcborstreamreader\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcborstreamwriter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcborvalue\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qchar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qchronotimer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcollator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcommandlineoption\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcommandlineparser\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qconcatenatetablesproxymodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcontiguouscache\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcoreapplication\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qcryptographichash\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qdatastream\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qdatetime\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qdeadlinetimer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qdebug\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qdir\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qdiriterator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qdirlisting\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qeasingcurve\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qelapsedtimer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qeventloop\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qexception\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfactoryinterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfiledevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfileinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfileselector\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfilesystemwatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qflags\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfloat16\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qforeach\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfunctionpointer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfuture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfutureinterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfuturesynchronizer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qfuturewatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qglobalstatic\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qhash\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qhashfunctions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qidentityproxymodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qiodevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qiodevicebase\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qitemselectionmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qiterable\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qjsonarray\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qjsondocument\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qjsonobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qjsonparseerror\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qjsonvalue\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qlatin1stringmatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qlatin1stringview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qlibrary\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qlibraryinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qline\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qlist\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qlocale\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qlockfile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qloggingcategory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmargins\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmessageauthenticationcode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmetaassociation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmetacontainer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmetasequence\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmetatype\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmimedata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmimedatabase\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmimetype\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qminmax\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qmutex\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qobjectcleanuphandler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qoperatingsystemversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qoverload\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpair\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qparallelanimationgroup\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpauseanimation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpermissions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpluginloader\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpoint\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpointer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qprocess\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpromise\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qproperty\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qpropertyanimation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qqueue\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qrangemodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qrangemodeladapter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qreadwritelock\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qrect\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qregularexpression\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qresource\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qrunnable\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsavefile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qscopedpointer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qscopedvaluerollback\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qscopeguard\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsemaphore\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsequentialanimationgroup\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsequentialiterable\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qset\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsettings\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qshareddata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsharedmemory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsharedpointer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsignalmapper\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsize\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsocketnotifier\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsortfilterproxymodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qspan\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstack\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstandardpaths\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstaticlatin1stringmatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstorageinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstring\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringalgorithms\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringbuilder\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringconverter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringlist\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringlistmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringliteral\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringmatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringtokenizer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qstringview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsysinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qsystemsemaphore\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtaggedpointer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtclasshelpermacros\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtcoreglobal\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtcoreversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtdeprecationmarkers\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtemporarydir\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtemporaryfile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtenvironmentvariables\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtextboundaryfinder\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtextstream\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qthread\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qthreadpool\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qthreadstorage\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtimeline\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtimer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtimezone\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtpreprocessorsupport\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtranslator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtransposeproxymodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtresource\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qttranslation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qttypetraits\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtversionchecks\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtypeinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtyperevision\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qtypes\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qurl\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qurlquery\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qutf8stringview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?quuid\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qvariant\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qvariantanimation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qvarianthash\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qvariantlist\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qvariantmap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qvarlengtharray\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qvector\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qversionnumber\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qwaitcondition\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore/)?qwineventnotifier\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore5Compat/)?qbinaryjson\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore5Compat/)?qlinkedlist\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore5Compat/)?qregexp\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore5Compat/)?qstringref\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore5Compat/)?qtcore5compatversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtCore5Compat/)?qtextcodec\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusabstractadaptor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusabstractinterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusargument\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusconnection\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusconnectioninterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbuscontext\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbuserror\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusinterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusmessage\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusmetatype\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbuspendingcall\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbuspendingreply\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusreply\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusserver\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusservicewatcher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusunixfiledescriptor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qdbusvirtualobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDBus/)?qtdbusversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtDeviceDiscoverySupport/)?qtdevicediscoverysupportversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtFFmpegMediaPluginImpl/)?qtffmpegmediapluginimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtFbSupport/)?qtfbsupportversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qabstractfileiconprovider\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qabstracttextdocumentlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qaccessibilityhints\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qaccessible\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qaccessiblebridge\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qaccessibleobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qaccessibleplugin\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qaction\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qactiongroup\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qbackingstore\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qbitmap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qbrush\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qclipboard\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qcolor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qcolorspace\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qcolortransform\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qcursor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qdesktopservices\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qdrag\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qeventpoint\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qfilesystemmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qfont\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qfontdatabase\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qfontinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qfontmetrics\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qfontvariableaxis\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qgenericmatrix\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qgenericplugin\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qgenericpluginfactory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qglyphrun\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qguiapplication\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qicon\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qiconengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qiconengineplugin\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qimage\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qimageiohandler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qimagereader\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qimagewriter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qinputdevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qinputmethod\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qkeysequence\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qmatrix4x4\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qmovie\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qoffscreensurface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qopenglcontext\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qopenglextrafunctions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qopenglfunctions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpagedpaintdevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpagelayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpageranges\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpagesize\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpaintdevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpaintdevicewindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpaintengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpainter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpainterpath\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpainterstateguard\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpalette\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpdfoutputintent\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpdfwriter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpen\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpicture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpixelformat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpixmap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpixmapcache\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpointingdevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qpolygon\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qquaternion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qrasterwindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qrawfont\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qregion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qrgb\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qrgba64\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qrgbafloat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qscreen\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qsessionmanager\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qshortcut\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qstandarditemmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qstatictext\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qstylehints\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qsurface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qsurfaceformat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qsyntaxhighlighter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextcursor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextdocument\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextdocumentfragment\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextdocumentwriter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextformat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextlist\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtextoption\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtexttable\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtguiversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qtransform\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qundogroup\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qundostack\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qvalidator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qvulkanfunctions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qvulkaninstance\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qvulkanwindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtGui/)?qwindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qcompressedhelpinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpcontentitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpcontentwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpenginecore\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpfilterdata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpfilterengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpfiltersettingswidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpindexwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelplink\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpsearchengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpsearchenginecore\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpsearchquerywidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpsearchresult\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qhelpsearchresultwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtHelp/)?qthelpversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtInputSupport/)?qtinputsupportversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtKmsSupport/)?qtkmssupportversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsAnimation/)?qtlabsanimationversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsFolderListModel/)?qtlabsfolderlistmodelversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsPlatform/)?qtlabsplatformversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsQmlModels/)?qtlabsqmlmodelsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsSettings/)?qtlabssettingsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsSharedImage/)?qtlabssharedimageversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsStyleKit/)?qtlabsstylekitversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsStyleKitImpl/)?qtlabsstylekitimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsSynchronizer/)?qtlabssynchronizerversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtLabsWavefrontMesh/)?qtlabswavefrontmeshversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qabstractvideobuffer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudio\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiobuffer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiobufferinput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiobufferoutput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiodecoder\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiodevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudioformat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudioinput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiooutput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiosink\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qaudiosource\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qcamera\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qcameradevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qcapturablewindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qimagecapture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qmediacapturesession\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qmediadevices\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qmediaformat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qmediametadata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qmediaplayer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qmediarecorder\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qmediatimerange\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qplaybackoptions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qscreencapture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qsoundeffect\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qtaudio\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qtmultimediaversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qvideoframe\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qvideoframeformat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qvideoframeinput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qvideosink\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qwavedecoder\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimedia/)?qwindowcapture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimediaQuick/)?qtmultimediaquickversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimediaTestLib/)?qtmultimediatestlibversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimediaWidgets/)?qgraphicsvideoitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimediaWidgets/)?qtmultimediawidgetsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtMultimediaWidgets/)?qvideowidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qabstractnetworkcache\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qabstractsocket\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qauthenticator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qdnslookup\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qdtls\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qformdatabuilder\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qhostaddress\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qhostinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qhstspolicy\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qhttp1configuration\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qhttp2configuration\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qhttpheaders\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qhttpmultipart\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qlocalserver\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qlocalsocket\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkaccessmanager\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkcookie\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkcookiejar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkdatagram\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkdiskcache\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkinformation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkinterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkproxy\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkreply\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qnetworkrequestfactory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qocspresponse\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qpassworddigestor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qrestaccessmanager\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qrestreply\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qssl\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslcertificate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslcertificateextension\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslcipher\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslconfiguration\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qssldiffiehellmanparameters\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslellipticcurve\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslerror\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslkey\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslpresharedkeyauthenticator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslserver\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qsslsocket\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qtcpserver\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qtcpsocket\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qtnetworkversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetwork/)?qudpsocket\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qabstractoauth\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qabstractoauth2\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qabstractoauthreplyhandler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qoauth1\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qoauth1signature\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qoauth2authorizationcodeflow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qoauth2deviceauthorizationflow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qoauthhttpserverreplyhandler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qoauthoobreplyhandler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qoauthurischemereplyhandler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtNetworkAuth/)?qtnetworkauthversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglbuffer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglframebufferobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_1_0\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_1_1\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_1_2\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_1_3\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_1_4\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_1_5\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_2_0\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_2_1\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_3_0\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_3_1\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_3_2_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_3_2_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_3_3_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_3_3_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_0_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_0_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_1_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_1_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_2_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_2_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_3_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_3_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_4_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_4_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_5_compatibility\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglfunctions_4_5_core\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglpaintdevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglpixeltransferoptions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglshaderprogram\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopengltexture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopengltextureblitter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopengltimerquery\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglversionfunctions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglversionfunctionsfactory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglversionprofile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglvertexarrayobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qopenglwindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGL/)?qtopenglversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGLWidgets/)?qopenglwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtOpenGLWidgets/)?qtopenglwidgetsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPacketProtocol/)?qtpacketprotocolversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdfbookmarkmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdfdocument\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdfdocumentrenderoptions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdflink\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdflinkmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdfpagenavigator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdfpagerenderer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdfsearchmodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qpdfselection\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdf/)?qtpdfversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdfQuick/)?qtpdfquickversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdfWidgets/)?qpdfpageselector\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdfWidgets/)?qpdfview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPdfWidgets/)?qtpdfwidgetsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qabstractprintdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qpagesetupdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qprintdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qprintengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qprinter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qprinterinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qprintpreviewdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qprintpreviewwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtPrintSupport/)?qtprintsupportversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qjsengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qjslist\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qjsmanagedvalue\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qjsnumbercoercion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qjsprimitivevalue\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qjsvalue\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qjsvalueiterator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlabstracturlinterceptor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlapplicationengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlcomponent\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlcontext\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlerror\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlexpression\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlextensioninterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlextensionplugin\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlfile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlfileselector\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlincubator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlmoduleregistration\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlnetworkaccessmanagerfactory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlparserstatus\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlproperty\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlpropertymap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlpropertyvaluesource\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qqmlscriptstring\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQml/)?qtqmlversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlCompiler/)?qtqmlcompilerversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlCore/)?qtqmlcoreversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlDebug/)?qtqmldebugversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlDom/)?qtqmldomversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlFormat/)?qtqmlformatversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlIntegration/)?qtqmlintegrationversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlLocalStorage/)?qtqmllocalstorageversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlMeta/)?qtqmlmetaversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlModels/)?qtqmlmodelsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlNetwork/)?qtqmlnetworkversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlToolingSettings/)?qtqmltoolingsettingsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlTypeRegistrar/)?qtqmltyperegistrarversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlWorkerScript/)?qtqmlworkerscriptversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmlXmlListModel/)?qtqmlxmllistmodelversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQmltc/)?qtqmltcversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickframebufferobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickgraphicsconfiguration\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickgraphicsdevice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickimageprovider\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickitemgrabresult\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickopenglutils\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickpainteditem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickrendercontrol\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickrendertarget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickrhiitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquicktextdocument\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qquickwindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgflatcolormaterial\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsggeometry\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgimagenode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgmaterial\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgmaterialshader\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgninepatchnode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgnode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgrectanglenode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgrendererinterface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgrendernode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgsimplerectnode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgsimpletexturenode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgtextnode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgtexture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgtexturematerial\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgtextureprovider\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qsgvertexcolormaterial\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick/)?qtquickversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3D/)?qquick3d\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3D/)?qquick3dgeometry\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3D/)?qquick3dinstancing\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3D/)?qquick3dobject\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3D/)?qquick3dtexturedata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3D/)?qquick3dtextureproviderextension\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3D/)?qtquick3dversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DAssetImport/)?qtquick3dassetimportversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DAssetUtils/)?qtquick3dassetutilsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DGlslParser/)?qtquick3dglslparserversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DHelpers/)?qtquick3dhelpersversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DHelpersImpl/)?qtquick3dhelpersimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DIblBaker/)?qtquick3diblbakerversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DParticles/)?qtquick3dparticlesversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DRuntimeRender/)?qtquick3druntimerenderversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DSpatialAudio/)?qtquick3dspatialaudioversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuick3DUtils/)?qtquick3dutilsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2/)?qquickattachedpropertypropagator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2/)?qquickstyle\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2/)?qtquickcontrols2version\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2Basic/)?qtquickcontrols2basicversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2BasicStyleImpl/)?qtquickcontrols2basicstyleimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2FluentWinUI3StyleImpl/)?qtquickcontrols2fluentwinui3styleimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2Fusion/)?qtquickcontrols2fusionversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2FusionStyleImpl/)?qtquickcontrols2fusionstyleimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2Imagine/)?qtquickcontrols2imagineversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2ImagineStyleImpl/)?qtquickcontrols2imaginestyleimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2Impl/)?qtquickcontrols2implversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2Material/)?qtquickcontrols2materialversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2MaterialStyleImpl/)?qtquickcontrols2materialstyleimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2Universal/)?qtquickcontrols2universalversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControls2UniversalStyleImpl/)?qtquickcontrols2universalstyleimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickControlsTestUtils/)?qtquickcontrolstestutilsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickDialogs2/)?qtquickdialogs2version\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickDialogs2QuickImpl/)?qtquickdialogs2quickimplversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickDialogs2Utils/)?qtquickdialogs2utilsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickEffects/)?qtquickeffectsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickLayouts/)?qtquicklayoutsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickParticles/)?qtquickparticlesversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickShapes/)?qtquickshapesversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickShapesDesignHelpers/)?qtquickshapesdesignhelpersversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickTemplates2/)?qtquicktemplates2version\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickTest/)?qtquicktestversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickTestUtils/)?qtquicktestutilsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickTimeline/)?qtquicktimelineversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickTimelineBlendTrees/)?qtquicktimelineblendtreesversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickVectorImage/)?qtquickvectorimageversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickVectorImageGenerator/)?qtquickvectorimagegeneratorversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickVectorImageHelpers/)?qtquickvectorimagehelpersversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickWidgets/)?qquickwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtQuickWidgets/)?qtquickwidgetsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmlcompiler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmlcppdatamodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmldatamodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmlerror\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmlevent\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmlinvokableservice\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmlnulldatamodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmlstatemachine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qscxmltabledata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxml/)?qtscxmlversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxmlGlobal/)?qtscxmlglobalversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtScxmlQml/)?qtscxmlqmlversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtShaderTools/)?qtshadertoolsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSpatialAudio/)?qambientsound\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSpatialAudio/)?qaudioengine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSpatialAudio/)?qaudiolistener\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSpatialAudio/)?qaudioroom\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSpatialAudio/)?qspatialsound\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSpatialAudio/)?qtspatialaudioversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqldatabase\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqldriver\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqldriverplugin\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlerror\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlfield\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlindex\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlquery\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlquerymodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlrecord\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlrelationaldelegate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlrelationaltablemodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqlresult\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qsqltablemodel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSql/)?qtsqlversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qabstractstate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qabstracttransition\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qeventtransition\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qfinalstate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qhistorystate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qkeyeventtransition\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qmouseeventtransition\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qsignaltransition\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qstate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qstatemachine\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachine/)?qtstatemachineversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtStateMachineQml/)?qtstatemachineqmlversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSvg/)?qsvggenerator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSvg/)?qsvgrenderer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSvg/)?qtsvgversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSvgWidgets/)?qgraphicssvgitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSvgWidgets/)?qsvgwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtSvgWidgets/)?qtsvgwidgetsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTest/)?qabstractitemmodeltester\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTest/)?qsignalspy\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTest/)?qtest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTest/)?qtestdata\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTest/)?qtestevent\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTest/)?qtesteventloop\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTest/)?qttestversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtTools/)?qttoolsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtUiPlugin/)?qdesignerexportwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtUiPlugin/)?qtuipluginversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtUiTools/)?qtuitoolsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtUiTools/)?quiloader\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandClient/)?qtwaylandclientversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandClient/)?qwaylandclientextension\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qtwaylandcompositorversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandbufferref\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandclient\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandcompositor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandcompositorextension\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylanddestroylistener\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylanddrag\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandinputmethodcontrol\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandiviapplication\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandivisurface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandkeyboard\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandkeymap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandoutput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandoutputmode\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandpointer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandqttextinputmethod\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandqttextinputmethodmanager\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandqtwindowmanager\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquickcompositor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquickextension\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquickitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquickoutput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquickshellintegration\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquickshellsurfaceitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquicksurface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandquickxdgoutputv1\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandresource\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandseat\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandshell\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandshellsurface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandsurface\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandsurfacegrabber\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandtextinput\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandtextinputmanager\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandtextinputmanagerv3\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandtextinputv3\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandtouch\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandviewporter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandwlshell\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandxdgoutputv1\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositor/)?qwaylandxdgshell\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositorIviapplication/)?qtwaylandcompositoriviapplicationversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositorPresentationTime/)?qtwaylandcompositorpresentationtimeversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositorWLShell/)?qtwaylandcompositorwlshellversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandCompositorXdgShell/)?qtwaylandcompositorxdgshellversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandEglCompositorHwIntegration/)?qtwaylandeglcompositorhwintegrationversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWaylandGlobal/)?qtwaylandglobalversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebChannel/)?qtwebchannelversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebChannel/)?qwebchannel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebChannel/)?qwebchannelabstracttransport\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebChannelQuick/)?qqmlwebchannel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebChannelQuick/)?qtwebchannelquickversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qtwebenginecoreversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginecertificateerror\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineclientcertificateselection\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineclientcertificatestore\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineclienthints\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginecontextmenurequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginecookiestore\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginedesktopmediarequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginedownloadrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineextensioninfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineextensionmanager\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginefilesystemaccessrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginefindtextresult\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineframe\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginefullscreenrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineglobalsettings\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginehistory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginehttprequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineloadinginfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginenavigationrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginenewwindowrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginenotification\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginepage\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginepermission\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineprofile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineprofilebuilder\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginequotarequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineregisterprotocolhandlerrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginescript\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginescriptcollection\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginesettings\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineurlrequestinfo\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineurlrequestinterceptor\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineurlrequestjob\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineurlscheme\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebengineurlschemehandler\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineCore/)?qwebenginewebauthuxrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineQuick/)?qquickwebenginedownloadrequest\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineQuick/)?qquickwebengineprofile\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineQuick/)?qtwebenginequickversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineWidgets/)?qtwebenginewidgetsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebEngineWidgets/)?qwebengineview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebSockets/)?qmaskgenerator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebSockets/)?qtwebsocketsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebSockets/)?qwebsocket\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebSockets/)?qwebsocketcorsauthenticator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebSockets/)?qwebsockethandshakeoptions\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebSockets/)?qwebsocketprotocol\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWebSockets/)?qwebsocketserver\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qabstractbutton\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qabstractitemdelegate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qabstractitemview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qabstractscrollarea\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qabstractslider\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qabstractspinbox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qaccessiblewidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qapplication\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qboxlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qbuttongroup\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcalendarwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcheckbox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcolordialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcolormap\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcolumnview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcombobox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcommandlinkbutton\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcommonstyle\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qcompleter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qdatawidgetmapper\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qdatetimeedit\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qdial\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qdialogbuttonbox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qdockwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qerrormessage\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qfiledialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qfileiconprovider\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qfocusframe\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qfontcombobox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qfontdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qformlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qframe\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgesture\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgesturerecognizer\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicsanchorlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicseffect\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicsgridlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicsitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicsitemanimation\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicslayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicslayoutitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicslinearlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicsproxywidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicsscene\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicssceneevent\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicstransform\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicsview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgraphicswidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgridlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qgroupbox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qheaderview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qinputdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qitemdelegate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qitemeditorfactory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qkeysequenceedit\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qlabel\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qlayoutitem\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qlcdnumber\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qlineedit\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qlistview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qlistwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qmainwindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qmdiarea\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qmdisubwindow\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qmenu\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qmenubar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qmessagebox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qplaintextedit\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qprogressbar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qprogressdialog\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qproxystyle\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qpushbutton\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qradiobutton\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qrhiwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qrubberband\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qscrollarea\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qscrollbar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qscroller\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qscrollerproperties\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qsizegrip\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qsizepolicy\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qslider\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qspinbox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qsplashscreen\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qsplitter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstackedlayout\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstackedwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstatusbar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstyle\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstyleditemdelegate\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstylefactory\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstyleoption\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstylepainter\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qstyleplugin\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qsystemtrayicon\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtabbar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtableview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtablewidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtabwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtextbrowser\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtextedit\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtoolbar\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtoolbox\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtoolbutton\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtooltip\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtreeview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtreewidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtreewidgetitemiterator\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qtwidgetsversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qundoview\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qwhatsthis\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qwidget\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qwidgetaction\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWidgets/)?qwizard\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtWlShellIntegration/)?qtwlshellintegrationversion\\.h[\">]", "private", "", "public"] }, + { "include": [ "@[\"<](QtXml/)?qtxmlversion\\.h[\">]", "private", "", "public"] } +] diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index 21f71a908..b45608d86 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -27,6 +27,14 @@ set(servatrice_SOURCES set(servatrice_RESOURCES servatrice.qrc) +# Qxt SMTP is vendored. +cockatrice_disable_sanitizers_for( + src/smtp/qxthmac.cpp src/smtp/qxtmailattachment.cpp src/smtp/qxtmailmessage.cpp src/smtp/qxtsmtp.cpp +) +cockatrice_disable_coverage_for( + src/smtp/qxthmac.cpp src/smtp/qxtmailattachment.cpp src/smtp/qxtmailmessage.cpp src/smtp/qxtsmtp.cpp +) + if(WIN32) set(servatrice_SOURCES ${servatrice_SOURCES} servatrice.rc) endif(WIN32) diff --git a/servatrice/servatrice.ini.example b/servatrice/servatrice.ini.example index ccd4f3c3f..3ee52dd21 100644 --- a/servatrice/servatrice.ini.example +++ b/servatrice/servatrice.ini.example @@ -41,6 +41,12 @@ websocket_host=any ; The TCP port number servatrice will listen on for websockets clients; default is 4748 websocket_port=4748 +; If websockets are served through a reverse proxy (e.g. nginx), the real client address can be +; read from an HTTP header such as X-Forwarded-For. The header is ONLY trusted when the websocket +; connection itself originates from an address listed in security/trusted_sources (default 127.0.0.1,::1), +; so that clients cannot spoof their address to bypass bans or rate limits. +web_socket_ip_header= + ; When database is enabled, servatrice writes the server status in the "update" database table; this ; setting defines every how many milliseconds servatrice will update its status; default is 15000 (15 secs) statusupdate=15000 @@ -244,6 +250,16 @@ email=root@localhost ; Sender email name name="Cockatrice server" +; Maximum number of attempts to deliver a given e-mail before giving up. +; If the smtp server is unreachable or repeatedly rejects a message, the server +; will retry with an exponentially growing delay up to this many times, then drop +; the message from the queue and log the failure. Default: 5 +maxretries=5 + +; Initial retry delay in seconds between delivery attempts. Doubles with each +; failed attempt (capped at 30 minutes). Default: 60 +retrydelay=60 + ; Email subject subject="Cockatrice server account activation token" diff --git a/servatrice/src/email_parser.cpp b/servatrice/src/email_parser.cpp index d8c30d852..44c788e67 100644 --- a/servatrice/src/email_parser.cpp +++ b/servatrice/src/email_parser.cpp @@ -1,6 +1,8 @@ #include "email_parser.h" #include +#include +#include #include QPair EmailParser::parseEmailAddress(const QString &dirtyEmailAddress) diff --git a/servatrice/src/event_loop_watchdog.cpp b/servatrice/src/event_loop_watchdog.cpp index e50bd4201..a2f20ff1c 100644 --- a/servatrice/src/event_loop_watchdog.cpp +++ b/servatrice/src/event_loop_watchdog.cpp @@ -8,6 +8,8 @@ #include "servatrice.h" #include +#include +#include EventLoopWatchdog::EventLoopWatchdog(Servatrice *_servatrice, QString _threadName) : QObject(nullptr), servatrice(_servatrice), threadName(std::move(_threadName)) diff --git a/servatrice/src/event_loop_watchdog.h b/servatrice/src/event_loop_watchdog.h index b9061ff97..d05430eaa 100644 --- a/servatrice/src/event_loop_watchdog.h +++ b/servatrice/src/event_loop_watchdog.h @@ -9,6 +9,7 @@ #include #include #include +#include class Servatrice; class QTimer; diff --git a/servatrice/src/isl_interface.cpp b/servatrice/src/isl_interface.cpp index b0ee201bf..a78ee9e72 100644 --- a/servatrice/src/isl_interface.cpp +++ b/servatrice/src/isl_interface.cpp @@ -1,11 +1,34 @@ #include "isl_interface.h" +#include "libcockatrice/protocol/pb/commands.pb.h" +#include "libcockatrice/protocol/pb/room_commands.pb.h" +#include "libcockatrice/protocol/pb/room_event.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_room.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" +#include "libcockatrice/protocol/pb/session_event.pb.h" #include "main.h" +#include "servatrice.h" +#include "server_abstractuserinterface.h" #include "server_logger.h" +#include "serverinfo_user_container.h" +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include #include #include #include @@ -17,11 +40,15 @@ #include #include #include -#include #include +#include +#include #include #include +// Maximum size of a single ISL message. +static const int MAX_ISL_MESSAGE_SIZE = 4 * 1024 * 1024; + inline Q_LOGGING_CATEGORY(IslInterfaceLog, "isl_interface"); void IslInterface::sharedCtor(const QSslCertificate &cert, const QSslKey &privateKey) @@ -243,6 +270,13 @@ void IslInterface::readClient() (((quint32)(unsigned char)inputBuffer[1]) << 16) + (((quint32)(unsigned char)inputBuffer[2]) << 8) + ((quint32)(unsigned char)inputBuffer[3]); + // Reject implausible lengths instead of buffering until they arrive. + // This also handles lengths that overflow into negative int values. + if (messageLength < 0 || messageLength > MAX_ISL_MESSAGE_SIZE) { + qCWarning(IslInterfaceLog) << "Invalid message length" << messageLength << "from" << peerAddress; + socket->disconnectFromHost(); + return; + } inputBuffer.remove(0, 4); messageInProgress = true; } else { diff --git a/servatrice/src/isl_interface.h b/servatrice/src/isl_interface.h index 27e5b8293..f7680c0a2 100644 --- a/servatrice/src/isl_interface.h +++ b/servatrice/src/isl_interface.h @@ -1,21 +1,26 @@ #ifndef ISL_INTERFACE_H #define ISL_INTERFACE_H -#include "servatrice.h" - +#include +#include +#include +#include #include -#include +#include + +// IWYU pragma: keep +// ServerInfo_User and ServerInfo_Game are passed by value to signals, so the +// moc-generated code needs the complete types. +#include #include -#include #include +#include class Servatrice; class QSslSocket; class QSslKey; class IslMessage; - class Event_ServerCompleteList; -class Event_UserMessage; class Event_UserJoined; class Event_UserLeft; class Event_JoinRoom; @@ -24,6 +29,11 @@ class Event_RoomSay; class Event_ListGames; class Event_RemoveMessages; class Command_JoinGame; +class CommandContainer; +class GameEventContainer; +class Response; +class RoomEvent; +class SessionEvent; class IslInterface : public QObject { diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index 13bf95a82..eb019a2b7 100644 --- a/servatrice/src/main.cpp +++ b/servatrice/src/main.cpp @@ -18,6 +18,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include "libcockatrice/rng/rng_abstract.h" #include "servatrice.h" #include "server_logger.h" #include "settingscache.h" @@ -25,16 +26,29 @@ #include "smtpclient.h" #include "version_string.h" +#include #include #include #include +#include #include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include +#include RNG_Abstract *rng; ServerLogger *logger; diff --git a/servatrice/src/metrics_registry.cpp b/servatrice/src/metrics_registry.cpp index 99ce390f1..51abb7e3e 100644 --- a/servatrice/src/metrics_registry.cpp +++ b/servatrice/src/metrics_registry.cpp @@ -1,6 +1,7 @@ #include "metrics_registry.h" #include +#include void MetricsRegistry::observeCommand(int typeId, qint64 elapsedMs) { diff --git a/servatrice/src/metrics_registry.h b/servatrice/src/metrics_registry.h index 4df1057c2..1175d03c4 100644 --- a/servatrice/src/metrics_registry.h +++ b/servatrice/src/metrics_registry.h @@ -7,7 +7,7 @@ #define METRICS_REGISTRY_H #include -#include +#include #include #include diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 3dd7ab510..9ec9ef5bc 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -22,10 +22,14 @@ #include "email_parser.h" #include "event_loop_watchdog.h" #include "isl_interface.h" +#include "libcockatrice/protocol/pb/response_report_stats.pb.h" +#include "libcockatrice/protocol/pb/session_event.pb.h" #include "main.h" #include "servatrice_connection_pool.h" #include "servatrice_database_interface.h" +#include "server.h" #include "server_logger.h" +#include "server_protocolhandler.h" #include "serversocketinterface.h" #include "settingscache.h" #include "smtpclient.h" @@ -33,20 +37,40 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include #include #include +#include #include +#include #include +#include +#include +#include #include -#include -#include +#include #include #include #include #include +#include +#include +#include #include +#include + +inline Q_LOGGING_CATEGORY(ServatriceLog, "servatrice"); Servatrice_GameServer::Servatrice_GameServer(Servatrice *_server, int _numberPools, @@ -314,6 +338,11 @@ bool Servatrice::initServer() servatriceDatabaseInterface->clearSessionTables(); } + // Connect the SMTP client's delivery-confirmation signals to the database cleanup handlers. + // Emails are removed from the queue tables only after delivery is confirmed (see statusUpdate()). + connect(smtpClient, &SmtpClient::mailDelivered, this, &Servatrice::onEmailDelivered); + connect(smtpClient, &SmtpClient::mailPermanentlyFailed, this, &Servatrice::onEmailPermanentlyFailed); + if (getRoomsMethodString() == "sql") { QSqlQuery *query = servatriceDatabaseInterface->prepareQuery( "select id, name, descr, permissionlevel, privlevel, auto_join, join_message, chat_history_size from " @@ -716,41 +745,36 @@ void Servatrice::statusUpdate() return; } - auto *queryDelete = - servatriceDatabaseInterface->prepareQuery("delete from {prefix}_activation_emails where name = :name"); - + // Rows are intentionally NOT deleted here: the durable source of truth for a pending + // activation e-mail is the database row, which is only removed once delivery has been + // confirmed by the SMTP client (see onEmailDelivered). This makes sending resilient to + // transient SMTP failures and server restarts. while (servDbSelQuery->next()) { const QString userName = servDbSelQuery->value(0).toString(); const auto emailAddress = EmailParser::getParsedEmailAddress(servDbSelQuery->value(1).toString()); const QString token = servDbSelQuery->value(2).toString(); - if (smtpClient->enqueueActivationTokenMail(userName, emailAddress, token)) { - queryDelete->bindValue(":name", userName); - servatriceDatabaseInterface->execSqlQuery(queryDelete); - } + smtpClient->enqueueActivationTokenMail(userName, emailAddress, token); } } if (getEnableForgotPassword()) { auto *forgotPwQuery = servatriceDatabaseInterface->prepareQuery( - "select a.name, b.email, b.token from {prefix}_forgot_password a left join {prefix}_users b on a.name " - "= b.name where a.emailed = 0"); + "select a.id, a.name, b.email, b.token from {prefix}_forgot_password a left join {prefix}_users b on " + "a.name = b.name where a.emailed = 0"); if (!servatriceDatabaseInterface->execSqlQuery(forgotPwQuery)) { return; } - QSqlQuery *queryDelete = servatriceDatabaseInterface->prepareQuery( - "update {prefix}_forgot_password set emailed = 1 where name = :name"); - + // Rows are intentionally left with emailed = 0 here; they are marked emailed only once + // delivery is confirmed by the SMTP client (see onEmailDelivered). while (forgotPwQuery->next()) { - const QString userName = forgotPwQuery->value(0).toString(); - const auto emailAddress = EmailParser::getParsedEmailAddress(forgotPwQuery->value(1).toString()); - const QString token = forgotPwQuery->value(2).toString(); + const qint64 rowId = forgotPwQuery->value(0).toLongLong(); + const QString userName = forgotPwQuery->value(1).toString(); + const auto emailAddress = EmailParser::getParsedEmailAddress(forgotPwQuery->value(2).toString()); + const QString token = forgotPwQuery->value(3).toString(); - if (smtpClient->enqueueForgotPasswordTokenMail(userName, emailAddress, token)) { - queryDelete->bindValue(":name", userName); - servatriceDatabaseInterface->execSqlQuery(queryDelete); - } + smtpClient->enqueueForgotPasswordTokenMail(userName, emailAddress, token, rowId); } } @@ -758,6 +782,69 @@ void Servatrice::statusUpdate() } } +void Servatrice::onEmailDelivered(const QString &userName, EmailType type, const QString &token, qint64 rowId) +{ + if (cleanupDatabaseForEmail(userName, type, token, rowId)) { + qCDebug(ServatriceLog) << "E-mail delivered to" << userName; + } else { + qCWarning(ServatriceLog) << "Failed to clean up database row for delivered e-mail to" << userName + << "- row may be re-enqueued on next status update"; + } +} + +void Servatrice::onEmailPermanentlyFailed(const QString &userName, + EmailType type, + FailureReason reason, + const QString &token, + qint64 rowId) +{ + switch (reason) { + case FailureReason::RetryExhausted: + qCWarning(ServatriceLog) << "E-mail to" << userName << "permanently failed after max retries"; + break; + case FailureReason::RecipientRejected: + qCWarning(ServatriceLog) << "E-mail to" << userName << "permanently failed: recipient rejected"; + break; + case FailureReason::SenderRejected: + qCWarning(ServatriceLog) << "E-mail to" << userName << "permanently failed: sender rejected"; + break; + } + + if (!cleanupDatabaseForEmail(userName, type, token, rowId)) { + qCWarning(ServatriceLog) << "Failed to clean up database row for permanently failed e-mail to" << userName + << "- row may be re-enqueued on next status update"; + } +} + +bool Servatrice::cleanupDatabaseForEmail(const QString &userName, EmailType type, const QString &token, qint64 rowId) +{ + Q_UNUSED(token); + switch (type) { + case EmailType::Activation: { + QSqlQuery *query = + servatriceDatabaseInterface->prepareQuery("delete from {prefix}_activation_emails where name = :name"); + query->bindValue(":name", userName); + return servatriceDatabaseInterface->execSqlQuery(query); + } + case EmailType::ForgotPassword: { + // Scope the update to the row that was actually sent: the table + // holds one row per request, and marking by name would also mark + // rows for newer tokens that were never delivered. + if (rowId >= 0) { + QSqlQuery *query = servatriceDatabaseInterface->prepareQuery( + "update {prefix}_forgot_password set emailed = 1 where id = :id"); + query->bindValue(":id", rowId); + return servatriceDatabaseInterface->execSqlQuery(query); + } + QSqlQuery *query = servatriceDatabaseInterface->prepareQuery( + "update {prefix}_forgot_password set emailed = 1 where name = :name"); + query->bindValue(":name", userName); + return servatriceDatabaseInterface->execSqlQuery(query); + } + } + return false; +} + SessionEvent *Servatrice::makeShutdownEvent() const { Event_ServerShutdown event; diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index f39a44d51..205a4f04d 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -21,35 +21,46 @@ #define SERVATRICE_H #include "metrics_registry.h" +#include "smtpclient.h" +#include #include #include +#include +#include #include #include +#include #include -#include #include #include +#include + +// IWYU pragma: keep +// Q_DECLARE_METATYPE below needs the complete type. +#include #include #include +#include #include #include #include +#include #include #include +class QObject; +class QThread; +class SessionEvent; + Q_DECLARE_METATYPE(QSqlDatabase) -class QSqlQuery; class QTimer; - -class GameReplay; class Servatrice; class Servatrice_ConnectionPool; class Servatrice_DatabaseInterface; class AbstractServerSocketInterface; class IslInterface; -class FeatureSet; class Servatrice_GameServer : public QTcpServer { @@ -171,6 +182,7 @@ private: QMap serverRequiredFeatureList; QString officialWarnings; Servatrice_DatabaseInterface *servatriceDatabaseInterface; + bool cleanupDatabaseForEmail(const QString &userName, EmailType type, const QString &token, qint64 rowId); int serverId; int uptime; QMutex txBytesMutex, rxBytesMutex; @@ -221,6 +233,12 @@ public slots: void scheduleShutdown(const QString &reason, int minutes); void updateLoginMessage(); void setRequiredFeatures(const QString &featureList); + void onEmailDelivered(const QString &userName, EmailType type, const QString &token, qint64 rowId); + void onEmailPermanentlyFailed(const QString &userName, + EmailType type, + FailureReason reason, + const QString &token, + qint64 rowId); public: explicit Servatrice(QObject *parent = nullptr); diff --git a/servatrice/src/servatrice_connection_pool.h b/servatrice/src/servatrice_connection_pool.h index 7479122cf..ddd12fc95 100644 --- a/servatrice/src/servatrice_connection_pool.h +++ b/servatrice/src/servatrice_connection_pool.h @@ -4,6 +4,7 @@ #include #include #include +#include class Servatrice_DatabaseInterface; diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index bb67d78eb..ac3a19c8e 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -1,24 +1,46 @@ #include "servatrice_database_interface.h" #include "deck_tag_serialization.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_chat_message.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_game.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_moderator_login.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user_alt.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_user_session.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_warning.pb.h" #include "servatrice.h" -#include "serversocketinterface.h" +#include "server.h" +#include "server_protocolhandler.h" #include "settingscache.h" +#include #include #include #include -#include #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include #include #include #include #include +#include +#include +#include inline Q_LOGGING_CATEGORY(DatabaseInterfaceLog, "database_interface"); diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index ce51a2474..0509d1a03 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -1,18 +1,26 @@ #ifndef SERVATRICE_DATABASE_INTERFACE_H #define SERVATRICE_DATABASE_INTERFACE_H -#include +#include "libcockatrice/protocol/pb/serverinfo_user.pb.h" + #include -#include +#include #include +#include +#include +#include +#include #include #include #include #include #include +#include #include #include +class QSqlQuery; + #define DATABASE_SCHEMA_VERSION 37 class Servatrice; diff --git a/servatrice/src/server_logger.cpp b/servatrice/src/server_logger.cpp index 620780052..1972444f1 100644 --- a/servatrice/src/server_logger.cpp +++ b/servatrice/src/server_logger.cpp @@ -6,8 +6,16 @@ #include #include #include +#include +#include #include +#include +#include +#include #include +#include +#include +#include ServerLogger::ServerLogger(bool _logToConsole, QObject *parent) : QObject(parent), logToConsole(_logToConsole), flushRunning(false) diff --git a/servatrice/src/server_logger.h b/servatrice/src/server_logger.h index 0ad092b66..f2875a6a3 100644 --- a/servatrice/src/server_logger.h +++ b/servatrice/src/server_logger.h @@ -1,14 +1,14 @@ #ifndef SERVER_LOGGER_H #define SERVER_LOGGER_H +#include #include #include +#include #include -#include -#include +#include class QFile; -class Server_ProtocolHandler; class ServerLogger : public QObject { diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index a8d13675d..5f5d1ced5 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -22,28 +22,63 @@ #include "deck_tag_serialization.h" #include "email_parser.h" +#include "libcockatrice/protocol/pb/admin_commands.pb.h" +#include "libcockatrice/protocol/pb/developer_commands.pb.h" +#include "libcockatrice/protocol/pb/moderator_commands.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_deck_share_item.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_deck_share_summary.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_replay_match.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_report.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_warning.pb.h" +#include "libcockatrice/protocol/pb/session_commands.pb.h" +#include "libcockatrice/protocol/pb/session_event.pb.h" +#include "libcockatrice/utility/card_ref.h" #include "main.h" +#include "metrics_registry.h" #include "servatrice.h" #include "servatrice_database_interface.h" +#include "server.h" +#include "server_database_interface.h" #include "server_logger.h" +#include "server_protocolhandler.h" #include "settingscache.h" #include "version_string.h" +#include +#include #include #include #include #include #include #include +#include +#include #include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include #include #include #include +#include +#include +#include +#include #include -#include +#include #include +#include +#include +#include +#include #include #include #include @@ -75,6 +110,7 @@ #include #include #include +#include #include #include #include @@ -85,8 +121,6 @@ #include #include #include -#include -#include #include #include #include @@ -131,9 +165,16 @@ #include #include #include +#include +#include +#include #include #include +#include #include +#include + +class QObject; inline Q_LOGGING_CATEGORY(AbstractServerSocketInterfaceLog, "abstract_server_socket_interface"); inline Q_LOGGING_CATEGORY(TcpServerSocketInterfaceLog, "tcp_server_socket_interface"); @@ -141,6 +182,9 @@ inline Q_LOGGING_CATEGORY(WebsocketServerSocketInterfaceLog, "websocket_server_s static const int protocolVersion = 14; +// Maximum size of a single TCP protocol message. Matches the websocket limit. +static const int MAX_TCP_MESSAGE_SIZE = 1500000; + AbstractServerSocketInterface::AbstractServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, QObject *parent) @@ -391,6 +435,8 @@ Response::ResponseCode AbstractServerSocketInterface::processExtendedModeratorCo return cmdReportAssign(cmd.GetExtension(Command_ReportAssign::ext), rc); case ModeratorCommand::REPORT_RESOLVE: return cmdReportResolve(cmd.GetExtension(Command_ReportResolve::ext), rc); + case ModeratorCommand::REPORT_REOPEN: + return cmdReportReopen(cmd.GetExtension(Command_ReportReopen::ext), rc); case ModeratorCommand::VIEWLOG_HISTORY: return cmdGetLogHistory(cmd.GetExtension(Command_ViewLogHistory::ext), rc, true); case ModeratorCommand::GRANT_REPLAY_ACCESS: @@ -1940,6 +1986,29 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com return Response::RespOk; } +namespace +{ +int reportUserLevel(bool userExists, int adminFlags) +{ + int userLevel = ServerInfo_User::IsUser; + if (userExists) { + userLevel |= ServerInfo_User::IsRegistered; + if (adminFlags & 1) { + userLevel |= ServerInfo_User::IsAdmin | ServerInfo_User::IsModerator; + } else if (adminFlags & 2) { + userLevel |= ServerInfo_User::IsModerator; + } + if (adminFlags & 4) { + userLevel |= ServerInfo_User::IsJudge; + } + if (adminFlags & 8) { + userLevel |= ServerInfo_User::IsDeveloper; + } + } + return userLevel; +} +} // namespace + Response::ResponseCode AbstractServerSocketInterface::cmdReportList(const Command_ReportList &cmd, ResponseContainer &rc) { @@ -1953,8 +2022,9 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportList(const Comman // Columns: 0=id, 1=reporter_name, 2=reported_user_name, 3=game_id, // 4=category, 5=description, 6=created_at, 7=status, - // 8=resolution_note, 9=assigned_mod_name, - // 10=room_id, 11=replay_id + // 8=resolution_note, 9=assigned_mod_name, 10=resolved_by_name, + // 11=room_id, 12=replay_id, + // 13=reported_user_id, 14=reported_user_admin QString whereClause; if (unresolvedOnly) { whereClause = "WHERE r.status = 'open' OR r.status = 'assigned' "; @@ -1969,11 +2039,13 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportList(const Comman QString queryStr = "SELECT r.id, r.reporter_name, r.reported_user_name, r.game_id, " "r.category, r.description, r.created_at, r.status, " - "r.resolution_note, u.name AS assigned_mod_name, r.room_id, " + "r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.room_id, " "(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) " - "AS replay_id " + "AS replay_id, u2.id AS reported_user_id, u2.admin AS reported_user_admin " "FROM {prefix}_reports r " - "LEFT JOIN {prefix}_users u ON r.assigned_to = u.id "; + "LEFT JOIN {prefix}_users u ON r.assigned_to = u.id " + "LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id " + "LEFT JOIN {prefix}_users u2 ON u2.name = r.reported_user_name "; if (unresolvedOnly) { queryStr += "WHERE r.status = 'open' OR r.status = 'assigned' "; @@ -2014,14 +2086,19 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportList(const Comman if (!query->value(9).isNull()) { info->set_assigned_mod_name(query->value(9).toString().toStdString()); } - if (!query->value(10).isNull()) { - info->set_room_id(query->value(10).toInt()); + info->set_resolved_by_name(query->value(10).toString().toStdString()); } if (!query->value(11).isNull()) { - info->set_replay_id(query->value(11).toInt()); + info->set_room_id(query->value(11).toInt()); } + + if (!query->value(12).isNull()) { + info->set_replay_id(query->value(12).toInt()); + } + + info->set_reported_user_level(reportUserLevel(!query->value(13).isNull(), query->value(14).toInt())); } rc.setResponseExtension(re); @@ -2694,11 +2771,13 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportMyList(const Comm QString queryStr = "SELECT r.id, r.reporter_name, r.reported_user_name, r.game_id, " "r.category, r.description, r.created_at, r.status, " - "r.resolution_note, u.name AS assigned_mod_name, r.room_id, " + "r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.room_id, " "(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) " - "AS replay_id " + "AS replay_id, u2.id AS reported_user_id, u2.admin AS reported_user_admin " "FROM {prefix}_reports r " "LEFT JOIN {prefix}_users u ON r.assigned_to = u.id " + "LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id " + "LEFT JOIN {prefix}_users u2 ON u2.name = r.reported_user_name " "WHERE r.reporter_id = :reporter_id " "ORDER BY r.created_at DESC LIMIT 200"; @@ -2734,20 +2813,61 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportMyList(const Comm if (!query->value(9).isNull()) { info->set_assigned_mod_name(query->value(9).toString().toStdString()); } - if (!query->value(10).isNull()) { - info->set_room_id(query->value(10).toInt()); + info->set_resolved_by_name(query->value(10).toString().toStdString()); } if (!query->value(11).isNull()) { - info->set_replay_id(query->value(11).toInt()); + info->set_room_id(query->value(11).toInt()); } + + if (!query->value(12).isNull()) { + info->set_replay_id(query->value(12).toInt()); + } + + info->set_reported_user_level(reportUserLevel(!query->value(13).isNull(), query->value(14).toInt())); } rc.setResponseExtension(re); return Response::RespOk; } +Response::ResponseCode AbstractServerSocketInterface::cmdReportReopen(const Command_ReportReopen &cmd, + ResponseContainer & /*rc*/) +{ + if (!sqlInterface->checkSql()) { + return Response::RespInternalError; + } + + int reportId = cmd.report_id(); + QString note = textFromStdString(cmd.reopen_note()); + + QSqlQuery *query = sqlInterface->prepareQuery("UPDATE {prefix}_reports " + "SET status = 'open', resolution_note = NULL, " + "resolution_time = NULL, resolved_by = NULL, assigned_to = NULL, " + "notified = 0 " + "WHERE id = :id AND status IN ('resolved', 'dismissed')"); + + query->bindValue(":id", reportId); + + if (!sqlInterface->execSqlQuery(query)) { + return Response::RespInternalError; + } + + if (query->numRowsAffected() == 0) { + return Response::RespInvalidData; + } + + QString auditDetails = QString("Report #%1 reopened").arg(reportId); + if (!note.isEmpty()) { + auditDetails += QString(". Reason: %1").arg(note.left(200)); + } + sqlInterface->addAuditRecord(QString::number(reportId), this->getAddress(), + QString::fromStdString(userInfo->clientid()), "REPORT_REOPENED", auditDetails, true); + + return Response::RespOk; +} + Response::ResponseCode AbstractServerSocketInterface::cmdReportDetails(const Command_ReportDetails &cmd, ResponseContainer &rc) { @@ -2763,17 +2883,19 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportDetails(const Com // Columns: 0=id, 1=reporter_id, 2=reporter_name, 3=reported_user_name, 4=game_id, // 5=category, 6=description, 7=created_at, 8=status, - // 9=resolution_note, 10=assigned_mod_name, 11=chat_log, - // 12=room_id, 13=resolution_time, 14=replay_id - QString queryStr = "SELECT r.id, r.reporter_id, r.reporter_name, r.reported_user_name, r.game_id, " - "r.category, r.description, r.created_at, r.status, " - "r.resolution_note, u.name AS assigned_mod_name, r.chat_log, r.room_id, " - "r.resolution_time, " - "(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) " - "AS replay_id " - "FROM {prefix}_reports r " - "LEFT JOIN {prefix}_users u ON r.assigned_to = u.id " - "WHERE r.id = :id"; + // 9=resolution_note, 10=assigned_mod_name, 11=resolved_by_name, + // 12=chat_log, 13=room_id, 14=resolution_time, 15=replay_id + QString queryStr = + "SELECT r.id, r.reporter_id, r.reporter_name, r.reported_user_name, r.game_id, " + "r.category, r.description, r.created_at, r.status, " + "r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.chat_log, r.room_id, " + "r.resolution_time, " + "(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) " + "AS replay_id " + "FROM {prefix}_reports r " + "LEFT JOIN {prefix}_users u ON r.assigned_to = u.id " + "LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id " + "WHERE r.id = :id"; QSqlQuery *query = sqlInterface->prepareQuery(queryStr); query->bindValue(":id", reportId); @@ -2812,21 +2934,24 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportDetails(const Com if (!query->value(10).isNull()) { info->set_assigned_mod_name(query->value(10).toString().toStdString()); } - if (!query->value(11).isNull()) { - info->set_chat_log(query->value(11).toString().toStdString()); + info->set_resolved_by_name(query->value(11).toString().toStdString()); } if (!query->value(12).isNull()) { - info->set_room_id(query->value(12).toInt()); + info->set_chat_log(query->value(12).toString().toStdString()); } if (!query->value(13).isNull()) { - info->set_resolution_time(query->value(13).toDateTime().toSecsSinceEpoch()); + info->set_room_id(query->value(13).toInt()); } if (!query->value(14).isNull()) { - info->set_replay_id(query->value(14).toInt()); + info->set_resolution_time(query->value(14).toDateTime().toSecsSinceEpoch()); + } + + if (!query->value(15).isNull()) { + info->set_replay_id(query->value(15).toInt()); } QSqlQuery *commentQuery = @@ -4186,13 +4311,21 @@ void TcpServerSocketInterface::readClient() (((quint32)(unsigned char)inputBuffer[1]) << 16) + (((quint32)(unsigned char)inputBuffer[2]) << 8) + ((quint32)(unsigned char)inputBuffer[3]); + // Reject implausible lengths instead of buffering until they arrive. + // This also handles lengths that overflow into negative int values. + if (messageLength < 0 || messageLength > MAX_TCP_MESSAGE_SIZE) { + qCWarning(TcpServerSocketInterfaceLog) + << "Invalid message length" << messageLength << "from" << getAddress(); + prepareDestroy(); + return; + } inputBuffer.remove(0, 4); messageInProgress = true; } else { return; } } - if (inputBuffer.size() < messageLength || messageLength < 0) { + if (inputBuffer.size() < messageLength) { return; } @@ -4298,10 +4431,15 @@ void WebsocketServerSocketInterface::initConnection(void *_socket) QByteArray websocketIPHeader = settingsCache->value("server/web_socket_ip_header", "").toByteArray(); if (websocketIPHeader.length() > 0 && socket->request().hasRawHeader(websocketIPHeader)) { - QString header(socket->request().rawHeader(websocketIPHeader)); - QHostAddress parsed(header); - if (!parsed.isNull()) { - address = parsed; + // Only trust the forwarded header if the connection itself comes from a trusted proxy, + // otherwise a client could spoof its address to bypass bans and rate limits. + QString trustedSources = settingsCache->value("security/trusted_sources", "127.0.0.1,::1").toString(); + if (trustedSources.contains(socket->peerAddress().toString(), Qt::CaseInsensitive)) { + QString header(socket->request().rawHeader(websocketIPHeader)); + QHostAddress parsed(header); + if (!parsed.isNull()) { + address = parsed; + } } } diff --git a/servatrice/src/serversocketinterface.h b/servatrice/src/serversocketinterface.h index 36b900d28..7de742c66 100644 --- a/servatrice/src/serversocketinterface.h +++ b/servatrice/src/serversocketinterface.h @@ -20,28 +20,26 @@ #ifndef SERVERSOCKETINTERFACE_H #define SERVERSOCKETINTERFACE_H +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/server_message.pb.h" + +#include +#include #include +#include #include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include class Servatrice; class Servatrice_DatabaseInterface; class DeckList; class ServerInfo_DeckStorage_Folder; - class Command_AddToList; class Command_RemoveFromList; class Command_DeckList; @@ -64,16 +62,52 @@ class Command_ReplayModifyMatch; class Command_ReplayDeleteMatch; class Command_ReplayGetCode; class Command_ReplaySubmitCode; - class Command_BanFromServer; class Command_UpdateServerMessage; class Command_ShutdownServer; class Command_ReloadConfig; class Command_ReplayDownloadByGameId; - class Command_AccountEdit; class Command_AccountImage; class Command_AccountPassword; +class Command_Activate; +class Command_AddCardArtRule; +class Command_AdjustMod; +class Command_ForceActivateUser; +class Command_ForgotPasswordChallenge; +class Command_ForgotPasswordRequest; +class Command_ForgotPasswordReset; +class Command_GetAdminNotes; +class Command_GetBanHistory; +class Command_GetModeratorLastLogins; +class Command_GetServerStats; +class Command_GetUserAlts; +class Command_GetUserSessions; +class Command_GetWarnHistory; +class Command_GetWarnList; +class Command_GrantReplayAccess; +class Command_ListCardArtRules; +class Command_Register; +class Command_RemoveCardArtRule; +class Command_RemoveUserAvatar; +class Command_Report; +class Command_ReportAddComment; +class Command_ReportAssign; +class Command_ReportDetails; +class Command_ReportList; +class Command_ReportMyList; +class Command_ReportReopen; +class Command_ReportResolve; +class Command_ReportStats; +class Command_ReportUserInfo; +class Command_RequestPasswordSalt; +class Command_ResetUserPassword; +class Command_SetCardArtParams; +class Command_UpdateAdminNotes; +class Command_ViewLogHistory; +class Command_WarnUser; +class QObject; +class ResponseContainer; class AbstractServerSocketInterface : public Server_ProtocolHandler { @@ -148,6 +182,7 @@ private: Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc); Response::ResponseCode cmdReportAssign(const Command_ReportAssign &cmd, ResponseContainer &); Response::ResponseCode cmdReportResolve(const Command_ReportResolve &cmd, ResponseContainer &); + Response::ResponseCode cmdReportReopen(const Command_ReportReopen &cmd, ResponseContainer &); Response::ResponseCode cmdReportUserInfo(const Command_ReportUserInfo &cmd, ResponseContainer &rc); Response::ResponseCode cmdReportStats(const Command_ReportStats &cmd, ResponseContainer &rc); Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc); diff --git a/servatrice/src/settingscache.cpp b/servatrice/src/settingscache.cpp index f6c862904..4ecac7319 100644 --- a/servatrice/src/settingscache.cpp +++ b/servatrice/src/settingscache.cpp @@ -4,6 +4,13 @@ #include #include #include +#include +#include +#include +#include +#include + +class QObject; SettingsCache::SettingsCache(const QString &fileName, QSettings::Format format, QObject *parent) : QSettings(fileName, format, parent) diff --git a/servatrice/src/settingscache.h b/servatrice/src/settingscache.h index 6922d3508..817a62bfa 100644 --- a/servatrice/src/settingscache.h +++ b/servatrice/src/settingscache.h @@ -5,6 +5,9 @@ #include #include #include +#include + +class QObject; class SettingsCache : public QSettings { diff --git a/servatrice/src/signalhandler.cpp b/servatrice/src/signalhandler.cpp index b4513979f..32cd5b206 100644 --- a/servatrice/src/signalhandler.cpp +++ b/servatrice/src/signalhandler.cpp @@ -5,6 +5,10 @@ #include "settingscache.h" #include +#include +#include +#include +#include #ifdef Q_OS_UNIX #include diff --git a/servatrice/src/signalhandler.h b/servatrice/src/signalhandler.h index bf8d9e52a..82652a43a 100644 --- a/servatrice/src/signalhandler.h +++ b/servatrice/src/signalhandler.h @@ -2,6 +2,7 @@ #define SIGNALHANDLER_H #include +#include class QSocketNotifier; diff --git a/servatrice/src/smtp/qxtsmtp.cpp b/servatrice/src/smtp/qxtsmtp.cpp index c81e0955c..a4da649f7 100644 --- a/servatrice/src/smtp/qxtsmtp.cpp +++ b/servatrice/src/smtp/qxtsmtp.cpp @@ -94,6 +94,38 @@ int QxtSmtp::pendingMessages() const return qxt_d().pending.count(); } +/*! + * \brief Drops all queued (not yet transmitted) messages without sending them. + * + * Any message still awaiting delivery is discarded. This is used by callers that + * keep their own authoritative queue and wish to rebuild the SMTP buffer from scratch + * (e.g. after a reconnect) without risking duplicates. + */ +void QxtSmtp::clearPending() +{ + qxt_d().pending.clear(); +} + +/*! + * \brief Clears the outgoing queue and resets the SMTP state machine. + * + * Unlike clearPending(), this also resets the internal state to Disconnected so + * that subsequent send() calls will not fire sendNext() prematurely on a + * not-yet-connected socket. Use this when rebuilding the queue from scratch + * before a fresh connectToHost() / connectToSecureHost() cycle. + */ +void QxtSmtp::reset() +{ + qxt_d().pending.clear(); + qxt_d().extensions.clear(); + qxt_d().buffer.clear(); + qxt_d().recipients.clear(); + qxt_d().rcptNumber = 0; + qxt_d().rcptAck = 0; + qxt_d().mailAck = false; + qxt_d().state = QxtSmtpPrivate::Disconnected; +} + QTcpSocket *QxtSmtp::socket() const { return qxt_d().socket; diff --git a/servatrice/src/smtp/qxtsmtp.h b/servatrice/src/smtp/qxtsmtp.h index 747e22df9..d264d1047 100644 --- a/servatrice/src/smtp/qxtsmtp.h +++ b/servatrice/src/smtp/qxtsmtp.h @@ -66,6 +66,8 @@ public: int send(const QxtMailMessage& message); int pendingMessages() const; + void clearPending(); + void reset(); QTcpSocket* socket() const; void connectToHost(const QString& hostName, quint16 port = 25); diff --git a/servatrice/src/smtpclient.cpp b/servatrice/src/smtpclient.cpp index 3ec333413..82824e496 100644 --- a/servatrice/src/smtpclient.cpp +++ b/servatrice/src/smtpclient.cpp @@ -1,15 +1,62 @@ #include "smtpclient.h" #include "settingscache.h" +#include "smtp/qxtmailmessage.h" #include "smtp/qxtsmtp.h" +#include +#include +#include +#include +#include #include +#include #include +#include +#include +#include + +static const qint64 DEFAULT_MAX_RETRIES = 5; +static const qint64 DEFAULT_RETRY_DELAY = 60; +static const qint64 MAX_RETRY_DELAY = 1800; // 30 minutes +static const qint64 IDLE_TIMEOUT_MS = 60000; // 60 seconds +// Maximum bit-shift exponent used in the exponential back-off formula. +// With a base delay of 60 s, shift 10 gives 60 * 1024 ≈ 17 h before the +// MAX_RETRY_DELAY cap is applied, preventing unbounded intermediate values. +static const int MAX_BACKOFF_SHIFT = 10; + +inline Q_LOGGING_CATEGORY(SmtpClientLog, "smtp_client") + +static QString pendingKey(const QString &userName, EmailType type, const QString &token) +{ + const char *typeName = (type == EmailType::Activation) ? "activation" : "forgotpassword"; + // The token is part of the key: a regenerated token (forgot-password issues a + // fresh one per request) must not be suppressed by a stale pending entry. + return userName + '/' + typeName + '/' + token; +} + +// True only for permanent 5xx replies. Anything else (4xx greylisting/rate +// limiting, or an unparsable reply) must be retried, never treated as final: +// destroying the durable queue row on a transient failure loses the mail. +static bool isPermanentSmtpReply(const QByteArray &msg) +{ + for (char c : msg) { + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '-') { + continue; + } + return c == '5'; + } + return false; +} SmtpClient::SmtpClient(QObject *parent) : QObject(parent) { smtp = new QxtSmtp(this); + idleTimer = new QTimer(this); + idleTimer->setSingleShot(true); + connect(idleTimer, SIGNAL(timeout()), this, SLOT(idleTimeout())); + connect(smtp, SIGNAL(authenticated()), this, SLOT(authenticated())); connect(smtp, SIGNAL(authenticationFailed(const QByteArray &)), this, SLOT(authenticationFailed(const QByteArray &))); @@ -32,104 +79,151 @@ SmtpClient::~SmtpClient() { if (smtp) { delete smtp; - smtp = 0; + smtp = nullptr; } } +int SmtpClient::maxRetries() const +{ + // Bounded like retryDelaySeconds(): an unset/blank value must not turn the + // first transient failure into a permanent one (attempts >= 0 is immediate). + return qBound(1, settingsCache->value("smtp/maxretries", DEFAULT_MAX_RETRIES).toInt(), 100); +} + +int SmtpClient::retryDelaySeconds() const +{ + return qBound(1, settingsCache->value("smtp/retrydelay", DEFAULT_RETRY_DELAY).toInt(), + static_cast(MAX_RETRY_DELAY)); +} + +QDateTime SmtpClient::nextRetryTime(int attempts, int retryDelay) const +{ + // Exponential backoff, capped to avoid hammering an unreachable server. + const int shift = qMax(0, qMin(attempts - 1, MAX_BACKOFF_SHIFT)); + const qint64 delay = qMin(retryDelay * qint64(1) << shift, MAX_RETRY_DELAY); + return QDateTime::currentDateTime().addSecs(delay); +} + +SmtpClient::PendingEmail SmtpClient::buildEmail(const QString &nickname, + EmailType type, + const QString &subject, + const QString &body, + const QString &recipient, + const QString &token, + const QString &email, + qint64 rowId) +{ + QString name = settingsCache->value("smtp/name", "").toString(); + + PendingEmail pending; + pending.userName = nickname; + pending.type = type; + pending.token = token; + pending.rowId = rowId; + pending.maxAttempts = maxRetries(); + pending.retryDelay = retryDelaySeconds(); + pending.nextAttempt = QDateTime::currentDateTime(); + + QString emailBody = body; + emailBody.replace("%username", nickname).replace("%token", token); + + pending.message.setSender(name + " <" + email + ">"); + pending.message.addRecipient(recipient); + pending.message.setSubject(subject); + pending.message.setBody(emailBody); + + return pending; +} + +bool SmtpClient::enqueue(const PendingEmail &email) +{ + const QString key = pendingKey(email.userName, email.type, email.token); + if (pendingEmails.contains(key)) { + qCDebug(SmtpClientLog) << "Email already pending for" << email.userName << "- not duplicating"; + return false; + } + + // A fresher database row for the same user/type supersedes a stale pending + // entry: drop the stale one so only the current token is ever delivered. + // (Any in-flight mapping for the dropped key is removed as well; the + // mailSent/recordFailed lookups tolerate missing entries.) + for (auto it = pendingEmails.begin(); it != pendingEmails.end();) { + if (it.value().userName == email.userName && it.value().type == email.type) { + for (auto mapIt = mailIdToUser.begin(); mapIt != mailIdToUser.end();) { + if (mapIt.value() == it.key()) { + mapIt = mailIdToUser.erase(mapIt); + } else { + ++mapIt; + } + } + qCDebug(SmtpClientLog) << "Replacing stale pending email for" << email.userName; + it = pendingEmails.erase(it); + } else { + ++it; + } + } + + pendingEmails.insert(key, email); + qCDebug(SmtpClientLog) << "Enqueued" << (email.type == EmailType::Activation ? "activation" : "password reset") + << "mail to" << email.userName; + return true; +} + bool SmtpClient::enqueueActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token) { - QString email = settingsCache->value("smtp/email", "").toString(); - QString name = settingsCache->value("smtp/name", "").toString(); + if (pendingEmails.contains(pendingKey(nickname, EmailType::Activation, token))) { + qCDebug(SmtpClientLog) << "Activation email already pending for" << nickname << "- skipping"; + return false; + } + QString subject = settingsCache->value("smtp/subject", "").toString(); QString body = settingsCache->value("smtp/body", "").toString(); + QString email = settingsCache->value("smtp/email", "").toString(); - if (email.isEmpty()) { - qDebug() << "[MAIL] Missing sender email in configuration"; + if (!validateEmailFields(email, subject, body, recipient, token, nickname)) { return false; } - if (subject.isEmpty()) { - qDebug() << "[MAIL] Missing subject field in configuration"; - return false; - } - - if (body.isEmpty()) { - qDebug() << "[MAIL] Missing body field in configuration"; - return false; - } - - if (recipient.isEmpty()) { - qDebug() << "[MAIL] Missing recipient field for user " << nickname; - return false; - } - - if (token.isEmpty()) { - qDebug() << "[MAIL] Missing token field for user " << nickname; - return false; - } - - QxtMailMessage message; - message.setSender(name + " <" + email + ">"); - message.addRecipient(recipient); - message.setSubject(subject); - message.setBody(body.replace("%username", nickname).replace("%token", token)); - - int id = smtp->send(message); - qDebug() << "[MAIL] Enqueued mail to" << recipient << "as" << id; - return true; + return enqueue(buildEmail(nickname, EmailType::Activation, subject, body, recipient, token, email)); } -bool SmtpClient::enqueueForgotPasswordTokenMail(const QString &nickname, const QString &recipient, const QString &token) +bool SmtpClient::enqueueForgotPasswordTokenMail(const QString &nickname, + const QString &recipient, + const QString &token, + qint64 rowId) { - QString email = settingsCache->value("smtp/email", "").toString(); - QString name = settingsCache->value("smtp/name", "").toString(); + if (pendingEmails.contains(pendingKey(nickname, EmailType::ForgotPassword, token))) { + qCDebug(SmtpClientLog) << "Password reset email already pending for" << nickname << "- skipping"; + return false; + } + QString subject = settingsCache->value("forgotpassword/subject", "").toString(); QString body = settingsCache->value("forgotpassword/body", "").toString(); + QString email = settingsCache->value("smtp/email", "").toString(); - if (email.isEmpty()) { - qDebug() << "[MAIL] Missing sender email in configuration"; + if (!validateEmailFields(email, subject, body, recipient, token, nickname)) { return false; } - if (subject.isEmpty()) { - qDebug() << "[MAIL] Missing subject field in configuration"; - return false; - } - - if (body.isEmpty()) { - qDebug() << "[MAIL] Missing body field in configuration"; - return false; - } - - if (recipient.isEmpty()) { - qDebug() << "[MAIL] Missing recipient field for user " << nickname; - return false; - } - - if (token.isEmpty()) { - qDebug() << "[MAIL] Missing token field for user " << nickname; - return false; - } - - QxtMailMessage message; - message.setSender(name + " <" + email + ">"); - message.addRecipient(recipient); - message.setSubject(subject); - message.setBody(body.replace("%username", nickname).replace("%token", token)); - - int id = smtp->send(message); - qDebug() << "[MAIL] Enqueued mail to" << recipient << "as" << id; - return true; + return enqueue(buildEmail(nickname, EmailType::ForgotPassword, subject, body, recipient, token, email, rowId)); } void SmtpClient::sendAllEmails() { // still connected from the previous round - if (smtp->socket()->state() == QAbstractSocket::ConnectedState) { + if (smtp->socket()->state() == QAbstractSocket::ConnectedState || + smtp->socket()->state() == QAbstractSocket::ConnectingState || + smtp->socket()->state() == QAbstractSocket::HostLookupState || + smtp->socket()->state() == QAbstractSocket::ClosingState) { return; } - if (smtp->pendingMessages() == 0) { + if (pendingEmails.isEmpty()) { + return; + } + + // Respect connection-level backoff after auth/conn/encryption failures. + if (connectionAttempts > 0 && QDateTime::currentDateTime() < connectionBackoffUntil) { return; } @@ -143,6 +237,16 @@ void SmtpClient::sendAllEmails() smtp->setUsername(username); smtp->setPassword(password); + // Push due emails into QxtSmtp *before* connecting so they are already + // queued when the authenticated() signal fires and QxtSmtp's internal + // sendNext() runs. + relayoutForSending(); + + // Nothing due right now — skip the SMTP round-trip. + if (mailIdToUser.isEmpty()) { + return; + } + // Connect if (connectionType == "ssl") { if (acceptAllCerts) { @@ -154,64 +258,286 @@ void SmtpClient::sendAllEmails() } } -void SmtpClient::authenticated() +void SmtpClient::relayoutForSending() { - qDebug() << "[MAIL] authenticated"; -} + // Rebuild the SMTP buffer exclusively from our authoritative set, so a reconnect + // after a partial transmission never results in duplicate deliveries. + // reset() also clears the internal state machine so that send() does not + // fire sendNext() prematurely on a not-yet-connected socket. + smtp->reset(); + mailIdToUser.clear(); -void SmtpClient::authenticationFailed(const QByteArray &msg) -{ - qDebug() << "[MAIL] authenticationFailed" << QString(msg); -} - -void SmtpClient::connected() -{ - qDebug() << "[MAIL] connected"; -} - -void SmtpClient::connectionFailed(const QByteArray &msg) -{ - qDebug() << "[MAIL] connectionFailed" << QString(msg); -} - -void SmtpClient::disconnected() -{ - qDebug() << "[MAIL] disconnected"; -} - -void SmtpClient::encrypted() -{ - qDebug() << "[MAIL] encrypted"; -} - -void SmtpClient::encryptionFailed(const QByteArray &msg) -{ - qDebug() << "[MAIL] encryptionFailed" << QString(msg); - qDebug() << "[MAIL] Try enabling the \"acceptallcerts\" option in servatrice.ini"; + const QDateTime now = QDateTime::currentDateTime(); + for (auto it = pendingEmails.begin(); it != pendingEmails.end(); ++it) { + PendingEmail &pending = it.value(); + if (pending.nextAttempt > now) { + continue; // not yet due; honours the backoff schedule + } + int id = smtp->send(pending.message); + mailIdToUser.insert(id, pendingKey(pending.userName, pending.type, pending.token)); + } } void SmtpClient::finished() { - qDebug() << "[MAIL] finished"; + qCDebug(SmtpClientLog) << "finished"; smtp->disconnectFromHost(); } +void SmtpClient::authenticated() +{ + qCDebug(SmtpClientLog) << "authenticated"; + // The session has actually succeeded (TCP connect alone proves nothing: + // TLS/auth may still fail), so the connection-level backoff resets here. + connectionAttempts = 0; + // Start the idle timer here, once the connection is fully ready to send, + // rather than on TCP connect: SSL/STARTTLS handshake and auth may take a + // while and must not be cut short by the idle timeout. + idleTimer->start(IDLE_TIMEOUT_MS); +} + +void SmtpClient::authenticationFailed(const QByteArray &msg) +{ + qCWarning(SmtpClientLog) << "authenticationFailed" << QString::fromUtf8(msg); + idleTimer->stop(); + recordConnectionFailure(); + mailIdToUser.clear(); + smtp->disconnectFromHost(); +} + +void SmtpClient::connected() +{ + qCDebug(SmtpClientLog) << "connected"; + // NOTE: connectionAttempts is deliberately not reset here. This fires on + // TCP connect, before the TLS handshake and AUTH; resetting here would pin + // the connection-level backoff at its base delay for exactly the failures + // (bad password/cert/STARTTLS) it is meant to cover. It resets in + // authenticated() and on the first successful mailSent instead. +} + +void SmtpClient::connectionFailed(const QByteArray &msg) +{ + qCWarning(SmtpClientLog) << "connectionFailed" << QString::fromUtf8(msg); + idleTimer->stop(); + recordConnectionFailure(); + mailIdToUser.clear(); + smtp->disconnectFromHost(); +} + +void SmtpClient::disconnected() +{ + qCDebug(SmtpClientLog) << "disconnected - emails still pending:" << pendingEmails.count(); + idleTimer->stop(); + // A mid-session drop (peer close/RST past the connect phase, or the idle + // timeout firing mid-batch) emits no mailFailed/connectionFailed signal, so + // route every in-flight mail through recordFailed(): otherwise attempts and + // backoff are bypassed and the mails requeue with stale state forever. + const QList inFlight = mailIdToUser.keys(); + for (int mailID : inFlight) { + recordFailed(mailID); + } + mailIdToUser.clear(); +} + +void SmtpClient::encrypted() +{ + qCDebug(SmtpClientLog) << "encrypted"; +} + +void SmtpClient::encryptionFailed(const QByteArray &msg) +{ + qCWarning(SmtpClientLog) << "encryptionFailed" << QString::fromUtf8(msg); + qCWarning(SmtpClientLog) << "Try enabling the \"acceptallcerts\" option in servatrice.ini"; + idleTimer->stop(); + recordConnectionFailure(); + mailIdToUser.clear(); + smtp->disconnectFromHost(); +} + +void SmtpClient::idleTimeout() +{ + qCDebug(SmtpClientLog) << "idle timeout - disconnecting"; + smtp->disconnectFromHost(); +} + +void SmtpClient::recordFailed(int mailID) +{ + auto it = mailIdToUser.find(mailID); + if (it == mailIdToUser.end()) { + return; + } + const QString key = it.value(); + mailIdToUser.erase(it); + + auto pendingIt = pendingEmails.find(key); + if (pendingIt == pendingEmails.end()) { + return; + } + + PendingEmail &pending = pendingIt.value(); + pending.attempts++; + + if (pending.attempts >= pending.maxAttempts) { + const QString userName = pending.userName; + const EmailType type = pending.type; + const QString token = pending.token; + const qint64 rowId = pending.rowId; + qCWarning(SmtpClientLog) << "Email to" << userName << "permanently failed after" << pending.attempts + << "attempts - dropping from pending set"; + pendingEmails.erase(pendingIt); + emit mailPermanentlyFailed(userName, type, FailureReason::RetryExhausted, token, rowId); + return; + } + + pending.nextAttempt = nextRetryTime(pending.attempts, pending.retryDelay); + qCWarning(SmtpClientLog) << "Email to" << pending.userName << "failed (attempt" << pending.attempts << "of" + << pending.maxAttempts << "), retrying" << pending.nextAttempt.toString(Qt::ISODate); +} + +void SmtpClient::recordConnectionFailure() +{ + ++connectionAttempts; + connectionBackoffUntil = nextRetryTime(connectionAttempts, retryDelaySeconds()); + qCWarning(SmtpClientLog) << "Connection-layer failure #" << connectionAttempts << "- next attempt after" + << connectionBackoffUntil.toString(Qt::ISODate); + + // Connection failures count toward the per-email retry budget so that + // undeliverable mail eventually gives up rather than retrying forever. + QList keysToRemove; + for (auto it = pendingEmails.begin(); it != pendingEmails.end(); ++it) { + PendingEmail &pending = it.value(); + pending.attempts++; + if (pending.attempts >= pending.maxAttempts) { + qCWarning(SmtpClientLog) << "Email to" << pending.userName << "permanently failed after" << pending.attempts + << "connection failures - dropping from pending set"; + keysToRemove.append(it.key()); + emit mailPermanentlyFailed(pending.userName, pending.type, FailureReason::RetryExhausted, pending.token, + pending.rowId); + } + } + for (const QString &key : keysToRemove) { + pendingEmails.remove(key); + } +} + +bool SmtpClient::validateEmailFields(const QString &email, + const QString &subject, + const QString &body, + const QString &recipient, + const QString &token, + const QString &nickname) +{ + if (email.isEmpty()) { + qCCritical(SmtpClientLog) << "Missing sender email in configuration"; + return false; + } + if (subject.isEmpty()) { + qCCritical(SmtpClientLog) << "Missing subject field in configuration"; + return false; + } + if (body.isEmpty()) { + qCCritical(SmtpClientLog) << "Missing body field in configuration"; + return false; + } + if (recipient.isEmpty()) { + qCCritical(SmtpClientLog) << "Missing recipient field for user" << nickname; + return false; + } + if (token.isEmpty()) { + qCCritical(SmtpClientLog) << "Missing token field for user" << nickname; + return false; + } + return true; +} + void SmtpClient::mailFailed(int mailID, int errorCode, const QByteArray &msg) { - qDebug() << "[MAIL] mailFailed id=" << mailID << " errorCode=" << errorCode << "msg=" << QString(msg); + qCWarning(SmtpClientLog) << "mailFailed id=" << mailID << " errorCode=" << errorCode + << "msg=" << QString::fromUtf8(msg); + // Progress was made (the server answered), so the idle timer measures from + // here rather than acting as a cap on the whole session. + idleTimer->start(IDLE_TIMEOUT_MS); + recordFailed(mailID); } void SmtpClient::mailSent(int mailID) { - qDebug() << "[MAIL] mailSent" << mailID; + qCDebug(SmtpClientLog) << "mailSent" << mailID; + // A delivered mail proves the session works: reset the connection-level + // backoff and restart the idle timer from this point of progress. + connectionAttempts = 0; + idleTimer->start(IDLE_TIMEOUT_MS); + + auto it = mailIdToUser.find(mailID); + if (it == mailIdToUser.end()) { + return; + } + const QString key = it.value(); + mailIdToUser.erase(it); + + auto pendingIt = pendingEmails.find(key); + if (pendingIt == pendingEmails.end()) { + return; + } + + const QString userName = pendingIt.value().userName; + const EmailType type = pendingIt.value().type; + const QString token = pendingIt.value().token; + const qint64 rowId = pendingIt.value().rowId; + pendingEmails.erase(pendingIt); + qCDebug(SmtpClientLog) << "Delivered email to" << userName; + emit mailDelivered(userName, type, token, rowId); } void SmtpClient::recipientRejected(int mailID, const QString &address, const QByteArray &msg) { - qDebug() << "[MAIL] recipientRejected id=" << mailID << " address=" << address << "msg=" << QString(msg); + qCWarning(SmtpClientLog) << "recipientRejected id=" << mailID << " address=" << address + << "msg=" << QString::fromUtf8(msg); + if (!isPermanentSmtpReply(msg)) { + // Transient 4xx (e.g. greylisting): consume one attempt and reschedule + // with backoff instead of destroying the durable queue row. + recordFailed(mailID); + return; + } + // A rejected recipient is a permanent condition; consider the mail undeliverable. + auto it = mailIdToUser.find(mailID); + if (it != mailIdToUser.end()) { + const QString key = it.value(); + if (auto pendingIt = pendingEmails.find(key); pendingIt != pendingEmails.end()) { + const QString userName = pendingIt.value().userName; + const EmailType type = pendingIt.value().type; + const QString token = pendingIt.value().token; + const qint64 rowId = pendingIt.value().rowId; + pendingEmails.erase(pendingIt); + qCWarning(SmtpClientLog) << "Email to" << userName << "rejected - dropping from pending set"; + emit mailPermanentlyFailed(userName, type, FailureReason::RecipientRejected, token, rowId); + } + mailIdToUser.erase(it); + } } void SmtpClient::senderRejected(int mailID, const QString &address, const QByteArray &msg) { - qDebug() << "[MAIL] senderRejected id=" << mailID << " address=" << address << "msg=" << QString(msg); + qCWarning(SmtpClientLog) << "senderRejected id=" << mailID << " sender=" << address + << "msg=" << QString::fromUtf8(msg); + if (!isPermanentSmtpReply(msg)) { + // Transient 4xx on MAIL FROM (e.g. rate limiting): retry with backoff. + recordFailed(mailID); + return; + } + // A rejected sender is a permanent condition; consider the mail undeliverable. + auto it = mailIdToUser.find(mailID); + if (it != mailIdToUser.end()) { + const QString key = it.value(); + if (auto pendingIt = pendingEmails.find(key); pendingIt != pendingEmails.end()) { + const QString userName = pendingIt.value().userName; + const EmailType type = pendingIt.value().type; + const QString token = pendingIt.value().token; + const qint64 rowId = pendingIt.value().rowId; + pendingEmails.erase(pendingIt); + qCWarning(SmtpClientLog) << "Email to" << userName << "sender rejected - dropping from pending set"; + emit mailPermanentlyFailed(userName, type, FailureReason::SenderRejected, token, rowId); + } + mailIdToUser.erase(it); + } } diff --git a/servatrice/src/smtpclient.h b/servatrice/src/smtpclient.h index be97ed44d..9fc11bf36 100644 --- a/servatrice/src/smtpclient.h +++ b/servatrice/src/smtpclient.h @@ -1,24 +1,67 @@ #ifndef SMTPCLIENT_H #define SMTPCLIENT_H +#include "smtp/qxtmailmessage.h" + +#include +#include #include +#include +#include +#include class QxtSmtp; -class QxtMailMessage; +class QByteArray; + +/** + * @brief Types of e-mail the SMTP client is able to deliver. + */ +enum class EmailType +{ + Activation, + ForgotPassword +}; + +Q_DECLARE_METATYPE(EmailType) + +/** + * @brief Why a permanent e-mail delivery failure occurred. + */ +enum class FailureReason +{ + RetryExhausted, + RecipientRejected, + SenderRejected +}; + +Q_DECLARE_METATYPE(FailureReason) class SmtpClient : public QObject { Q_OBJECT public: - SmtpClient(QObject *parent = 0); - ~SmtpClient(); + SmtpClient(QObject *parent = nullptr); + ~SmtpClient() override; + +public slots: + bool enqueueActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token); + bool enqueueForgotPasswordTokenMail(const QString &nickname, + const QString &recipient, + const QString &token, + qint64 rowId = -1); + void sendAllEmails(); + +signals: + void mailDelivered(const QString &userName, EmailType type, const QString &token, qint64 rowId); + void mailPermanentlyFailed(const QString &userName, + EmailType type, + FailureReason reason, + const QString &token, + qint64 rowId); protected: QxtSmtp *smtp; -public slots: - bool enqueueActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token); - bool enqueueForgotPasswordTokenMail(const QString &nickname, const QString &recipient, const QString &token); - void sendAllEmails(); + protected slots: void authenticated(); void authenticationFailed(const QByteArray &msg); @@ -28,10 +71,55 @@ protected slots: void encrypted(); void encryptionFailed(const QByteArray &msg); void finished(); + void idleTimeout(); void mailFailed(int mailID, int errorCode, const QByteArray &msg); void mailSent(int mailID); void recipientRejected(int mailID, const QString &address, const QByteArray &msg); void senderRejected(int mailID, const QString &address, const QByteArray &msg); + +private: + struct PendingEmail + { + QString userName; + EmailType type; + QString token; + // Database row id for tables that allow multiple rows per user + // ({prefix}_forgot_password); -1 when the name alone identifies the row. + qint64 rowId = -1; + QxtMailMessage message; + int attempts = 0; + int maxAttempts = 0; + int retryDelay = 0; + QDateTime nextAttempt; + }; + + PendingEmail buildEmail(const QString &nickname, + EmailType type, + const QString &subject, + const QString &body, + const QString &recipient, + const QString &token, + const QString &email, + qint64 rowId = -1); + bool enqueue(const PendingEmail &email); + void relayoutForSending(); + QDateTime nextRetryTime(int attempts, int retryDelay) const; + void recordFailed(int mailID); + void recordConnectionFailure(); + bool validateEmailFields(const QString &email, + const QString &subject, + const QString &body, + const QString &recipient, + const QString &token, + const QString &nickname); + int maxRetries() const; + int retryDelaySeconds() const; + + QHash pendingEmails; + QHash mailIdToUser; + QTimer *idleTimer; + int connectionAttempts = 0; + QDateTime connectionBackoffUntil; }; -#endif \ No newline at end of file +#endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b51d10560..9955e1189 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,102 +2,10 @@ # If a new test needs additional Qt modules, add them there — not in individual test CMakeLists.txt files. enable_testing() -add_test(NAME dummy_test COMMAND dummy_test) -add_test(NAME expression_test COMMAND expression_test) -add_test(NAME clamped_arithmetic_test COMMAND clamped_arithmetic_test) -add_test(NAME test_age_formatting COMMAND test_age_formatting) -add_test(NAME password_hash_test COMMAND password_hash_test) -add_test(NAME playmat_resolver_test COMMAND playmat_resolver_test) -add_test(NAME server_card_counter_test COMMAND server_card_counter_test) -add_test(NAME server_counter_test COMMAND server_counter_test) -add_test(NAME server_rate_limiter_test COMMAND server_rate_limiter_test) -add_test(NAME server_developer_role_test COMMAND server_developer_role_test) -add_test(NAME server_game_join_test COMMAND server_game_join_test) -add_test(NAME warning_categories_test COMMAND warning_categories_test) -# The translation loader test compiles a .qm fixture, which needs lrelease from Qt Linguist. -if(TARGET Qt6::lrelease) - add_test(NAME translation_loader_test COMMAND translation_loader_test) -endif() -add_test(NAME report_categories_test COMMAND report_categories_test) -add_test(NAME lag_monitor_test COMMAND lag_monitor_test) -add_test(NAME latency_tracker_test COMMAND latency_tracker_test) -add_test(NAME metrics_registry_test COMMAND metrics_registry_test) -add_test(NAME loader_local_matching_test COMMAND loader_local_matching_test) - -add_test(NAME deck_hash_performance_test COMMAND deck_hash_performance_test) -set_tests_properties(deck_hash_performance_test PROPERTIES TIMEOUT 15) +include(GoogleTest) # Find GTest -add_executable(dummy_test dummy_test.cpp) -add_executable(expression_test expression_test.cpp) -add_executable(clamped_arithmetic_test clamped_arithmetic_test.cpp) -add_executable(test_age_formatting test_age_formatting.cpp) -add_executable(password_hash_test password_hash_test.cpp) -add_executable(playmat_resolver_test playmat_resolver_test.cpp) -add_executable(deck_hash_performance_test deck_hash_performance_test.cpp) -add_executable(server_card_counter_test server_card_counter_test.cpp) -add_executable(server_counter_test server_counter_test.cpp) -add_executable(server_rate_limiter_test server_rate_limiter_test.cpp) -add_executable(server_developer_role_test server_developer_role_test.cpp) -add_executable(server_game_join_test server_game_join_test.cpp) -add_executable(warning_categories_test warning_categories_test.cpp) -if(TARGET Qt6::lrelease) - add_executable(translation_loader_test translation_loader_test.cpp) - - # QTranslator only accepts real .qm files, so the translation loader test gets one compiled from its - # own .ts fixture rather than a stub. - set(TRANSLATION_LOADER_TEST_QM "${CMAKE_CURRENT_BINARY_DIR}/translation_loader_test_de.qm") - add_custom_command( - OUTPUT "${TRANSLATION_LOADER_TEST_QM}" - COMMAND Qt6::lrelease "${CMAKE_CURRENT_SOURCE_DIR}/translation_loader_test.ts" -qm "${TRANSLATION_LOADER_TEST_QM}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/translation_loader_test.ts" - COMMENT "Compiling translation_loader_test.ts" - ) - add_custom_target(translation_loader_test_qm DEPENDS "${TRANSLATION_LOADER_TEST_QM}") - add_dependencies(translation_loader_test translation_loader_test_qm) - target_compile_definitions(translation_loader_test PRIVATE TRANSLATION_LOADER_TEST_DIR="${CMAKE_CURRENT_BINARY_DIR}") - - # A multi-config generator (MSBuild, Xcode) puts the executable in a per-config subdirectory while - # the .qm stays in the current binary directory, so copy the fixture next to the binary: that is the - # layout ABuildTreeFindsTheTranslationsNextToTheExecutable is about, and the only one it finds on - # those generators. - add_custom_command( - TARGET translation_loader_test - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${TRANSLATION_LOADER_TEST_QM}" - "$/" - VERBATIM - ) -endif() -add_executable(report_categories_test report_categories_test.cpp) -add_executable(lag_monitor_test ${CMAKE_SOURCE_DIR}/cockatrice/src/client/lag_monitor.cpp lag_monitor_test.cpp) -target_include_directories(lag_monitor_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src) -add_executable(latency_tracker_test latency_tracker_test.cpp) -add_executable(metrics_registry_test ../servatrice/src/metrics_registry.cpp metrics_registry_test.cpp) -add_executable( - loader_local_matching_test - ${CMAKE_SOURCE_DIR}/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.cpp - ${CMAKE_SOURCE_DIR}/cockatrice/src/client/settings/cache_settings.cpp - ${CMAKE_SOURCE_DIR}/cockatrice/src/client/settings/card_counter_settings.cpp - ${CMAKE_SOURCE_DIR}/cockatrice/src/client/settings/shortcuts_settings.cpp - ${CMAKE_SOURCE_DIR}/cockatrice/src/client/network/update/client/release_channel.cpp - ${VERSION_STRING_CPP} - loader_local_matching_test.cpp -) -target_include_directories(loader_local_matching_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src) - -# Guard must match the condition for src/single_instance_manager.cpp in cockatrice/CMakeLists.txt. -if(WITH_CLIENT) - add_executable( - single_instance_manager_test ${CMAKE_SOURCE_DIR}/cockatrice/src/single_instance_manager.cpp - single_instance_manager_test.cpp - ) - target_include_directories(single_instance_manager_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src) - - add_test(NAME single_instance_manager_test COMMAND single_instance_manager_test) -endif() - find_package(GTest) if(NOT GTEST_FOUND) @@ -122,91 +30,353 @@ if(NOT GTEST_FOUND) target_include_directories(gtest INTERFACE "$") set(GTEST_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/gtest-src/include") - set(GTEST_BOTH_LIBRARIES gtest) - add_dependencies(dummy_test gtest) - add_dependencies(expression_test gtest) - add_dependencies(clamped_arithmetic_test gtest) - add_dependencies(test_age_formatting gtest) - add_dependencies(password_hash_test gtest) - add_dependencies(playmat_resolver_test gtest) - add_dependencies(deck_hash_performance_test gtest) - add_dependencies(server_card_counter_test gtest) - add_dependencies(server_counter_test gtest) - add_dependencies(server_rate_limiter_test gtest) - add_dependencies(server_developer_role_test gtest) - add_dependencies(server_game_join_test gtest) - add_dependencies(warning_categories_test gtest) - if(TARGET translation_loader_test) - add_dependencies(translation_loader_test gtest) - endif() - add_dependencies(report_categories_test gtest) - add_dependencies(lag_monitor_test gtest) - add_dependencies(latency_tracker_test gtest) - add_dependencies(metrics_registry_test gtest) - add_dependencies(loader_local_matching_test gtest) - add_dependencies(single_instance_manager_test gtest) + # gtest_main is not optional here. FindGTest sets GTEST_BOTH_LIBRARIES to both halves, so this + # has to match it or the two paths disagree about what provides main(). A test source that + # defines its own main() gets away with the omission; one that does not fails at link with + # `undefined reference to main` pointing at crt1.o, which names neither gtest nor this line. + set(GTEST_BOTH_LIBRARIES gtest gtest_main) endif() +# Directory-scoped on purpose: the test subdirectories below add targets that include the +# fetched gtest headers and do not repeat this path themselves. include_directories(${GTEST_INCLUDE_DIRS}) -target_link_libraries(dummy_test Threads::Threads ${GTEST_BOTH_LIBRARIES}) -target_link_libraries(expression_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) -target_link_libraries( - clamped_arithmetic_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_link_libraries( - test_age_formatting libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_link_libraries( - password_hash_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_link_libraries( - playmat_resolver_test libcockatrice_deck_list libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} -) -target_link_libraries( - deck_hash_performance_test libcockatrice_deck_list libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} -) -target_link_libraries( - server_card_counter_test libcockatrice_network Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_link_libraries( - server_counter_test libcockatrice_network Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_link_libraries( - server_rate_limiter_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_link_libraries( - server_developer_role_test libcockatrice_network libcockatrice_rng Threads::Threads ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} -) -target_link_libraries( - server_game_join_test libcockatrice_network_server_remote libcockatrice_rng Threads::Threads ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} -) -target_link_libraries( - warning_categories_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -if(TARGET translation_loader_test) + +# --- Test registration ---------------------------------------------------------- +# +# Every test target needs the same four steps: build the executable, depend on gtest when it +# was fetched from source, link the shared test libraries, and hand the cases to CTest. The +# `if(NOT GTEST_FOUND)` branch is the easy one to forget — omit it and the link fails with +# undefined gtest symbols — so it lives here once instead of being repeated per test. +# +# This also replaces `add_test(NAME x COMMAND x)`. Naming the binary as a single CTest entry +# hides which case failed and makes `ctest -R Suite.Case` impossible; discovery exposes each +# TEST() as its own CTest entry instead. +# +# Labels: exactly one per test, because gtest_discover_tests() cannot carry more than one. +# GoogleTestAddTests.cmake accumulates the generated script with `foreach(arg ${ARGN})`, so a +# label list serialises as bare `LABELS ci server` in the CTestTestfile, and CTest reads only +# the first value of a property and silently discards the rest. A label therefore classifies a +# test into exactly one group, and the three groups cover every selection worth making: +# +# ci the default hermetic set, so `ctest -LE bench` runs everything but benchmarks +# server servatrice-facing tests, so `ctest -L server` works +# bench the slow suites, kept out of the default run +# +# A second label is a configure-time FATAL_ERROR rather than a line CTest quietly reads as one. +# Anything orthogonal to a test's kind belongs in a helper flag beside the label, so it +# composes with the group instead of competing for the single slot. NO_SANITIZE is such a flag. +# +# TIMEOUT is bounded per test because CTest's implicit default is 1500s: one hung socket wait +# would otherwise stall CI for 25 minutes. +# +# EXTRA_LIBS is appended after the shared libraries so a caller adding a static archive (zlib, +# lzma) keeps it last, which is where the linker needs it. + +function(cockatrice_add_test) + cmake_parse_arguments( + PARSE_ARGV 0 ARG "MANUAL;NO_SANITIZE" "NAME" "SOURCES;LIBS;LABELS;DEFINITIONS;INCLUDE_DIRS;EXTRA_LIBS" + ) + + if(NOT ARG_NAME OR NOT ARG_SOURCES) + message(FATAL_ERROR "cockatrice_add_test requires at least NAME and SOURCES") + endif() + + add_executable(${ARG_NAME} ${ARG_SOURCES}) + + if(ARG_INCLUDE_DIRS) + target_include_directories(${ARG_NAME} PRIVATE ${ARG_INCLUDE_DIRS}) + endif() + + if(ARG_DEFINITIONS) + target_compile_definitions(${ARG_NAME} PRIVATE ${ARG_DEFINITIONS}) + endif() + target_link_libraries( - translation_loader_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} + ${ARG_NAME} ${ARG_LIBS} Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} ${ARG_EXTRA_LIBS} + ) + + # Only needed when gtest was downloaded and add_subdirectory'd above. An imported gtest + # target already carries its own dependency, so this must stay conditional. + if(NOT GTEST_FOUND) + add_dependencies(${ARG_NAME} gtest gtest_main) + endif() + + # MANUAL targets are built but deliberately kept out of ctest: benchmarks that need a card + # database, hit the network, or measure RAM. Leaving them unregistered keeps CI hermetic + # and fast. They still link gtest so they can use TEST() without a second code path. + if(ARG_MANUAL) + return() + endif() + + # NO_SANITIZE marks a target the sanitizer leg cannot run. Excluded by not handing its cases + # to CTest at all, rather than by a label, so the exclusion cannot rot into a line CTest + # quietly reads as something else. The target still builds, and still runs on the other legs. + if(ARG_NO_SANITIZE AND COCKATRICE_SANITIZERS) + return() + endif() + + # One label only, per the note above. Rejecting a second loudly beats emitting a + # CTestTestfile line that CTest will quietly read as one label. + list(LENGTH ARG_LABELS _label_count) + if(_label_count GREATER 1) + message(FATAL_ERROR "${ARG_NAME}: pass at most one label, got '${ARG_LABELS}'") + endif() + if(NOT ARG_LABELS) + set(ARG_LABELS ci) + endif() + + # GoogleTestAddTests defaults DISCOVERY_TIMEOUT to 5s, which is ample for a plain debug + # binary (--gtest_list_tests costs 0.04s) but not for an instrumented one (~2.8s cold, and + # discovery runs several binaries concurrently behind a -j build). Left at the default, a + # sanitizer build fails at the *link* step with a bare "Process terminated due to timeout" + # and no hint that discovery, not the test, is what is slow. + if(COCKATRICE_SANITIZERS) + set(_discovery_timeout 300) + else() + set(_discovery_timeout 60) + endif() + + gtest_discover_tests( + ${ARG_NAME} DISCOVERY_MODE POST_BUILD DISCOVERY_TIMEOUT ${_discovery_timeout} + PROPERTIES LABELS "${ARG_LABELS}" + TIMEOUT 60 + ) +endfunction() + +# Same wiring for targets that are built but deliberately kept out of ctest: benchmarks that +# need a card database, hit the network, or measure RAM. A separate name rather than a MANUAL +# flag spelled out at each call site, so "this is not in the CI suite" is visible in the CMake +# file. Note the unquoted expansions: an unset multi-value keyword expands to zero arguments, +# which is what lets this forward a caller's keywords verbatim without tripping the FATAL_ERROR +# guard above on an empty list. +function(cockatrice_add_manual_test) + cmake_parse_arguments(PARSE_ARGV 0 ARG "" "NAME" "SOURCES;LIBS;DEFINITIONS;INCLUDE_DIRS;EXTRA_LIBS") + + cockatrice_add_test( + NAME + ${ARG_NAME} + SOURCES + ${ARG_SOURCES} + LIBS + ${ARG_LIBS} + DEFINITIONS + ${ARG_DEFINITIONS} + INCLUDE_DIRS + ${ARG_INCLUDE_DIRS} + EXTRA_LIBS + ${ARG_EXTRA_LIBS} + MANUAL + ) +endfunction() + +# --- Unit tests ------------------------------------------------------------------ + +cockatrice_add_test(NAME expression_test SOURCES expression_test.cpp LIBS libcockatrice_utility) +cockatrice_add_test(NAME clamped_arithmetic_test SOURCES clamped_arithmetic_test.cpp LIBS libcockatrice_utility) +cockatrice_add_test(NAME test_age_formatting SOURCES test_age_formatting.cpp LIBS libcockatrice_utility) +cockatrice_add_test(NAME password_hash_test SOURCES password_hash_test.cpp LIBS libcockatrice_utility) +cockatrice_add_test(NAME report_categories_test SOURCES report_categories_test.cpp LIBS libcockatrice_utility) +cockatrice_add_test(NAME warning_categories_test SOURCES warning_categories_test.cpp LIBS libcockatrice_utility) +cockatrice_add_test( + NAME + playmat_resolver_test + SOURCES + playmat_resolver_test.cpp + LIBS + libcockatrice_deck_list + libcockatrice_utility +) +cockatrice_add_test( + NAME + server_rate_limiter_test + SOURCES + server_rate_limiter_test.cpp + LIBS + libcockatrice_utility + LABELS + server +) +cockatrice_add_test( + NAME + server_card_counter_test + SOURCES + server_card_counter_test.cpp + LIBS + libcockatrice_network + LABELS + server +) +cockatrice_add_test( + NAME + server_dump_zone_test + SOURCES + server_dump_zone_test.cpp + LIBS + libcockatrice_rng + libcockatrice_network + LABELS + server +) +cockatrice_add_test( + NAME + server_counter_test + SOURCES + server_counter_test.cpp + LIBS + libcockatrice_network + LABELS + server +) +cockatrice_add_test( + NAME + server_developer_role_test + NO_SANITIZE + SOURCES + server_developer_role_test.cpp + LIBS + libcockatrice_network + libcockatrice_rng + LABELS + server +) +cockatrice_add_test( + NAME + server_moderator_role_test + NO_SANITIZE + SOURCES + server_moderator_role_test.cpp + LIBS + libcockatrice_network + libcockatrice_rng + LABELS + server +) +cockatrice_add_test( + NAME + server_game_join_test + SOURCES + server_game_join_test.cpp + LIBS + libcockatrice_network_server_remote + libcockatrice_rng + LABELS + server +) +cockatrice_add_test( + NAME + latency_tracker_test + SOURCES + latency_tracker_test.cpp + LIBS + libcockatrice_network + LABELS + server +) +cockatrice_add_test( + NAME + lag_monitor_test + SOURCES + ${CMAKE_SOURCE_DIR}/cockatrice/src/client/lag_monitor.cpp + lag_monitor_test.cpp + INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/cockatrice/src +) +cockatrice_add_test( + NAME + metrics_registry_test + SOURCES + ${CMAKE_SOURCE_DIR}/servatrice/src/metrics_registry.cpp + metrics_registry_test.cpp + INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/servatrice/src + LABELS + server +) +cockatrice_add_test( + NAME + card_update_progress_test + SOURCES + ${CMAKE_SOURCE_DIR}/cockatrice/src/interface/card_database_update/card_update_progress.cpp + card_update_progress_test.cpp + INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/cockatrice/src +) +cockatrice_add_test( + NAME + loader_local_matching_test + SOURCES + ${CMAKE_SOURCE_DIR}/cockatrice/src/interface/card_picture_loader/card_picture_loader_local.cpp + ${CMAKE_SOURCE_DIR}/cockatrice/src/client/settings/cache_settings.cpp + ${CMAKE_SOURCE_DIR}/cockatrice/src/client/settings/card_counter_settings.cpp + ${CMAKE_SOURCE_DIR}/cockatrice/src/client/settings/shortcuts_settings.cpp + ${CMAKE_SOURCE_DIR}/cockatrice/src/client/network/update/client/release_channel.cpp + ${VERSION_STRING_CPP} + loader_local_matching_test.cpp + LIBS + libcockatrice_settings + INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/cockatrice/src +) +cockatrice_add_test( + NAME + deck_hash_performance_test + SOURCES + deck_hash_performance_test.cpp + LIBS + libcockatrice_deck_list + libcockatrice_utility + LABELS + bench +) + +# The translation loader test compiles a .qm fixture, which needs lrelease from Qt Linguist. +if(TARGET Qt6::lrelease) + set(TRANSLATION_LOADER_TEST_QM "${CMAKE_CURRENT_BINARY_DIR}/translation_loader_test_de.qm") + add_custom_command( + OUTPUT "${TRANSLATION_LOADER_TEST_QM}" + COMMAND Qt6::lrelease "${CMAKE_CURRENT_SOURCE_DIR}/translation_loader_test.ts" -qm "${TRANSLATION_LOADER_TEST_QM}" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/translation_loader_test.ts" + COMMENT "Compiling translation_loader_test.ts" + ) + add_custom_target(translation_loader_test_qm DEPENDS "${TRANSLATION_LOADER_TEST_QM}") + + cockatrice_add_test( + NAME + translation_loader_test + SOURCES + translation_loader_test.cpp + LIBS + libcockatrice_utility + DEFINITIONS + TRANSLATION_LOADER_TEST_DIR="${CMAKE_CURRENT_BINARY_DIR}" + ) + add_dependencies(translation_loader_test translation_loader_test_qm) + + # A multi-config generator (MSBuild, Xcode) puts the executable in a per-config subdirectory while + # the .qm stays in the current binary directory, so copy the fixture next to the binary: that is the + # layout ABuildTreeFindsTheTranslationsNextToTheExecutable is about, and the only one it finds on + # those generators. + add_custom_command( + TARGET translation_loader_test + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${TRANSLATION_LOADER_TEST_QM}" + "$/" + VERBATIM ) endif() -target_link_libraries( - report_categories_test libcockatrice_utility Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_link_libraries(lag_monitor_test Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) -target_link_libraries( - latency_tracker_test libcockatrice_network Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_include_directories(metrics_registry_test PRIVATE ${CMAKE_SOURCE_DIR}/servatrice/src) -target_link_libraries(metrics_registry_test ${TEST_QT_MODULES} Threads::Threads ${GTEST_BOTH_LIBRARIES}) -target_link_libraries( - loader_local_matching_test libcockatrice_settings Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) +# Guard must match the condition for src/single_instance_manager.cpp in cockatrice/CMakeLists.txt. if(WITH_CLIENT) - target_link_libraries(single_instance_manager_test Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) + cockatrice_add_test( + NAME + single_instance_manager_test + SOURCES + ${CMAKE_SOURCE_DIR}/cockatrice/src/single_instance_manager.cpp + single_instance_manager_test.cpp + INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/cockatrice/src + ${CMAKE_SOURCE_DIR}/libcockatrice_utility + ) endif() add_subdirectory(card_zone_algorithms) diff --git a/tests/card_update_progress_test.cpp b/tests/card_update_progress_test.cpp new file mode 100644 index 000000000..849cf623c --- /dev/null +++ b/tests/card_update_progress_test.cpp @@ -0,0 +1,93 @@ +#include "interface/card_database_update/card_update_progress.h" + +#include +#include +#include + +namespace +{ +std::optional parseLine(const QByteArray &line) +{ + return CardUpdateProgress::fromProtocolLine(line); +} +} // namespace + +TEST(CardUpdateProgressTest, ParsesAValidDownloadLine) +{ + const std::optional progress = parseLine("PROGRESS download 42 100"); + ASSERT_TRUE(progress.has_value()); + EXPECT_EQ(CardUpdateStage::Download, progress->stage); + EXPECT_EQ(42, progress->done); + EXPECT_EQ(100, progress->total); +} + +TEST(CardUpdateProgressTest, ParsesTrailingNewline) +{ + const std::optional progress = parseLine("PROGRESS scan 7 99\n"); + ASSERT_TRUE(progress.has_value()); + EXPECT_EQ(CardUpdateStage::Scan, progress->stage); + EXPECT_EQ(7, progress->done); + EXPECT_EQ(99, progress->total); +} + +TEST(CardUpdateProgressTest, ParsesWithSurroundingWhitespace) +{ + const std::optional progress = parseLine(QByteArray(" PROGRESS import 3 10 ")); + ASSERT_TRUE(progress.has_value()); + EXPECT_EQ(CardUpdateStage::Import, progress->stage); + EXPECT_EQ(3, progress->done); + EXPECT_EQ(10, progress->total); +} + +TEST(CardUpdateProgressTest, AcceptsZeroProgress) +{ + const std::optional progress = parseLine("PROGRESS download 0 0"); + ASSERT_TRUE(progress.has_value()); + EXPECT_EQ(0, progress->done); + EXPECT_EQ(0, progress->total); +} + +TEST(CardUpdateProgressTest, RejectsLinesWithoutProgressPrefix) +{ + EXPECT_FALSE(parseLine("download 42 100").has_value()); + EXPECT_FALSE(parseLine("PROGRESSdownload 42 100").has_value()); + EXPECT_FALSE(parseLine("").has_value()); +} + +TEST(CardUpdateProgressTest, RejectsMalformedLines) +{ + EXPECT_FALSE(parseLine("PROGRESS").has_value()); + EXPECT_FALSE(parseLine("PROGRESS download").has_value()); + EXPECT_FALSE(parseLine("PROGRESS download 42 100 extra").has_value()); + EXPECT_FALSE(parseLine("PROGRESS download 42").has_value()); + EXPECT_FALSE(parseLine("PROGRESS download notANumber 100").has_value()); +} + +TEST(CardUpdateProgressTest, RejectsNegativeValues) +{ + EXPECT_FALSE(parseLine("PROGRESS download -1 100").has_value()); + EXPECT_FALSE(parseLine("PROGRESS download 42 -100").has_value()); +} + +TEST(CardUpdateProgressTest, AcceptsUnknownStagesSchemalessly) +{ + const std::optional progress = parseLine("PROGRESS spoilers 1 2"); + ASSERT_TRUE(progress.has_value()); + EXPECT_EQ(CardUpdateStage::Unknown, progress->stage); + EXPECT_EQ(1, progress->done); + EXPECT_EQ(2, progress->total); +} + +TEST(CardUpdateProgressTest, StageTokensRoundTrip) +{ + EXPECT_EQ("download", CardUpdateProgress{CardUpdateStage::Download}.stageToken()); + EXPECT_EQ("scan", CardUpdateProgress{CardUpdateStage::Scan}.stageToken()); + EXPECT_EQ("import", CardUpdateProgress{CardUpdateStage::Import}.stageToken()); + EXPECT_EQ("unknown", CardUpdateProgress{CardUpdateStage::Unknown}.stageToken()); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/tests/card_zone_algorithms/CMakeLists.txt b/tests/card_zone_algorithms/CMakeLists.txt index e03d8f77d..945f8a0ed 100644 --- a/tests/card_zone_algorithms/CMakeLists.txt +++ b/tests/card_zone_algorithms/CMakeLists.txt @@ -1,15 +1,4 @@ -add_executable(card_zone_algorithms_test card_zone_algorithms_test.cpp) - -target_include_directories(card_zone_algorithms_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src/game/zones) - -target_link_libraries( - card_zone_algorithms_test - PRIVATE Threads::Threads - PRIVATE ${GTEST_BOTH_LIBRARIES} +cockatrice_add_test( + NAME card_zone_algorithms_test SOURCES card_zone_algorithms_test.cpp INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/cockatrice/src/game/zones ) - -add_test(NAME card_zone_algorithms_test COMMAND card_zone_algorithms_test) - -if(NOT GTEST_FOUND) - add_dependencies(card_zone_algorithms_test gtest) -endif() diff --git a/tests/card_zone_algorithms/card_zone_algorithms_test.cpp b/tests/card_zone_algorithms/card_zone_algorithms_test.cpp index 8fab42566..4f5282235 100644 --- a/tests/card_zone_algorithms/card_zone_algorithms_test.cpp +++ b/tests/card_zone_algorithms/card_zone_algorithms_test.cpp @@ -1,6 +1,7 @@ #include "card_zone_algorithms.h" #include +#include #include struct MockCardRef diff --git a/tests/carddatabase/CMakeLists.txt b/tests/carddatabase/CMakeLists.txt index 811cebc1d..22171a9e8 100644 --- a/tests/carddatabase/CMakeLists.txt +++ b/tests/carddatabase/CMakeLists.txt @@ -9,61 +9,46 @@ add_definitions("-DCARDDB_DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}/data/\"") # ------------------------ # Card Database Test # ------------------------ -add_executable(carddatabase_test ${MOCKS_SOURCES} ${VERSION_STRING_CPP} carddatabase_test.cpp mocks.cpp) - -target_link_libraries( +cockatrice_add_test( + NAME carddatabase_test - PRIVATE libcockatrice_card - PRIVATE Threads::Threads - PRIVATE ${GTEST_BOTH_LIBRARIES} - PRIVATE ${TEST_QT_MODULES} + SOURCES + ${VERSION_STRING_CPP} + carddatabase_test.cpp + mocks.cpp + LIBS + libcockatrice_card ) -add_test(NAME carddatabase_test COMMAND carddatabase_test) - -# ------------------------ -# Load Benchmark (manual, not run in CI) -# ------------------------ -add_executable(load_benchmark ${MOCKS_SOURCES} ${VERSION_STRING_CPP} load_benchmark.cpp mocks.cpp) - -target_link_libraries( - load_benchmark - PRIVATE libcockatrice_card - PRIVATE libcockatrice_models - PRIVATE Threads::Threads - PRIVATE ${GTEST_BOTH_LIBRARIES} - PRIVATE ${TEST_QT_MODULES} -) - -if(NOT GTEST_FOUND) - add_dependencies(load_benchmark gtest) -endif() - # ------------------------ # Filter String Test # (guard must match the condition for libcockatrice_filters in the root CMakeLists.txt) # ------------------------ if(WITH_ORACLE OR WITH_CLIENT) - add_executable(filter_string_test ${MOCKS_SOURCES} ${VERSION_STRING_CPP} filter_string_test.cpp mocks.cpp) - - target_link_libraries( + cockatrice_add_test( + NAME filter_string_test - PRIVATE libcockatrice_filters - PRIVATE Threads::Threads - PRIVATE ${GTEST_BOTH_LIBRARIES} - PRIVATE ${TEST_QT_MODULES} + SOURCES + ${VERSION_STRING_CPP} + filter_string_test.cpp + mocks.cpp + LIBS + libcockatrice_filters ) - - add_test(NAME filter_string_test COMMAND filter_string_test) - - if(NOT GTEST_FOUND) - add_dependencies(filter_string_test gtest) - endif() endif() # ------------------------ -# Dependencies on gtest +# Load Benchmark (manual, not run in CI) # ------------------------ -if(NOT GTEST_FOUND) - add_dependencies(carddatabase_test gtest) -endif() +cockatrice_add_manual_test( + NAME + load_benchmark + SOURCES + ${VERSION_STRING_CPP} + load_benchmark.cpp + mocks.cpp + LIBS + libcockatrice_card + libcockatrice_models + MANUAL +) diff --git a/tests/carddatabase/carddatabase_test.cpp b/tests/carddatabase/carddatabase_test.cpp index 392f6395a..1b48d934b 100644 --- a/tests/carddatabase/carddatabase_test.cpp +++ b/tests/carddatabase/carddatabase_test.cpp @@ -1,15 +1,36 @@ -#include "mocks.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_loader.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/set/card_set.h" +#include "libcockatrice/card/set/card_set_list.h" #include "test_card_database_path_provider.h" #include "gtest/gtest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include #include #include #include +#include +#include #include #include +#include + namespace { @@ -64,12 +85,11 @@ TEST(CardDatabaseTest, Xml4LocalizedDataRoundTrip) QTemporaryDir tempDir; const QString fileName = tempDir.filePath("cards.xml"); - NoopCardPreferenceProvider prefProvider; - CockatriceXml4Parser writer(&prefProvider, &controller); + CockatriceXml4Parser writer(&controller); ASSERT_TRUE(writer.saveToFile({}, sets, cards, fileName)); CardDatabaseData data; - CockatriceXml4Parser parser(&prefProvider, &controller); + CockatriceXml4Parser parser(&controller); QFile file(fileName); ASSERT_TRUE(file.open(QIODevice::ReadOnly)); parser.parseFileInto(file, data); @@ -81,6 +101,413 @@ TEST(CardDatabaseTest, Xml4LocalizedDataRoundTrip) ASSERT_EQ(loaded->getLocalizedText("de"), "Blitzschlag fügt 3 Schadenspunkte zu."); ASSERT_EQ(loaded->getLocalizedText("fr"), "Deal 3 damage."); } + +/** + * @brief Path provider serving a sandboxed copy of the test card database. + */ +class SandboxPathProvider : public ICardDatabasePathProvider +{ +public: + explicit SandboxPathProvider(const QString &_root) : root(_root) + { + } + + QString getCardDatabasePath() const override + { + return root + "/cards.xml"; + } + + QString getCustomCardDatabasePath() const override + { + return root + "/customsets/"; + } + + QString getTokenDatabasePath() const override + { + return root + "/tokens.xml"; + } + + QString getSpoilerCardDatabasePath() const override + { + return root + "/spoiler.xml"; + } + +private: + QString root; +}; + +/** + * @brief Set priority controller whose enablement state the test drives directly. + * + * Seeded short names behave like entries present in cardDatabase.ini (enabled, + * known). Anything the parser discovers but the test did not seed falls back to + * the default SetOptions, i.e. disabled and unknown, mirroring + * CardDatabaseSettings for sets without an ini group. + */ +class SeededSetPriorityController : public ICardSetPriorityController +{ +public: + void seed(const QStringList &shortNames) + { + for (const QString &shortName : shortNames) { + SetOptions options; + options.enabled = true; + options.isKnown = true; + setOptions.insert(shortName, options); + } + } + + void setSortKey(QString shortName, unsigned int sortKey) override + { + ++individualWrites; + setOptions[shortName].sortKey = sortKey; + } + + void setEnabled(QString shortName, bool enabled) override + { + ++individualWrites; + setOptions[shortName].enabled = enabled; + } + + void setIsKnown(QString shortName, bool isknown) override + { + ++individualWrites; + setOptions[shortName].isKnown = isknown; + } + + unsigned int getSortKey(QString shortName) const override + { + return setOptions.value(shortName).sortKey; + } + + bool isEnabled(QString shortName) const override + { + return setOptions.value(shortName).enabled; + } + + bool isKnown(QString shortName) const override + { + return setOptions.value(shortName).isKnown; + } + + SetOptions getSetOptions(QString shortName) const override + { + return setOptions.value(shortName); + } + + QStringList getEnabledSetNames() const override + { + QStringList names; + for (auto it = setOptions.constBegin(); it != setOptions.constEnd(); ++it) { + if (it.value().enabled) { + names << it.key(); + } + } + names.sort(); + return names; + } + + void saveSets(const QVector &data) override + { + ++batchedWrites; + for (const SetSaveData &entry : data) { + setOptions[entry.shortName].sortKey = entry.sortKey; + setOptions[entry.shortName].enabled = entry.enabled; + setOptions[entry.shortName].isKnown = entry.isKnown; + } + } + + int individualWrites = 0; ///< Per-set/per-option controller writes (the slow path). + int batchedWrites = 0; ///< Batched saveSets() flushes (the fast path). + +private: + QHash setOptions; +}; + +/** + * @brief Sandboxed card database plus enablement controller for cache tests. + * + * Copies the checked-in fixture XML into a temporary directory so each test + * owns the files (and the binary cache written next to them). + */ +class CardDatabaseCacheInvalidationTest : public ::testing::Test +{ +protected: + void SetUp() override + { + ASSERT_TRUE(tempDir.isValid()); + root = tempDir.path(); + ASSERT_TRUE(QFile::copy(QString(CARDDB_DATADIR) + "cards.xml", root + "/cards.xml")); + ASSERT_TRUE(QFile::copy(QString(CARDDB_DATADIR) + "tokens.xml", root + "/tokens.xml")); + ASSERT_TRUE(QDir(root).mkpath("customsets")); + ASSERT_TRUE( + QFile::copy(QString(CARDDB_DATADIR) + "customsets/customset1.xml", root + "/customsets/customset1.xml")); + controller.seed({"CAT", "DOG", "WHO", " Not a Card", "BRD"}); + } + + /** + * @brief Contents of the binary cache written next to cards.xml. + * @return The cache file bytes, or an empty array if no cache exists. + */ + QByteArray cacheContents() const + { + QFile file(root + "/cards.xml.cache"); + if (!file.open(QIODevice::ReadOnly)) { + return {}; + } + return file.readAll(); + } + + QTemporaryDir tempDir; + QString root; + SeededSetPriorityController controller; +}; + +TEST_F(CardDatabaseCacheInvalidationTest, DisablingSetBustsCacheAndDropsPrintings) +{ + NoopCardPreferenceProvider prefs; + SandboxPathProvider pathProvider(root); + CardDatabase db(nullptr, &prefs, &pathProvider, &controller); + + db.loadCardDatabases(); + const QByteArray initialCache = cacheContents(); + ASSERT_FALSE(initialCache.isEmpty()) << "first load must write the binary cache"; + ASSERT_FALSE(db.getCardList().value("Cat").isNull()); + ASSERT_TRUE(db.getCardList().value("Cat")->getSets().contains("CAT")); + + // A cache-aware load with unchanged inputs keeps the cache: the parse + // result would be identical, so there is nothing to invalidate. + db.loadCardDatabases(); + EXPECT_EQ(initialCache, cacheContents()) << "load with unchanged inputs must keep the cache"; + + // Disabling a set changes the source hash, so the next load re-parses and + // the set's printings disappear everywhere. + controller.setEnabled("CAT", false); + db.reloadCardDatabasesAndNotify(); + EXPECT_NE(initialCache, cacheContents()) << "toggling set enablement must bust the cache"; + ASSERT_FALSE(db.getCardList().value("Cat").isNull()); + EXPECT_FALSE(db.getCardList().value("Cat")->getSets().contains("CAT")) << "disabled set printings must be dropped"; + ASSERT_FALSE(db.getCardList().value("Kitten").isNull()); + EXPECT_FALSE(db.getCardList().value("Kitten")->getSets().contains("CAT")); +} + +TEST_F(CardDatabaseCacheInvalidationTest, AddingAndEnablingCustomSetBustsCache) +{ + NoopCardPreferenceProvider prefs; + SandboxPathProvider pathProvider(root); + CardDatabase db(nullptr, &prefs, &pathProvider, &controller); + + db.loadCardDatabases(); + const QByteArray initialCache = cacheContents(); + ASSERT_FALSE(initialCache.isEmpty()) << "first load must write the binary cache"; + + // Drop a new custom set in: the input file list changes, so the next load + // must re-parse. BRD2 is unknown, so its set starts disabled. + QFile customSetFile(root + "/customsets/customset2.xml"); + ASSERT_TRUE(customSetFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); + customSetFile.write("\n" + "\n" + " \n" + " \n" + " Finch\n" + " BRD2\n" + " 0\n" + " Chirp!\n" + " \n" + " \n" + "\n"); + customSetFile.close(); + + db.reloadCardDatabasesAndNotify(); + const QByteArray afterCustomSetAdded = cacheContents(); + EXPECT_NE(initialCache, afterCustomSetAdded) << "adding a custom card database must bust the cache"; + ASSERT_FALSE(db.getCardList().value("Finch").isNull()) << "the custom card must be loaded"; + EXPECT_TRUE(db.getCardList().value("Finch")->getSets().isEmpty()) + << "BRD2 starts disabled, so Finch has no printings yet"; + + // Enabling the freshly discovered set busts the cache again, so the next + // load finally parses its printings (#7455). + controller.setEnabled("BRD2", true); + db.reloadCardDatabasesAndNotify(); + EXPECT_NE(afterCustomSetAdded, cacheContents()) << "enabling a set must bust the cache"; + ASSERT_FALSE(db.getCardList().value("Finch").isNull()); + EXPECT_TRUE(db.getCardList().value("Finch")->getSets().contains("BRD2")); +} + +TEST_F(CardDatabaseCacheInvalidationTest, ExplicitReloadBypassesCache) +{ + NoopCardPreferenceProvider prefs; + SandboxPathProvider pathProvider(root); + CardDatabase db(nullptr, &prefs, &pathProvider, &controller); + + db.loadCardDatabases(); + ASSERT_FALSE(db.getCardList().value("Cat").isNull()); + ASSERT_TRUE(db.getCardList().value("Cat")->getSets().contains("CAT")); + + // Move Cat to the DOG set in place, keeping the file size identical and + // restoring the modification time afterwards: the source hash (path, size, + // mtime) still matches, so the cache stays valid by construction and only + // an explicit reload can pick the edit up. + const QString cardsPath = root + "/cards.xml"; + QFile file(cardsPath); + ASSERT_TRUE(file.open(QIODevice::ReadOnly)); + const qint64 stampedSecs = QFileInfo(cardsPath).lastModified().toSecsSinceEpoch(); + QByteArray contents = file.readAll(); + file.close(); + const QByteArray oldSetCode("CAT"); + const QByteArray newSetCode("DOG"); + ASSERT_EQ(contents.count(oldSetCode), 1) << "fixture must contain exactly one CAT printing"; + contents.replace(contents.indexOf(oldSetCode), oldSetCode.size(), newSetCode); + ASSERT_TRUE(file.open(QIODevice::ReadWrite)); + ASSERT_EQ(file.write(contents), contents.size()); + // Flush the pending write before stamping the time: close() would otherwise + // flush it afterwards and bump the modification time again, invalidating the + // cache on platforms that buffer writes (e.g. macOS). + ASSERT_TRUE(file.flush()); + ASSERT_TRUE(file.setFileTime(QDateTime::fromSecsSinceEpoch(stampedSecs), QFileDevice::FileModificationTime)); + file.close(); + ASSERT_EQ(QFileInfo(cardsPath).lastModified().toSecsSinceEpoch(), stampedSecs) + << "the sandbox file's modification time must be restored for the cache to stay valid"; + + // The cache is still valid for a regular load, which serves the stale data. + db.loadCardDatabases(); + ASSERT_FALSE(db.getCardList().value("Cat").isNull()); + EXPECT_TRUE(db.getCardList().value("Cat")->getSets().contains("CAT")) << "regular load must hit the cache"; + EXPECT_FALSE(db.getCardList().value("Cat")->getSets().contains("DOG")); + + // The explicit reload ignores the cache and re-reads the file. + const QByteArray staleCache = cacheContents(); + db.reloadCardDatabasesAndNotify(); + EXPECT_NE(staleCache, cacheContents()) << "explicit reload must rewrite the cache from disk"; + ASSERT_FALSE(db.getCardList().value("Cat").isNull()); + EXPECT_FALSE(db.getCardList().value("Cat")->getSets().contains("CAT")); + EXPECT_TRUE(db.getCardList().value("Cat")->getSets().contains("DOG")); +} + +TEST_F(CardDatabaseCacheInvalidationTest, FirstRunWithNoSetsEnabledSkipsCacheWrite) +{ + // A blank config: the parser discovers every set, but none of them has an + // ini entry, so all of them default to disabled (first run). + SeededSetPriorityController blankController; + NoopCardPreferenceProvider prefs; + SandboxPathProvider pathProvider(root); + CardDatabase db(nullptr, &prefs, &pathProvider, &blankController); + + db.loadCardDatabases(); + ASSERT_FALSE(db.getCardList().value("Cat").isNull()) << "cards are parsed even while their sets are disabled"; + EXPECT_TRUE(db.getCardList().value("Cat")->getSets().isEmpty()) + << "no printings survive an all-sets-disabled parse"; + EXPECT_TRUE(cacheContents().isEmpty()) << "a stripped first-run snapshot must not be cached"; +} + +TEST_F(CardDatabaseCacheInvalidationTest, EnablingAllSetsAfterFirstRunRestoresPrintings) +{ + SeededSetPriorityController blankController; + NoopCardPreferenceProvider prefs; + SandboxPathProvider pathProvider(root); + CardDatabase db(nullptr, &prefs, &pathProvider, &blankController); + + db.loadCardDatabases(); + ASSERT_TRUE(cacheContents().isEmpty()); + + // This mirrors what checkUnknownSets() does on a first run: enable every + // set, then reload so the parser keeps the printings and the complete + // snapshot gets cached under the enabled-set hash. + for (const CardSetPtr &set : db.getSetList()) { + blankController.setEnabled(set->getShortName(), true); + } + db.reloadCardDatabasesAndNotify(); + + ASSERT_FALSE(db.getCardList().value("Cat").isNull()); + EXPECT_TRUE(db.getCardList().value("Cat")->getSets().contains("CAT")); + EXPECT_FALSE(cacheContents().isEmpty()) << "the enabled-set snapshot must be cached"; +} + +TEST_F(CardDatabaseCacheInvalidationTest, CheckUnknownSetsBatchesFirstRunEnableAll) +{ + // Same first-run starting point as above, but driven through the real + // checkUnknownSets() path, which must persist the enable-all with a single + // batched saveSets() instead of per-set/per-option controller writes. + SeededSetPriorityController blankController; + NoopCardPreferenceProvider prefs; + SandboxPathProvider pathProvider(root); + CardDatabase db(nullptr, &prefs, &pathProvider, &blankController); + + db.loadCardDatabases(); + ASSERT_TRUE(db.getSetList().getEnabledSetsNum() == 0); + + db.checkUnknownSets(); + + EXPECT_EQ(blankController.individualWrites, 0) << "first-run enable-all must not write per set"; + EXPECT_EQ(blankController.batchedWrites, 1) << "first-run enable-all must persist with a single flush"; + for (const CardSetPtr &set : db.getSetList()) { + EXPECT_TRUE(set->getEnabled()) << set->getShortName().toStdString(); + EXPECT_TRUE(blankController.isEnabled(set->getShortName())) << set->getShortName().toStdString(); + if (!set->getIsKnownIgnored()) { + EXPECT_TRUE(set->getIsKnown()) << set->getShortName().toStdString(); + EXPECT_TRUE(blankController.isKnown(set->getShortName())) << set->getShortName().toStdString(); + } + } + + // The follow-up reload re-parses with the sets enabled, restoring printings. + db.reloadCardDatabasesAndNotify(); + ASSERT_FALSE(db.getCardList().value("Cat").isNull()); + EXPECT_TRUE(db.getCardList().value("Cat")->getSets().contains("CAT")); +} + +TEST_F(CardDatabaseCacheInvalidationTest, EnableAllUnknownSetsIsBatched) +{ + // The "new sets found" dialog path: enabling the unknown delta must persist + // with a single flush no matter how many sets the database holds, so users + // with hundreds of custom sets don't stall the GUI thread. Built directly + // on CardSet objects because the fixture sets carry no metadata (and would + // all count as ignored). + SeededSetPriorityController controller; + CardSetList sets; + sets.append( + CardSet::newInstance(&controller, "AAA", "Alpha Set", "core", QDate(2020, 1, 1), CardSet::PriorityPrimary)); + sets.append( + CardSet::newInstance(&controller, "BBB", "Beta Set", "expansion", QDate(2021, 6, 1), CardSet::PriorityPrimary)); + sets.append(CardSet::newInstance(&controller, "XXX")); // no metadata: ignored + + sets.enableAllUnknownBatched(&controller); + + EXPECT_EQ(controller.individualWrites, 0) << "unknown-set enable must not write per set"; + EXPECT_EQ(controller.batchedWrites, 1) << "unknown-set enable must persist with a single flush"; + for (const CardSetPtr &set : sets) { + EXPECT_TRUE(set->getEnabled()) << set->getShortName().toStdString(); + EXPECT_TRUE(controller.isEnabled(set->getShortName())) << set->getShortName().toStdString(); + if (set->getIsKnownIgnored()) { + EXPECT_FALSE(set->getIsKnown()) << set->getShortName().toStdString(); + } else { + EXPECT_TRUE(set->getIsKnown()) << set->getShortName().toStdString(); + EXPECT_TRUE(controller.isKnown(set->getShortName())) << set->getShortName().toStdString(); + } + } +} + +TEST_F(CardDatabaseCacheInvalidationTest, MarkAllSetsAsKnownIsBatched) +{ + // The dialog's "No" path: same single-flush requirement as enabling. + SeededSetPriorityController controller; + CardSetList sets; + sets.append( + CardSet::newInstance(&controller, "AAA", "Alpha Set", "core", QDate(2020, 1, 1), CardSet::PriorityPrimary)); + sets.append( + CardSet::newInstance(&controller, "BBB", "Beta Set", "expansion", QDate(2021, 6, 1), CardSet::PriorityPrimary)); + sets.append(CardSet::newInstance(&controller, "XXX")); // no metadata: ignored + + sets.markAllAsKnownBatched(&controller); + + EXPECT_EQ(controller.individualWrites, 0) << "mark-known must not write per set"; + EXPECT_EQ(controller.batchedWrites, 1) << "mark-known must persist with a single flush"; + EXPECT_TRUE(controller.isKnown("AAA")); + EXPECT_TRUE(controller.isKnown("BBB")); + EXPECT_FALSE(controller.isEnabled("AAA")); + EXPECT_FALSE(controller.isEnabled("BBB")); + // Ignored sets keep their known state but are enabled. + EXPECT_TRUE(controller.isEnabled("XXX")); +} } // namespace int main(int argc, char **argv) diff --git a/tests/carddatabase/filter_string_test.cpp b/tests/carddatabase/filter_string_test.cpp index dcf1cf0a2..95225e28c 100644 --- a/tests/carddatabase/filter_string_test.cpp +++ b/tests/carddatabase/filter_string_test.cpp @@ -1,13 +1,29 @@ -#include "mocks.h" +#include "libcockatrice/card/card_localization.h" +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/card/database/card_database_querier.h" +#include "libcockatrice/card/set/card_set.h" #include "test_card_database_path_provider.h" #include "gtest/gtest.h" +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include +#include +#include + +namespace +{ +class CardQuery; +} #define QUERY(name, card, query, match) \ TEST_F(CardQuery, name) \ diff --git a/tests/carddatabase/load_benchmark.cpp b/tests/carddatabase/load_benchmark.cpp index 8e9e80e4d..5492b9531 100644 --- a/tests/carddatabase/load_benchmark.cpp +++ b/tests/carddatabase/load_benchmark.cpp @@ -12,25 +12,30 @@ * (~/.local/share/Cockatrice/Cockatrice/...). */ -#include "mocks.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/set/card_set_list.h" -#include "gtest/gtest.h" #include #include -#include +#include #include #include -#include #include +#include +#include #include +#include +#include +#include #include -#include +#include #include #include #include #include #include #include +#include static QString defaultXdgPath(const QString &file) { diff --git a/tests/carddatabase/mocks.h b/tests/carddatabase/mocks.h index 016642005..b7cfe8243 100644 --- a/tests/carddatabase/mocks.h +++ b/tests/carddatabase/mocks.h @@ -7,7 +7,7 @@ #define PICTURELOADER_H -#include +#include "libcockatrice/card/card_info.h" class CardPictureLoader { diff --git a/tests/clamped_arithmetic_test.cpp b/tests/clamped_arithmetic_test.cpp index 2471d5870..e5fd070b0 100644 --- a/tests/clamped_arithmetic_test.cpp +++ b/tests/clamped_arithmetic_test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include TEST(AddClamped, AddsWithinBounds) { diff --git a/tests/deck_hash_performance_test.cpp b/tests/deck_hash_performance_test.cpp index 154283e8e..135c218c5 100644 --- a/tests/deck_hash_performance_test.cpp +++ b/tests/deck_hash_performance_test.cpp @@ -1,6 +1,10 @@ #include "gtest/gtest.h" -#include +#include +#include +#include +#include #include +#include static constexpr int amount = 1e5; QString repeatDeck; diff --git a/tests/deck_list_model/CMakeLists.txt b/tests/deck_list_model/CMakeLists.txt index e3096c559..cd7d693f3 100644 --- a/tests/deck_list_model/CMakeLists.txt +++ b/tests/deck_list_model/CMakeLists.txt @@ -1,33 +1,23 @@ -add_executable(deck_list_model_custom_zones_test ${VERSION_STRING_CPP} deck_list_model_custom_zones_test.cpp) - -if(NOT GTEST_FOUND) - add_dependencies(deck_list_model_custom_zones_test gtest) -endif() - -target_link_libraries( +cockatrice_add_test( + NAME deck_list_model_custom_zones_test + SOURCES + ${VERSION_STRING_CPP} + deck_list_model_custom_zones_test.cpp + LIBS libcockatrice_models libcockatrice_card libcockatrice_deck_list - Threads::Threads - ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} ) -add_test(NAME deck_list_model_custom_zones_test COMMAND deck_list_model_custom_zones_test) -add_executable(deck_list_model_zone_integration_test ${VERSION_STRING_CPP} deck_list_model_zone_integration_test.cpp) - -if(NOT GTEST_FOUND) - add_dependencies(deck_list_model_zone_integration_test gtest) -endif() - -target_link_libraries( +cockatrice_add_test( + NAME deck_list_model_zone_integration_test + SOURCES + ${VERSION_STRING_CPP} + deck_list_model_zone_integration_test.cpp + LIBS libcockatrice_models libcockatrice_card libcockatrice_deck_list - Threads::Threads - ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} ) -add_test(NAME deck_list_model_zone_integration_test COMMAND deck_list_model_zone_integration_test) diff --git a/tests/deck_list_model/deck_list_model_custom_zones_test.cpp b/tests/deck_list_model/deck_list_model_custom_zones_test.cpp index 7f4ab81e1..95df74702 100644 --- a/tests/deck_list_model/deck_list_model_custom_zones_test.cpp +++ b/tests/deck_list_model/deck_list_model_custom_zones_test.cpp @@ -9,10 +9,19 @@ * full model and card database machinery. */ +#include "deck_list_model_custom_zones.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" + +#include +#include +#include #include #include #include #include +#include +#include +#include namespace { diff --git a/tests/deck_list_model/deck_list_model_zone_integration_test.cpp b/tests/deck_list_model/deck_list_model_zone_integration_test.cpp index a4562c95d..63c904910 100644 --- a/tests/deck_list_model/deck_list_model_zone_integration_test.cpp +++ b/tests/deck_list_model/deck_list_model_zone_integration_test.cpp @@ -1,3 +1,12 @@ +#include "libcockatrice/card/database/card_database.h" +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" + +#include +#include +#include +#include +#include +#include #include #include #include @@ -8,6 +17,10 @@ #include #include #include +#include +#include + +class QModelIndex; namespace { diff --git a/tests/deck_list_zones/CMakeLists.txt b/tests/deck_list_zones/CMakeLists.txt index 0710be94d..7af8fd187 100644 --- a/tests/deck_list_zones/CMakeLists.txt +++ b/tests/deck_list_zones/CMakeLists.txt @@ -1,10 +1 @@ -add_executable(deck_list_zones_test deck_list_zones_test.cpp) - -if(NOT GTEST_FOUND) - add_dependencies(deck_list_zones_test gtest) -endif() - -target_link_libraries( - deck_list_zones_test libcockatrice_deck_list Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -add_test(NAME deck_list_zones_test COMMAND deck_list_zones_test) +cockatrice_add_test(NAME deck_list_zones_test SOURCES deck_list_zones_test.cpp LIBS libcockatrice_deck_list) diff --git a/tests/deck_list_zones/deck_list_zones_test.cpp b/tests/deck_list_zones/deck_list_zones_test.cpp index 801f226a9..1903b70df 100644 --- a/tests/deck_list_zones/deck_list_zones_test.cpp +++ b/tests/deck_list_zones/deck_list_zones_test.cpp @@ -7,12 +7,20 @@ * "main" are still mainboard cards for hashing, sideboard size, legality and export. */ +#include "libcockatrice/deck_list/tree/abstract_deck_list_node.h" + +#include +#include +#include +#include #include +#include #include #include #include #include #include +#include namespace { diff --git a/tests/dummy_test.cpp b/tests/dummy_test.cpp deleted file mode 100644 index 31a01bcff..000000000 --- a/tests/dummy_test.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "gtest/gtest.h" - -namespace -{ -class FooTest : public ::testing::Test -{ -}; - -TEST(DummyTest, Works) -{ - ASSERT_EQ(1, 1) << "One is not equal to one"; -} -} // namespace - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/tests/expression_test.cpp b/tests/expression_test.cpp index 4fbe98cb9..b3c4b586c 100644 --- a/tests/expression_test.cpp +++ b/tests/expression_test.cpp @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include #include +#include #define TEST_EXPR(name, a, b) \ TEST(ExpressionTest, name) \ diff --git a/tests/lag_monitor_test.cpp b/tests/lag_monitor_test.cpp index 9948eeabb..b404a2c9e 100644 --- a/tests/lag_monitor_test.cpp +++ b/tests/lag_monitor_test.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include namespace { diff --git a/tests/latency_tracker_test.cpp b/tests/latency_tracker_test.cpp index 68631b7ca..a77051799 100644 --- a/tests/latency_tracker_test.cpp +++ b/tests/latency_tracker_test.cpp @@ -1,5 +1,9 @@ +#include +#include #include +#include #include +#include TEST(LatencyTrackerTest, EmptyTrackerYieldsZeroedStats) { diff --git a/tests/loader_local_matching_test.cpp b/tests/loader_local_matching_test.cpp index 6ce684fdd..13d3e5bb3 100644 --- a/tests/loader_local_matching_test.cpp +++ b/tests/loader_local_matching_test.cpp @@ -1,7 +1,11 @@ #include "client/settings/cache_settings.h" #include "interface/card_picture_loader/card_picture_loader_local.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/printing/printing_info.h" #include "gtest/gtest.h" +#include +#include #include #include #include @@ -9,13 +13,18 @@ #include #include #include +#include #include +#include #include +#include #include #include #include #include #include +#include +#include namespace { diff --git a/tests/loading_from_clipboard/CMakeLists.txt b/tests/loading_from_clipboard/CMakeLists.txt index 719d62f45..88711e457 100644 --- a/tests/loading_from_clipboard/CMakeLists.txt +++ b/tests/loading_from_clipboard/CMakeLists.txt @@ -1,12 +1,13 @@ add_definitions("-DCARDDB_DATADIR=\"${CMAKE_CURRENT_SOURCE_DIR}/data/\"") -add_executable(loading_from_clipboard_test ${VERSION_STRING_CPP} clipboard_testing.cpp loading_from_clipboard_test.cpp) -if(NOT GTEST_FOUND) - add_dependencies(loading_from_clipboard_test gtest) -endif() - -target_link_libraries( - loading_from_clipboard_test libcockatrice_deck_list libcockatrice_card Threads::Threads ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} +cockatrice_add_test( + NAME + loading_from_clipboard_test + SOURCES + ${VERSION_STRING_CPP} + clipboard_testing.cpp + loading_from_clipboard_test.cpp + LIBS + libcockatrice_deck_list + libcockatrice_card ) -add_test(NAME loading_from_clipboard_test COMMAND loading_from_clipboard_test) diff --git a/tests/loading_from_clipboard/clipboard_testing.cpp b/tests/loading_from_clipboard/clipboard_testing.cpp index a9977b800..3f652a495 100644 --- a/tests/loading_from_clipboard/clipboard_testing.cpp +++ b/tests/loading_from_clipboard/clipboard_testing.cpp @@ -1,6 +1,12 @@ #include "clipboard_testing.h" +#include "libcockatrice/deck_list/deck_list.h" +#include "libcockatrice/deck_list/tree/inner_deck_list_node.h" + +#include #include +#include +#include #include #include diff --git a/tests/loading_from_clipboard/clipboard_testing.h b/tests/loading_from_clipboard/clipboard_testing.h index 41d8ea794..c9852e5d7 100644 --- a/tests/loading_from_clipboard/clipboard_testing.h +++ b/tests/loading_from_clipboard/clipboard_testing.h @@ -1,8 +1,11 @@ #ifndef CLIPBOARD_TESTING_H #define CLIPBOARD_TESTING_H -#include "gtest/gtest.h" -#include +#include +#include +#include +#include +#include // using std types because qt types aren't understood by gtest (without this you'll get less nice errors) using CardRows = QVector>; diff --git a/tests/loading_from_clipboard/loading_from_clipboard_test.cpp b/tests/loading_from_clipboard/loading_from_clipboard_test.cpp index fcfbb22db..e1797818e 100644 --- a/tests/loading_from_clipboard/loading_from_clipboard_test.cpp +++ b/tests/loading_from_clipboard/loading_from_clipboard_test.cpp @@ -1,5 +1,11 @@ #include "clipboard_testing.h" +#include +#include +#include +#include +#include + // Testing is done by using the DeckList::loadFromString_Plain function in common/decklist.h // It does not check if cards are in the database at all, so no comparisons to the database will be made. @@ -74,6 +80,20 @@ TEST(LoadingFromClipboardTest, WeirdWhitespaceIsIgnored) testDeck(clipboard, result); } +TEST(LoadingFromClipboardTest, TabSeparatedImport) +{ + QString clipboard("2\tMystic Snake\tStreets of New Capenna\n" + "3x\tCounterspell\tNPH\n" + "\t2\tSol Ring\tFMB\n" + "1\tForest\n" + "\n" + "2x\tDoom Blade\tM11\n"); + + Result result("", "", {{"Mystic Snake", 2}, {"Counterspell", 3}, {"Sol Ring", 2}, {"Forest", 1}}, + {{"Doom Blade", 2}}); + testDeck(clipboard, result); +} + TEST(LoadingFromClipboardTest, RemoveBlankEntriesFromBeginningAndEnd) { QString clipboard("\n" diff --git a/tests/metrics_registry_test.cpp b/tests/metrics_registry_test.cpp index 1abef58e1..39a8f8aaf 100644 --- a/tests/metrics_registry_test.cpp +++ b/tests/metrics_registry_test.cpp @@ -2,6 +2,7 @@ #include #include #include +#include TEST(MetricsRegistryTest, EmptyRegistryHasZeroedCounters) { diff --git a/tests/movecard_tests/CMakeLists.txt b/tests/movecard_tests/CMakeLists.txt index 769047148..68d8fc84c 100755 --- a/tests/movecard_tests/CMakeLists.txt +++ b/tests/movecard_tests/CMakeLists.txt @@ -1,16 +1,11 @@ -add_executable(reverse_card_move_test reverse_card_move_test.cpp) - -if(NOT GTEST_FOUND) - add_dependencies(reverse_card_move_test gtest) -endif() - -target_link_libraries( +cockatrice_add_test( + NAME reverse_card_move_test - PRIVATE libcockatrice_network_server_remote - PRIVATE libcockatrice_rng - PRIVATE Threads::Threads - PRIVATE ${GTEST_BOTH_LIBRARIES} - PRIVATE ${TEST_QT_MODULES} + SOURCES + reverse_card_move_test.cpp + LIBS + libcockatrice_network_server_remote + libcockatrice_rng + LABELS + server ) - -add_test(NAME reverse_card_move_test COMMAND reverse_card_move_test) diff --git a/tests/movecard_tests/reverse_card_move_test.cpp b/tests/movecard_tests/reverse_card_move_test.cpp index 64c93078c..6bed20d18 100644 --- a/tests/movecard_tests/reverse_card_move_test.cpp +++ b/tests/movecard_tests/reverse_card_move_test.cpp @@ -3,15 +3,20 @@ #include "game/server_card.h" #include "game/server_cardzone.h" #include "game/server_game.h" +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/serverinfo_zone.pb.h" #include "server_response_containers.h" #include "server_room.h" #include "server_test_helpers.h" +#include +#include #include #include #include #include #include +#include RNG_Abstract *rng = nullptr; // this needs to be defined due to other functions in server diff --git a/tests/oracle/CMakeLists.txt b/tests/oracle/CMakeLists.txt index 9bc5ee5be..6958673f7 100644 --- a/tests/oracle/CMakeLists.txt +++ b/tests/oracle/CMakeLists.txt @@ -1,37 +1,32 @@ -add_executable(parse_cipt_test ../../oracle/src/parsehelpers.cpp parse_cipt_test.cpp) - -if(NOT GTEST_FOUND) - add_dependencies(parse_cipt_test gtest) -endif() - -target_link_libraries(parse_cipt_test Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) - -add_test(NAME parse_cipt_test COMMAND parse_cipt_test) +cockatrice_add_test(NAME parse_cipt_test SOURCES ../../oracle/src/parsehelpers.cpp parse_cipt_test.cpp) # Oracle importer unit tests -add_executable( - oracle_importer_test ${VERSION_STRING_CPP} ../../oracle/src/oracleimporter.cpp ../../oracle/src/parsehelpers.cpp - ../../oracle/src/raw_json_scanner.cpp oracle_importer_test.cpp +cockatrice_add_test( + NAME + oracle_importer_test + SOURCES + ${VERSION_STRING_CPP} + ../../oracle/src/oracleimporter.cpp + ../../oracle/src/parsehelpers.cpp + ../../oracle/src/raw_json_scanner.cpp + oracle_importer_test.cpp + LIBS + libcockatrice_card + libcockatrice_interfaces ) -if(NOT GTEST_FOUND) - add_dependencies(oracle_importer_test gtest) -endif() - -target_link_libraries( - oracle_importer_test libcockatrice_card libcockatrice_interfaces Threads::Threads ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} -) - -add_test(NAME oracle_importer_test COMMAND oracle_importer_test) - # Oracle importer benchmark tests (manual, not run in CI, incl. RAM benchmark) # Optional compression libs, mirrored from oracle/CMakeLists.txt, so the benchmark # can download and decompress whatever AllPrintings format the default URL selects. +# add_definitions() is directory-scoped and order-independent, so HAS_ZLIB/HAS_LZMA also +# reach the two unit tests above. That is harmless: those macros gate code only in +# oracle/src/pages.cpp and oracle/src/pagetemplates.cpp, which no test target compiles. find_package(ZLIB) if(ZLIB_FOUND) add_definitions("-DHAS_ZLIB") set(_ORACLE_BENCH_EXTRA_SOURCES ../../oracle/src/zip/unzip.cpp ../../oracle/src/zip/zipglobal.cpp) + cockatrice_disable_sanitizers_for(${_ORACLE_BENCH_EXTRA_SOURCES}) + cockatrice_disable_coverage_for(${_ORACLE_BENCH_EXTRA_SOURCES}) set(_ORACLE_BENCH_EXTRA_LIBRARIES ${ZLIB_LIBRARIES}) include_directories(${ZLIB_INCLUDE_DIRS}) else() @@ -42,28 +37,28 @@ find_package(LibLZMA) if(LIBLZMA_FOUND) add_definitions("-DHAS_LZMA") list(APPEND _ORACLE_BENCH_EXTRA_SOURCES ../../oracle/src/lzma/decompress.cpp) + cockatrice_disable_sanitizers_for(../../oracle/src/lzma/decompress.cpp) + cockatrice_disable_coverage_for(../../oracle/src/lzma/decompress.cpp) list(APPEND _ORACLE_BENCH_EXTRA_LIBRARIES ${LIBLZMA_LIBRARIES}) include_directories(${LIBLZMA_INCLUDE_DIRS}) else() message(STATUS "Oracle tests: LibLZMA not found; xz download benchmark disabled") endif() -add_executable( - oracle_importer_benchmark_test - ${VERSION_STRING_CPP} ../../oracle/src/oracleimporter.cpp ../../oracle/src/parsehelpers.cpp - ../../oracle/src/raw_json_scanner.cpp oracle_importer_benchmark_test.cpp ${_ORACLE_BENCH_EXTRA_SOURCES} -) - -if(NOT GTEST_FOUND) - add_dependencies(oracle_importer_benchmark_test gtest) -endif() - -target_link_libraries( +cockatrice_add_manual_test( + NAME oracle_importer_benchmark_test + SOURCES + ${VERSION_STRING_CPP} + ../../oracle/src/oracleimporter.cpp + ../../oracle/src/parsehelpers.cpp + ../../oracle/src/raw_json_scanner.cpp + oracle_importer_benchmark_test.cpp + ${_ORACLE_BENCH_EXTRA_SOURCES} + LIBS libcockatrice_card libcockatrice_interfaces - Threads::Threads - ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} + EXTRA_LIBS ${_ORACLE_BENCH_EXTRA_LIBRARIES} + MANUAL ) diff --git a/tests/oracle/oracle_importer_benchmark_test.cpp b/tests/oracle/oracle_importer_benchmark_test.cpp index 633c9e40a..c2a4aaf4b 100644 --- a/tests/oracle/oracle_importer_benchmark_test.cpp +++ b/tests/oracle/oracle_importer_benchmark_test.cpp @@ -1,21 +1,37 @@ #include "../../oracle/src/oracleimporter.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/set/card_set.h" #include "gtest/gtest.h" #include +#include +#include #include #include #include #include #include +#include #include #include #include +#include +#include +#include #include #include #include +#include +#include +#include #include #include +#include #include +#include +#include +#include +#include #if defined(HAS_LZMA) #include "../../oracle/src/lzma/decompress.h" @@ -46,12 +62,10 @@ static QByteArray buildSyntheticData(int numSets, int cardsPerSet) card["colors"] = QJsonArray{"W"}; card["colorIdentity"] = QJsonArray{"W"}; card["types"] = QJsonArray{"Creature"}; - // Real MTGJSON types: floats and booleans, not strings. This + // Real MTGJSON types: floats, not strings. This // exercises the QVariant coercion in the property reader. card["convertedManaCost"] = 1.0; card["manaValue"] = 1.0; - card["isOnlineOnly"] = false; - card["isRebalanced"] = false; QJsonObject legalities; legalities["standard"] = "legal"; diff --git a/tests/oracle/oracle_importer_test.cpp b/tests/oracle/oracle_importer_test.cpp index f66616e37..83d77d465 100644 --- a/tests/oracle/oracle_importer_test.cpp +++ b/tests/oracle/oracle_importer_test.cpp @@ -1,15 +1,34 @@ #include "../../oracle/src/oracleimporter.h" +#include "../../oracle/src/raw_json_scanner.h" +#include "libcockatrice/card/card_info.h" #include "gtest/gtest.h" +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include class OracleImporterTest : public ::testing::Test { diff --git a/tests/oracle/parse_cipt_test.cpp b/tests/oracle/parse_cipt_test.cpp index f5036f962..10268d659 100644 --- a/tests/oracle/parse_cipt_test.cpp +++ b/tests/oracle/parse_cipt_test.cpp @@ -1,6 +1,7 @@ #include "../../oracle/src/parsehelpers.h" #include "gtest/gtest.h" +#include TEST(ParseCiptTest, parsesThisEntersTapped) { diff --git a/tests/password_hash_test.cpp b/tests/password_hash_test.cpp index 2b8f8bdb7..2a504b81c 100644 --- a/tests/password_hash_test.cpp +++ b/tests/password_hash_test.cpp @@ -1,6 +1,9 @@ #include "gtest/gtest.h" +#include +#include #include #include +#include namespace { diff --git a/tests/picture_loader_benchmark/CMakeLists.txt b/tests/picture_loader_benchmark/CMakeLists.txt index a3b75fe88..0684f58f4 100644 --- a/tests/picture_loader_benchmark/CMakeLists.txt +++ b/tests/picture_loader_benchmark/CMakeLists.txt @@ -1,8 +1,10 @@ -# Manual benchmark hitting the real card image hosts. Not registered with -# add_test(): it requires a cards.xml, touches the network for minutes at a -# time, and needs network access. Build it explicitly and run by hand. -add_executable( +# Manual benchmark hitting the real card image hosts. Not registered with CTest: it requires a +# cards.xml, touches the network for minutes at a time, and needs network access. Build it +# explicitly and run by hand. +cockatrice_add_manual_test( + NAME picture_loader_benchmark_test + SOURCES ${VERSION_STRING_CPP} ../../cockatrice/src/interface/card_picture_loader/card_picture_loader_local.cpp ../../cockatrice/src/interface/card_picture_loader/card_picture_to_load.cpp @@ -11,16 +13,12 @@ add_executable( ../../cockatrice/src/client/settings/cache_settings.h picture_loader_benchmark.cpp settings_cache_mock.cpp -) - -target_include_directories(picture_loader_benchmark_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src) - -target_link_libraries( - picture_loader_benchmark_test + LIBS libcockatrice_card libcockatrice_settings libcockatrice_interfaces libcockatrice_utility - Threads::Threads - ${TEST_QT_MODULES} + INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/cockatrice/src + MANUAL ) diff --git a/tests/picture_loader_benchmark/picture_loader_benchmark.cpp b/tests/picture_loader_benchmark/picture_loader_benchmark.cpp index f991f2ec0..587cef65f 100644 --- a/tests/picture_loader_benchmark/picture_loader_benchmark.cpp +++ b/tests/picture_loader_benchmark/picture_loader_benchmark.cpp @@ -25,22 +25,34 @@ #include "client/settings/cache_settings.h" #include "interface/card_picture_loader/card_picture_loader_worker.h" #include "interface/card_picture_loader/card_picture_to_load.h" +#include "libcockatrice/card/card_info.h" +#include "libcockatrice/card/database/card_database_loader.h" +#include #include #include #include #include #include +#include #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include +#include +#include #include #include #include @@ -51,6 +63,8 @@ #include #include #include +#include +#include class BenchmarkCardDatabasePathProvider : public ICardDatabasePathProvider { diff --git a/tests/picture_loader_benchmark/settings_cache_mock.cpp b/tests/picture_loader_benchmark/settings_cache_mock.cpp index d93c7e002..13e831b62 100644 --- a/tests/picture_loader_benchmark/settings_cache_mock.cpp +++ b/tests/picture_loader_benchmark/settings_cache_mock.cpp @@ -17,15 +17,21 @@ #include "client/settings/cache_settings.h" #include "interface/card_picture_loader/card_picture_loader_cache_method.h" +#include #include #include +#include +#include #include +#include #include +#include +#include #include #include #include #include -#include +#include QString SettingsCache::getDataPath() { diff --git a/tests/playmat_resolver_test.cpp b/tests/playmat_resolver_test.cpp index a931c0647..6730ec137 100644 --- a/tests/playmat_resolver_test.cpp +++ b/tests/playmat_resolver_test.cpp @@ -1,6 +1,15 @@ +#include "libcockatrice/interfaces/interface_interface_settings_provider.h" +#include "libcockatrice/utility/card_ref.h" +#include "libcockatrice/utility/playmat_params.h" + +#include +#include +#include +#include #include #include #include +#include namespace { diff --git a/tests/report_categories_test.cpp b/tests/report_categories_test.cpp index 790b2cff6..1e08938db 100644 --- a/tests/report_categories_test.cpp +++ b/tests/report_categories_test.cpp @@ -3,6 +3,7 @@ #include #include #include +#include TEST(ReportCategoriesTest, CanonicalListIsNonEmptyAndStable) { diff --git a/tests/server_card_counter_test.cpp b/tests/server_card_counter_test.cpp index c8bc43f8f..6308d80b9 100644 --- a/tests/server_card_counter_test.cpp +++ b/tests/server_card_counter_test.cpp @@ -3,12 +3,14 @@ * @ingroup Tests */ +#include +#include #include #include #include #include #include -#include +#include TEST(ServerCardCounter, IncrementNewCounter) { diff --git a/tests/server_counter_test.cpp b/tests/server_counter_test.cpp index 0f41f2cbd..492aecf66 100644 --- a/tests/server_counter_test.cpp +++ b/tests/server_counter_test.cpp @@ -3,9 +3,13 @@ * @ingroup Tests */ +#include "libcockatrice/protocol/pb/color.pb.h" + +#include #include #include #include +#include TEST(ServerCounter, IncrementDoesNotOverflow) { diff --git a/tests/server_developer_role_test.cpp b/tests/server_developer_role_test.cpp index 127f606a8..c77fc5b21 100644 --- a/tests/server_developer_role_test.cpp +++ b/tests/server_developer_role_test.cpp @@ -3,6 +3,10 @@ * @ingroup Tests */ +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/server_message.pb.h" + +#include #include #include #include @@ -11,6 +15,8 @@ #include #include #include +#include +#include // The server_remote library references the global RNG, which is normally // defined by the servatrice/client executable main(). Provide a stub so the diff --git a/tests/server_dump_zone_test.cpp b/tests/server_dump_zone_test.cpp new file mode 100644 index 000000000..71c410655 --- /dev/null +++ b/tests/server_dump_zone_test.cpp @@ -0,0 +1,125 @@ +/** @file server_dump_zone_test.cpp + * @brief Tests for resolving a client's zone dump request against a zone's card count. + * @ingroup Tests + */ + +#include +#include +#include +#include +#include + +namespace +{ +/// Indices a dump request resolves to, as the handler would walk them. +std::vector walked(qsizetype cardCount, int numberCards, bool isReversed) +{ + const auto [begin, end] = dumpZoneCardRange(cardCount, numberCards, isReversed); + std::vector out; + for (qsizetype i = begin; i < end; ++i) { + out.push_back(i); + } + return out; +} +} // namespace + +TEST(ServerDumpZone, ForwardTakesLeadingCards) +{ + EXPECT_EQ(walked(5, 2, false), (std::vector{0, 1})); +} + +TEST(ServerDumpZone, ForwardTakingAllCardsCoversTheZone) +{ + EXPECT_EQ(walked(3, 3, false), (std::vector{0, 1, 2})); +} + +TEST(ServerDumpZone, ForwardAskingForOneDumpsOne) +{ + EXPECT_EQ(walked(3, 1, false), (std::vector{0})); +} + +TEST(ServerDumpZone, MinusOneMeansTheWholeZone) +{ + EXPECT_EQ(walked(4, -1, false), (std::vector{0, 1, 2, 3})); +} + +TEST(ServerDumpZone, ReversedTakesTrailingCards) +{ + EXPECT_EQ(walked(5, 2, true), (std::vector{3, 4})); +} + +TEST(ServerDumpZone, ReversedAskingForOneTakesTheLast) +{ + EXPECT_EQ(walked(5, 1, true), (std::vector{4})); +} + +TEST(ServerDumpZone, ZeroDumpsNothing) +{ + EXPECT_TRUE(walked(5, 0, false).empty()); + EXPECT_TRUE(walked(5, 0, true).empty()); +} + +// A request for more cards than the zone holds is clamped rather than walked off the end. +// Forward, the old loop stopped at the zone's size on its own. +TEST(ServerDumpZone, ForwardOversizedRequestIsClamped) +{ + EXPECT_EQ(walked(3, 1000, false), (std::vector{0, 1, 2})); +} + +// Reversed, an oversized request put the offset at cardCount - numberCards, which is +// negative, so the walk started before the first card. +TEST(ServerDumpZone, ReversedOversizedRequestIsClamped) +{ + EXPECT_EQ(walked(3, 1000, true), (std::vector{0, 1, 2})); +} + +// Reversed, -1 put the offset at cardCount + 1, so the walk started one past the last card. +TEST(ServerDumpZone, ReversedWholeZoneRequestStaysInRange) +{ + EXPECT_EQ(walked(3, -1, true), (std::vector{0, 1, 2})); +} + +// Only -1 means "the whole zone". Any other negative count is not a request for anything, +// so it resolves to an empty range rather than to the whole zone. +TEST(ServerDumpZone, OtherNegativeCountsDumpNothing) +{ + EXPECT_TRUE(walked(5, -2, false).empty()); + EXPECT_TRUE(walked(5, -2, true).empty()); + EXPECT_TRUE(walked(5, INT_MIN, true).empty()); +} + +TEST(ServerDumpZone, EmptyZoneYieldsAnEmptyRange) +{ + EXPECT_TRUE(walked(0, -1, false).empty()); + EXPECT_TRUE(walked(0, -1, true).empty()); + EXPECT_TRUE(walked(0, 10, false).empty()); + EXPECT_TRUE(walked(0, 10, true).empty()); +} + +TEST(ServerDumpZone, NonPositiveCardCountYieldsAnEmptyRange) +{ + EXPECT_TRUE(walked(-1, -1, false).empty()); + EXPECT_TRUE(walked(-1, -1, true).empty()); +} + +// The invariant the handler depends on: whatever a client asks for, the indices it walks +// are a subset of the zone's cards and never step outside the list. number_cards is an +// unbounded client-supplied sint32, so this sweeps the edges rather than a chosen few. +TEST(ServerDumpZone, ResolvedRangeIsAlwaysWithinTheZone) +{ + const QList cardCounts = {0, 1, 2, 3, 7, 60, 1000000}; + const QList requests = {INT_MIN, -1000, -2, -1, 0, 1, 2, 3, 59, 60, 61, 999999, INT_MAX}; + + for (int cardCount : cardCounts) { + for (int request : requests) { + for (bool isReversed : {false, true}) { + const auto [begin, end] = dumpZoneCardRange(cardCount, request, isReversed); + SCOPED_TRACE(testing::Message() + << "cardCount=" << cardCount << " request=" << request << " isReversed=" << isReversed); + ASSERT_GE(begin, 0); + ASSERT_GE(end, begin); + ASSERT_LE(end, cardCount); + } + } + } +} diff --git a/tests/server_game_join_test.cpp b/tests/server_game_join_test.cpp index c84e4e066..8a2ae8c45 100644 --- a/tests/server_game_join_test.cpp +++ b/tests/server_game_join_test.cpp @@ -3,14 +3,19 @@ * @ingroup Tests */ +#include "game/game_config.h" #include "game/server_game.h" +#include "libcockatrice/protocol/pb/response.pb.h" #include "server.h" #include "server_database_interface.h" #include "server_room.h" +#include +#include #include #include #include +#include RNG_Abstract *rng = nullptr; // referenced by the server_remote library diff --git a/tests/server_moderator_role_test.cpp b/tests/server_moderator_role_test.cpp new file mode 100644 index 000000000..2517a2d86 --- /dev/null +++ b/tests/server_moderator_role_test.cpp @@ -0,0 +1,156 @@ +/** @file server_moderator_role_test.cpp + * @brief Tests for the moderator staff role authorization and dispatch. + * @ingroup Tests + */ + +#include "libcockatrice/protocol/pb/response.pb.h" +#include "libcockatrice/protocol/pb/server_message.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// The server_remote library references the global RNG, which is normally +// defined by the servatrice/client executable main(). Provide a stub so the +// unit test can link against it. +RNG_Abstract *rng = nullptr; + +namespace +{ + +class TestModeratorHandler : public Server_ProtocolHandler +{ +public: + explicit TestModeratorHandler(Server *_server) : Server_ProtocolHandler(_server, nullptr) + { + } + + QString getAddress() const override + { + return {}; + } + QString getConnectionType() const override + { + return {}; + } + + // Buffer the last response code sent to the client so tests can assert on + // the outcome of processCommandContainer(). + Response::ResponseCode lastResponseCode = Response::RespNothing; + int dispatchCount = 0; + +protected: + void transmitProtocolItem(const ServerMessage &item) override + { + if (item.message_type() == ServerMessage::RESPONSE) { + lastResponseCode = item.response().response_code(); + } + } + + Response::ResponseCode + processExtendedModeratorCommand(int cmdType, const ModeratorCommand &, ResponseContainer &) override + { + ++dispatchCount; + // Fail closed for anything not explicitly handled. + if (cmdType != ModeratorCommand::REPORT_REOPEN) { + return Response::RespFunctionNotAllowed; + } + return Response::RespOk; + } +}; + +class ModeratorRoleTest : public ::testing::Test +{ +protected: + Server server; + TestModeratorHandler handler{&server}; + + void setUserLevel(uint32_t level) + { + ServerInfo_User user; + user.set_user_level(level); + handler.setUserInfo(user); + } +}; + +TEST_F(ModeratorRoleTest, RejectsWhenNotLoggedIn) +{ + CommandContainer cont; + cont.add_moderator_command(); + handler.processCommandContainer(cont); + EXPECT_EQ(handler.lastResponseCode, Response::RespLoginNeeded); + EXPECT_EQ(handler.dispatchCount, 0); +} + +TEST_F(ModeratorRoleTest, RejectsPlainUser) +{ + setUserLevel(ServerInfo_User::IsUser | ServerInfo_User::IsRegistered); + + CommandContainer cont; + cont.add_moderator_command(); + handler.processCommandContainer(cont); + EXPECT_EQ(handler.lastResponseCode, Response::RespLoginNeeded); + EXPECT_EQ(handler.dispatchCount, 0); +} + +TEST_F(ModeratorRoleTest, DispatchesToModeratorCommandForModerator) +{ + setUserLevel(ServerInfo_User::IsModerator); + + CommandContainer cont; + ModeratorCommand *cmd = cont.add_moderator_command(); + cmd->MutableExtension(Command_ReportReopen::ext); + handler.processCommandContainer(cont); + EXPECT_EQ(handler.lastResponseCode, Response::RespOk); + EXPECT_EQ(handler.dispatchCount, 1); +} + +TEST_F(ModeratorRoleTest, DispatchesToModeratorCommandForAdmin) +{ + setUserLevel(ServerInfo_User::IsModerator | ServerInfo_User::IsAdmin); + + CommandContainer cont; + ModeratorCommand *cmd = cont.add_moderator_command(); + cmd->MutableExtension(Command_ReportReopen::ext); + handler.processCommandContainer(cont); + EXPECT_EQ(handler.lastResponseCode, Response::RespOk); + EXPECT_EQ(handler.dispatchCount, 1); +} + +TEST_F(ModeratorRoleTest, RejectsDeveloperThatIsNotModerator) +{ + setUserLevel(ServerInfo_User::IsDeveloper); + + CommandContainer cont; + cont.add_moderator_command(); + handler.processCommandContainer(cont); + EXPECT_EQ(handler.lastResponseCode, Response::RespLoginNeeded); + EXPECT_EQ(handler.dispatchCount, 0); +} + +TEST_F(ModeratorRoleTest, FailClosedForUnknownModeratorCommand) +{ + setUserLevel(ServerInfo_User::IsModerator); + + CommandContainer cont; + cont.add_moderator_command(); // no extension set -> getPbExtension() returns -1 + handler.processCommandContainer(cont); + EXPECT_EQ(handler.lastResponseCode, Response::RespFunctionNotAllowed); + EXPECT_EQ(handler.dispatchCount, 1); +} + +} // namespace + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tests/server_rate_limiter_test.cpp b/tests/server_rate_limiter_test.cpp index bc15ca421..8459c9690 100644 --- a/tests/server_rate_limiter_test.cpp +++ b/tests/server_rate_limiter_test.cpp @@ -1,7 +1,11 @@ #include "gtest/gtest.h" #include +#include #include +#include +#include #include +#include namespace { diff --git a/tests/settings/CMakeLists.txt b/tests/settings/CMakeLists.txt index 7ee32a645..98bed1f4b 100644 --- a/tests/settings/CMakeLists.txt +++ b/tests/settings/CMakeLists.txt @@ -1,26 +1,14 @@ -add_executable(settings_manager_test settings_manager_test.cpp) -add_executable(settings_defaults_test settings_defaults_test.cpp) -add_executable(settings_migration_test settings_migration_test.cpp) +cockatrice_add_test(NAME settings_manager_test SOURCES settings_manager_test.cpp LIBS libcockatrice_settings) -target_link_libraries( - settings_manager_test libcockatrice_settings Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} +cockatrice_add_test( + NAME + settings_defaults_test + SOURCES + settings_defaults_test.cpp + LIBS + libcockatrice_settings + DEFINITIONS + SETTINGS_UNIT_TEST ) -target_link_libraries( - settings_defaults_test libcockatrice_settings Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) -target_compile_definitions(settings_defaults_test PRIVATE SETTINGS_UNIT_TEST) - -target_link_libraries( - settings_migration_test libcockatrice_settings Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES} -) - -add_test(NAME settings_manager_test COMMAND settings_manager_test) -add_test(NAME settings_defaults_test COMMAND settings_defaults_test) -add_test(NAME settings_migration_test COMMAND settings_migration_test) - -if(NOT GTEST_FOUND) - add_dependencies(settings_manager_test gtest) - add_dependencies(settings_defaults_test gtest) - add_dependencies(settings_migration_test gtest) -endif() +cockatrice_add_test(NAME settings_migration_test SOURCES settings_migration_test.cpp LIBS libcockatrice_settings) diff --git a/tests/settings/settings_defaults_test.cpp b/tests/settings/settings_defaults_test.cpp index 379f6cd84..2ba9f3fbb 100644 --- a/tests/settings/settings_defaults_test.cpp +++ b/tests/settings/settings_defaults_test.cpp @@ -1,5 +1,11 @@ +#include "libcockatrice/card/card_localization.h" + #include "gtest/gtest.h" -#include +#include +#include +#include +#include +#include #include #include #include @@ -10,11 +16,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include namespace { @@ -159,6 +168,12 @@ TEST_F(SettingsDefaultsTest, Updates_NotifyAboutNewVersion_Default) ASSERT_EQ(s.getNotifyAboutNewVersion(), true); } +TEST_F(SettingsDefaultsTest, Updates_CardDatabaseUpdateTrayNotification_Default) +{ + UpdatesSettings s(settingsPath, nullptr); + ASSERT_EQ(s.getCardDatabaseUpdateTrayNotification(), true); +} + TEST_F(SettingsDefaultsTest, Updates_UpdateReleaseChannelIndex_Default) { UpdatesSettings s(settingsPath, nullptr); @@ -682,6 +697,55 @@ TEST_F(SettingsDefaultsTest, VisualDeckStorage_ShowUploadTime_SetAndGet) ASSERT_EQ(s.getVisualDeckStorageShowUploadTime(), false); } +TEST_F(SettingsDefaultsTest, Paths_AppDirWarningAcknowledged_Default) +{ + PathsSettings s(settingsPath, nullptr); + ASSERT_EQ(s.getAppDirWarningAcknowledged(), false); +} + +TEST_F(SettingsDefaultsTest, Paths_AppDirWarningAcknowledged_SetAndGet) +{ + PathsSettings s(settingsPath, nullptr); + s.setAppDirWarningAcknowledged(true); + ASSERT_EQ(s.getAppDirWarningAcknowledged(), true); +} + +TEST_F(SettingsDefaultsTest, Paths_PathsInsideDir_DetectsNestedAndIgnoresSiblings) +{ + PathsSettings s(settingsPath, nullptr); + const QString base = QDir::cleanPath(settingsPath); + + s.setDeckPath(base + "/decks/"); + s.setPicsPath(base + "/pics"); + s.setReplaysPath(base + "2"); // sibling sharing the name prefix, not nested + + const QStringList offenders = s.pathsInsideDir(base); + ASSERT_EQ(offenders.size(), 2); + ASSERT_TRUE(offenders.contains(base + "/decks")); + ASSERT_TRUE(offenders.contains(base + "/pics")); +} + +TEST_F(SettingsDefaultsTest, Paths_PathsInsideDir_EmptyWhenNothingMatches) +{ + PathsSettings s(settingsPath, nullptr); + s.setDeckPath("/somewhere/else/decks"); + ASSERT_TRUE(s.pathsInsideDir(QDir::cleanPath(settingsPath)).isEmpty()); +} + +TEST_F(SettingsDefaultsTest, Paths_PathsInsideDir_MatchesExactBaseAndNormalizesDots) +{ + PathsSettings s(settingsPath, nullptr); + const QString base = QDir::cleanPath(settingsPath); + + s.setCustomPicsPath(base); // exactly the base directory + s.setThemesPath(base + "/pics/../decks"); // needs cleanPath normalization + + const QStringList offenders = s.pathsInsideDir(base); + ASSERT_EQ(offenders.size(), 2); + ASSERT_TRUE(offenders.contains(base)); + ASSERT_TRUE(offenders.contains(base + "/decks")); +} + } // namespace int main(int argc, char **argv) diff --git a/tests/settings/settings_manager_test.cpp b/tests/settings/settings_manager_test.cpp index 51eb66dbb..23d27aa78 100644 --- a/tests/settings/settings_manager_test.cpp +++ b/tests/settings/settings_manager_test.cpp @@ -1,7 +1,11 @@ #include "gtest/gtest.h" #include +#include #include +#include +#include #include +#include namespace { diff --git a/tests/settings/settings_migration_test.cpp b/tests/settings/settings_migration_test.cpp index 84b948d2e..2c4dcf7a9 100644 --- a/tests/settings/settings_migration_test.cpp +++ b/tests/settings/settings_migration_test.cpp @@ -1,13 +1,24 @@ #include "gtest/gtest.h" +#include +#include +#include #include #include #include #include #include +#include +#include #include +#include #include +#include #include +#include +#include #include +#include +#include namespace { @@ -225,7 +236,6 @@ TEST_F(SettingsMigrationTest, MigratesAllSettingsGroups) g.setValue("cards/roundcardcorners", false); g.setValue("cards/overrideallcardartwithpersonalpreference", true); g.setValue("cards/bumpsetswithcardsindecktotop", false); - g.setValue("cards/includerebalancedcards", false); g.setValue("cards/autorotatesidewayslayoutcards", false); g.setValue("cards/tapanimation", true); g.setValue("cards/scaleCards", false); @@ -384,7 +394,6 @@ TEST_F(SettingsMigrationTest, MigratesAllSettingsGroups) ASSERT_EQ(readFromIni("cards_display.ini", "cards/roundCardCorners"), QVariant(false)); ASSERT_EQ(readFromIni("cards_display.ini", "cards/overrideAllCardArtWithPersonalPreference"), QVariant(true)); ASSERT_EQ(readFromIni("cards_display.ini", "cards/bumpSetsWithCardsInDeckToTop"), QVariant(false)); - ASSERT_EQ(readFromIni("cards_display.ini", "cards/includerebalancedcards"), QVariant(false)); ASSERT_EQ(readFromIni("cards_display.ini", "cards/autoRotateSidewaysLayoutCards"), QVariant(false)); ASSERT_EQ(readFromIni("cards_display.ini", "cards/tapAnimation"), QVariant(true)); ASSERT_EQ(readFromIni("cards_display.ini", "cards/scaleCards"), QVariant(false)); @@ -696,6 +705,71 @@ TEST_F(SettingsMigrationTest, LegacyMigrationCamelCasesKeys) ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/gameType/deadbeef"), QVariant(true)); } +TEST_F(SettingsMigrationTest, LegacyMigrationMapsCreatorNameFilterToHostNameFilter) +{ + { + QSettings nativeSettings; + nativeSettings.setValue("filter_games/creator_name_filter", QStringList({"Alice", "Bob"})); + nativeSettings.sync(); + } + + ASSERT_TRUE(SettingsMigration::migrateLegacySettings(settingsPath)); + + ASSERT_TRUE(fileExists("gamefilters.ini")); + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/hostNameFilter"), QVariant(QStringList({"Alice", "Bob"}))); +} + +TEST_F(SettingsMigrationTest, GameFiltersIniSnakeCaseMigratesToCamelCase) +{ + { + QSettings filtersIni(settingsPath + "gamefilters.ini", QSettings::IniFormat); + filtersIni.setValue("filter_games/hide_full_games", true); + filtersIni.setValue("filter_games/hide_games_that_started", true); + filtersIni.setValue("filter_games/game_name_filter", "test game"); + filtersIni.setValue("filter_games/creator_name_filter", QStringList({"Alice"})); + filtersIni.setValue("filter_games/game_type/deadbeef", true); + filtersIni.sync(); + } + + ASSERT_TRUE(SettingsMigration::migrateGameFiltersToCamelCase(settingsPath)); + + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/hideFullGames"), QVariant(true)); + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/hideGamesThatStarted"), QVariant(true)); + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/gameNameFilter"), QVariant("test game")); + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/hostNameFilter"), QVariant(QStringList({"Alice"}))); + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/gameType/deadbeef"), QVariant(true)); + + // Idempotent: a second run has nothing left to do + ASSERT_FALSE(SettingsMigration::migrateGameFiltersToCamelCase(settingsPath)); +} + +TEST_F(SettingsMigrationTest, GameFiltersIniOrphanCreatorNameFilterMigratesToHostName) +{ + { + QSettings filtersIni(settingsPath + "gamefilters.ini", QSettings::IniFormat); + filtersIni.setValue("filter_games/creatorNameFilter", QStringList({"Alice"})); + filtersIni.sync(); + } + + ASSERT_TRUE(SettingsMigration::migrateGameFiltersToCamelCase(settingsPath)); + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/hostNameFilter"), QVariant(QStringList({"Alice"}))); + ASSERT_FALSE(SettingsMigration::migrateGameFiltersToCamelCase(settingsPath)); +} + +TEST_F(SettingsMigrationTest, GameFiltersIniKeepsNewerCamelCaseValues) +{ + { + QSettings filtersIni(settingsPath + "gamefilters.ini", QSettings::IniFormat); + filtersIni.setValue("filter_games/hide_full_games", true); + filtersIni.setValue("filter_games/hideFullGames", false); + filtersIni.sync(); + } + + // Nothing to do: the current-format key already exists and must win + ASSERT_FALSE(SettingsMigration::migrateGameFiltersToCamelCase(settingsPath)); + ASSERT_EQ(readFromIni("gamefilters.ini", "filter_games/hideFullGames"), QVariant(false)); +} + TEST_F(SettingsMigrationTest, LegacyMigrationEmptyNativeFormatWritesSentinel) { QSettings().clear(); diff --git a/tests/single_instance_manager_test.cpp b/tests/single_instance_manager_test.cpp index 49193850d..bc8074580 100644 --- a/tests/single_instance_manager_test.cpp +++ b/tests/single_instance_manager_test.cpp @@ -1,12 +1,18 @@ #include "single_instance_manager.h" +#include #include #include #include +#include +#include #include #include +#include #include +#include #include +#include namespace { diff --git a/tests/test_age_formatting.cpp b/tests/test_age_formatting.cpp index 6a9d5d4af..8602ffdc0 100644 --- a/tests/test_age_formatting.cpp +++ b/tests/test_age_formatting.cpp @@ -1,5 +1,8 @@ #include "gtest/gtest.h" +#include +#include #include +#include namespace { diff --git a/tests/theme_migration/CMakeLists.txt b/tests/theme_migration/CMakeLists.txt index ac202210e..93493ee5f 100644 --- a/tests/theme_migration/CMakeLists.txt +++ b/tests/theme_migration/CMakeLists.txt @@ -1,5 +1,7 @@ -add_executable( +cockatrice_add_test( + NAME theme_migration_test + SOURCES ${CMAKE_SOURCE_DIR}/cockatrice/src/interface/theme_manager.cpp ${CMAKE_SOURCE_DIR}/cockatrice/src/interface/theme_config.cpp ${CMAKE_SOURCE_DIR}/cockatrice/src/interface/pixel_map_generator.cpp @@ -9,22 +11,11 @@ add_executable( ${CMAKE_SOURCE_DIR}/cockatrice/src/client/network/update/client/release_channel.cpp ${VERSION_STRING_CPP} theme_migration_test.cpp -) -target_include_directories(theme_migration_test PRIVATE ${CMAKE_SOURCE_DIR}/cockatrice/src) - -target_link_libraries( - theme_migration_test + LIBS libcockatrice_settings libcockatrice_network libcockatrice_network_server_remote libcockatrice_protocol - Threads::Threads - ${GTEST_BOTH_LIBRARIES} - ${TEST_QT_MODULES} + INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/cockatrice/src ) - -add_test(NAME theme_migration_test COMMAND theme_migration_test) - -if(NOT GTEST_FOUND) - add_dependencies(theme_migration_test gtest) -endif() diff --git a/tests/theme_migration/theme_migration_test.cpp b/tests/theme_migration/theme_migration_test.cpp index 147833630..d77c2f62d 100644 --- a/tests/theme_migration/theme_migration_test.cpp +++ b/tests/theme_migration/theme_migration_test.cpp @@ -1,11 +1,15 @@ #include "interface/theme_manager.h" +#include #include #include #include +#include #include +#include #include #include +#include // Owned by main.cpp in the real application; pixel_map_generator.cpp references // it, so the test binary needs a definition even though it never renders. diff --git a/tests/translation_loader_test.cpp b/tests/translation_loader_test.cpp index d54001ad3..745cd04bc 100644 --- a/tests/translation_loader_test.cpp +++ b/tests/translation_loader_test.cpp @@ -1,12 +1,17 @@ #include "gtest/gtest.h" +#include #include #include #include +#include #include #include +#include +#include #include #include #include +#include // The directory holding translation_loader_test_de.qm, compiled from translation_loader_test.ts by the // build. QTranslator rejects anything that is not a real .qm file, so a stub cannot stand in here. diff --git a/tests/warning_categories_test.cpp b/tests/warning_categories_test.cpp index 432885dd9..549c373b5 100644 --- a/tests/warning_categories_test.cpp +++ b/tests/warning_categories_test.cpp @@ -1,6 +1,8 @@ #include "gtest/gtest.h" +#include #include #include +#include TEST(WarningCategoriesTest, EmptyValueYieldsNoCategories) { diff --git a/tools/generate_qt_mappings.py b/tools/generate_qt_mappings.py new file mode 100755 index 000000000..42836b6da --- /dev/null +++ b/tools/generate_qt_mappings.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +"""Generate an include-what-you-use mapping file for Qt 6 headers. + +Qt 6 ships a capital forwarding header (e.g. ) for each lowercase +private header (e.g. qwidget.h). include-what-you-use resolves symbols to the +lowercase header by default, so this script emits a mapping that makes IWYU +prefer the canonical capital includes, mirroring the qt5_11.imp bundled with +IWYU but adapted to the Qt 6 module layout. + +For every capital header that forwards to exactly one lowercase header: + +* a "symbol" mapping is emitted so IWYU suggests when the definition + of a class is needed, and +* an "include" mapping is emitted so a literal `#include ` in source + is rewritten to its canonical capital header. + +A lowercase header can be forwarded to by several capital headers (e.g. +qevent.h provides QCloseEvent, QMouseEvent, ...). In that case the include +mapping targets the primary class, i.e. the capital header whose lowercased +name equals the private header (QWidget for qwidget.h); headers with no such +primary (aggregates like qevent.h) get no include mapping and are left alone. + +Usage: + tools/generate_qt_mappings.py [QT_INSTALL_HEADERS] + +QT_INSTALL_HEADERS defaults to `qmake6 -query QT_INSTALL_HEADERS` (falling back +to common locations). The mapping is written to stdout. +""" + +import argparse +import os +import re +import subprocess +import sys + +INCLUDE_RE = re.compile(r'^\s*#include\s*<\s*Qt[A-Za-z0-9_]+/+\s*([^>\s]+)>') +CAPITAL_NAME_RE = re.compile(r'^Q[A-Za-z0-9_]+$') +PRIVATE_NAME_RE = re.compile(r'^q[a-z0-9_]+\.h$') + +# Private Qt headers whose public spelling has to be named explicitly. Keep an +# entry here only if the target header exists in every Qt we support; IWYU would +# otherwise keep suggesting the private lowercase include, which is correct only +# for headers that have shipped publicly since Qt 5. +PORTABLE_WRAPPERS = { + # Qt 6.5 split the declarations that used to live in qglobal.h out into + # separate headers, under both a QtFoo wrapper and a qfoo.h private name. + # Neither spelling exists on the oldest Qt we support (6.4.2), and qtypes.h + # itself only appeared in Qt 6.9, so all of them are hard compile errors + # there. QtGlobal has been public since Qt 5, defines these declarations + # itself up to Qt 6.4, and includes the split headers from Qt 6.5 on, so it + # is the one spelling that resolves across the whole supported range. + 'qtypes.h': 'QtGlobal', + 'qtpreprocessorsupport.h': 'QtGlobal', + 'qtversionchecks.h': 'QtGlobal', + 'qassert.h': 'QtGlobal', + 'qminmax.h': 'QtGlobal', + 'qtclasshelpermacros.h': 'QtGlobal', + 'qtenvironmentvariables.h': 'QtGlobal', + 'qttranslation.h': 'QtGlobal', + 'qoverload.h': 'QtGlobal', +} + + +def run_or_empty(cmd): + try: + return subprocess.run(cmd, capture_output=True, text=True, + check=True).stdout.strip() + except (OSError, subprocess.CalledProcessError): + return '' + + +def default_qt_headers_dir(): + for cmd in (['qmake6', '-query', 'QT_INSTALL_HEADERS'], + ['qmake', '-query', 'QT_INSTALL_HEADERS']): + path = run_or_empty(cmd) + if path: + return path + for path in ('/usr/include/qt6', '/usr/lib64/qt6/include', + '/usr/local/include/qt6'): + if os.path.isdir(path): + return path + return '' + + +def collect_mappings(qt_headers_dir): + forwarders = {} # (module_dir, private) -> [capital names] + symbols = {} # capital name -> (module_dir, private) + for entry in sorted(os.listdir(qt_headers_dir)): + module_dir = os.path.join(qt_headers_dir, entry) + if not entry.startswith('Qt') or not os.path.isdir(module_dir): + continue + for name in sorted(os.listdir(module_dir)): + path = os.path.join(module_dir, name) + if not os.path.isfile(path) or not CAPITAL_NAME_RE.match(name): + continue + forwarded = [] + with open(path, 'r', encoding='utf-8', errors='replace') as f: + for line in f: + match = INCLUDE_RE.match(line) + if match: + forwarded.append(match.group(1)) + if len(forwarded) > 1: + break + if len(forwarded) != 1: + continue + private = forwarded[0] + if not PRIVATE_NAME_RE.match(private): + continue + forwarders.setdefault((module_dir, private), []).append(name) + symbols[name] = (module_dir, private) + return forwarders, symbols + + +def primary_include_mappings(forwarders): + mappings = {} + for (module_dir, private), names in sorted(forwarders.items()): + # Curated overrides win over the name rule below. They exist to redirect + # an include to a header that is valid across our whole supported Qt + # range, which the name rule cannot know about because it is generated + # from whatever Qt happens to be installed. + curated = PORTABLE_WRAPPERS.get(private) + if curated is not None: + mappings[(module_dir, private)] = curated + continue + # Prefer the forwarder whose name mirrors the private header + # (QAbstractAnimation -> qabstractanimation.h). + primary = next((n for n in names if n.lower() + '.h' == private), None) + if primary is not None: + mappings[(module_dir, private)] = primary + return mappings + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('qt_headers_dir', nargs='?', default=None, + help='Qt 6 headers dir (default: qmake query)') + args = parser.parse_args() + + qt_headers_dir = args.qt_headers_dir or default_qt_headers_dir() + if not qt_headers_dir or not os.path.isdir(qt_headers_dir): + sys.stderr.write('error: could not locate Qt headers, pass the include ' + 'dir\n') + return 1 + + forwarders, symbols = collect_mappings(qt_headers_dir) + includes = primary_include_mappings(forwarders) + + # A curated key that matches nothing is almost always a typo, and it fails + # silently: the entry just falls back to the name rule and emits the + # version-incompatible wrapper the override was meant to prevent. + known_private = {private for (_module_dir, private) in forwarders} + unknown = sorted(set(PORTABLE_WRAPPERS) - known_private) + if unknown: + sys.stderr.write('error: PORTABLE_WRAPPERS keys not found in the Qt ' + 'headers: %s\n' % ', '.join(unknown)) + return 1 + + entries = [] + # Headers we redirect in PORTABLE_WRAPPERS do not exist on the oldest + # supported Qt, so do not advertise them as the home of a symbol either. + redirected = {name + for (module_dir, private), names in forwarders.items() + if private in PORTABLE_WRAPPERS + for name in names} + for name in sorted(symbols): + if name in redirected: + continue + entries.append( + f' {{ "symbol": [ "{name}", "private", "<{name}>", "public"] }},') + + # Free operators of QSharedPointer/QWeakPointer live in qsharedpointer.h. + # IWYU does not apply "include" mappings when *adding* an include for an + # operator or other non-class symbol, so map them to the canonical capital + # header explicitly. A use is only reported when the operator is not + # already covered by an included header, so this does not mis-attribute + # comparison operators of other types (which are provided by their own + # type headers). + for name in ('operator==', 'operator!=', 'operator<', 'operator<=', + 'operator>', 'operator>=', 'comparesEqual'): + entries.append( + f' {{ "symbol": [ "{name}", "private", "", "public"] }},') + for (module_dir, private), public in sorted(includes.items()): + module = os.path.basename(module_dir) + # IWYU's .imp tokenizer treats the value as a JSON-ish string: + # '\"' becomes a quote and '\\' becomes a backslash for the regex. + quoted = '\\"' # \" -- a JSON-escaped double quote in the .imp file + dotted = re.escape(private).replace('\\', '\\\\') + pattern = ('@[' + quoted + '<](' + re.escape(module) + r'/)?' + + dotted + '[' + quoted + '>]') + entries.append( + f' {{ "include": [ "{pattern}", "private", "<{public}>", "public"] }},') + + if not entries: + sys.stderr.write('error: no Qt header mappings found\n') + return 1 + + print(f'# Do not edit! Generated by {os.path.basename(__file__)} from') + print(f'# {qt_headers_dir}') + print('[') + for entry in entries[:-1]: + print(entry) + print(entries[-1].rstrip(',')) + print(']') + return 0 + + +if __name__ == '__main__': + sys.exit(main())