mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-26 12:50:46 -08:00
Compare commits
18 Commits
more_webat
...
tooomm-set
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad7e1795db | ||
|
|
8b809826d5 | ||
|
|
121fcf09d4 | ||
|
|
717a272291 | ||
|
|
4fc81b159d | ||
|
|
66bcedd9c4 | ||
|
|
c450471f12 | ||
|
|
56fb4e09e0 | ||
|
|
7a7db574b3 | ||
|
|
5f8d5479da | ||
|
|
1538d4b187 | ||
|
|
0ea4a73fd2 | ||
|
|
cb5b8d34b2 | ||
|
|
a7faa5c139 | ||
|
|
6561ca216c | ||
|
|
2f924ccb4e | ||
|
|
f98809eabf | ||
|
|
71b79915d3 |
@@ -8,11 +8,9 @@ RUN pacman --sync --refresh --sysupgrade --needed --noconfirm \
|
||||
gtest \
|
||||
mariadb-libs \
|
||||
protobuf \
|
||||
qt6-base \
|
||||
qt6-imageformats \
|
||||
qt6-multimedia \
|
||||
qt6-svg \
|
||||
qt6-tools \
|
||||
qt6-translations \
|
||||
qt6-websockets \
|
||||
qt5-base \
|
||||
qt5-multimedia \
|
||||
qt5-svg \
|
||||
qt5-tools \
|
||||
qt5-websockets \
|
||||
&& pacman --sync --clean --clean --noconfirm
|
||||
|
||||
24
.ci/Debian10/Dockerfile
Normal file
24
.ci/Debian10/Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
FROM debian:10
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ccache \
|
||||
clang-format \
|
||||
cmake \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
liblzma-dev \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt5multimedia5-plugins \
|
||||
libqt5sql5-mysql \
|
||||
libqt5svg5-dev \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-default \
|
||||
qtbase5-dev \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -17,7 +17,6 @@ RUN apt-get update && \
|
||||
libqt5svg5-dev \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-image-formats-plugins \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
|
||||
21
.ci/Fedora34/Dockerfile
Normal file
21
.ci/Fedora34/Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
FROM fedora:34
|
||||
|
||||
RUN dnf install -y \
|
||||
@development-tools \
|
||||
ccache \
|
||||
cmake \
|
||||
desktop-file-utils \
|
||||
file \
|
||||
gcc-c++ \
|
||||
git \
|
||||
hicolor-icon-theme \
|
||||
libappstream-glib \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt5-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
rpm-build \
|
||||
sqlite-devel \
|
||||
wget \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
21
.ci/Fedora35/Dockerfile
Normal file
21
.ci/Fedora35/Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
FROM fedora:35
|
||||
|
||||
RUN dnf install -y \
|
||||
@development-tools \
|
||||
ccache \
|
||||
cmake \
|
||||
desktop-file-utils \
|
||||
file \
|
||||
gcc-c++ \
|
||||
git \
|
||||
hicolor-icon-theme \
|
||||
libappstream-glib \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt5-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
rpm-build \
|
||||
sqlite-devel \
|
||||
wget \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
@@ -1,15 +0,0 @@
|
||||
FROM fedora:39
|
||||
|
||||
RUN dnf install -y \
|
||||
ccache \
|
||||
cmake \
|
||||
gcc-c++ \
|
||||
git \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt6-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
qt6-qtimageformats \
|
||||
rpm-build \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
@@ -1,15 +0,0 @@
|
||||
FROM fedora:40
|
||||
|
||||
RUN dnf install -y \
|
||||
ccache \
|
||||
cmake \
|
||||
gcc-c++ \
|
||||
git \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt6-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
qt6-qtimageformats \
|
||||
rpm-build \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
@@ -17,7 +17,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-default \
|
||||
qt5-image-formats-plugins \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
|
||||
@@ -18,7 +18,6 @@ RUN apt-get update && \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-default \
|
||||
qt5-image-formats-plugins \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:12
|
||||
FROM ubuntu:hirsute
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
@@ -9,19 +9,16 @@ RUN apt-get update && \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
libgl-dev \
|
||||
liblzma-dev \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt6multimedia6 \
|
||||
libqt6sql6-mysql \
|
||||
qt6-svg-dev \
|
||||
qt6-websockets-dev \
|
||||
libqt5multimedia5-plugins \
|
||||
libqt5sql5-mysql \
|
||||
libqt5svg5-dev \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt6-image-formats-plugins \
|
||||
qt6-l10n-tools \
|
||||
qt6-multimedia-dev \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:noble
|
||||
FROM ubuntu:impish
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
@@ -9,19 +9,16 @@ RUN apt-get update && \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
libgl-dev \
|
||||
liblzma-dev \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt6multimedia6 \
|
||||
libqt6sql6-mysql \
|
||||
qt6-svg-dev \
|
||||
qt6-websockets-dev \
|
||||
libqt5multimedia5-plugins \
|
||||
libqt5sql5-mysql \
|
||||
libqt5svg5-dev \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt6-image-formats-plugins \
|
||||
qt6-l10n-tools \
|
||||
qt6-multimedia-dev \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -1,27 +0,0 @@
|
||||
FROM ubuntu:jammy
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ccache \
|
||||
clang-format \
|
||||
cmake \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
libgl-dev \
|
||||
liblzma-dev \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt6multimedia6 \
|
||||
libqt6sql6-mysql \
|
||||
libqt6svg6-dev \
|
||||
libqt6websockets6-dev \
|
||||
protobuf-compiler \
|
||||
qt6-image-formats-plugins \
|
||||
qt6-l10n-tools \
|
||||
qt6-multimedia-dev \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
137
.ci/compile.sh
137
.ci/compile.sh
@@ -2,26 +2,16 @@
|
||||
|
||||
# This script is to be used by the ci environment from the project root directory, do not use it from somewhere else.
|
||||
|
||||
# Compiles cockatrice inside of a ci environment
|
||||
# --install runs make install
|
||||
# --package [<package type>] runs make package, optionally force the type
|
||||
# --suffix <suffix> renames package with this suffix, requires arg
|
||||
# --server compiles servatrice
|
||||
# --test runs tests
|
||||
# --debug or --release sets the build type ie CMAKE_BUILD_TYPE
|
||||
# --ccache [<size>] uses ccache and shows stats, optionally provide size
|
||||
# --dir <dir> sets the name of the build dir, default is "build"
|
||||
# --parallel <core count> sets how many cores cmake should build with in parallel
|
||||
# uses env: BUILDTYPE MAKE_INSTALL MAKE_PACKAGE PACKAGE_TYPE PACKAGE_SUFFIX MAKE_SERVER MAKE_TEST USE_CCACHE CCACHE_SIZE BUILD_DIR PARALLEL_COUNT
|
||||
# (correspond to args: --debug/--release --install --package <package type> --suffix <suffix> --server --test --ccache <ccache_size> --dir <dir> --parallel <core_count>)
|
||||
# exitcode: 1 for failure, 3 for invalid arguments
|
||||
|
||||
# Read arguments
|
||||
while [[ $# != 0 ]]; do
|
||||
while [[ "$@" ]]; do
|
||||
case "$1" in
|
||||
'--')
|
||||
shift
|
||||
;;
|
||||
'--format')
|
||||
CHECK_FORMAT=1
|
||||
shift
|
||||
;;
|
||||
'--install')
|
||||
MAKE_INSTALL=1
|
||||
shift
|
||||
@@ -29,7 +19,7 @@ while [[ $# != 0 ]]; do
|
||||
'--package')
|
||||
MAKE_PACKAGE=1
|
||||
shift
|
||||
if [[ $# != 0 && ${1:0:1} != - ]]; then
|
||||
if [[ $# != 0 && $1 != -* ]]; then
|
||||
PACKAGE_TYPE="$1"
|
||||
shift
|
||||
fi
|
||||
@@ -38,7 +28,7 @@ while [[ $# != 0 ]]; do
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--suffix expects an argument"
|
||||
exit 3
|
||||
exit 1
|
||||
fi
|
||||
PACKAGE_SUFFIX="$1"
|
||||
shift
|
||||
@@ -62,140 +52,101 @@ while [[ $# != 0 ]]; do
|
||||
'--ccache')
|
||||
USE_CCACHE=1
|
||||
shift
|
||||
if [[ $# != 0 && ${1:0:1} != - ]]; then
|
||||
CCACHE_SIZE="$1"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
'--dir')
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--dir expects an argument"
|
||||
exit 3
|
||||
fi
|
||||
BUILD_DIR="$1"
|
||||
shift
|
||||
;;
|
||||
'--parallel')
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--parallel expects an argument"
|
||||
exit 3
|
||||
fi
|
||||
PARALLEL_COUNT="$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "::error file=$0::unrecognized option: $1"
|
||||
exit 3
|
||||
if [[ $1 == -* ]]; then
|
||||
echo "::error file=$0::unrecognized option: $1"
|
||||
exit 3
|
||||
fi
|
||||
BUILDTYPE="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check formatting using clang-format
|
||||
if [[ $CHECK_FORMAT ]]; then
|
||||
echo "::group::Run linter"
|
||||
source ./.ci/lint.sh
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
# Setup
|
||||
./servatrice/check_schema_version.sh
|
||||
if [[ ! $BUILDTYPE ]]; then
|
||||
BUILDTYPE=Release
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
if [[ ! $CMAKE_BUILD_PARALLEL_LEVEL ]]; then
|
||||
CMAKE_BUILD_PARALLEL_LEVEL=2 # default machines have 2 cores
|
||||
fi
|
||||
if [[ ! $BUILD_DIR ]]; then
|
||||
BUILD_DIR="build"
|
||||
fi
|
||||
mkdir -p "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Add cmake flags
|
||||
flags=("-DCMAKE_BUILD_TYPE=$BUILDTYPE")
|
||||
if [[ $MAKE_SERVER ]]; then
|
||||
flags+=("-DWITH_SERVER=1")
|
||||
flags+=" -DWITH_SERVER=1"
|
||||
fi
|
||||
if [[ $MAKE_TEST ]]; then
|
||||
flags+=("-DTEST=1")
|
||||
flags+=" -DTEST=1"
|
||||
fi
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
flags+=("-DUSE_CCACHE=1")
|
||||
if [[ $CCACHE_SIZE ]]; then
|
||||
# note, this setting persists after running the script
|
||||
ccache --max-size "$CCACHE_SIZE"
|
||||
fi
|
||||
if [[ $BUILDTYPE ]]; then
|
||||
flags+=" -DCMAKE_BUILD_TYPE=$BUILDTYPE"
|
||||
fi
|
||||
if [[ $PACKAGE_TYPE ]]; then
|
||||
flags+=("-DCPACK_GENERATOR=$PACKAGE_TYPE")
|
||||
flags+=" -DCPACK_GENERATOR=$PACKAGE_TYPE"
|
||||
fi
|
||||
|
||||
# Add cmake --build flags
|
||||
buildflags=(--config "$BUILDTYPE")
|
||||
if [[ $PARALLEL_COUNT ]]; then
|
||||
if [[ $(cmake --build /not_a_dir --parallel 2>&1 | head -1) =~ parallel ]]; then
|
||||
# workaround for bionic having an old cmake
|
||||
echo "this version of cmake does not support --parallel, using native build tool -j instead"
|
||||
buildflags+=(-- -j "$PARALLEL_COUNT")
|
||||
# note, no normal build flags should be added after this
|
||||
else
|
||||
buildflags+=(--parallel "$PARALLEL_COUNT")
|
||||
if [[ $(uname) == "Darwin" ]]; then
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
# prepend ccache compiler binaries to path
|
||||
PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
fi
|
||||
# Add qt install location when using homebrew
|
||||
flags+=" -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5/"
|
||||
fi
|
||||
|
||||
function ccachestatsverbose() {
|
||||
# note, verbose only works on newer ccache, discard the error
|
||||
local got
|
||||
if got="$(ccache --show-stats --verbose 2>/dev/null)"; then
|
||||
echo "$got"
|
||||
else
|
||||
ccache --show-stats
|
||||
fi
|
||||
}
|
||||
|
||||
# Compile
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
echo "::group::Show ccache stats"
|
||||
ccachestatsverbose
|
||||
ccache --show-stats
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
echo "::group::Configure cmake"
|
||||
cmake --version
|
||||
cmake .. "${flags[@]}"
|
||||
cmake .. $flags
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build project"
|
||||
if [[ $RUNNER_OS == Windows ]]; then
|
||||
# Enable MTT, see https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||
# and https://devblogs.microsoft.com/cppblog/cpp-build-throughput-investigation-and-tune-up/#multitooltask-mtt
|
||||
cmake --build . "${buildflags[@]}" -- -p:UseMultiToolTask=true -p:EnableClServerMode=true
|
||||
else
|
||||
cmake --build . "${buildflags[@]}"
|
||||
fi
|
||||
cmake --build .
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
echo "::group::Show ccache stats again"
|
||||
ccachestatsverbose
|
||||
ccache --show-stats
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $MAKE_TEST ]]; then
|
||||
echo "::group::Run tests"
|
||||
ctest -C "$BUILDTYPE" --output-on-failure
|
||||
cmake --build . --target test
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $MAKE_INSTALL ]]; then
|
||||
echo "::group::Install"
|
||||
cmake --build . --target install --config "$BUILDTYPE"
|
||||
cmake --build . --target install
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $MAKE_PACKAGE ]]; then
|
||||
echo "::group::Create package"
|
||||
cmake --build . --target package --config "$BUILDTYPE"
|
||||
cmake --build . --target package
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ $PACKAGE_SUFFIX ]]; then
|
||||
echo "::group::Update package name"
|
||||
cd ..
|
||||
BUILD_DIR="$BUILD_DIR" .ci/name_build.sh "$PACKAGE_SUFFIX"
|
||||
../.ci/name_build.sh "$PACKAGE_SUFFIX"
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -3,15 +3,11 @@
|
||||
# This script is to be used by the ci environment from the project root directory, do not use it from somewhere else.
|
||||
|
||||
# Creates or loads docker images to use in compilation, creates RUN function to start compilation on the docker image.
|
||||
# <arg> sets the name of the docker image, these correspond to directories in .ci
|
||||
# --get loads the image from a previously saved image cache, will build if no image is found
|
||||
# --build builds the image from the Dockerfile in .ci/$NAME
|
||||
# --save stores the image, if an image was loaded it will not be stored
|
||||
# --interactive immediately starts the image interactively for debugging
|
||||
# --set-cache <location> sets the location to cache the image or for ccache
|
||||
# requires: docker
|
||||
# uses env: NAME CACHE BUILD GET SAVE INTERACTIVE
|
||||
# (correspond to args: <name> --set-cache <cache> --build --get --save --interactive)
|
||||
# uses env: NAME CACHE BUILD GET SAVE (correspond to args: <name> --set-cache <cache> --build --get --save)
|
||||
# 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
|
||||
export BUILD_SCRIPT=".ci/compile.sh"
|
||||
@@ -22,7 +18,7 @@ image_cache="image"
|
||||
ccache_cache=".ccache"
|
||||
|
||||
# Read arguments
|
||||
while [[ $# != 0 ]]; do
|
||||
while [[ "$@" ]]; do
|
||||
case "$1" in
|
||||
'--build')
|
||||
BUILD=1
|
||||
@@ -32,10 +28,6 @@ while [[ $# != 0 ]]; do
|
||||
GET=1
|
||||
shift
|
||||
;;
|
||||
'--interactive')
|
||||
INTERACTIVE=1
|
||||
shift
|
||||
;;
|
||||
'--save')
|
||||
SAVE=1
|
||||
shift
|
||||
@@ -44,12 +36,12 @@ while [[ $# != 0 ]]; do
|
||||
CACHE=$2
|
||||
if ! [[ -d $CACHE ]]; then
|
||||
echo "could not find cache path: $CACHE" >&2
|
||||
return 3
|
||||
exit 3
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
if [[ ${1:0:1} == - ]]; then
|
||||
if [[ $1 == -* ]]; then
|
||||
echo "unrecognized option: $1"
|
||||
return 3
|
||||
fi
|
||||
@@ -75,27 +67,27 @@ fi
|
||||
|
||||
if ! [[ $CACHE ]]; then
|
||||
echo "cache dir is not set!" >&2
|
||||
CACHE="$(mktemp -d)"
|
||||
echo "set cache dir to $CACHE" >&2
|
||||
fi
|
||||
if ! [[ -d $CACHE ]]; then
|
||||
echo "could not find cache dir: $CACHE" >&2
|
||||
mkdir -p "$CACHE"
|
||||
unset GET # the dir is empty
|
||||
fi
|
||||
if [[ $GET || $SAVE ]]; then
|
||||
img_dir="$CACHE/$image_cache"
|
||||
img_save="$img_dir/$IMAGE_NAME$save_extension"
|
||||
if ! [[ -d $img_dir ]]; then
|
||||
echo "could not find image dir: $img_dir" >&2
|
||||
mkdir -p "$img_dir"
|
||||
else
|
||||
if ! [[ -d $CACHE ]]; then
|
||||
echo "could not find cache dir: $CACHE" >&2
|
||||
mkdir -p $CACHE
|
||||
unset GET # the dir is empty
|
||||
fi
|
||||
if [[ $GET || $SAVE ]]; then
|
||||
img_dir="$CACHE/$image_cache"
|
||||
img_save="$img_dir/$IMAGE_NAME$save_extension"
|
||||
if ! [[ -d $img_dir ]]; then
|
||||
echo "could not find image dir: $img_dir" >&2
|
||||
mkdir -p "$img_dir"
|
||||
fi
|
||||
fi
|
||||
export CCACHE_DIR="$CACHE/$ccache_cache"
|
||||
if ! [[ -d $CCACHE_DIR ]]; then
|
||||
echo "could not find ccache dir: $CCACHE_DIR" >&2
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
fi
|
||||
fi
|
||||
export CCACHE_DIR="$CACHE/$ccache_cache"
|
||||
if ! [[ -d $CCACHE_DIR ]]; then
|
||||
echo "could not find ccache dir: $CCACHE_DIR" >&2
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
fi
|
||||
|
||||
|
||||
# Get the docker image from previously stored save
|
||||
if [[ $GET ]]; then
|
||||
@@ -140,26 +132,15 @@ fi
|
||||
function RUN ()
|
||||
{
|
||||
echo "running image:"
|
||||
if [[ $(docker images) =~ "$IMAGE_NAME" ]]; then
|
||||
local args=(--mount "type=bind,source=$PWD,target=/src")
|
||||
args+=(--workdir "/src")
|
||||
args+=(--user "$(id -u):$(id -g)")
|
||||
if docker images | grep "$IMAGE_NAME"; then
|
||||
args="--mount type=bind,source=$PWD,target=/src -w=/src"
|
||||
if [[ $CCACHE_DIR ]]; then
|
||||
args+=(--mount "type=bind,source=$CCACHE_DIR,target=/.ccache")
|
||||
args+=(--env "CCACHE_DIR=/.ccache")
|
||||
args+=" --mount type=bind,source=$CCACHE_DIR,target=/.ccache -e CCACHE_DIR=/.ccache"
|
||||
fi
|
||||
docker run "${args[@]}" $RUN_ARGS "$IMAGE_NAME" bash "$BUILD_SCRIPT" $RUN_OPTS "$@"
|
||||
docker run $args $RUN_ARGS "$IMAGE_NAME" bash "$BUILD_SCRIPT" $RUN_OPTS $@
|
||||
return $?
|
||||
else
|
||||
echo "could not find docker image: $IMAGE_NAME" >&2
|
||||
return 3
|
||||
fi
|
||||
}
|
||||
|
||||
# for debugging, start the docker image interactively instead of building
|
||||
# starts immediately, does not require sourcing or RUN
|
||||
if [[ $INTERACTIVE ]]; then
|
||||
export BUILD_SCRIPT="-i"
|
||||
export RUN_ARGS="$RUN_ARGS -it"
|
||||
RUN
|
||||
fi
|
||||
|
||||
@@ -10,10 +10,10 @@ if ! git merge-base origin/master HEAD; then
|
||||
git fetch --unshallow
|
||||
fi
|
||||
|
||||
# Check formatting using format.sh
|
||||
echo "Checking your code using clang-format/cmake-format..."
|
||||
# Check formatting using clangify
|
||||
echo "Checking your code using clang-format..."
|
||||
|
||||
diff="$(./format.sh --diff --cmake --cf-version --branch origin/master)"
|
||||
diff="$(./clangify.sh --diff --cf-version --branch origin/master)"
|
||||
err=$?
|
||||
|
||||
case $err in
|
||||
@@ -24,7 +24,7 @@ case $err in
|
||||
*** ***
|
||||
*** Your code does not comply with our style guide. ***
|
||||
*** ***
|
||||
*** Please correct it or run the "format.sh" script. ***
|
||||
*** Please correct it or run the "clangify.sh" script. ***
|
||||
*** Then commit and push those changes to this branch. ***
|
||||
*** Check our CONTRIBUTING.md file for more details. ***
|
||||
*** ***
|
||||
@@ -32,23 +32,21 @@ case $err in
|
||||
*** ***
|
||||
***********************************************************
|
||||
|
||||
Used version:
|
||||
Used clang-format version:
|
||||
${diff%%
|
||||
----------
|
||||
*}
|
||||
|
||||
The following changes should be made:
|
||||
${diff#*
|
||||
----------
|
||||
}
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
exit 2
|
||||
;;
|
||||
exit 2
|
||||
;;
|
||||
|
||||
0)
|
||||
cat <<EOM
|
||||
0)
|
||||
cat <<EOM
|
||||
|
||||
***********************************************************
|
||||
*** ***
|
||||
@@ -60,10 +58,12 @@ EOM
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
exit 0
|
||||
;;
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Something went wrong in our formatting checks: format.sh returned $err" >&2
|
||||
;;
|
||||
esac
|
||||
*)
|
||||
echo ""
|
||||
echo "Something went wrong in our formatting checks: clangify returned $err" >&2
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
# renames the file to [original name][SUFFIX].[original extension]
|
||||
# where SUFFIX is either available in the environment or as the first arg
|
||||
# if MAKE_ZIP is set instead a zip is made
|
||||
# expected to be run in the build directory unless BUILD_DIR is set
|
||||
# adds output to GITHUB_OUTPUT
|
||||
builddir="${BUILD_DIR:=.}"
|
||||
# expected to be run in the build directory
|
||||
builddir="."
|
||||
findrx="Cockatrice-*.*"
|
||||
|
||||
if [[ $1 ]]; then
|
||||
@@ -28,7 +27,6 @@ if [[ ! $file ]]; then
|
||||
echo "::error file=$0::could not find package"
|
||||
exit 1
|
||||
fi
|
||||
oldpwd="$PWD"
|
||||
if ! cd "$path"; then
|
||||
echo "::error file=$0::could not get file path"
|
||||
exit 1
|
||||
@@ -47,9 +45,6 @@ else
|
||||
echo "renaming '$file' to '$filename'"
|
||||
mv "$file" "$filename"
|
||||
fi
|
||||
|
||||
cd "$oldpwd"
|
||||
relative_path="$path/$filename"
|
||||
ls -l "$relative_path"
|
||||
echo "path=$relative_path" >>"$GITHUB_OUTPUT"
|
||||
echo "name=$filename" >>"$GITHUB_OUTPUT"
|
||||
ls -l "$PWD/$filename"
|
||||
echo "::set-output name=path::$PWD/$filename"
|
||||
echo "::set-output name=name::$filename"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# the releases are first made as drafts and will be vetted by a human
|
||||
# it just has to provide a template
|
||||
# this requires the repo to be unshallowed
|
||||
# adds output to GITHUB_OUTPUT
|
||||
template_path=".ci/release_template.md"
|
||||
body_path="/tmp/release.md"
|
||||
beta_regex='beta'
|
||||
@@ -23,22 +22,22 @@ fi
|
||||
|
||||
# create title
|
||||
if [[ $TAG =~ $beta_regex ]]; then
|
||||
echo "is_beta=yes" >>"$GITHUB_OUTPUT"
|
||||
echo "::set-output name=is_beta::yes"
|
||||
title="$TAG"
|
||||
echo "creating beta release '$title'"
|
||||
elif [[ ! $(cat CMakeLists.txt) =~ $name_regex ]]; then
|
||||
echo "::error file=$0::could not find releasename in CMakeLists.txt"
|
||||
exit 1
|
||||
else
|
||||
echo "is_beta=no" >>"$GITHUB_OUTPUT"
|
||||
echo "::set-output name=is_beta::no"
|
||||
name="${BASH_REMATCH[1]}"
|
||||
version="${TAG##*-}"
|
||||
title="Cockatrice $version: $name"
|
||||
no_beta=1
|
||||
echo "friendly_name=$name" >>"$GITHUB_OUTPUT"
|
||||
echo "::set-output name=friendly_name::$name"
|
||||
echo "creating full release '$title'"
|
||||
fi
|
||||
echo "title=$title" >>"$GITHUB_OUTPUT"
|
||||
echo "::set-output name=title::$title"
|
||||
|
||||
# add release notes template
|
||||
if [[ $no_beta ]]; then
|
||||
@@ -61,9 +60,9 @@ fi
|
||||
all_tags="
|
||||
$(git tag)" # tags are ordered alphabetically
|
||||
before="${all_tags%%
|
||||
"$TAG"*}" # strip line with current tag an all lines after it
|
||||
$TAG*}" # strip line with current tag an all lines after it
|
||||
# note the extra newlines are needed to always have a last line
|
||||
if [[ $all_tags == "$before" ]]; then
|
||||
if [[ $all_tags == $before ]]; then
|
||||
echo "::warning file=$0::could not find current tag"
|
||||
else
|
||||
while
|
||||
@@ -75,7 +74,7 @@ else
|
||||
beta_list+=" $previous" # add to list of skipped betas
|
||||
next_before="${before%
|
||||
*}" # strip the last line
|
||||
if [[ $next_before == "$before" ]]; then
|
||||
if [[ $next_before == $before ]]; then
|
||||
unset previous
|
||||
break
|
||||
fi
|
||||
@@ -109,5 +108,5 @@ else
|
||||
fi
|
||||
|
||||
# write to file
|
||||
echo "body_path=$body_path" >>"$GITHUB_OUTPUT"
|
||||
echo "::set-output name=body_path::$body_path"
|
||||
echo "$body" >"$body_path"
|
||||
|
||||
@@ -8,25 +8,26 @@ git push -d origin --REPLACE-WITH-BETA-LIST--
|
||||
include different targets -->
|
||||
<pre>
|
||||
<b>Pre-compiled binaries we serve:</b>
|
||||
- <kbd>Windows 7+</kbd>
|
||||
- <kbd>Windows 10+</kbd>
|
||||
- <kbd>macOS 10.15+</kbd> ("Catalina")
|
||||
- <kbd>macOS 13+</kbd> ("Ventura")
|
||||
- <kbd>Ubuntu 18.04 LTS</kbd> ("Bionic Beaver")
|
||||
- <kbd>Ubuntu 20.04 LTS</kbd> ("Focal Fossa")
|
||||
- <kbd>Ubuntu 22.04 LTS</kbd> ("Jammy Jellyfish")
|
||||
- <kbd>Ubuntu 24.04 LTS</kbd> ("Noble Numbat")
|
||||
- <kbd>Debian 11</kbd> ("Bullseye")
|
||||
- <kbd>Debian 12</kbd> ("Bookworm")
|
||||
- <kbd>Fedora 39</kbd>
|
||||
- <kbd>Fedora 40</kbd>
|
||||
- <kbd>Windows 7/8/10 (32-bit)</kbd></i>
|
||||
- <kbd>Windows 7/8/10 (64-bit)</kbd></i>
|
||||
- <kbd>macOS 10.14</kbd> ("Mojave")</i>
|
||||
- <kbd>macOS 10.15</kbd> ("Catalina")</i>
|
||||
- <kbd>macOS 11.0</kbd> ("Big Sur")</i>
|
||||
- <kbd>Ubuntu 18.04</kbd> ("Bionic Beaver")</i>
|
||||
- <kbd>Ubuntu 20.04</kbd> ("Focal Fossa")</i>
|
||||
- <kbd>Ubuntu 20.10</kbd> ("Groovy Gorilla")</i>
|
||||
- <kbd>Ubuntu 21.04</kbd> ("Hirsute Hippo")</i>
|
||||
- <kbd>Debian 10</kbd> ("Buster")</i>
|
||||
- <kbd>Fedora 33</kbd></i>
|
||||
- <kbd>Fedora 34</kbd></i>
|
||||
<kbd>We are also packaged in Arch Linux's official community repository, courtesy of @FFY00</kbd></i>
|
||||
<kbd>General Linux support is available via a flatpak package (Flathub)</kbd></i>
|
||||
<kbd>General linux support is available via a flatpak package (Flathub)</kbd></i>
|
||||
</pre>
|
||||
|
||||
|
||||
## General Notes
|
||||
|
||||
<!-- --REPLACE-WITH-RELEASE-TITLE-- should be placed here by the ci -->
|
||||
We're pleased to announce the newest official release: <kbd>--REPLACE-WITH-RELEASE-TITLE--</kbd>
|
||||
|
||||
We hope you enjoy the changes made and we have listed all changes, with their corresponding tickets, since the last version of Cockatrice was released for your convenience.
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ci script to update translation files
|
||||
# usage:
|
||||
# $0 cockatrice/cockatrice_en@source.ts cockatrice/src common
|
||||
# or
|
||||
# FILE="cockatrice/cockatrice_en@source.ts"
|
||||
# DIRS="cockatrice/src common"
|
||||
# $0
|
||||
# note: directories can't contain spaces
|
||||
|
||||
# check parameters
|
||||
if [[ ! $FILE ]]; then
|
||||
FILE="$1"
|
||||
shift
|
||||
fi
|
||||
if [[ ! $FILE ]]; then
|
||||
echo "no output file selected" >&2
|
||||
exit 2;
|
||||
fi
|
||||
if [[ ! $DIRS ]]; then
|
||||
DIRS="$*"
|
||||
fi
|
||||
if [[ ! $DIRS ]]; then
|
||||
echo "no source directories selected to translate" >&2
|
||||
exit 2;
|
||||
fi
|
||||
if [[ ! -e $FILE ]]; then
|
||||
echo "output file does not exist at: $FILE" >&2
|
||||
exit 3;
|
||||
fi
|
||||
|
||||
# print version
|
||||
if ! lupdate -version; then
|
||||
echo "failed to run lupdate" >&2
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# run lupdate, duplicating the output in stderr and saving it
|
||||
# for convenience we ignore that $DIRS will be split on spaces
|
||||
# shellcheck disable=SC2086
|
||||
if ! got="$(lupdate $DIRS -ts "$FILE" | tee /dev/stderr)"; then
|
||||
echo "failed to update $FILE with $DIRS" >&2
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# trim output
|
||||
# the line we are interested in is:
|
||||
# Found xxx source text(s) (x new and xxx already existing)
|
||||
output="${got##* source text(s) (}" # get stuff in between brackets
|
||||
output="${output%%)*}" # trim everything after first )
|
||||
if [[ $output == "$got" ]]; then
|
||||
echo "could not parse generated output" >&2
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# write output to ci environment file
|
||||
echo "output=$output" >> "$GITHUB_OUTPUT"
|
||||
@@ -1,14 +0,0 @@
|
||||
Updated source strings for translations:
|
||||
- {{ .cockatrice_output }} (Cockatrice)
|
||||
- {{ .oracle_output }} (Oracle)
|
||||
|
||||
<br>
|
||||
|
||||
Last changes are based on commit {{ .commit }}.
|
||||
|
||||
---
|
||||
*This PR is automatically generated and updated by the workflow at `.github/workflows/translations-push.yml`. Review [action runs][2].*<br>
|
||||
*After merging, all changes to the source language are available for translation at [Transifex][1] shortly.*
|
||||
|
||||
[1]: https://app.transifex.com/cockatrice/cockatrice/
|
||||
[2]: https://github.com/Cockatrice/Cockatrice/actions/workflows/translations-push.yml?query=branch%3Amaster
|
||||
@@ -1,109 +0,0 @@
|
||||
{
|
||||
"format": {
|
||||
"_help_line_width": [
|
||||
"How wide to allow formatted cmake files"
|
||||
],
|
||||
"line_width": 120,
|
||||
"_help_tab_size": [
|
||||
"How many spaces to tab for indent"
|
||||
],
|
||||
"tab_size": 2,
|
||||
"_help_max_subgroups_hwrap": [
|
||||
"If an argument group contains more than this many sub-groups",
|
||||
"(parg or kwarg groups) then force it to a vertical layout."
|
||||
],
|
||||
"max_subgroups_hwrap": 2,
|
||||
"_help_max_pargs_hwrap": [
|
||||
"If a positional argument group contains more than this many",
|
||||
"arguments, then force it to a vertical layout."
|
||||
],
|
||||
"max_pargs_hwrap": 6,
|
||||
"_help_max_rows_cmdline": [
|
||||
"If a cmdline positional group consumes more than this many",
|
||||
"lines without nesting, then invalidate the layout (and nest)"
|
||||
],
|
||||
"max_rows_cmdline": 5,
|
||||
"_help_separate_ctrl_name_with_space": [
|
||||
"If true, separate flow control names from their parentheses",
|
||||
"with a space"
|
||||
],
|
||||
"separate_ctrl_name_with_space": false,
|
||||
"_help_separate_fn_name_with_space": [
|
||||
"If true, separate function names from parentheses with a",
|
||||
"space"
|
||||
],
|
||||
"separate_fn_name_with_space": false,
|
||||
"_help_dangle_parens": [
|
||||
"If a statement is wrapped to more than one line, than dangle",
|
||||
"the closing parenthesis on its own line."
|
||||
],
|
||||
"dangle_parens": true,
|
||||
"_help_dangle_align": [
|
||||
"If the trailing parenthesis must be 'dangled' on its on",
|
||||
"line, then align it to this reference: `prefix`: the start",
|
||||
"of the statement, `prefix-indent`: the start of the",
|
||||
"statement, plus one indentation level, `child`: align to",
|
||||
"the column of the arguments"
|
||||
],
|
||||
"dangle_align": "prefix",
|
||||
"_help_min_prefix_chars": [
|
||||
"If the statement spelling length (including space and",
|
||||
"parenthesis) is smaller than this amount, then force reject",
|
||||
"nested layouts."
|
||||
],
|
||||
"min_prefix_chars": 4,
|
||||
"_help_max_prefix_chars": [
|
||||
"If the statement spelling length (including space and",
|
||||
"parenthesis) is larger than the tab width by more than this",
|
||||
"amount, then force reject un-nested layouts."
|
||||
],
|
||||
"max_prefix_chars": 10,
|
||||
"_help_max_lines_hwrap": [
|
||||
"If a candidate layout is wrapped horizontally but it exceeds",
|
||||
"this many lines, then reject the layout."
|
||||
],
|
||||
"max_lines_hwrap": 2,
|
||||
"_help_line_ending": [
|
||||
"What style line endings to use in the output."
|
||||
],
|
||||
"line_ending": "auto",
|
||||
"_help_command_case": [
|
||||
"Format command names consistently as 'lower' or 'upper' case"
|
||||
],
|
||||
"command_case": "lower",
|
||||
"_help_keyword_case": [
|
||||
"Format keywords consistently as 'lower' or 'upper' case"
|
||||
],
|
||||
"keyword_case": "upper",
|
||||
"_help_always_wrap": [
|
||||
"A list of command names which should always be wrapped"
|
||||
],
|
||||
"always_wrap": [],
|
||||
"_help_enable_sort": [
|
||||
"If true, the argument lists which are known to be sortable",
|
||||
"will be sorted lexicographically"
|
||||
],
|
||||
"enable_sort": true,
|
||||
"_help_autosort": [
|
||||
"If true, the parsers may infer whether or not an argument",
|
||||
"list is sortable (without annotation)."
|
||||
],
|
||||
"autosort": true,
|
||||
"_help_require_valid_layout": [
|
||||
"By default, if cmake-format cannot successfully fit",
|
||||
"everything into the desired line-width it will apply the",
|
||||
"last, most aggressive attempt that it made. If this flag is",
|
||||
"True, however, cmake-format will print error, exit with non-",
|
||||
"zero status code, and write-out nothing"
|
||||
],
|
||||
"require_valid_layout": false,
|
||||
"_help_layout_passes": [
|
||||
"A dictionary mapping layout nodes to a list of wrap",
|
||||
"decisions. See the documentation for more information."
|
||||
],
|
||||
"layout_passes": {}
|
||||
},
|
||||
"markup": {
|
||||
"enable_markup": false
|
||||
}
|
||||
}
|
||||
93
.github/CONTRIBUTING.md
vendored
93
.github/CONTRIBUTING.md
vendored
@@ -41,8 +41,8 @@ albeit slightly less active.
|
||||
|
||||
We use a separate job on the CI to check your code for formatting issues. If
|
||||
your pull request failed the test, you can check the output on the checks tab.
|
||||
It's the first job called "linter", you can click the "Check code formatting"
|
||||
step to see the output of the test.
|
||||
It's the first job called "linter", you can click the "Run clangify" step to
|
||||
see the output of the test.
|
||||
|
||||
The message will look like this:
|
||||
```
|
||||
@@ -50,7 +50,7 @@ The message will look like this:
|
||||
*** ***
|
||||
*** Your code does not comply with our style guide. ***
|
||||
*** ***
|
||||
*** Please correct it or run the "format.sh" script. ***
|
||||
*** Please correct it or run the "clangify.sh" script. ***
|
||||
*** Then commit and push those changes to this branch. ***
|
||||
*** Check our CONTRIBUTING.md file for more details. ***
|
||||
*** ***
|
||||
@@ -81,9 +81,9 @@ The handy tool `clang-format` can format your code for you, it is available for
|
||||
almost any environment. A special `.clang-format` configuration file is
|
||||
included in the project and is used to format your code.
|
||||
|
||||
We've also included a bash script, `format.sh`, that will use clang-format to
|
||||
format all files in your pr in one go. Use `./format.sh --help` to show a full
|
||||
help page.
|
||||
We've also included a bash script, `clangify.sh`, that will use clang-format to
|
||||
format all files in your pr in one go. Use `./clangify.sh --help` to show a
|
||||
full help page.
|
||||
|
||||
To run clang-format on a single source file simply use the command
|
||||
`clang-format -i <filename>` to format it in place. (Some systems install
|
||||
@@ -290,21 +290,20 @@ be included in the next release 👍
|
||||
|
||||
Basic workflow for translations:
|
||||
1. Developer adds a `tr("foo")` string in the code;
|
||||
2. CI updates the `*_en@source.ts files` regularly and creates a PR automatically;
|
||||
3. Maintainer verifies and merges the change;
|
||||
4. Transifex picks up the new files from GitHub automatically;
|
||||
5. Translators translate the new untranslated strings on Transifex;
|
||||
6. Before a release, a maintainer fetches the updated translations from Transifex.
|
||||
2. Every few days, a maintainer updates the `*_en.ts files` with the new strings;
|
||||
3. Transifex picks up the new files from GitHub every 24 hours;
|
||||
4. Translators translate the new untranslated strings on Transifex;
|
||||
5. Before a release, a maintainer fetches the updated translations from Transifex.
|
||||
|
||||
### Using Translations (for developers) ###
|
||||
|
||||
All user interface strings inside Cockatrice's source code must be written
|
||||
in English (US).
|
||||
All the user-interface strings inside Cockatrice's source code must be written
|
||||
in English(US).
|
||||
Translations to other languages are managed using [Transifex](
|
||||
https://www.transifex.com/projects/p/cockatrice/).
|
||||
|
||||
Adding a new string to translate is as easy as adding the string in the
|
||||
`tr("")` function, the string will be picked up as translatable automatically
|
||||
'tr("")' function, the string will be picked up as translatable automatically
|
||||
and translated as needed.
|
||||
For example, setting the text of a label in the way that the string
|
||||
`"My name is:"` can be translated:
|
||||
@@ -313,7 +312,7 @@ nameLabel.setText(tr("My name is:"));
|
||||
```
|
||||
|
||||
To translate a string that would have plural forms you can add the amount to
|
||||
the tr() call, also you can add an extra string as a hint for translators:
|
||||
the tr call, also you can add an extra string as a hint for translators:
|
||||
```c++
|
||||
QString message = tr("Everyone draws %n cards", "pop up message", amount);
|
||||
```
|
||||
@@ -322,46 +321,20 @@ https://doc.qt.io/qt-5/i18n-source-translation.html#handling-plurals)
|
||||
|
||||
If you're about to propose a change that adds or modifies any translatable
|
||||
string in the code, you don't need to take care of adding the new strings to
|
||||
the translation files.<br>
|
||||
We have an automated process to update our language source files on a schedule
|
||||
and provide the translators on Transifex with the new contents.<br>
|
||||
Maintainers can also manually trigger this on demand.
|
||||
the translation files.
|
||||
Every few days, or when a lot of new strings have been added, someone from the
|
||||
development team will take care of extracting all the new strings and adding
|
||||
them to the english translation files and making them available to translators
|
||||
on Transifex.
|
||||
|
||||
### Maintaining Translations (for maintainers) ###
|
||||
|
||||
When new translatable strings have been added to the code, a maintainer has to
|
||||
make them available to translators on Transifex.
|
||||
When new translatable strings have been added to the code, a maintainer should
|
||||
make them available to translators on Transifex. Every few days, or when a lot
|
||||
of new strings have been added, a maintainer should take care of extracting all
|
||||
the new strings and add them to the english translation files.
|
||||
|
||||
To help with that, we have an automated CI workflow, that regularly looks at the
|
||||
code in the master branch, extracts all strings and updates dedicated source string
|
||||
files with any changes. These updates are not commited right away, the CI creates a
|
||||
PR for reviewing instead.<br>
|
||||
After approval, our translation tool automatically picks the changes up and deploys
|
||||
them to our translators. Be mindful when merging only a few changes!
|
||||
|
||||
Once a release is planned, or when a lot of strings have been added or changed, a
|
||||
maintainer can manually trigger a CI run to extract all strings on demand.
|
||||
|
||||
<details>
|
||||
<summary><b>Manually trigger CI run (Workflow Dispatch)</b></summary>
|
||||
|
||||
Maintainers can always request the CI to run on demand if it's required.
|
||||
|
||||
Go to the `Actions` tab and select our dedicated translation workflow:
|
||||
https://github.com/Cockatrice/Cockatrice/actions/workflows/translations.yml
|
||||
|
||||
You see a "This workflow has a workflow_dispatch event trigger." hint at the top of
|
||||
the list.<br>
|
||||
Select `Run workflow` on the right and trigger a run from master branch.
|
||||
|
||||
The CI will now check for changed strings and create a PR if there are any updates.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Manually update source strings locally</b></summary>
|
||||
|
||||
To update the english source files for translation, re-run cmake enabling the appropriate
|
||||
To update the english translation files, re-run cmake enabling the appropriate
|
||||
parameter and then run make:
|
||||
```sh
|
||||
cd cockatrice/build
|
||||
@@ -371,26 +344,24 @@ make
|
||||
If the parameter has been enabled correctly, when running "make" you should see
|
||||
a line similar to this one (the numbers may vary):
|
||||
```sh
|
||||
[ 76%] Generating ../../cockatrice/translations/cockatrice_en@source.ts
|
||||
Updating '../../cockatrice/translations/cockatrice_en@source.ts'...
|
||||
[ 76%] Generating ../../cockatrice/translations/cockatrice_en.ts
|
||||
Updating '../../cockatrice/translations/cockatrice_en.ts'...
|
||||
Found 857 source text(s) (8 new and 849 already existing)
|
||||
```
|
||||
You should then notice that the following files have uncommitted changes:
|
||||
|
||||
cockatrice/translations/cockatrice_en@source.ts
|
||||
oracle/translations/oracle_en@source.ts
|
||||
cockatrice/translations/cockatrice_en.ts
|
||||
oracle/translations/oracle_en.ts
|
||||
|
||||
It is recommended to disable the parameter afterwards using:
|
||||
```sh
|
||||
cmake .. -DUPDATE_TRANSLATIONS=OFF
|
||||
```
|
||||
Now you are ready to commit your changes and open a PR.
|
||||
Now you are ready to propose your change.
|
||||
|
||||
</details>
|
||||
|
||||
Once the changes get merged, Transifex will pick up the modified files
|
||||
automatically (checked every few hours) and update their online editor where
|
||||
translators will be able to translate the new strings right in the browser.
|
||||
Once your change gets merged, Transifex will pick up the modified files
|
||||
automatically (checked every 24 hours) and update the interface where
|
||||
translators will be able to translate the new strings.
|
||||
|
||||
### Releasing Translations (for maintainers) ###
|
||||
|
||||
|
||||
49
.github/dependabot.yml
vendored
49
.github/dependabot.yml
vendored
@@ -1,49 +0,0 @@
|
||||
# Configuration options: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# # Enable version updates for git submodules
|
||||
# Not yet possible to bump only on tags or releases, see:
|
||||
# https://github.com/dependabot/dependabot-core/issues/1639
|
||||
# https://github.com/dependabot/dependabot-core/issues/2192
|
||||
# Alternative: Action that updates submodule and can be manually run on demand (workflow_dispatch)
|
||||
# - package-ecosystem: "gitsubmodule"
|
||||
# # Look for `.gitmodules` in the `root` directory
|
||||
# directory: "/"
|
||||
# # Check for updates once a month
|
||||
# schedule:
|
||||
# interval: "monthly"
|
||||
# # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
# open-pull-requests-limit: 1
|
||||
|
||||
# # Enable version updates for Docker
|
||||
# Not yet possible to bump from one LTS version to the next and skip others, see:
|
||||
# https://github.com/dependabot/dependabot-core/issues/2247
|
||||
# - package-ecosystem: "docker"
|
||||
# # Look for a `Dockerfile` in the `root` directory
|
||||
# directory: "/"
|
||||
# # Check for updates once a week
|
||||
# schedule:
|
||||
# interval: "weekly"
|
||||
# # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
# open-pull-requests-limit: 1
|
||||
|
||||
# Enable version updates for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
# Directory must be set to "/" to check for workflow files in .github/workflows
|
||||
directory: "/"
|
||||
# Check for updates to GitHub Actions once a week
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
# Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
open-pull-requests-limit: 2
|
||||
|
||||
# # Enable version updates for npm
|
||||
# - package-ecosystem: "npm"
|
||||
# # Look for `package.json` and `lock` files in the `webclient` subdirectory
|
||||
# directory: "/webclient"
|
||||
# # Check the npm registry for updates once a week
|
||||
# schedule:
|
||||
# interval: "weekly"
|
||||
# # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
# open-pull-requests-limit: 5
|
||||
364
.github/workflows/desktop-build.yml
vendored
364
.github/workflows/desktop-build.yml
vendored
@@ -8,30 +8,33 @@ on:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
|
||||
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on master)
|
||||
concurrency:
|
||||
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
|
||||
cancel-in-progress: ${{ github.ref_name != 'master' }}
|
||||
|
||||
jobs:
|
||||
configure:
|
||||
name: Configure
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
tag: ${{steps.configure.outputs.tag}}
|
||||
sha: ${{steps.configure.outputs.sha}}
|
||||
upload_url: ${{steps.create_release.outputs.upload_url}}
|
||||
|
||||
steps:
|
||||
- name: Cancel previous runs
|
||||
uses: styfle/cancel-workflow-action@0.6.0
|
||||
with:
|
||||
access_token: ${{github.token}} # needs other token https://github.com/styfle/cancel-workflow-action/issues/7
|
||||
|
||||
steps:
|
||||
- name: Configure
|
||||
id: configure
|
||||
shell: bash
|
||||
@@ -42,19 +45,19 @@ jobs:
|
||||
elif [[ $GITHUB_REF =~ $tag_regex ]]; then # release
|
||||
sha="$GITHUB_SHA"
|
||||
tag="${GITHUB_REF/refs\/tags\//}"
|
||||
echo "tag=$tag" >>"$GITHUB_OUTPUT"
|
||||
echo "::set-output name=tag::$tag"
|
||||
else # push to branch
|
||||
sha="$GITHUB_SHA"
|
||||
fi
|
||||
echo "sha=$sha" >>"$GITHUB_OUTPUT"
|
||||
echo "::set-output name=sha::$sha"
|
||||
|
||||
- name: Checkout
|
||||
if: steps.configure.outputs.tag != null
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare release parameters
|
||||
- name: Prepare release paramaters
|
||||
id: prepare
|
||||
if: steps.configure.outputs.tag != null
|
||||
shell: bash
|
||||
@@ -65,21 +68,15 @@ jobs:
|
||||
- name: Create release
|
||||
if: steps.configure.outputs.tag != null
|
||||
id: create_release
|
||||
shell: bash
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{steps.configure.outputs.tag}}
|
||||
target: ${{steps.configure.outputs.sha}}
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
tag_name: ${{github.ref}}
|
||||
release_name: ${{steps.prepare.outputs.title}}
|
||||
body_path: ${{steps.prepare.outputs.body_path}}
|
||||
prerelease: ${{steps.prepare.outputs.is_beta}}
|
||||
run: |
|
||||
if [[ $prerelease == yes ]]; then
|
||||
args="--prerelease"
|
||||
fi
|
||||
gh release create "$tag_name" --draft --verify-tag $args \
|
||||
--target "$target" --title "$release_name" \
|
||||
--notes-file "$body_path"
|
||||
draft: true
|
||||
prerelease: ${{steps.prepare.outputs.is_beta == 'yes'}}
|
||||
|
||||
build-linux:
|
||||
strategy:
|
||||
@@ -87,58 +84,61 @@ jobs:
|
||||
matrix:
|
||||
# these names correspond to the files in .ci/$distro
|
||||
include:
|
||||
- distro: ArchLinux
|
||||
package: skip # we are packaged in arch already
|
||||
allow-failure: yes
|
||||
|
||||
- distro: Debian11
|
||||
- distro: UbuntuImpish
|
||||
package: DEB
|
||||
|
||||
- distro: Debian12
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora39
|
||||
package: RPM
|
||||
|
||||
- distro: Fedora40
|
||||
package: RPM
|
||||
|
||||
- distro: UbuntuBionic
|
||||
- distro: UbuntuHirsute
|
||||
package: DEB
|
||||
test: skip
|
||||
|
||||
- distro: UbuntuFocal
|
||||
package: DEB
|
||||
test: skip # UbuntuFocal has a broken qt for debug builds
|
||||
|
||||
- distro: UbuntuJammy
|
||||
- distro: UbuntuBionic
|
||||
package: DEB
|
||||
test: skip # running tests on all distros is superfluous
|
||||
|
||||
- distro: UbuntuNoble
|
||||
- distro: ArchLinux
|
||||
package: skip # we are packaged in arch already
|
||||
allow-failure: yes
|
||||
|
||||
- distro: Debian10
|
||||
package: DEB
|
||||
|
||||
- distro: Debian11
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora34
|
||||
package: RPM
|
||||
test: skip # gtest does not compile for some reason
|
||||
|
||||
- distro: Fedora35
|
||||
package: RPM
|
||||
|
||||
|
||||
name: ${{matrix.distro}}
|
||||
|
||||
needs: configure
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
continue-on-error: ${{matrix.allow-failure == 'yes'}}
|
||||
|
||||
env:
|
||||
NAME: ${{matrix.distro}}
|
||||
CACHE: /tmp/${{matrix.distro}}-cache # ${{runner.temp}} does not work?
|
||||
# cache size over the entire repo is 10Gi link:
|
||||
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy
|
||||
CCACHE_SIZE: 200M
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get cache timestamp
|
||||
id: cache_timestamp
|
||||
shell: bash
|
||||
run: echo "timestamp=$(date -u '+%Y%m%d%H%M%S')" >>"$GITHUB_OUTPUT"
|
||||
run: echo "::set-output name=timestamp::$(date -u '+%Y%m%d%H%M%S')"
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
timestamp: ${{steps.cache_timestamp.outputs.timestamp}}
|
||||
with:
|
||||
@@ -154,197 +154,245 @@ jobs:
|
||||
- name: Build debug and test
|
||||
if: matrix.test != 'skip'
|
||||
shell: bash
|
||||
env:
|
||||
distro: '${{matrix.distro}}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --debug --test --ccache "$CCACHE_SIZE" --parallel 4
|
||||
RUN --server --debug --test --ccache
|
||||
|
||||
- name: Build release package
|
||||
id: build
|
||||
id: package
|
||||
if: matrix.package != 'skip'
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_DIR: build
|
||||
SUFFIX: '-${{matrix.distro}}'
|
||||
distro: '${{matrix.distro}}'
|
||||
suffix: '-${{matrix.distro}}'
|
||||
type: '${{matrix.package}}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --release --package "$type" --dir "$BUILD_DIR" \
|
||||
--ccache "$CCACHE_SIZE" --parallel 4
|
||||
.ci/name_build.sh
|
||||
RUN --server --release --package "$type" --suffix "$suffix"
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.package != 'skip'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{matrix.distro}}-package
|
||||
path: ${{steps.build.outputs.path}}
|
||||
path: ./build/${{steps.package.outputs.name}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{needs.configure.outputs.tag}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
upload_url: ${{needs.configure.outputs.upload_url}}
|
||||
asset_path: ./build/${{steps.package.outputs.name}}
|
||||
asset_name: ${{steps.package.outputs.name}}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-macos:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- Debug
|
||||
- 10.14_Mojave
|
||||
- 10.15_Catalina
|
||||
- 11_Big_Sur
|
||||
include:
|
||||
- target: 12_Monterey_and_13_Ventura
|
||||
os: macos-12
|
||||
xcode: "14.0.1"
|
||||
type: Release
|
||||
make_package: 1
|
||||
|
||||
- target: 14_Sonoma
|
||||
os: macos-14
|
||||
xcode: "15.4"
|
||||
type: Release
|
||||
make_package: 1
|
||||
|
||||
- target: 14_Sonoma_Debug
|
||||
os: macos-14
|
||||
xcode: "15.4"
|
||||
- target: Debug # tests only
|
||||
os: macos-latest
|
||||
xcode: 12.5.1
|
||||
type: Debug
|
||||
do_tests: 0 # tests do not work yet on mac
|
||||
make_package: false
|
||||
|
||||
- target: 10.14_Mojave
|
||||
os: macos-10.15 # runs on Catalina
|
||||
xcode: 10.3 # allows compatibility with macOS 10.14
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
|
||||
- target: 10.15_Catalina
|
||||
os: macos-10.15
|
||||
xcode: 12.1
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
|
||||
- target: 11_Big_Sur
|
||||
os: macos-11
|
||||
xcode: 12.5.1
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
|
||||
name: macOS ${{matrix.target}}
|
||||
|
||||
name: macOS${{matrix.target}}
|
||||
needs: configure
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
continue-on-error: ${{matrix.allow-failure == 'yes'}}
|
||||
|
||||
env:
|
||||
DEVELOPER_DIR:
|
||||
/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies using Homebrew
|
||||
- name: Install dependencies using homebrew
|
||||
shell: bash
|
||||
# cmake cannot find the mysql connector
|
||||
# neither of these works: mariadb-connector-c mysql-connector-c++
|
||||
env:
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
|
||||
run: |
|
||||
brew update
|
||||
brew install protobuf qt --force-bottle
|
||||
run: brew update && brew install protobuf
|
||||
|
||||
- name: Install QT using homebrew
|
||||
id: brew_install_qt
|
||||
continue-on-error: true
|
||||
shell: bash
|
||||
run: brew install qt@5 --force-bottle
|
||||
|
||||
- name: Install QT using actions
|
||||
if: steps.brew_install_qt.outcome != 'success'
|
||||
uses: jurplel/install-qt-action@v2
|
||||
|
||||
- name: Build on Xcode ${{matrix.xcode}}
|
||||
shell: bash
|
||||
id: build
|
||||
env:
|
||||
BUILDTYPE: '${{matrix.type}}'
|
||||
MAKE_TEST: 1
|
||||
MAKE_PACKAGE: '${{matrix.make_package}}'
|
||||
PACKAGE_SUFFIX: '-macOS-${{matrix.target}}'
|
||||
# macOS runner actually have only 3 cores
|
||||
# See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
||||
run: .ci/compile.sh --server --parallel 3
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: 3 # mac machines actually have 3 cores
|
||||
run: .ci/compile.sh ${{matrix.type}} --server
|
||||
|
||||
- name: Test
|
||||
if: matrix.do_tests == 1
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: cmake --build . --target test
|
||||
|
||||
- name: Package for ${{matrix.target}}
|
||||
id: package
|
||||
if: matrix.make_package
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake --build . --target package
|
||||
../.ci/name_build.sh "-macOS-${{matrix.target}}"
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.make_package
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: macOS-${{matrix.target}}-dmg
|
||||
path: ${{steps.build.outputs.path}}
|
||||
name: macOS-${{matrix.target}}-xcode-${{matrix.xcode}}-dmg
|
||||
path: ${{steps.package.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
if: matrix.make_package && needs.configure.outputs.tag != null
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{needs.configure.outputs.tag}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
upload_url: ${{needs.configure.outputs.upload_url}}
|
||||
asset_path: ${{steps.package.outputs.path}}
|
||||
asset_name: ${{steps.package.outputs.name}}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- 64
|
||||
- 32
|
||||
include:
|
||||
- target: 7
|
||||
qt_version: 5.15.*
|
||||
qt_arch: msvc2019_64
|
||||
qt_tools: "tools_opensslv3_x64"
|
||||
- arch: 64
|
||||
triplet: x64
|
||||
cmake: x64
|
||||
append: _64
|
||||
|
||||
- target: 10
|
||||
qt_version: 6.5.*
|
||||
qt_arch: msvc2019_64
|
||||
qt_tools: "tools_opensslv3_x64"
|
||||
qt_modules: "qtmultimedia qtwebsockets"
|
||||
- arch: 32
|
||||
triplet: x86
|
||||
cmake: Win32
|
||||
|
||||
name: Windows ${{matrix.arch}}
|
||||
|
||||
name: Windows ${{matrix.target}}
|
||||
needs: configure
|
||||
runs-on: windows-2022
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
CMAKE_GENERATOR: 'Visual Studio 17 2022'
|
||||
QT_VERSION: '5.15.2'
|
||||
QT_ARCH: msvc2019${{matrix.append}}
|
||||
CMAKE_GENERATOR: 'Visual Studio 16 2019'
|
||||
|
||||
steps:
|
||||
- name: Add msbuild to PATH
|
||||
id: add-msbuild
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt ${{matrix.qt_version}}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
- name: Restore Qt ${{env.QT_VERSION}} ${{matrix.arch}}-bit from cache
|
||||
id: cache-qt
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
cache: true
|
||||
setup-python: false
|
||||
version: ${{matrix.qt_version}}
|
||||
arch: win64_${{matrix.qt_arch}}
|
||||
tools: ${{matrix.qt_tools}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
key: ${{runner.os}}-QtCache-${{env.QT_VERSION}}-${{matrix.arch}}
|
||||
path: ${{runner.workspace}}/Qt
|
||||
|
||||
- name: Run vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
- name: Install ${{matrix.arch}}-bit Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
runVcpkgInstall: true
|
||||
doNotCache: false
|
||||
env:
|
||||
VCPKG_DEFAULT_TRIPLET: 'x64-windows'
|
||||
VCPKG_DISABLE_METRICS: 1
|
||||
cached: ${{steps.cache-qt.outputs.cache-hit}}
|
||||
version: ${{env.QT_VERSION}}
|
||||
arch: win${{matrix.arch}}_${{env.QT_ARCH}}
|
||||
|
||||
- name: Build Cockatrice
|
||||
id: build
|
||||
- name: Restore or setup vcpkg
|
||||
uses: lukka/run-vcpkg@v6
|
||||
with:
|
||||
vcpkgArguments: '@${{github.workspace}}/vcpkg.txt'
|
||||
vcpkgDirectory: ${{github.workspace}}/vcpkg
|
||||
appendedCacheKey: ${{hashFiles('**/vcpkg.txt')}}
|
||||
vcpkgTriplet: ${{matrix.triplet}}-windows
|
||||
|
||||
- name: Configure Cockatrice ${{matrix.arch}}-bit
|
||||
shell: bash
|
||||
env:
|
||||
PACKAGE_SUFFIX: '-Win${{matrix.target}}'
|
||||
CMAKE_GENERATOR: '${{env.CMAKE_GENERATOR}}'
|
||||
CMAKE_GENERATOR_PLATFORM: 'x64'
|
||||
QTDIR: '${{github.workspace}}\Qt\${{matrix.qt_version}}\win64_${{matrix.qt_arch}}'
|
||||
# No need for --parallel flag, MTT is added in the compile script to let cmake/msbuild manage core count,
|
||||
# project and process parallelism: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||
run: .ci/compile.sh --server --release --test --package
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
export QTDIR="${{runner.workspace}}/Qt/${{env.QT_VERSION}}/${{env.QT_ARCH}}"
|
||||
cmake .. -G "${{env.CMAKE_GENERATOR}}" -A "${{matrix.cmake}}" -DCMAKE_BUILD_TYPE="Release" -DWITH_SERVER=1 -DTEST=1
|
||||
|
||||
- name: Build Cockatrice ${{matrix.arch}}-bit
|
||||
id: package
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake --build . --target package --config Release
|
||||
../.ci/name_build.sh "-win${{matrix.arch}}"
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: ctest -T Test -C Release
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Windows${{matrix.target}}-installer
|
||||
path: ${{steps.build.outputs.path}}
|
||||
name: Windows-${{matrix.arch}}bit-installer
|
||||
path: ./build/${{steps.package.outputs.name}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
if: needs.configure.outputs.tag != null
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{needs.configure.outputs.tag}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
upload_url: ${{needs.configure.outputs.upload_url}}
|
||||
asset_path: ./build/${{steps.package.outputs.name}}
|
||||
asset_name: ${{steps.package.outputs.name}}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
15
.github/workflows/desktop-lint.yml
vendored
15
.github/workflows/desktop-lint.yml
vendored
@@ -2,28 +2,29 @@ name: Code Style (C++)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-22.04
|
||||
clang-format:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 20 # should be enough to find merge base
|
||||
|
||||
- name: Install dependencies
|
||||
- name: Install clang-format
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends clang-format cmake-format
|
||||
sudo apt-get install -y --no-install-recommends clang-format
|
||||
|
||||
- name: Check code formatting
|
||||
- name: Run clangify
|
||||
shell: bash
|
||||
run: ./.ci/lint_cpp.sh
|
||||
|
||||
72
.github/workflows/translations-pull.yml
vendored
72
.github/workflows/translations-pull.yml
vendored
@@ -1,72 +0,0 @@
|
||||
name: Update Translations
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# runs in the middle of each month starting a quarter (UTC) = two weeks after new strings are built
|
||||
- cron: '0 0 15 1,4,7,10 *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/translations-pull.yml'
|
||||
|
||||
jobs:
|
||||
translations:
|
||||
# Do not run the scheduled workflow on forks
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'Cockatrice'
|
||||
|
||||
name: Pull languages
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Pull translated strings from Transifex
|
||||
uses: transifex/cli-action@v2
|
||||
with:
|
||||
# used config file: https://github.com/Cockatrice/Cockatrice/blob/master/.tx/config
|
||||
# https://github.com/transifex/cli#pulling-files-from-transifex
|
||||
token: ${{ secrets.TX_TOKEN }}
|
||||
args: pull --force --all
|
||||
|
||||
- name: Create pull request
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/translations/*.ts
|
||||
oracle/translations/*.ts
|
||||
webclient/public/locales/*/translation.json
|
||||
commit-message: Update translation files
|
||||
# author is the owner of the commit
|
||||
author: github-actions <github-actions@github.com>
|
||||
branch: ci-update_translations
|
||||
delete-branch: true
|
||||
title: 'Update translations'
|
||||
body: |
|
||||
Pulled all translated strings from [Transifex][1].
|
||||
|
||||
---
|
||||
*This PR is automatically generated and updated by the workflow at `.github/workflows/translations-pull.yml`. Review [action runs][2].*<br>
|
||||
*After merging, all new languages and translations are available in the next build.*
|
||||
|
||||
[1]: https://app.transifex.com/cockatrice/cockatrice/
|
||||
[2]: https://github.com/Cockatrice/Cockatrice/actions/workflows/translations-pull.yml?query=branch%3Amaster
|
||||
labels: |
|
||||
CI
|
||||
Translation
|
||||
draft: false
|
||||
|
||||
- name: PR Status
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
env:
|
||||
STATUS: ${{ steps.create_pr.outputs.pull-request-operation }}
|
||||
run: |
|
||||
if [[ "$STATUS" == "" ]]; then
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} unchanged!" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} $STATUS!" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "URL: ${{ steps.create_pr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY
|
||||
87
.github/workflows/translations-push.yml
vendored
87
.github/workflows/translations-push.yml
vendored
@@ -1,87 +0,0 @@
|
||||
name: Update Translation Source
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# runs at the start of each quarter (UTC)
|
||||
- cron: '0 0 1 1,4,7,10 *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/translations-push.yml'
|
||||
|
||||
jobs:
|
||||
translations:
|
||||
# Do not run the scheduled workflow on forks
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'Cockatrice'
|
||||
|
||||
name: Push strings
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install lupdate
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends qttools5-dev-tools
|
||||
|
||||
- name: Update Cockatrice translation source
|
||||
id: cockatrice
|
||||
shell: bash
|
||||
env:
|
||||
FILE: 'cockatrice/cockatrice_en@source.ts'
|
||||
DIRS: 'cockatrice/src common'
|
||||
run: .ci/update_translation_source_strings.sh
|
||||
|
||||
- name: Update Oracle translation source
|
||||
id: oracle
|
||||
shell: bash
|
||||
env:
|
||||
FILE: 'oracle/oracle_en@source.ts'
|
||||
DIRS: 'oracle/src'
|
||||
run: .ci/update_translation_source_strings.sh
|
||||
|
||||
- name: Render template
|
||||
id: template
|
||||
uses: chuhlomin/render-template@v1
|
||||
with:
|
||||
template: .ci/update_translation_source_strings_template.md
|
||||
vars: |
|
||||
cockatrice_output: ${{ steps.cockatrice.outputs.output }}
|
||||
oracle_output: ${{ steps.oracle.outputs.output }}
|
||||
commit: ${{ github.sha }}
|
||||
|
||||
- name: Create pull request
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/cockatrice_en@source.ts
|
||||
oracle/oracle_en@source.ts
|
||||
commit-message: Update translation source strings
|
||||
# author is the owner of the commit
|
||||
author: github-actions <github-actions@github.com>
|
||||
branch: ci-update_translation_source
|
||||
delete-branch: true
|
||||
title: 'Update source strings'
|
||||
body: ${{ steps.template.outputs.result }}
|
||||
labels: |
|
||||
CI
|
||||
Translation
|
||||
draft: false
|
||||
|
||||
- name: PR Status
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
env:
|
||||
STATUS: ${{ steps.create_pr.outputs.pull-request-operation }}
|
||||
run: |
|
||||
if [[ "$STATUS" == "" ]]; then
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} unchanged!" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} $STATUS!" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "URL: ${{ steps.create_pr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY
|
||||
9
.github/workflows/web-build.yml
vendored
9
.github/workflows/web-build.yml
vendored
@@ -9,6 +9,8 @@ on:
|
||||
- 'webclient/**'
|
||||
- '!**.md'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
@@ -28,15 +30,15 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node_version:
|
||||
- 16
|
||||
- 12
|
||||
- lts/*
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{matrix.node_version}}
|
||||
cache: 'npm'
|
||||
@@ -50,3 +52,4 @@ jobs:
|
||||
|
||||
- name: Test app
|
||||
run: npm run test
|
||||
|
||||
|
||||
6
.github/workflows/web-lint.yml
vendored
6
.github/workflows/web-lint.yml
vendored
@@ -2,6 +2,8 @@ name: Code Style (TypeScript)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
@@ -17,10 +19,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'webclient/package-lock.json'
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,10 +6,8 @@ mysql.cnf
|
||||
.DS_Store
|
||||
.idea/
|
||||
*.aps
|
||||
cmake-build-debug*
|
||||
cmake-build-debug/
|
||||
preferences
|
||||
compile_commands.json
|
||||
.vs/
|
||||
.vscode/
|
||||
.cache
|
||||
.gdb_history
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
cd webclient
|
||||
npm run translate
|
||||
|
||||
git add src/i18n-default.json
|
||||
27
.tx/config
27
.tx/config
@@ -1,26 +1,13 @@
|
||||
[main]
|
||||
host = https://app.transifex.com
|
||||
host = https://www.transifex.com
|
||||
|
||||
[o:cockatrice:p:cockatrice:r:cockatrice-cockatrice-en-source-ts--master]
|
||||
resource_name = Cockatrice
|
||||
source_lang = en
|
||||
source_file = cockatrice/cockatrice_en@source.ts
|
||||
[cockatrice.cockatrice]
|
||||
file_filter = cockatrice/translations/cockatrice_<lang>.ts
|
||||
type = QT
|
||||
minimum_perc = 10
|
||||
|
||||
[o:cockatrice:p:cockatrice:r:oracle-oracle-en-source-ts--master]
|
||||
resource_name = Oracle
|
||||
source_file = cockatrice/translations/cockatrice_en.ts
|
||||
source_lang = en
|
||||
source_file = oracle/oracle_en@source.ts
|
||||
|
||||
[cockatrice.oracle]
|
||||
file_filter = oracle/translations/oracle_<lang>.ts
|
||||
type = QT
|
||||
minimum_perc = 10
|
||||
|
||||
[o:cockatrice:p:cockatrice:r:webclient-src-i18n-default-json--master]
|
||||
resource_name = Webclient
|
||||
source_file = oracle/translations/oracle_en.ts
|
||||
source_lang = en
|
||||
source_file = webclient/src/i18n-default.json
|
||||
file_filter = webclient/public/locales/<lang>/translation.json
|
||||
type = KEYVALUEJSON
|
||||
minimum_perc = 10
|
||||
|
||||
|
||||
438
CMakeLists.txt
438
CMakeLists.txt
@@ -5,95 +5,58 @@
|
||||
# This file sets all the variables shared between the projects
|
||||
# like the installation path, compilation flags etc..
|
||||
|
||||
# cmake 3.16 is required if using qt6
|
||||
# Cmake 3.1 is required to enable C++11 support correctly
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# Early detect ccache
|
||||
option(USE_CCACHE "Cache the build results with ccache" ON)
|
||||
# Treat warnings as errors (Debug builds only)
|
||||
option(WARNING_AS_ERROR "Treat warnings as errors in debug builds" ON)
|
||||
# Check for translation updates
|
||||
option(UPDATE_TRANSLATIONS "Update translations on compile" OFF)
|
||||
# Compile servatrice
|
||||
option(WITH_SERVER "build servatrice" OFF)
|
||||
# Compile cockatrice
|
||||
option(WITH_CLIENT "build cockatrice" ON)
|
||||
# Compile oracle
|
||||
option(WITH_ORACLE "build oracle" ON)
|
||||
# Compile dbconverter
|
||||
option(WITH_DBCONVERTER "build dbconverter" ON)
|
||||
# Compile tests
|
||||
option(TEST "build tests" OFF)
|
||||
|
||||
# Default to "Release" build type
|
||||
# User-provided value for CMAKE_BUILD_TYPE must be checked before the PROJECT() call
|
||||
if(DEFINED CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE
|
||||
${CMAKE_BUILD_TYPE}
|
||||
CACHE STRING "Type of build"
|
||||
)
|
||||
else()
|
||||
set(CMAKE_BUILD_TYPE
|
||||
Release
|
||||
CACHE STRING "Type of build"
|
||||
)
|
||||
endif()
|
||||
IF(DEFINED CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Type of build")
|
||||
ELSE()
|
||||
SET(CMAKE_BUILD_TYPE Release CACHE STRING "Type of build")
|
||||
ENDIF()
|
||||
|
||||
# Early detect ccache
|
||||
OPTION(USE_CCACHE "Cache the build results with ccache" ON)
|
||||
if(USE_CCACHE)
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
# Support Unix Makefiles and Ninja
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
message(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
# Support Unix Makefiles and Ninja
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
MESSAGE(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Use vcpkg toolchain on Windows
|
||||
set(CMAKE_TOOLCHAIN_FILE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
CACHE STRING "Vcpkg toolchain file"
|
||||
)
|
||||
# Qt path set by user or env var
|
||||
if(QTDIR
|
||||
OR DEFINED ENV{QTDIR}
|
||||
OR DEFINED ENV{QTDIR32}
|
||||
OR DEFINED ENV{QTDIR64}
|
||||
)
|
||||
|
||||
else()
|
||||
set(QTDIR
|
||||
""
|
||||
CACHE PATH "Path to Qt (e.g. C:/Qt/5.7/msvc2015_64)"
|
||||
)
|
||||
message(
|
||||
WARNING "QTDIR variable is missing. Please set this variable to specify path to Qt (e.g. C:/Qt/5.7/msvc2015_64)"
|
||||
)
|
||||
endif()
|
||||
# Use vcpkg toolchain on Windows
|
||||
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
CACHE STRING "Vcpkg toolchain file")
|
||||
# Qt path set by user or env var
|
||||
if (QTDIR OR DEFINED ENV{QTDIR} OR DEFINED ENV{QTDIR32} OR DEFINED ENV{QTDIR64})
|
||||
else()
|
||||
set(QTDIR "" CACHE PATH "Path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
|
||||
message(WARNING "QTDIR variable is missing. Please set this variable to specify path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# A project name is needed for CPack
|
||||
# Version can be overriden by git tags, see cmake/getversion.cmake
|
||||
project("Cockatrice" VERSION 2.9.1)
|
||||
PROJECT("Cockatrice" VERSION 2.8.1)
|
||||
|
||||
# Set release name if not provided via env/cmake var
|
||||
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
||||
set(GIT_TAG_RELEASENAME "Rings of the Wild")
|
||||
set(GIT_TAG_RELEASENAME "Prismatic Bridge")
|
||||
endif()
|
||||
|
||||
# Use c++17 for all targets
|
||||
set(CMAKE_CXX_STANDARD
|
||||
17
|
||||
CACHE STRING "C++ ISO Standard"
|
||||
)
|
||||
# Use c++11 for all targets
|
||||
set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ ISO Standard")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# Set conventional loops
|
||||
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
|
||||
|
||||
# Search path for cmake modules
|
||||
set(COCKATRICE_CMAKE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${COCKATRICE_CMAKE_PATH}")
|
||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
include(getversion)
|
||||
|
||||
@@ -102,150 +65,152 @@ include(createversionfile)
|
||||
|
||||
# Define a proper install path
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
# macOS
|
||||
# Due to the special bundle structure ignore
|
||||
# the prefix eventually set by the user.
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/release)
|
||||
if(APPLE)
|
||||
# macOS
|
||||
# Due to the special bundle structure ignore
|
||||
# the prefix eventually set by the user.
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/release)
|
||||
|
||||
# Force ccache usage if available
|
||||
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
||||
if(RULE_LAUNCH_COMPILE)
|
||||
message(STATUS "Force enabling CCache usage under macOS")
|
||||
# Set up wrapper scripts
|
||||
configure_file("${COCKATRICE_CMAKE_PATH}/launch-c.in" launch-c)
|
||||
configure_file("${COCKATRICE_CMAKE_PATH}/launch-cxx.in" launch-cxx)
|
||||
execute_process(COMMAND chmod a+rx "${CMAKE_BINARY_DIR}/launch-c" "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
# Force ccache usage if available
|
||||
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
||||
if(RULE_LAUNCH_COMPILE)
|
||||
MESSAGE(STATUS "Force enabling CCache usage under macOS")
|
||||
# Set up wrapper scripts
|
||||
configure_file(${CMAKE_MODULE_PATH}/launch-c.in launch-c)
|
||||
configure_file(${CMAKE_MODULE_PATH}/launch-cxx.in launch-cxx)
|
||||
execute_process(COMMAND chmod a+rx
|
||||
"${CMAKE_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
|
||||
# Set Xcode project attributes to route compilation through our scripts
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
# Set Xcode project attributes to route compilation through our scripts
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
endif()
|
||||
else()
|
||||
# Linux / BSD
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
#fix package build
|
||||
if(PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX ${PREFIX})
|
||||
else()
|
||||
set(CMAKE_INSTALL_PREFIX /usr/local)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# Linux / BSD
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
#fix package build
|
||||
if(PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX ${PREFIX})
|
||||
else()
|
||||
set(CMAKE_INSTALL_PREFIX /usr/local)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/rundir/${CMAKE_BUILD_TYPE})
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/rundir/${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
||||
# Treat warnings as errors (Debug builds only)
|
||||
option(WARNING_AS_ERROR "Treat warnings as errors in debug builds" ON)
|
||||
|
||||
# Define proper compilation flags
|
||||
if(MSVC)
|
||||
# Visual Studio: Maximum optimization, disable warning C4251, establish C++17 compatibility
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD /wd4251 /Zc:__cplusplus /std:c++17 /permissive- /W4")
|
||||
# Generate complete debugging information
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# linux/gcc, bsd/gcc, windows/mingw
|
||||
include(CheckCXXCompilerFlag)
|
||||
IF(MSVC)
|
||||
# Visual Studio: Maximum optimization, disable warning C4251
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD /wd4251 ")
|
||||
# Generate complete debugging information
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
|
||||
# linux/gcc, bsd/gcc, windows/mingw
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -Werror")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17")
|
||||
endif()
|
||||
|
||||
set(ADDITIONAL_DEBUG_FLAGS
|
||||
-Wcast-align
|
||||
-Wmissing-declarations
|
||||
-Wno-long-long
|
||||
-Wno-error=extra
|
||||
-Wno-error=delete-non-virtual-dtor
|
||||
-Wno-error=sign-compare
|
||||
-Wno-error=missing-declarations
|
||||
)
|
||||
|
||||
foreach(FLAG ${ADDITIONAL_DEBUG_FLAGS})
|
||||
check_cxx_compiler_flag("${FLAG}" CXX_HAS_WARNING_${FLAG})
|
||||
if(CXX_HAS_WARNING_${FLAG})
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -Werror")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra")
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
# other: osx/llvm, bsd/llvm
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Werror -Wno-unused-parameter")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ADDITIONAL_DEBUG_FLAGS -Wcast-align -Wmissing-declarations -Wno-long-long -Wno-error=extra -Wno-error=delete-non-virtual-dtor -Wno-error=sign-compare -Wno-error=missing-declarations)
|
||||
|
||||
FOREACH(FLAG ${ADDITIONAL_DEBUG_FLAGS})
|
||||
CHECK_CXX_COMPILER_FLAG("${FLAG}" CXX_HAS_WARNING_${FLAG})
|
||||
IF(CXX_HAS_WARNING_${FLAG})
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ELSE()
|
||||
# other: osx/llvm, bsd/llvm
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Werror")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra")
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
# 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")
|
||||
endif()
|
||||
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
ADD_DEFINITIONS("-DSFMT_MEXP=19937")
|
||||
ENDIF()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
FIND_PACKAGE(Threads REQUIRED)
|
||||
|
||||
# Determine 32 or 64 bit build
|
||||
# Find Qt5
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_lib_suffix 64)
|
||||
set(_lib_suffix 64)
|
||||
else()
|
||||
set(_lib_suffix 32)
|
||||
set(_lib_suffix 32)
|
||||
endif()
|
||||
|
||||
if(DEFINED QTDIR${_lib_suffix})
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
|
||||
elseif(DEFINED QTDIR)
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR}")
|
||||
elseif(DEFINED ENV{QTDIR${_lib_suffix}})
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}")
|
||||
elseif(DEFINED ENV{QTDIR})
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Update Translations: ${UPDATE_TRANSLATIONS}")
|
||||
FIND_PACKAGE(Qt5Core 5.5.0 REQUIRED)
|
||||
|
||||
include(FindQtRuntime)
|
||||
IF(Qt5Core_FOUND)
|
||||
MESSAGE(STATUS "Found Qt ${Qt5Core_VERSION_STRING}")
|
||||
|
||||
# FIX: Qt was built with -reduce-relocations
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE)
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
# guess plugins and libraries directory
|
||||
set(QT_PLUGINS_DIR "${Qt5Core_DIR}/../../../plugins")
|
||||
get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION)
|
||||
get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH)
|
||||
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "No Qt5 found!")
|
||||
ENDIF()
|
||||
|
||||
# Check for translation updates
|
||||
OPTION(UPDATE_TRANSLATIONS "Update translations on compile" OFF)
|
||||
MESSAGE(STATUS "UPDATE TRANSLATIONS: ${UPDATE_TRANSLATIONS}")
|
||||
|
||||
set(CMAKE_AUTOMOC TRUE)
|
||||
|
||||
# Find other needed libraries
|
||||
find_package(Protobuf CONFIG)
|
||||
if(NOT Protobuf_FOUND)
|
||||
find_package(Protobuf REQUIRED)
|
||||
endif()
|
||||
|
||||
if(${Protobuf_VERSION} VERSION_LESS "3.21.0.0" AND NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||
message(FATAL_ERROR "No protoc command found!")
|
||||
endif()
|
||||
FIND_PACKAGE(Protobuf REQUIRED)
|
||||
IF(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||
MESSAGE(FATAL_ERROR "No protoc command found!")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Protoc version ${Protobuf_VERSION} found!")
|
||||
ENDIF()
|
||||
|
||||
#Find OpenSSL
|
||||
if(WIN32)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
if(OPENSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIRS})
|
||||
else()
|
||||
message(
|
||||
WARNING
|
||||
"Could not find OpenSSL runtime libraries. They are not required for compiling, but needs to be available at runtime."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
IF(WIN32)
|
||||
FIND_PACKAGE(Win32SslRuntime)
|
||||
ENDIF()
|
||||
|
||||
#Find VCredist
|
||||
if(MSVC)
|
||||
find_package(VCredistRuntime)
|
||||
endif()
|
||||
IF(MSVC)
|
||||
FIND_PACKAGE(VCredistRuntime)
|
||||
ENDIF()
|
||||
|
||||
# Package builder
|
||||
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zach@cockatrice.us>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME}")
|
||||
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zahalpern+github@gmail.com>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME})
|
||||
set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
@@ -255,95 +220,82 @@ set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_VERSION_FILENAME}")
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
set(CPACK_DMG_FORMAT "UDBZ")
|
||||
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
||||
set(CPACK_SYSTEM_NAME "OSX")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns")
|
||||
set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeDMGSetup.script")
|
||||
set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/dmgBackground.tif")
|
||||
else()
|
||||
# linux
|
||||
if(CPACK_GENERATOR STREQUAL "RPM")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
|
||||
set(CPACK_RPM_MAIN_COMPONENT "cockatrice")
|
||||
if(Qt6_FOUND)
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt6-qttools, qt6-qtsvg, qt6-qtmultimedia")
|
||||
elseif(Qt5_FOUND)
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt5-qttools, qt5-qtsvg, qt5-qtmultimedia")
|
||||
endif()
|
||||
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games")
|
||||
set(CPACK_RPM_PACKAGE_URL "http://github.com/Cockatrice/Cockatrice")
|
||||
# stop directories from making package conflicts
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
||||
/usr/share/applications
|
||||
/usr/share/icons
|
||||
/usr/share/icons/hicolor
|
||||
/usr/share/icons/hicolor/48x48
|
||||
/usr/share/icons/hicolor/48x48/apps
|
||||
/usr/share/icons/hicolor/scalable
|
||||
/usr/share/icons/hicolor/scalable/apps
|
||||
)
|
||||
if(APPLE)
|
||||
set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
set(CPACK_DMG_FORMAT "UDBZ")
|
||||
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
||||
set(CPACK_SYSTEM_NAME "OSX")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns")
|
||||
else()
|
||||
set(CPACK_GENERATOR DEB)
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "games")
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://github.com/Cockatrice/Cockatrice")
|
||||
if(Qt6_FOUND)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt6multimedia6, libqt6svg6, qt6-qpa-plugins")
|
||||
elseif(Qt5_FOUND)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins, libqt5svg5")
|
||||
endif()
|
||||
# linux
|
||||
IF(CPACK_GENERATOR STREQUAL "RPM")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt5-qttools, qt5-qtsvg, qt5-qtmultimedia")
|
||||
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games")
|
||||
set(CPACK_RPM_PACKAGE_URL "http://github.com/Cockatrice/Cockatrice")
|
||||
ELSE()
|
||||
set(CPACK_GENERATOR DEB)
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "games")
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://github.com/Cockatrice/Cockatrice")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins, libqt5svg5")
|
||||
ENDIF()
|
||||
endif()
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "(x64)")
|
||||
set(TRICE_IS_64_BIT 1)
|
||||
else()
|
||||
set(TRICE_IS_64_BIT 0)
|
||||
endif()
|
||||
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "(x64)")
|
||||
set(TRICE_IS_64_BIT 1)
|
||||
else()
|
||||
set(TRICE_IS_64_BIT 0)
|
||||
endif()
|
||||
|
||||
# Configure file with custom definitions for NSIS.
|
||||
configure_file("${COCKATRICE_CMAKE_PATH}/NSIS.definitions.nsh.in" "${PROJECT_BINARY_DIR}/NSIS.definitions.nsh")
|
||||
# Configure file with custom definitions for NSIS.
|
||||
configure_file(
|
||||
${CMAKE_MODULE_PATH}/NSIS.definitions.nsh.in
|
||||
${PROJECT_BINARY_DIR}/NSIS.definitions.nsh
|
||||
)
|
||||
|
||||
# include vcredist into the package; NSIS will take care of running it
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
install(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
|
||||
endif()
|
||||
# include vcredist into the package; NSIS will take care of running it
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
INSTALL(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
# Compile servatrice (default off)
|
||||
option(WITH_SERVER "build servatrice" OFF)
|
||||
add_subdirectory(common)
|
||||
if(WITH_SERVER)
|
||||
add_subdirectory(servatrice)
|
||||
set(CPACK_INSTALL_CMAKE_PROJECTS "Servatrice;Servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
add_subdirectory(servatrice)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Servatrice;Servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile cockatrice (default on)
|
||||
option(WITH_CLIENT "build cockatrice" ON)
|
||||
if(WITH_CLIENT)
|
||||
add_subdirectory(cockatrice)
|
||||
set(CPACK_INSTALL_CMAKE_PROJECTS "Cockatrice;Cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
add_subdirectory(cockatrice)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Cockatrice;Cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile oracle (default on)
|
||||
option(WITH_ORACLE "build oracle" ON)
|
||||
if(WITH_ORACLE)
|
||||
add_subdirectory(oracle)
|
||||
set(CPACK_INSTALL_CMAKE_PROJECTS "Oracle;Oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
add_subdirectory(oracle)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Oracle;Oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile dbconverter (default on)
|
||||
option(WITH_DBCONVERTER "build dbconverter" ON)
|
||||
if(WITH_DBCONVERTER)
|
||||
add_subdirectory(dbconverter)
|
||||
set(CPACK_INSTALL_CMAKE_PROJECTS "Dbconverter;Dbconverter;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
add_subdirectory(dbconverter)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Dbconverter;Dbconverter;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile tests (default off)
|
||||
option(TEST "build tests" OFF)
|
||||
if(TEST)
|
||||
include(CTest)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(Qt6_FOUND AND Qt6_VERSION_MINOR GREATER_EQUAL 3)
|
||||
# Qt6.3+ requires project finalization to support translations
|
||||
qt6_finalize_project()
|
||||
include(CTest)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
15
README.md
15
README.md
@@ -18,7 +18,7 @@
|
||||
<br><pre>
|
||||
<b>To get started, ⇢ [view our webpage](https://cockatrice.github.io/)</b><br>
|
||||
<b>To get support or suggest changes ⇢ [file an issue](https://github.com/Cockatrice/Cockatrice/issues) ([How?](https://github.com/Cockatrice/Cockatrice/wiki/How-to-Create-a-GitHub-Ticket-Regarding-Cockatrice))</b>
|
||||
<b>To help with development, see how to [get involved](#get-involved--)</b>
|
||||
<b>To help with development, see how to [get involved](#get-involved-)</b>
|
||||
</pre><br>
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ Downloads are available for full releases and the current beta version in develo
|
||||
- To be a Cockatrice Beta Tester, use this version. Find more information [here](https://github.com/Cockatrice/Cockatrice/wiki/Release-Channels)!
|
||||
|
||||
|
||||
# Get Involved [](https://discord.gg/3Z9yzmA)
|
||||
# Get Involved [](https://discord.gg/3Z9yzmA) [](https://gitter.im/Cockatrice/Cockatrice)
|
||||
|
||||
Join our [Discord community](https://discord.gg/3Z9yzmA) to connect with the project or fellow users of the app. The Cockatrice developers are also available on [Gitter](https://gitter.im/Cockatrice/Cockatrice). Come here to talk about the application, features, or just to hang out.<br>
|
||||
For support regarding specific servers, please contact that server's admin or forum for support rather than asking here.<br>
|
||||
@@ -52,6 +52,8 @@ We maintain two tags for contributors to find issues to work on:
|
||||
|
||||
For both tags, we're willing to provide help to contributors in showing them where and how they can make changes, as well as code review for changes they submit.
|
||||
|
||||
Read the long-term project **roadmap** to see planned edits and milestones [here](https://docs.google.com/document/d/1Ewe5uSaRE2nR2pNPMaGmP6gVZdqgFbBgwSscGqIr4W0/edit).
|
||||
|
||||
We try to be responsive to new issues. We'll provide advice on how best to implement a feature; alternately, we can show you where the codebase is doing something similar before you get too far along.
|
||||
|
||||
Cockatrice uses 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.
|
||||
@@ -65,9 +67,13 @@ Cockatrice uses the [Google Developer Documentation Style Guide](https://develop
|
||||
- [reddit r/Cockatrice](https://reddit.com/r/cockatrice)
|
||||
|
||||
|
||||
# Translations [](https://transifex.com/cockatrice/cockatrice/)
|
||||
# Translations [](https://www.transifex.com/projects/p/cockatrice/)
|
||||
|
||||
Cockatrice uses Transifex for translations. You can help us bring Cockatrice, Oracle and Webatrice to your language or just adjust single wordings right from within your browser by visiting our [Transifex project page](https://transifex.com/cockatrice/cockatrice/).<br>
|
||||
Cockatrice uses Transifex for translations. You can help us bring Cockatrice and Oracle to your language or just edit single wordings right from within your browser by visiting our [Transifex project page](https://www.transifex.com/projects/p/cockatrice/).<br>
|
||||
|
||||
| Cockatrice | Oracle |
|
||||
|:-:|:-:|
|
||||
| [](https://www.transifex.com/projects/p/cockatrice/) | [](https://www.transifex.com/projects/p/cockatrice/) |
|
||||
|
||||
Check out our [Translator FAQ](https://github.com/Cockatrice/Cockatrice/wiki/Translation-FAQ) for more information about contributing!<br>
|
||||
|
||||
@@ -111,7 +117,6 @@ The following flags can be passed to `cmake`:
|
||||
- `-DWARNING_AS_ERROR=0` Whether to treat compilation warnings as errors in debug mode (default 1 = yes).
|
||||
- `-DUPDATE_TRANSLATIONS=1` Configure `make` to update the translation .ts files for new strings in the source code. Note: Running `make clean` will remove the .ts files (default 0 = no).
|
||||
- `-DTEST=1` Enable regression tests (default 0 = no). Note: needs googletest, will be downloaded on the fly if unavailable. To run tests: ```make test```.
|
||||
- `-DFORCE_USE_QT5=1` Skip looking for Qt6 before trying to find Qt5
|
||||
|
||||
|
||||
# Run
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will run clang-format on all modified, non-3rd-party C++/Header files.
|
||||
# Optionally runs cmake-format on all modified cmake files.
|
||||
# Uses clang-format cmake-format git diff find
|
||||
# Never, ever, should this receive a path with a newline in it. Don't bother proofing it for that.
|
||||
# Never, ever, should this recieve a path with a newline in it. Don't bother proofing it for that.
|
||||
|
||||
set -o pipefail
|
||||
|
||||
# go to the project root directory, this file should be located in the project root directory
|
||||
olddir="$PWD"
|
||||
cd "${BASH_SOURCE%/*}/" || exit 2 # could not find path, this could happen with special links etc.
|
||||
|
||||
# defaults
|
||||
include=("common" \
|
||||
"cockatrice/src" \
|
||||
"dbconverter/src" \
|
||||
"oracle/src" \
|
||||
"servatrice/src" \
|
||||
"tests")
|
||||
@@ -27,30 +22,22 @@ exclude=("servatrice/src/smtp" \
|
||||
exts=("cpp" "h" "proto")
|
||||
cf_cmd="clang-format"
|
||||
branch="origin/master"
|
||||
cmakefile="CMakeLists.txt"
|
||||
cmakedir="cmake/.*\\.cmake"
|
||||
cmakeinclude=("cmake/gtest-CMakeLists.txt.in")
|
||||
color="--"
|
||||
|
||||
# parse options
|
||||
while [[ $* ]]; do
|
||||
while [[ $@ ]]; do
|
||||
case "$1" in
|
||||
'-b'|'--branch')
|
||||
branch=$2
|
||||
set_branch=1
|
||||
shift 2
|
||||
;;
|
||||
'--cmake')
|
||||
do_cmake=1
|
||||
shift
|
||||
;;
|
||||
'-c'|'--color-diff')
|
||||
color="--color=always"
|
||||
mode="diff"
|
||||
color=" --color=always"
|
||||
mode=diff
|
||||
shift
|
||||
;;
|
||||
'-d'|'--diff')
|
||||
mode="diff"
|
||||
mode=diff
|
||||
shift
|
||||
;;
|
||||
'-h'|'--help')
|
||||
@@ -62,6 +49,7 @@ If <dir>s are given, all source files in those directories of the project root
|
||||
path are formatted. To only format changed files in these directories use the
|
||||
--branch option in combination. <dir> has to be a path relative to the project
|
||||
root path or a full path inside $PWD.
|
||||
. can not be specified as a dir, if you really want to format everything use */.
|
||||
|
||||
USAGE: $0 [option] [--branch <git branch or object>] [<dir> ...]
|
||||
|
||||
@@ -80,9 +68,6 @@ OPTIONS:
|
||||
When not comparing to a branch, git will not be used at all and every
|
||||
source file in the entire project will be parsed.
|
||||
|
||||
--cmake
|
||||
Use cmake-format to format cmake files as well.
|
||||
|
||||
-c, --color-diff
|
||||
Display a colored diff. Implies --diff.
|
||||
Only available on systems which support 'diff --color'.
|
||||
@@ -109,25 +94,22 @@ EXIT CODES:
|
||||
3 if clang-format could not be found.
|
||||
|
||||
EXAMPLES:
|
||||
$0 --branch $USER/patch-2 ${include[0]}
|
||||
Formats all changed files compared to the git branch "$USER/patch-2"
|
||||
in the directory ${include[0]}.
|
||||
|
||||
$0 --test . || echo "code requires formatting"
|
||||
$0 --test \$PWD || echo "code requires formatting"
|
||||
Tests if the source files in the current directory are correctly
|
||||
formatted and prints an error message if formatting is required.
|
||||
|
||||
$0 --cmake --branch "" ""
|
||||
Unconditionally format all cmake files and no source files.
|
||||
$0 --branch $USER/patch-2 ${include[0]}
|
||||
Formats all changed files compared to the git branch "$USER/patch-2"
|
||||
in the directory ${include[0]}.
|
||||
EOM
|
||||
exit 0
|
||||
;;
|
||||
'-n'|'--names')
|
||||
mode="name"
|
||||
mode=name
|
||||
shift
|
||||
;;
|
||||
'-t'|'--test')
|
||||
mode="code"
|
||||
mode=code
|
||||
shift
|
||||
;;
|
||||
'--cf-version')
|
||||
@@ -135,28 +117,20 @@ EOM
|
||||
shift
|
||||
;;
|
||||
'--')
|
||||
dashdash=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if [[ ! $dashdash && $1 =~ ^-- ]]; then
|
||||
echo "error in parsing arguments of $0: $1 is an unrecognized option" >&2
|
||||
exit 2 # input error
|
||||
fi
|
||||
if [[ ! $1 ]] || next_dir=$(cd "$olddir" && cd -- "$1" && pwd); then
|
||||
if ! [[ $set_include ]]; then
|
||||
if next_dir=$(cd "$1" && pwd); then
|
||||
if [[ ${next_dir#$PWD/} == /* ]]; then
|
||||
echo "error in parsing arguments of $0: $next_dir is not in $PWD" >&2
|
||||
exit 2 # input error
|
||||
elif ! [[ $set_include ]]; then
|
||||
include=() # remove default includes
|
||||
set_include=1
|
||||
fi
|
||||
if [[ $1 ]]; then
|
||||
if [[ $next_dir != $PWD/* ]]; then
|
||||
echo "error in parsing arguments of $0: $next_dir is not in $PWD" >&2
|
||||
exit 2 # input error
|
||||
fi
|
||||
include+=("$next_dir")
|
||||
fi
|
||||
include+=("${next_dir#$PWD/}")
|
||||
else
|
||||
echo "error in parsing arguments of $0: $1 is not a directory" >&2
|
||||
echo "error in parsing arguments of $0: $PWD/$1 is not a directory" >&2
|
||||
exit 2 # input error
|
||||
fi
|
||||
if ! [[ $set_branch ]]; then
|
||||
@@ -179,93 +153,37 @@ if ! hash $cf_cmd 2>/dev/null; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# check availability of cmake-format
|
||||
if [[ $do_cmake ]] && ! hash cmake-format 2>/dev/null; then
|
||||
echo "could not find cmake-format" >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if [[ $branch ]]; then
|
||||
# get all dirty files through git
|
||||
if ! base=$(git merge-base "$branch" HEAD); then
|
||||
if ! base=$(git merge-base ${branch} HEAD); then
|
||||
echo "could not find git merge base" >&2
|
||||
exit 2 # input error
|
||||
fi
|
||||
mapfile -t basenames < <(git diff --diff-filter=d --name-only "$base")
|
||||
names=()
|
||||
for ex in "${exts[@]}"; do
|
||||
for path in "${include[@]}"; do
|
||||
for name in "${basenames[@]}"; do
|
||||
rx="^$path/.*\\.$ex$"
|
||||
if [[ $name =~ $rx ]]; then
|
||||
names+=("$name")
|
||||
fi
|
||||
done
|
||||
done
|
||||
declare -a reg
|
||||
for ex in ${exts[@]}; do
|
||||
reg+=(${include[@]/%/.*\\.$ex\$})
|
||||
done
|
||||
if [[ $do_cmake ]]; then
|
||||
cmake_names=()
|
||||
for name in "${basenames[@]}"; do
|
||||
dirrx="^$cmakedir$"
|
||||
filerx="(^|/)$cmakefile$"
|
||||
if [[ $name =~ $dirrx || $name =~ $filerx ]]; then
|
||||
cmake_names+=("$name")
|
||||
fi
|
||||
for include in "${cmakeinclude[@]}"; do
|
||||
if [[ $name == "$include" ]]; then
|
||||
cmake_names+=("$name")
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
names=$(git diff --diff-filter=d --name-only $base | grep ${reg[@]/#/-e ^})
|
||||
else
|
||||
exts_o=()
|
||||
for ext in "${exts[@]}"; do
|
||||
exts_o+=(-o -name "*\\.$ext")
|
||||
done
|
||||
unset "exts_o[0]" # remove first -o
|
||||
mapfile -t names < <(find "${include[@]}" -type f "${exts_o[@]}")
|
||||
if [[ $do_cmake ]]; then
|
||||
mapfile -t cmake_names < <(find . -maxdepth 2 -type f -name "$cmakefile" -o -path "./${cmakedir/.}")
|
||||
cmake_names+=("${cmakeinclude[@]}")
|
||||
fi
|
||||
names=$(find ${include[@]} -type f -false ${exts[@]/#/-o -name *\\.})
|
||||
fi
|
||||
|
||||
# filter excludes
|
||||
for path in "${exclude[@]}"; do
|
||||
for i in "${!names[@]}"; do
|
||||
rx="^$path/"
|
||||
if [[ ${names[$i]} =~ $rx ]]; then
|
||||
unset "names[$i]"
|
||||
fi
|
||||
done
|
||||
done
|
||||
names=$(<<<"$names" grep -v ${exclude[@]/#/-e ^})
|
||||
|
||||
# optionally print version
|
||||
if [[ $print_version ]]; then
|
||||
$cf_cmd -version
|
||||
[[ $do_cmake ]] && echo "cmake-format $(cmake-format --version)"
|
||||
echo "----------"
|
||||
fi
|
||||
|
||||
if [[ ! ${cmake_names[*]} ]]; then
|
||||
unset do_cmake
|
||||
fi
|
||||
if [[ ! ( ${names[*]} || $do_cmake ) ]]; then
|
||||
if ! [[ $names ]]; then
|
||||
exit 0 # nothing to format means format is successful!
|
||||
fi
|
||||
|
||||
# optionally print version
|
||||
[[ $print_version ]] && $cf_cmd -version
|
||||
|
||||
# format
|
||||
case $mode in
|
||||
diff)
|
||||
declare -i code=0
|
||||
for name in "${names[@]}"; do
|
||||
if ! $cf_cmd "$name" | diff "$name" - -p "$color"; then
|
||||
code=1
|
||||
fi
|
||||
done
|
||||
for name in "${cmake_names[@]}"; do
|
||||
if ! cmake-format "$name" | diff "$name" - -p "$color"; then
|
||||
for name in ${names[@]}; do
|
||||
if ! $cf_cmd "$name" | diff "$name" - -p $color; then
|
||||
code=1
|
||||
fi
|
||||
done
|
||||
@@ -273,34 +191,20 @@ case $mode in
|
||||
;;
|
||||
name)
|
||||
declare -i code=0
|
||||
for name in "${names[@]}"; do
|
||||
for name in ${names[@]}; do
|
||||
if ! $cf_cmd "$name" | diff "$name" - -q >/dev/null; then
|
||||
echo "$name"
|
||||
code=1
|
||||
fi
|
||||
done
|
||||
for name in "${cmake_names[@]}"; do
|
||||
if ! cmake-format "$name" --check; then
|
||||
echo "$name"
|
||||
code=1
|
||||
fi
|
||||
done
|
||||
exit $code
|
||||
;;
|
||||
code)
|
||||
for name in "${names[@]}"; do
|
||||
for name in ${names[@]}; do
|
||||
$cf_cmd "$name" | diff "$name" - -q >/dev/null || exit 1
|
||||
done
|
||||
for name in "${cmake_names[@]}"; do
|
||||
cmake-format "$name" --check || exit 1
|
||||
done
|
||||
;;
|
||||
*)
|
||||
if [[ "${names[*]}" ]]; then
|
||||
$cf_cmd -i "${names[@]}"
|
||||
fi
|
||||
if [[ $do_cmake ]]; then
|
||||
cmake-format -i "${cmake_names[@]}"
|
||||
fi
|
||||
$cf_cmd -i $names
|
||||
;;
|
||||
esac
|
||||
@@ -1,55 +0,0 @@
|
||||
on run argv
|
||||
set image_name to item 1 of argv
|
||||
|
||||
tell application "Finder"
|
||||
tell disk image_name
|
||||
|
||||
-- wait for the image to finish mounting
|
||||
set open_attempts to 0
|
||||
repeat while open_attempts < 4
|
||||
try
|
||||
open
|
||||
delay 1
|
||||
set open_attempts to 5
|
||||
close
|
||||
on error errStr number errorNumber
|
||||
set open_attempts to open_attempts + 1
|
||||
delay 10
|
||||
end try
|
||||
end repeat
|
||||
delay 5
|
||||
|
||||
-- open the image the first time and save a DS_Store with just
|
||||
-- background and icon setup
|
||||
open
|
||||
set current view of container window to icon view
|
||||
set theViewOptions to the icon view options of container window
|
||||
set background picture of theViewOptions to file ".background:background.tif"
|
||||
set arrangement of theViewOptions to not arranged
|
||||
set icon size of theViewOptions to 128
|
||||
delay 5
|
||||
close
|
||||
|
||||
-- next setup the position of the app and Applications symlink
|
||||
-- plus hide all the window decoration
|
||||
open
|
||||
update without registering applications
|
||||
tell container window
|
||||
set sidebar width to 0
|
||||
set statusbar visible to false
|
||||
set toolbar visible to false
|
||||
set the bounds to { 400, 100, 1400, 922 }
|
||||
set position of item "Cockatrice.app" to { 139, 214 }
|
||||
set position of item "Oracle.app" to { 139, 414 }
|
||||
set position of item "Servatrice.app" to { 139, 614 }
|
||||
set position of item "dbconverter.app" to { 1400, 1400 }
|
||||
set position of item "Applications" to { 861, 414 }
|
||||
end tell
|
||||
update without registering applications
|
||||
delay 5
|
||||
close
|
||||
|
||||
end tell
|
||||
delay 1
|
||||
end tell
|
||||
end run
|
||||
@@ -1,18 +1,18 @@
|
||||
# Find the LibExecinfo library - FreeBSD only
|
||||
|
||||
find_path(LIBEXECINFO_INCLUDE_DIR execinfo.h)
|
||||
find_library(LIBEXECINFO_LIBRARY NAMES execinfo)
|
||||
FIND_PATH(LIBEXECINFO_INCLUDE_DIR execinfo.h)
|
||||
FIND_LIBRARY(LIBEXECINFO_LIBRARY NAMES execinfo)
|
||||
|
||||
if(LIBEXECINFO_INCLUDE_DIR AND LIBEXECINFO_LIBRARY)
|
||||
set(LIBEXECINFO_FOUND TRUE)
|
||||
endif()
|
||||
IF(LIBEXECINFO_INCLUDE_DIR AND LIBEXECINFO_LIBRARY)
|
||||
SET(LIBEXECINFO_FOUND TRUE)
|
||||
ENDIF()
|
||||
|
||||
if(LIBEXECINFO_FOUND)
|
||||
if(NOT LIBEXECINFO_FIND_QUIETLY)
|
||||
message(STATUS "Found LibExecinfo: ${EXECINFO_LIBRARY}")
|
||||
endif()
|
||||
else()
|
||||
if(LIBEXECINFO_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find LibExecinfo")
|
||||
endif()
|
||||
endif()
|
||||
IF(LIBEXECINFO_FOUND)
|
||||
IF(NOT LIBEXECINFO_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found LibExecinfo: ${EXECINFO_LIBRARY}")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
IF(LIBEXECINFO_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find LibExecinfo")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
@@ -1,117 +0,0 @@
|
||||
# Find a compatible Qt version
|
||||
# Inputs: WITH_SERVER, WITH_CLIENT, WITH_ORACLE, WITH_DBCONVERTER, FORCE_USE_QT5
|
||||
# Optional Input: QT6_DIR -- Hint as to where Qt6 lives on the system
|
||||
# Optional Input: QT5_DIR -- Hint as to where Qt5 lives on the system
|
||||
# Output: COCKATRICE_QT_VERSION_NAME -- Example values: Qt5, Qt6
|
||||
# Output: SERVATRICE_QT_MODULES
|
||||
# Output: COCKATRICE_QT_MODULES
|
||||
# Output: ORACLE_QT_MODULES
|
||||
# Output: DBCONVERTER_QT_MODULES
|
||||
# Output: TEST_QT_MODULES
|
||||
|
||||
set(REQUIRED_QT_COMPONENTS Core)
|
||||
if(WITH_SERVER)
|
||||
set(_SERVATRICE_NEEDED Network Sql WebSockets)
|
||||
endif()
|
||||
if(WITH_CLIENT)
|
||||
set(_COCKATRICE_NEEDED
|
||||
Concurrent
|
||||
Gui
|
||||
Multimedia
|
||||
Network
|
||||
PrintSupport
|
||||
Svg
|
||||
WebSockets
|
||||
Widgets
|
||||
)
|
||||
endif()
|
||||
if(WITH_ORACLE)
|
||||
set(_ORACLE_NEEDED Concurrent Network Svg Widgets)
|
||||
endif()
|
||||
if(WITH_DBCONVERTER)
|
||||
set(_DBCONVERTER_NEEDED Network Widgets)
|
||||
endif()
|
||||
if(TEST)
|
||||
set(_TEST_NEEDED Widgets)
|
||||
endif()
|
||||
|
||||
set(REQUIRED_QT_COMPONENTS ${REQUIRED_QT_COMPONENTS} ${_SERVATRICE_NEEDED} ${_COCKATRICE_NEEDED} ${_ORACLE_NEEDED}
|
||||
${_DBCONVERTER_NEEDED} ${_TEST_NEEDED}
|
||||
)
|
||||
list(REMOVE_DUPLICATES REQUIRED_QT_COMPONENTS)
|
||||
|
||||
if(NOT FORCE_USE_QT5)
|
||||
# Linguist is now a component in Qt6 instead of an external package
|
||||
find_package(
|
||||
Qt6 6.2.3
|
||||
COMPONENTS ${REQUIRED_QT_COMPONENTS} Linguist
|
||||
QUIET HINTS ${Qt6_DIR}
|
||||
)
|
||||
endif()
|
||||
if(Qt6_FOUND)
|
||||
set(COCKATRICE_QT_VERSION_NAME Qt6)
|
||||
|
||||
list(FIND Qt6LinguistTools_TARGETS Qt6::lrelease QT6_LRELEASE_INDEX)
|
||||
if(QT6_LRELEASE_INDEX EQUAL -1)
|
||||
message(WARNING "Qt6 lrelease not found.")
|
||||
endif()
|
||||
|
||||
list(FIND Qt6LinguistTools_TARGETS Qt6::lupdate QT6_LUPDATE_INDEX)
|
||||
if(QT6_LUPDATE_INDEX EQUAL -1)
|
||||
message(WARNING "Qt6 lupdate not found.")
|
||||
endif()
|
||||
else()
|
||||
find_package(
|
||||
Qt5 5.8.0
|
||||
COMPONENTS ${REQUIRED_QT_COMPONENTS}
|
||||
QUIET HINTS ${Qt5_DIR}
|
||||
)
|
||||
if(Qt5_FOUND)
|
||||
set(COCKATRICE_QT_VERSION_NAME Qt5)
|
||||
else()
|
||||
message(FATAL_ERROR "No suitable version of Qt was found")
|
||||
endif()
|
||||
|
||||
# Qt5 Linguist is in a separate package
|
||||
find_package(Qt5LinguistTools QUIET)
|
||||
if(Qt5LinguistTools_FOUND)
|
||||
if(NOT Qt5_LRELEASE_EXECUTABLE)
|
||||
message(WARNING "Qt5 lrelease not found.")
|
||||
endif()
|
||||
if(NOT Qt5_LUPDATE_EXECUTABLE)
|
||||
message(WARNING "Qt5 lupdate not found.")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Linguist Tools not found, cannot handle translations")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt5_POSITION_INDEPENDENT_CODE OR Qt6_FOUND)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
# Establish Qt Plugins directory & Library directories
|
||||
get_target_property(QT_LIBRARY_DIR ${COCKATRICE_QT_VERSION_NAME}::Core LOCATION)
|
||||
get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} DIRECTORY)
|
||||
if(Qt6_FOUND)
|
||||
get_filename_component(QT_PLUGINS_DIR "${Qt6Core_DIR}/../../../${QT6_INSTALL_PLUGINS}" ABSOLUTE)
|
||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/../../.." ABSOLUTE)
|
||||
if(UNIX AND APPLE)
|
||||
# Mac needs a bit more help finding all necessary components
|
||||
list(APPEND QT_LIBRARY_DIR "/usr/local/lib")
|
||||
endif()
|
||||
elseif(Qt5_FOUND)
|
||||
get_filename_component(QT_PLUGINS_DIR "${Qt5Core_DIR}/../../../plugins" ABSOLUTE)
|
||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/.." ABSOLUTE)
|
||||
endif()
|
||||
message(DEBUG "QT_PLUGINS_DIR = ${QT_PLUGINS_DIR}")
|
||||
message(DEBUG "QT_LIBRARY_DIR = ${QT_LIBRARY_DIR}")
|
||||
|
||||
# Establish exports
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" SERVATRICE_QT_MODULES "${_SERVATRICE_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" COCKATRICE_QT_MODULES "${_COCKATRICE_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" ORACLE_QT_MODULES "${_ORACLE_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" DB_CONVERTER_QT_MODULES "${_DBCONVERTER_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" TEST_QT_MODULES "${_TEST_NEEDED}")
|
||||
|
||||
message(STATUS "Found Qt ${${COCKATRICE_QT_VERSION_NAME}_VERSION} at: ${${COCKATRICE_QT_VERSION_NAME}_DIR}")
|
||||
@@ -1,42 +1,36 @@
|
||||
# Find the MS Visual Studio VC redistributable package
|
||||
|
||||
if(WIN32)
|
||||
set(VCREDISTRUNTIME_FOUND "NO")
|
||||
if (WIN32)
|
||||
set(VCREDISTRUNTIME_FOUND "NO")
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
|
||||
set(REDIST_ARCH x64)
|
||||
else()
|
||||
set(REDIST_ARCH x86)
|
||||
endif()
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
|
||||
set(REDIST_ARCH x64)
|
||||
else()
|
||||
set(REDIST_ARCH x86)
|
||||
endif()
|
||||
|
||||
# VS 2017 uses vcredist_ARCH.exe, VS 2022 uses vc_redist.ARCH.exe
|
||||
set(REDIST_FILE_NAMES vcredist_${REDIST_ARCH}.exe vcredist.${REDIST_ARCH}.exe vc_redist.${REDIST_ARCH}.exe)
|
||||
set(REDIST_FILE vcredist_${REDIST_ARCH}.exe)
|
||||
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
# Check if the list contains minimum one element, to get the path from
|
||||
list(LENGTH CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS libsCount)
|
||||
if(libsCount GREATER 0)
|
||||
list(GET CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS 0 _path)
|
||||
# Check if the list contains minimum one element, to get the path from
|
||||
list(LENGTH CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS libsCount)
|
||||
if (libsCount GREATER 0)
|
||||
list(GET CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS 0 _path)
|
||||
|
||||
get_filename_component(_path ${_path} DIRECTORY)
|
||||
get_filename_component(_path ${_path}/../../ ABSOLUTE)
|
||||
get_filename_component(_path ${_path} DIRECTORY)
|
||||
get_filename_component(_path ${_path}/../../ ABSOLUTE)
|
||||
|
||||
foreach(redist_file ${REDIST_FILE_NAMES})
|
||||
if(EXISTS "${_path}/${redist_file}")
|
||||
set(VCREDISTRUNTIME_FOUND "YES")
|
||||
set(VCREDISTRUNTIME_FILE ${_path}/${redist_file})
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
if (EXISTS "${_path}/${REDIST_FILE}") # VS 2017
|
||||
set(VCREDISTRUNTIME_FOUND "YES")
|
||||
set(VCREDISTRUNTIME_FILE ${_path}/${REDIST_FILE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
message(STATUS "Found VCredist ${VCREDISTRUNTIME_FILE}")
|
||||
else()
|
||||
message(
|
||||
WARNING "Could not find VCredist package. It's not required for compiling, but needs to be available at runtime."
|
||||
)
|
||||
endif()
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
message(STATUS "Found VCredist ${VCREDISTRUNTIME_FILE}")
|
||||
else()
|
||||
message(WARNING "Could not find VCredist package. It's not required for compiling, but needs to be available at runtime.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
77
cmake/FindWin32SslRuntime.cmake
Normal file
77
cmake/FindWin32SslRuntime.cmake
Normal file
@@ -0,0 +1,77 @@
|
||||
# Find the OpenSSL runtime libraries (.dll) for Windows that
|
||||
# will be needed by Qt in order to access https urls.
|
||||
|
||||
if (WIN32)
|
||||
# Get standard installation paths for OpenSSL under Windows
|
||||
|
||||
# http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win64
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
"C:/Tools/vcpkg/installed/x64-windows/bin"
|
||||
"${_programfiles}/OpenSSL-Win64"
|
||||
"C:/OpenSSL-Win64/"
|
||||
)
|
||||
unset(_programfiles)
|
||||
else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win32
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
"C:/Tools/vcpkg/installed/x86-windows/bin"
|
||||
"${_programfiles}/OpenSSL"
|
||||
"${_programfiles}/OpenSSL-Win32"
|
||||
"C:/OpenSSL/"
|
||||
"C:/OpenSSL-Win32/"
|
||||
)
|
||||
unset(_programfiles)
|
||||
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
|
||||
else ()
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(_OPENSSL_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_OPENSSL_ROOT_HINTS}
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
)
|
||||
|
||||
# For OpenSSL < 1.1, they are named libeay32 and ssleay32 and even if the dll is 64bit, it's still suffixed as *32.dll
|
||||
# For OpenSSL >= 1.1, they are named libcrypto and libssl with no suffix
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win64
|
||||
FIND_FILE(WIN32SSLRUNTIME_LIBEAY NAMES libcrypto-1_1-x64.dll libcrypto.dll libeay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
FIND_FILE(WIN32SSLRUNTIME_SSLEAY NAMES libssl-1_1-x64.dll libssl.dll ssleay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win32
|
||||
FIND_FILE(WIN32SSLRUNTIME_LIBEAY NAMES libcrypto-1_1.dll libcrypto.dll libeay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
FIND_FILE(WIN32SSLRUNTIME_SSLEAY NAMES libssl-1_1.dll libssl.dll ssleay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
|
||||
IF(WIN32SSLRUNTIME_LIBEAY AND WIN32SSLRUNTIME_SSLEAY)
|
||||
SET(WIN32SSLRUNTIME_LIBRARIES "${WIN32SSLRUNTIME_LIBEAY}" "${WIN32SSLRUNTIME_SSLEAY}")
|
||||
SET(WIN32SSLRUNTIME_FOUND "YES")
|
||||
message(STATUS "Found OpenSSL ${WIN32SSLRUNTIME_LIBRARIES}")
|
||||
ELSE()
|
||||
SET(WIN32SSLRUNTIME_FOUND "NO")
|
||||
message(WARNING "Could not find OpenSSL runtime libraries. They are not required for compiling, but needs to be available at runtime.")
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
WIN32SSLRUNTIME_LIBEAY
|
||||
WIN32SSLRUNTIME_SSLEAY
|
||||
)
|
||||
@@ -248,20 +248,20 @@ ${If} $PortableMode = 0
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "VersionMajor" "@CPACK_PACKAGE_VERSION_MAJOR@"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "VersionMinor" "@CPACK_PACKAGE_VERSION_MINOR@"
|
||||
|
||||
IfFileExists "$INSTDIR\vc_redist.x86.exe" VcRedist86Exists PastVcRedist86Check
|
||||
IfFileExists "$INSTDIR\vcredist_x86.exe" VcRedist86Exists PastVcRedist86Check
|
||||
VcRedist86Exists:
|
||||
ExecWait '"$INSTDIR\vc_redist.x86.exe" /passive /norestart'
|
||||
ExecWait '"$INSTDIR\vcredist_x86.exe" /passive /norestart'
|
||||
DetailPrint "Wait to ensure unlock of vc_redist file after installation..."
|
||||
Sleep 3000
|
||||
Delete "$INSTDIR\vc_redist.x86.exe"
|
||||
Delete "$INSTDIR\vcredist_x86.exe"
|
||||
PastVcRedist86Check:
|
||||
|
||||
IfFileExists "$INSTDIR\vc_redist.x64.exe" VcRedist64Exists PastVcRedist64Check
|
||||
IfFileExists "$INSTDIR\vcredist_x64.exe" VcRedist64Exists PastVcRedist64Check
|
||||
VcRedist64Exists:
|
||||
ExecWait '"$INSTDIR\vc_redist.x64.exe" /passive /norestart'
|
||||
ExecWait '"$INSTDIR\vcredist_x64.exe" /passive /norestart'
|
||||
DetailPrint "Sleep to ensure unlock of vc_redist file after installation..."
|
||||
Sleep 3000
|
||||
Delete "$INSTDIR\vc_redist.x64.exe"
|
||||
Delete "$INSTDIR\vcredist_x64.exe"
|
||||
PastVcRedist64Check:
|
||||
|
||||
${Else}
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
set(VERSION_STRING_CPP "${PROJECT_BINARY_DIR}/version_string.cpp")
|
||||
set(VERSION_STRING_H "${PROJECT_BINARY_DIR}/version_string.h")
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
|
||||
|
||||
set(hstring
|
||||
"extern const char *VERSION_STRING\;
|
||||
set( hstring "extern const char *VERSION_STRING\;
|
||||
extern const char *VERSION_COMMIT\;
|
||||
extern const char *VERSION_DATE\;\n"
|
||||
)
|
||||
set(cppstring
|
||||
"const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
||||
extern const char *VERSION_DATE\;\n" )
|
||||
set( cppstring "const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
||||
const char *VERSION_COMMIT = \"${GIT_COMMIT_ID}\"\;
|
||||
const char *VERSION_DATE = \"${GIT_COMMIT_DATE_FRIENDLY}\"\;\n"
|
||||
)
|
||||
const char *VERSION_DATE = \"${GIT_COMMIT_DATE_FRIENDLY}\"\;\n")
|
||||
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${cppstring})
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.h.txt ${hstring})
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${cppstring} )
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.h.txt ${hstring} )
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.h.txt ${VERSION_STRING_H}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.h.txt ${VERSION_STRING_H}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${VERSION_STRING_CPP}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,187 +1,154 @@
|
||||
# HELPER FUNCTIONS
|
||||
|
||||
function(get_commit_id)
|
||||
# get last commit hash
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_ID
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
# get last commit hash
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_ID
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}")
|
||||
set(GIT_COMMIT_ID
|
||||
"${GIT_COM_ID}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_LABEL
|
||||
"custom(${GIT_COM_ID})"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}")
|
||||
set(GIT_COMMIT_ID "${GIT_COM_ID}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_LABEL "custom(${GIT_COM_ID})" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(get_commit_date)
|
||||
# get last commit date
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_DATE
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
# get last commit date
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_DATE
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE_FRIENDLY
|
||||
"${GIT_COM_DATE}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE_FRIENDLY "${GIT_COM_DATE}" PARENT_SCOPE)
|
||||
|
||||
string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE
|
||||
"${GIT_COM_DATE}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE "${GIT_COM_DATE}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(get_tag_name commit)
|
||||
if(${commit} STREQUAL "unknown")
|
||||
return()
|
||||
endif()
|
||||
if(${commit} STREQUAL "unknown")
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_TAG
|
||||
ERROR_VARIABLE GIT_TAG_ERR
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_TAG
|
||||
ERROR_VARIABLE GIT_TAG_ERR
|
||||
)
|
||||
|
||||
if((NOT ${res_var} EQUAL 0) OR (${GIT_TAG_ERR} MATCHES "fatal: no tag exactly matches.*"))
|
||||
message(STATUS "Commit is not a release or prerelease (no git tag found)")
|
||||
return()
|
||||
endif()
|
||||
if((NOT ${res_var} EQUAL 0) OR (${GIT_TAG_ERR} MATCHES "fatal: no tag exactly matches.*"))
|
||||
message(STATUS "Commit is not a release or prerelease (no git tag found)")
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}")
|
||||
message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}")
|
||||
string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}")
|
||||
message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}")
|
||||
|
||||
# Extract information from tag:
|
||||
# YYYY-MM-DD-Release-MAJ.MIN.PATCH
|
||||
# YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X
|
||||
string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}")
|
||||
string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}")
|
||||
# Extract information from tag:
|
||||
# YYYY-MM-DD-Release-MAJ.MIN.PATCH
|
||||
# YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X
|
||||
string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}")
|
||||
string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}")
|
||||
|
||||
# Sanity checks: length
|
||||
list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT)
|
||||
if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 9)
|
||||
message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens")
|
||||
return()
|
||||
endif()
|
||||
# Sanity checks: length
|
||||
list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT)
|
||||
if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 9)
|
||||
message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Year
|
||||
list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR)
|
||||
if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100)
|
||||
message(WARNING "Invalid tag year ${GIT_TAG_YEAR}")
|
||||
return()
|
||||
endif()
|
||||
# Year
|
||||
list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR)
|
||||
if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100)
|
||||
message(WARNING "Invalid tag year ${GIT_TAG_YEAR}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Month
|
||||
list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH)
|
||||
if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12)
|
||||
message(WARNING "Invalid tag month ${GIT_TAG_MONTH}")
|
||||
return()
|
||||
endif()
|
||||
# Month
|
||||
list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH)
|
||||
if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12)
|
||||
message(WARNING "Invalid tag month ${GIT_TAG_MONTH}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Day
|
||||
list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY)
|
||||
if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31)
|
||||
message(WARNING "Invalid tag day ${GIT_TAG_DAY}")
|
||||
return()
|
||||
endif()
|
||||
# Day
|
||||
list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY)
|
||||
if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31)
|
||||
message(WARNING "Invalid tag day ${GIT_TAG_DAY}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Type
|
||||
list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE)
|
||||
if(NOT (${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development"))
|
||||
message(WARNING "Invalid tag type ${GIT_TAG_TYPE}")
|
||||
return()
|
||||
endif()
|
||||
# Type
|
||||
list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE)
|
||||
if(NOT(${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development"))
|
||||
message(WARNING "Invalid tag type ${GIT_TAG_TYPE}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Major
|
||||
list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR)
|
||||
if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99)
|
||||
message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}")
|
||||
return()
|
||||
endif()
|
||||
# Major
|
||||
list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR)
|
||||
if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99)
|
||||
message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Minor
|
||||
list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR)
|
||||
if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99)
|
||||
message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}")
|
||||
return()
|
||||
endif()
|
||||
# Minor
|
||||
list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR)
|
||||
if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99)
|
||||
message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Patch
|
||||
list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH)
|
||||
if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99)
|
||||
message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}")
|
||||
return()
|
||||
endif()
|
||||
# Patch
|
||||
list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH)
|
||||
if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99)
|
||||
message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Label
|
||||
# 7 = Stable release
|
||||
# 8 = Dev release, first beta so only "beta" attached
|
||||
# 9 = Dev release, subsequent beta so "beta.N" attached (N>=2)
|
||||
if(${GIT_TAG_LISTCOUNT} EQUAL 8)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
elseif(${GIT_TAG_LISTCOUNT} EQUAL 9)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
list(GET GIT_TAG_EXPLODED 8 GIT_TAG_LABEL_NUM)
|
||||
set(GIT_TAG_LABEL ${GIT_TAG_LABEL} ${GIT_TAG_LABEL_NUM})
|
||||
string(REPLACE ";" "." GIT_TAG_LABEL "${GIT_TAG_LABEL}")
|
||||
else()
|
||||
set(GIT_TAG_LABEL "")
|
||||
endif()
|
||||
# Label
|
||||
# 7 = Stable release
|
||||
# 8 = Dev release, first beta so only "beta" attached
|
||||
# 9 = Dev release, subsequent beta so "beta.N" attached (N>=2)
|
||||
if(${GIT_TAG_LISTCOUNT} EQUAL 8)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
elseif(${GIT_TAG_LISTCOUNT} EQUAL 9)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
list(GET GIT_TAG_EXPLODED 8 GIT_TAG_LABEL_NUM)
|
||||
set(GIT_TAG_LABEL ${GIT_TAG_LABEL} ${GIT_TAG_LABEL_NUM})
|
||||
string(REPLACE ";" "." GIT_TAG_LABEL "${GIT_TAG_LABEL}")
|
||||
else()
|
||||
SET(GIT_TAG_LABEL "")
|
||||
endif()
|
||||
|
||||
# Override hardcoded version with the informations from the tag
|
||||
set(PROJECT_VERSION_MAJOR
|
||||
${GIT_TAG_MAJOR}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_MINOR
|
||||
${GIT_TAG_MINOR}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_PATCH
|
||||
${GIT_TAG_PATCH}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_LABEL
|
||||
${GIT_TAG_LABEL}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
# Override hardcoded version with the informations from the tag
|
||||
set(PROJECT_VERSION_MAJOR ${GIT_TAG_MAJOR} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_MINOR ${GIT_TAG_MINOR} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_PATCH ${GIT_TAG_PATCH} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE)
|
||||
|
||||
if(${GIT_TAG_TYPE} STREQUAL "Development")
|
||||
set(PROJECT_VERSION_LABEL
|
||||
${GIT_TAG_LABEL}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
elseif(${GIT_TAG_TYPE} STREQUAL "Release")
|
||||
set(PROJECT_VERSION_LABEL
|
||||
""
|
||||
PARENT_SCOPE
|
||||
)
|
||||
# set release name from env var
|
||||
set(PROJECT_VERSION_RELEASENAME
|
||||
"${GIT_TAG_RELEASENAME}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endif()
|
||||
if(${GIT_TAG_TYPE} STREQUAL "Development")
|
||||
set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE)
|
||||
elseif(${GIT_TAG_TYPE} STREQUAL "Release")
|
||||
set(PROJECT_VERSION_LABEL "" PARENT_SCOPE)
|
||||
# set release name from env var
|
||||
set(PROJECT_VERSION_RELEASENAME "${GIT_TAG_RELEASENAME}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
@@ -196,16 +163,16 @@ set(PROJECT_VERSION_RELEASENAME "")
|
||||
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
get_commit_id()
|
||||
get_commit_date()
|
||||
get_tag_name(${GIT_COMMIT_ID})
|
||||
get_commit_id()
|
||||
get_commit_date()
|
||||
get_tag_name(${GIT_COMMIT_ID})
|
||||
else()
|
||||
message(WARNING "Git not found. Build will not contain git revision info.")
|
||||
message( WARNING "Git not found. Build will not contain git revision info." )
|
||||
endif()
|
||||
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
if(PROJECT_VERSION_LABEL)
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}")
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}")
|
||||
endif()
|
||||
|
||||
set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})")
|
||||
@@ -213,7 +180,7 @@ set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})")
|
||||
# Format: <program name>[-ReleaseName]-MAJ.MIN.PATCH[-prerelease_label]
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_NAME}")
|
||||
if(PROJECT_VERSION_RELEASENAME)
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION_RELEASENAME}")
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION_RELEASENAME}")
|
||||
endif()
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION}")
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#
|
||||
# provides the cockatrice binary
|
||||
|
||||
project(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
PROJECT(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
|
||||
set(cockatrice_SOURCES
|
||||
SET(cockatrice_SOURCES
|
||||
src/abstractcarddragitem.cpp
|
||||
src/abstractcarditem.cpp
|
||||
src/abstractclient.cpp
|
||||
@@ -48,7 +48,6 @@ set(cockatrice_SOURCES
|
||||
src/dlg_load_remote_deck.cpp
|
||||
src/dlg_manage_sets.cpp
|
||||
src/dlg_register.cpp
|
||||
src/dlg_roll_dice.cpp
|
||||
src/dlg_settings.cpp
|
||||
src/dlg_tip_of_the_day.cpp
|
||||
src/dlg_update.cpp
|
||||
@@ -128,260 +127,160 @@ set(cockatrice_SOURCES
|
||||
src/zoneviewwidget.cpp
|
||||
src/zoneviewzone.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
)
|
||||
|
||||
add_subdirectory(sounds)
|
||||
add_subdirectory(themes)
|
||||
|
||||
set(cockatrice_RESOURCES cockatrice.qrc)
|
||||
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
file(GLOB_RECURSE translate_cockatrice_SRCS ${CMAKE_SOURCE_DIR}/cockatrice/src/*.cpp
|
||||
${CMAKE_SOURCE_DIR}/cockatrice/src/*.h
|
||||
)
|
||||
file(GLOB_RECURSE translate_common_SRCS ${CMAKE_SOURCE_DIR}/common/*.cpp ${CMAKE_SOURCE_DIR}/common/*.h)
|
||||
set(translate_SRCS ${translate_cockatrice_SRCS} ${translate_common_SRCS})
|
||||
set(cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice_en@source.ts")
|
||||
else()
|
||||
file(GLOB cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts")
|
||||
endif(UPDATE_TRANSLATIONS)
|
||||
IF(UPDATE_TRANSLATIONS)
|
||||
FILE(GLOB_RECURSE translate_cockatrice_SRCS ${CMAKE_SOURCE_DIR}/cockatrice/src/*.cpp ${CMAKE_SOURCE_DIR}/cockatrice/src/*.h)
|
||||
FILE(GLOB_RECURSE translate_common_SRCS ${CMAKE_SOURCE_DIR}/common/*.cpp ${CMAKE_SOURCE_DIR}/common/*.h)
|
||||
SET(translate_SRCS ${translate_cockatrice_SRCS} ${translate_common_SRCS})
|
||||
SET(cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/cockatrice_en.ts")
|
||||
ELSE()
|
||||
FILE(GLOB cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts")
|
||||
ENDIF(UPDATE_TRANSLATIONS)
|
||||
|
||||
if(WIN32)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} cockatrice.rc)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} cockatrice.rc)
|
||||
endif(WIN32)
|
||||
|
||||
if(APPLE)
|
||||
set(MACOSX_BUNDLE_ICON_FILE appicon.icns)
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
|
||||
endif(APPLE)
|
||||
set(MACOSX_BUNDLE_ICON_FILE appicon.icns)
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
|
||||
ENDIF(APPLE)
|
||||
|
||||
if(Qt6_FOUND)
|
||||
qt6_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||
elseif(Qt5_FOUND)
|
||||
qt5_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||
# Qt5
|
||||
find_package(Qt5 COMPONENTS Concurrent Multimedia Network PrintSupport Svg WebSockets Widgets REQUIRED)
|
||||
set(COCKATRICE_QT_MODULES Qt5::Concurrent Qt5::Multimedia Qt5::Network Qt5::PrintSupport Qt5::Svg Qt5::Widgets Qt5::WebSockets)
|
||||
|
||||
# Qt5LinguistTools
|
||||
find_package(Qt5LinguistTools)
|
||||
if(Qt5LinguistTools_FOUND)
|
||||
list(APPEND COCKATRICE_LIBS Qt5::LinguistTools)
|
||||
|
||||
if(NOT Qt5_LRELEASE_EXECUTABLE)
|
||||
MESSAGE(WARNING "Qt's lrelease not found.")
|
||||
endif()
|
||||
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
if(NOT Qt5_LUPDATE_EXECUTABLE)
|
||||
MESSAGE(WARNING "Qt's lupdate not found.")
|
||||
endif()
|
||||
QT5_CREATE_TRANSLATION(cockatrice_QM ${translate_SRCS} ${cockatrice_TS})
|
||||
else()
|
||||
QT5_ADD_TRANSLATION(cockatrice_QM ${cockatrice_TS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
QT5_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||
|
||||
# Declare path variables
|
||||
set(ICONDIR
|
||||
share/icons
|
||||
CACHE STRING "icon dir"
|
||||
)
|
||||
set(DESKTOPDIR
|
||||
share/applications
|
||||
CACHE STRING "desktop file destination"
|
||||
)
|
||||
set(ICONDIR share/icons CACHE STRING "icon dir")
|
||||
set(DESKTOPDIR share/applications CACHE STRING "desktop file destination")
|
||||
|
||||
# Include directories
|
||||
include_directories(../common)
|
||||
include_directories(${PROTOBUF_INCLUDE_DIR})
|
||||
include_directories(${CMAKE_BINARY_DIR}/common)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
INCLUDE_DIRECTORIES(../common)
|
||||
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(COCKATRICE_MAC_QM_INSTALL_DIR "cockatrice.app/Contents/Resources/translations")
|
||||
set(COCKATRICE_UNIX_QM_INSTALL_DIR "share/cockatrice/translations")
|
||||
set(COCKATRICE_WIN32_QM_INSTALL_DIR "translations")
|
||||
# Build cockatrice binary and link it
|
||||
ADD_EXECUTABLE(cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_SOURCES} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC} ${cockatrice_MOC_SRCS})
|
||||
|
||||
if(Qt6_FOUND)
|
||||
qt6_add_executable(
|
||||
cockatrice
|
||||
WIN32
|
||||
MACOSX_BUNDLE
|
||||
${cockatrice_SOURCES}
|
||||
${cockatrice_RESOURCES_RCC}
|
||||
${cockatrice_MOC_SRCS}
|
||||
MANUAL_FINALIZATION
|
||||
)
|
||||
elseif(Qt5_FOUND)
|
||||
# Qt5 Translations need to be linked at executable creation time
|
||||
if(Qt5LinguistTools_FOUND)
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
qt5_create_translation(cockatrice_QM ${translate_SRCS} ${cockatrice_TS})
|
||||
else()
|
||||
qt5_add_translation(cockatrice_QM ${cockatrice_TS})
|
||||
endif()
|
||||
endif()
|
||||
add_executable(
|
||||
cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_MOC_SRCS} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC}
|
||||
${cockatrice_SOURCES}
|
||||
)
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_MAC_QM_INSTALL_DIR})
|
||||
else()
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_UNIX_QM_INSTALL_DIR})
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_WIN32_QM_INSTALL_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt5_FOUND)
|
||||
target_link_libraries(cockatrice cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
else()
|
||||
target_link_libraries(cockatrice PUBLIC cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
endif()
|
||||
TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION})
|
||||
if(APPLE)
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION})
|
||||
|
||||
set_target_properties(cockatrice PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/Info.plist)
|
||||
set_target_properties(cockatrice PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/Info.plist)
|
||||
|
||||
install(TARGETS cockatrice BUNDLE DESTINATION ./)
|
||||
else()
|
||||
# Assume linux
|
||||
install(TARGETS cockatrice RUNTIME DESTINATION bin/)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.png DESTINATION ${ICONDIR}/hicolor/48x48/apps)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.svg DESTINATION ${ICONDIR}/hicolor/scalable/apps)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cockatrice.desktop DESTINATION ${DESKTOPDIR})
|
||||
endif()
|
||||
INSTALL(TARGETS cockatrice BUNDLE DESTINATION ./)
|
||||
INSTALL(FILES ${cockatrice_QM} DESTINATION ./cockatrice.app/Contents/Resources/translations)
|
||||
else()
|
||||
# Assume linux
|
||||
INSTALL(TARGETS cockatrice RUNTIME DESTINATION bin/)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.png DESTINATION ${ICONDIR}/hicolor/48x48/apps)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.svg DESTINATION ${ICONDIR}/hicolor/scalable/apps)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cockatrice.desktop DESTINATION ${DESKTOPDIR})
|
||||
INSTALL(FILES ${cockatrice_QM} DESTINATION share/cockatrice/translations)
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
install(TARGETS cockatrice RUNTIME DESTINATION ./)
|
||||
INSTALL(TARGETS cockatrice RUNTIME DESTINATION ./)
|
||||
INSTALL(FILES ${cockatrice_QM} DESTINATION ./translations)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir cockatrice.app/Contents/Plugins)
|
||||
set(qtconf_dest_dir cockatrice.app/Contents/Resources)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir cockatrice.app/Contents/Plugins)
|
||||
set(qtconf_dest_dir cockatrice.app/Contents/Resources)
|
||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/.." ABSOLUTE)
|
||||
|
||||
# Qt plugins: audio (Qt5), iconengines, imageformats, platforms, printsupport (Qt5), styles, tls (Qt6)
|
||||
install(
|
||||
DIRECTORY "${QT_PLUGINS_DIR}/"
|
||||
DESTINATION ${plugin_dest_dir}
|
||||
COMPONENT Runtime
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dSYM" EXCLUDE
|
||||
PATTERN "*_debug.dylib" EXCLUDE
|
||||
PATTERN "audio/*.dylib"
|
||||
PATTERN "iconengines/*.dylib"
|
||||
PATTERN "imageformats/*.dylib"
|
||||
PATTERN "platforms/*.dylib"
|
||||
PATTERN "printsupport/*.dylib"
|
||||
PATTERN "styles/*.dylib"
|
||||
PATTERN "tls/*.dylib"
|
||||
)
|
||||
# qt5 plugins: audio, iconengines, imageformats, platforms, printsupport
|
||||
install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dSYM" EXCLUDE
|
||||
PATTERN "*_debug.dylib" EXCLUDE
|
||||
PATTERN "audio/*.dylib"
|
||||
PATTERN "iconengines/*.dylib"
|
||||
PATTERN "imageformats/*.dylib"
|
||||
PATTERN "platforms/*.dylib"
|
||||
PATTERN "printsupport/*.dylib"
|
||||
PATTERN "styles/*.dylib"
|
||||
)
|
||||
|
||||
install(
|
||||
CODE "
|
||||
install(CODE "
|
||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
||||
Plugins = Plugins
|
||||
Translations = Resources/translations
|
||||
Data = Resources\")
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
" COMPONENT Runtime)
|
||||
|
||||
install(
|
||||
CODE "
|
||||
install(CODE "
|
||||
file(GLOB_RECURSE QTPLUGINS
|
||||
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dylib\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
" COMPONENT Runtime)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir Plugins)
|
||||
set(qtconf_dest_dir .)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir Plugins)
|
||||
set(qtconf_dest_dir .)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/${CMAKE_BUILD_TYPE}/"
|
||||
DESTINATION ./
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dll"
|
||||
)
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/${CMAKE_BUILD_TYPE}/" DESTINATION ./ FILES_MATCHING PATTERN "*.dll")
|
||||
|
||||
# Qt plugins: audio (Qt5), iconengines, imageformats, platforms, printsupport (Qt5), styles, tls (Qt6)
|
||||
install(
|
||||
DIRECTORY "${QT_PLUGINS_DIR}/"
|
||||
DESTINATION ${plugin_dest_dir}
|
||||
COMPONENT Runtime
|
||||
FILES_MATCHING
|
||||
PATTERN "audio/qtaudio_wasapi.dll"
|
||||
PATTERN "audio/qtaudio_windows.dll"
|
||||
PATTERN "iconengines/qsvgicon.dll"
|
||||
PATTERN "imageformats/*.dll"
|
||||
PATTERN "mediaservice/dsengine.dll"
|
||||
PATTERN "mediaservice/wmfengine.dll"
|
||||
PATTERN "platforms/qdirect2d.dll"
|
||||
PATTERN "platforms/qminimal.dll"
|
||||
PATTERN "platforms/qoffscreen.dll"
|
||||
PATTERN "platforms/qwindows.dll"
|
||||
PATTERN "printsupport/windowsprintersupport.dll"
|
||||
PATTERN "styles/qcertonlybackend.dll"
|
||||
PATTERN "styles/qopensslbackend.dll"
|
||||
PATTERN "styles/qschannelbackend.dll"
|
||||
PATTERN "styles/qwindowsvistastyle.dll"
|
||||
PATTERN "tls/qcertonlybackend.dll"
|
||||
PATTERN "tls/qopensslbackend.dll"
|
||||
PATTERN "tls/qschannelbackend.dll"
|
||||
)
|
||||
# qt5 plugins: audio, iconengines, imageformats, platforms, printsupport
|
||||
install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime
|
||||
FILES_MATCHING REGEX "(audio|iconengines|imageformats|platforms|printsupport|styles)/.*[^d]\\.dll")
|
||||
|
||||
install(
|
||||
CODE "
|
||||
install(CODE "
|
||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
||||
Plugins = Plugins
|
||||
Translations = Resources/translations
|
||||
Data = Resources\")
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
" COMPONENT Runtime)
|
||||
|
||||
install(
|
||||
CODE "
|
||||
install(CODE "
|
||||
file(GLOB_RECURSE QTPLUGINS
|
||||
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dll\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/Cockatrice.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
" COMPONENT Runtime)
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
install(FILES ${OPENSSL_INCLUDE_DIRS} DESTINATION ./)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt6_FOUND AND Qt6LinguistTools_FOUND)
|
||||
#Qt6 Translations happen after the executable is built up
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
qt6_add_translations(
|
||||
cockatrice
|
||||
TS_FILES
|
||||
${cockatrice_TS}
|
||||
SOURCES
|
||||
${translate_SRCS}
|
||||
QM_FILES_OUTPUT_VARIABLE
|
||||
cockatrice_QM
|
||||
)
|
||||
else()
|
||||
qt6_add_translations(cockatrice TS_FILES ${cockatrice_TS} QM_FILES_OUTPUT_VARIABLE cockatrice_QM)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_MAC_QM_INSTALL_DIR})
|
||||
else()
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_UNIX_QM_INSTALL_DIR})
|
||||
if(WIN32SSLRUNTIME_FOUND)
|
||||
install(FILES ${WIN32SSLRUNTIME_LIBRARIES} DESTINATION ./)
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_WIN32_QM_INSTALL_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt6_FOUND)
|
||||
qt6_finalize_target(cockatrice)
|
||||
endif()
|
||||
|
||||
@@ -126,7 +126,6 @@
|
||||
<file>resources/countries/er.svg</file>
|
||||
<file>resources/countries/es.svg</file>
|
||||
<file>resources/countries/et.svg</file>
|
||||
<file>resources/countries/eu.svg</file>
|
||||
<file>resources/countries/fi.svg</file>
|
||||
<file>resources/countries/fj.svg</file>
|
||||
<file>resources/countries/fk.svg</file>
|
||||
@@ -302,7 +301,6 @@
|
||||
<file>resources/countries/vu.svg</file>
|
||||
<file>resources/countries/wf.svg</file>
|
||||
<file>resources/countries/ws.svg</file>
|
||||
<file>resources/countries/xk.svg</file>
|
||||
<file>resources/countries/ye.svg</file>
|
||||
<file>resources/countries/yt.svg</file>
|
||||
<file>resources/countries/za.svg</file>
|
||||
@@ -351,10 +349,10 @@
|
||||
<file>resources/tips/images/cockatrice_wiki.png</file>
|
||||
<file>resources/tips/images/coin_flip.png</file>
|
||||
<file>resources/tips/images/counter_expression.png</file>
|
||||
<file>resources/tips/images/discord.png</file>
|
||||
<file>resources/tips/images/face_down.png</file>
|
||||
<file>resources/tips/images/filter_games.png</file>
|
||||
<file>resources/tips/images/github_logo.png</file>
|
||||
<file>resources/tips/images/gitter.png</file>
|
||||
<file>resources/tips/images/setpt.png</file>
|
||||
<file>resources/tips/images/shortcuts.png</file>
|
||||
<file>resources/tips/images/themes.png</file>
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 8.3 KiB |
@@ -1,7 +1,6 @@
|
||||
## Search Syntax Help
|
||||
## Syntax Help
|
||||
-----
|
||||
The search bar recognizes a set of special commands similar to some other card databases.<br>
|
||||
In this list of examples below, each entry has an explanation and can be clicked to test the query. Note that all searches are case insensitive.
|
||||
The search bar recognizes a set of special commands similar to some other card databases. Here is a list with examples. Each entry can be clicked to test the query and has a small explanation. Note that all searches are case insensitive.
|
||||
<dl>
|
||||
<dt>Name:</dt>
|
||||
<dd>[birds of paradise](#birds of paradise) <small>(Any card name containing the words birds, of, and paradise)</small></dd>
|
||||
@@ -47,7 +46,8 @@ In this list of examples below, each entry has an explanation and can be clicked
|
||||
|
||||
<dt><u>E</u>dition:</dt>
|
||||
<dd>[set:lea](#set:lea) <small>(Cards that appear in Alpha, which has the set code LEA)</small></dd>
|
||||
<dd>[e:lea or e:leb](#e:lea or e:leb) <small>(Cards that appear in Alpha or Beta)</small></dd>
|
||||
<dd>[e:lea,leb](#e:lea,leb) <small>(Cards that appear in Alpha or Beta)</small></dd>
|
||||
<dd><a href="#e:lea,leb -(e:lea e:leb)">e:lea,leb -(e:lea e:leb)</a> <small>(Cards that appear in Alpha or Beta but not in both editions)</small></dd>
|
||||
|
||||
<dt>Negate:</dt>
|
||||
<dd>[c:wu -c:m](#c:wu -c:m) <small>(Any card that is white or blue, but not multicolored)</small></dd>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB |
BIN
cockatrice/resources/tips/images/gitter.png
Normal file
BIN
cockatrice/resources/tips/images/gitter.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
@@ -7,9 +7,9 @@
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Suggesting New Tips</title>
|
||||
<text>You can suggest new Tips of the Day by reaching out to the development team on <a href="https://discord.gg/3Z9yzmA">Discord</a>!</text>
|
||||
<image>discord.png</image>
|
||||
<date>2023-10-18</date>
|
||||
<text>You can suggest new Tips of the Day by reaching out to the development team on <a href="https://gitter.im/cockatrice/cockatrice">Gitter</a>!</text>
|
||||
<image>gitter.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Reporting Bugs</title>
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
#
|
||||
# add sounds subfolders
|
||||
|
||||
set(defsounds Default Legacy)
|
||||
SET(defsounds
|
||||
Default
|
||||
Legacy
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
install(DIRECTORY ${defsounds} DESTINATION Cockatrice.app/Contents/Resources/sounds/)
|
||||
else()
|
||||
# Assume linux
|
||||
install(DIRECTORY ${defsounds} DESTINATION share/cockatrice/sounds/)
|
||||
endif()
|
||||
if(APPLE)
|
||||
INSTALL(DIRECTORY ${defsounds} DESTINATION Cockatrice.app/Contents/Resources/sounds/)
|
||||
else()
|
||||
# Assume linux
|
||||
INSTALL(DIRECTORY ${defsounds} DESTINATION share/cockatrice/sounds/)
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
install(DIRECTORY ${defsounds} DESTINATION sounds/)
|
||||
INSTALL(DIRECTORY ${defsounds} DESTINATION sounds/)
|
||||
endif()
|
||||
|
||||
@@ -20,8 +20,13 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item,
|
||||
parentDrag->addChildDrag(this);
|
||||
setZValue(2000000007 + hotSpot.x() * 1000000 + hotSpot.y() * 1000 + 1000);
|
||||
} else {
|
||||
hotSpot = QPointF{qBound(0.0, hotSpot.x(), static_cast<qreal>(CARD_WIDTH - 1)),
|
||||
qBound(0.0, hotSpot.y(), static_cast<qreal>(CARD_HEIGHT - 1))};
|
||||
if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) {
|
||||
qDebug() << "CardDragItem: coordinate overflow: x =" << hotSpot.x() << ", y =" << hotSpot.y();
|
||||
hotSpot = QPointF();
|
||||
} else if ((hotSpot.x() > CARD_WIDTH) || (hotSpot.y() > CARD_HEIGHT)) {
|
||||
qDebug() << "CardDragItem: coordinate overflow: x =" << hotSpot.x() << ", y =" << hotSpot.y();
|
||||
hotSpot = QPointF(CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
setZValue(2000000007);
|
||||
}
|
||||
@@ -40,19 +45,12 @@ AbstractCardDragItem::~AbstractCardDragItem()
|
||||
delete childDrags[i];
|
||||
}
|
||||
|
||||
QPainterPath AbstractCardDragItem::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
shape.addRoundedRect(boundingRect(), 0.05 * CARD_WIDTH, 0.05 * CARD_WIDTH);
|
||||
return shape;
|
||||
}
|
||||
|
||||
void AbstractCardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
item->paint(painter, option, widget);
|
||||
|
||||
// adds a mask to the card so it looks like the card hasnt been placed yet
|
||||
painter->fillPath(shape(), GHOST_MASK);
|
||||
painter->fillRect(boundingRect(), GHOST_MASK);
|
||||
}
|
||||
|
||||
void AbstractCardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
@@ -21,18 +21,17 @@ public:
|
||||
{
|
||||
Type = typeCardDrag
|
||||
};
|
||||
int type() const override
|
||||
int type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
AbstractCardDragItem(AbstractCardItem *_item, const QPointF &_hotSpot, AbstractCardDragItem *parentDrag = 0);
|
||||
~AbstractCardDragItem();
|
||||
QRectF boundingRect() const override
|
||||
QRectF boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
QPainterPath shape() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
AbstractCardItem *getItem() const
|
||||
{
|
||||
return item;
|
||||
@@ -45,7 +44,7 @@ public:
|
||||
virtual void updatePosition(const QPointF &cursorScenePos) = 0;
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,13 +34,6 @@ QRectF AbstractCardItem::boundingRect() const
|
||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
|
||||
QPainterPath AbstractCardItem::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
shape.addRoundedRect(boundingRect(), 0.05 * CARD_WIDTH, 0.05 * CARD_WIDTH);
|
||||
return shape;
|
||||
}
|
||||
|
||||
void AbstractCardItem::pixmapUpdated()
|
||||
{
|
||||
update();
|
||||
@@ -120,14 +113,24 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
|
||||
|
||||
if (paintImage) {
|
||||
painter->save();
|
||||
painter->setClipPath(shape());
|
||||
painter->drawPixmap(boundingRect(), translatedPixmap, QRectF({0, 0}, translatedPixmap.size()));
|
||||
transformPainter(painter, translatedSize, angle);
|
||||
painter->drawPixmap(QPointF(1, 1), translatedPixmap);
|
||||
painter->restore();
|
||||
} else {
|
||||
painter->setBrush(bgColor);
|
||||
painter->drawPath(shape());
|
||||
}
|
||||
|
||||
QPen pen(Qt::black);
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
const int penWidth = 2;
|
||||
pen.setWidth(penWidth);
|
||||
painter->setPen(pen);
|
||||
|
||||
if (!angle)
|
||||
painter->drawRect(QRectF(0, 0, CARD_WIDTH - 1, CARD_HEIGHT - penWidth));
|
||||
else
|
||||
painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 1.5));
|
||||
|
||||
if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) {
|
||||
painter->save();
|
||||
transformPainter(painter, translatedSize, angle);
|
||||
@@ -155,7 +158,9 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
||||
QSizeF translatedSize = getTranslatedSize(painter);
|
||||
paintPicture(painter, translatedSize, tapAngle);
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
transformPainter(painter, translatedSize, tapAngle);
|
||||
|
||||
if (isSelected() || isHovered) {
|
||||
QPen pen;
|
||||
@@ -163,12 +168,15 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
||||
pen.setColor(Qt::yellow);
|
||||
if (isSelected())
|
||||
pen.setColor(Qt::red);
|
||||
pen.setWidth(0); // Cosmetic pen
|
||||
const int penWidth = 1;
|
||||
pen.setWidth(penWidth);
|
||||
painter->setPen(pen);
|
||||
painter->drawPath(shape());
|
||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void AbstractCardItem::setName(const QString &_name)
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
{
|
||||
Type = typeCard
|
||||
};
|
||||
int type() const override
|
||||
int type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
@@ -53,11 +53,10 @@ public:
|
||||
int _id = -1,
|
||||
QGraphicsItem *parent = nullptr);
|
||||
~AbstractCardItem();
|
||||
QRectF boundingRect() const override;
|
||||
QPainterPath shape() const override;
|
||||
QRectF boundingRect() const;
|
||||
QSizeF getTranslatedSize(QPainter *painter) const;
|
||||
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
CardInfoPtr getInfo() const
|
||||
{
|
||||
return info;
|
||||
@@ -104,9 +103,9 @@ public:
|
||||
|
||||
protected:
|
||||
void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
|
||||
void cacheBgColor();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "abstractclient.h"
|
||||
|
||||
#include "client_metatypes.h"
|
||||
#include "featureset.h"
|
||||
#include "get_pb_extension.h"
|
||||
#include "pb/commands.pb.h"
|
||||
@@ -47,7 +48,6 @@ AbstractClient::AbstractClient(QObject *parent)
|
||||
qRegisterMetaType<QList<ServerInfo_User>>("QList<ServerInfo_User>");
|
||||
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
|
||||
qRegisterMetaType<QList<QString>>("missingFeatures");
|
||||
qRegisterMetaType<PendingCommand *>("pendingCommand");
|
||||
|
||||
FeatureSet features;
|
||||
features.initalizeFeatureList(clientFeatures);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QtMath>
|
||||
#include <cmath>
|
||||
|
||||
ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &_color)
|
||||
: QGraphicsItem(), player(_player), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color),
|
||||
@@ -71,7 +71,7 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
const double arrowWidth = 15.0;
|
||||
const double headWidth = 40.0;
|
||||
const double headLength =
|
||||
headWidth / qPow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++
|
||||
headWidth / pow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++
|
||||
const double phi = 15;
|
||||
|
||||
if (!startItem)
|
||||
@@ -86,7 +86,7 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
if (lineLength < 30)
|
||||
path = QPainterPath();
|
||||
else {
|
||||
QPointF c(lineLength / 2, qTan(phi * M_PI / 180) * lineLength);
|
||||
QPointF c(lineLength / 2, tan(phi * M_PI / 180) * lineLength);
|
||||
|
||||
QPainterPath centerLine;
|
||||
centerLine.moveTo(0, 0);
|
||||
@@ -97,22 +97,22 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
QLineF testLine(arrowBodyEndPoint, centerLine.pointAtPercent(percentage + 0.001));
|
||||
qreal alpha = testLine.angle() - 90;
|
||||
QPointF endPoint1 =
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(qCos(alpha * M_PI / 180), -qSin(alpha * M_PI / 180));
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180));
|
||||
QPointF endPoint2 =
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(-qCos(alpha * M_PI / 180), qSin(alpha * M_PI / 180));
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180));
|
||||
QPointF point1 =
|
||||
endPoint1 + (headWidth - arrowWidth) / 2 * QPointF(qCos(alpha * M_PI / 180), -qSin(alpha * M_PI / 180));
|
||||
endPoint1 + (headWidth - arrowWidth) / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180));
|
||||
QPointF point2 =
|
||||
endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-qCos(alpha * M_PI / 180), qSin(alpha * M_PI / 180));
|
||||
endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180));
|
||||
|
||||
path = QPainterPath(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
path = QPainterPath(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
||||
path.quadTo(c, endPoint1);
|
||||
path.lineTo(point1);
|
||||
path.lineTo(QPointF(lineLength, 0));
|
||||
path.lineTo(point2);
|
||||
path.lineTo(endPoint2);
|
||||
path.quadTo(c, arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
path.lineTo(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
path.quadTo(c, arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
||||
path.lineTo(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
||||
}
|
||||
|
||||
setPos(startPoint);
|
||||
@@ -138,8 +138,8 @@ void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
|
||||
QList<QGraphicsItem *> colliding = scene()->items(event->scenePos());
|
||||
for (QGraphicsItem *item : colliding) {
|
||||
if (qgraphicsitem_cast<CardItem *>(item)) {
|
||||
for (int i = 0; i < colliding.size(); ++i) {
|
||||
if (qgraphicsitem_cast<CardItem *>(colliding[i])) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
@@ -205,8 +205,8 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
update();
|
||||
|
||||
for (ArrowDragItem *child : childArrows) {
|
||||
child->mouseMoveEvent(event);
|
||||
for (int i = 0; i < childArrows.size(); ++i) {
|
||||
childArrows[i]->mouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,9 +251,8 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
delArrow();
|
||||
|
||||
for (ArrowDragItem *child : childArrows) {
|
||||
child->mouseReleaseEvent(event);
|
||||
}
|
||||
for (int i = 0; i < childArrows.size(); ++i)
|
||||
childArrows[i]->mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
|
||||
@@ -261,11 +260,6 @@ ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
|
||||
{
|
||||
}
|
||||
|
||||
void ArrowAttachItem::addChildArrow(ArrowAttachItem *childArrow)
|
||||
{
|
||||
childArrows.append(childArrow);
|
||||
}
|
||||
|
||||
void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!startItem)
|
||||
@@ -301,13 +295,9 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
updatePath();
|
||||
}
|
||||
update();
|
||||
|
||||
for (ArrowAttachItem *child : childArrows) {
|
||||
child->mouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
|
||||
{
|
||||
if (!startItem)
|
||||
return;
|
||||
@@ -329,8 +319,4 @@ void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
|
||||
delArrow();
|
||||
|
||||
for (ArrowAttachItem *child : childArrows) {
|
||||
child->mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,12 +85,8 @@ protected:
|
||||
class ArrowAttachItem : public ArrowItem
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QList<ArrowAttachItem *> childArrows;
|
||||
|
||||
public:
|
||||
ArrowAttachItem(ArrowTarget *_startItem);
|
||||
void addChildArrow(ArrowAttachItem *childArrow);
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
|
||||
@@ -43,8 +43,9 @@ public:
|
||||
}
|
||||
void removeArrowFrom(ArrowItem *arrow)
|
||||
{
|
||||
arrowsFrom.removeOne(arrow);
|
||||
arrowsFrom.removeAt(arrowsFrom.indexOf(arrow));
|
||||
}
|
||||
|
||||
const QList<ArrowItem *> &getArrowsTo() const
|
||||
{
|
||||
return arrowsTo;
|
||||
@@ -55,7 +56,8 @@ public:
|
||||
}
|
||||
void removeArrowTo(ArrowItem *arrow)
|
||||
{
|
||||
arrowsTo.removeOne(arrow);
|
||||
arrowsTo.removeAt(arrowsTo.indexOf(arrow));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -266,14 +266,9 @@ CardInfoPtr CardInfo::newInstance(const QString &_name,
|
||||
|
||||
QString CardInfo::getCorrectedName() const
|
||||
{
|
||||
// remove all the characters reserved in windows file paths,
|
||||
// other oses only disallow a subset of these so it covers all
|
||||
static const QRegularExpression rmrx(R"(( // |[*<>:"\\?\x00-\x08\x10-\x1f]))");
|
||||
static const QRegularExpression spacerx(R"([/\x09-\x0f])");
|
||||
static const QString space(' ');
|
||||
QString result = name;
|
||||
// Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
|
||||
return result.remove(rmrx).replace(spacerx, space);
|
||||
return result.remove(" // ").remove(':').remove('"').remove('?').replace('/', ' ');
|
||||
}
|
||||
|
||||
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
||||
@@ -592,9 +587,9 @@ void CardDatabase::refreshCachedReverseRelatedCards()
|
||||
continue;
|
||||
}
|
||||
|
||||
auto *newCardRelation = new CardRelation(
|
||||
card->getName(), cardRelation->getAttachType(), cardRelation->getIsCreateAllExclusion(),
|
||||
cardRelation->getIsVariable(), cardRelation->getDefaultCount(), cardRelation->getIsPersistent());
|
||||
auto *newCardRelation = new CardRelation(card->getName(), cardRelation->getDoesAttach(),
|
||||
cardRelation->getIsCreateAllExclusion(),
|
||||
cardRelation->getIsVariable(), cardRelation->getDefaultCount());
|
||||
cards.value(targetCard)->addReverseRelatedCards2Me(newCardRelation);
|
||||
}
|
||||
}
|
||||
@@ -612,22 +607,22 @@ QStringList CardDatabase::getAllMainCardTypes() const
|
||||
|
||||
void CardDatabase::checkUnknownSets()
|
||||
{
|
||||
auto _sets = getSetList();
|
||||
SetList sets = getSetList();
|
||||
|
||||
if (_sets.getEnabledSetsNum()) {
|
||||
if (sets.getEnabledSetsNum()) {
|
||||
// if some sets are first found on this run, ask the user
|
||||
int numUnknownSets = _sets.getUnknownSetsNum();
|
||||
QStringList unknownSetNames = _sets.getUnknownSetsNames();
|
||||
int numUnknownSets = sets.getUnknownSetsNum();
|
||||
QStringList unknownSetNames = sets.getUnknownSetsNames();
|
||||
if (numUnknownSets > 0) {
|
||||
emit cardDatabaseNewSetsFound(numUnknownSets, unknownSetNames);
|
||||
} else {
|
||||
_sets.markAllAsKnown();
|
||||
sets.markAllAsKnown();
|
||||
}
|
||||
} else {
|
||||
// No set enabled. Probably this is the first time running trice
|
||||
_sets.guessSortKeys();
|
||||
_sets.sortByKey();
|
||||
_sets.enableAll();
|
||||
sets.guessSortKeys();
|
||||
sets.sortByKey();
|
||||
sets.enableAll();
|
||||
notifyEnabledSetsChanged();
|
||||
|
||||
emit cardDatabaseAllNewSetsEnabled();
|
||||
@@ -636,14 +631,14 @@ void CardDatabase::checkUnknownSets()
|
||||
|
||||
void CardDatabase::enableAllUnknownSets()
|
||||
{
|
||||
auto _sets = getSetList();
|
||||
_sets.enableAllUnknown();
|
||||
SetList sets = getSetList();
|
||||
sets.enableAllUnknown();
|
||||
}
|
||||
|
||||
void CardDatabase::markAllSetsAsKnown()
|
||||
{
|
||||
auto _sets = getSetList();
|
||||
_sets.markAllAsKnown();
|
||||
SetList sets = getSetList();
|
||||
sets.markAllAsKnown();
|
||||
}
|
||||
|
||||
void CardDatabase::notifyEnabledSetsChanged()
|
||||
@@ -677,13 +672,12 @@ bool CardDatabase::saveCustomTokensToFile()
|
||||
}
|
||||
|
||||
CardRelation::CardRelation(const QString &_name,
|
||||
AttachType _attachType,
|
||||
bool _doesAttach,
|
||||
bool _isCreateAllExclusion,
|
||||
bool _isVariableCount,
|
||||
int _defaultCount,
|
||||
bool _isPersistent)
|
||||
: name(_name), attachType(_attachType), isCreateAllExclusion(_isCreateAllExclusion),
|
||||
isVariableCount(_isVariableCount), defaultCount(_defaultCount), isPersistent(_isPersistent)
|
||||
int _defaultCount)
|
||||
: name(_name), doesAttach(_doesAttach), isCreateAllExclusion(_isCreateAllExclusion),
|
||||
isVariableCount(_isVariableCount), defaultCount(_defaultCount)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -452,60 +452,31 @@ signals:
|
||||
class CardRelation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum AttachType
|
||||
{
|
||||
DoesNotAttach = 0,
|
||||
AttachTo = 1,
|
||||
TransformInto = 2,
|
||||
};
|
||||
|
||||
private:
|
||||
QString name;
|
||||
AttachType attachType;
|
||||
bool doesAttach;
|
||||
bool isCreateAllExclusion;
|
||||
bool isVariableCount;
|
||||
int defaultCount;
|
||||
bool isPersistent;
|
||||
|
||||
public:
|
||||
explicit CardRelation(const QString &_name = QString(),
|
||||
AttachType _attachType = DoesNotAttach,
|
||||
bool _doesAttach = false,
|
||||
bool _isCreateAllExclusion = false,
|
||||
bool _isVariableCount = false,
|
||||
int _defaultCount = 1,
|
||||
bool _isPersistent = false);
|
||||
int _defaultCount = 1);
|
||||
|
||||
inline const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
AttachType getAttachType() const
|
||||
{
|
||||
return attachType;
|
||||
}
|
||||
bool getDoesAttach() const
|
||||
{
|
||||
return attachType != DoesNotAttach;
|
||||
}
|
||||
bool getDoesTransform() const
|
||||
{
|
||||
return attachType == TransformInto;
|
||||
}
|
||||
QString getAttachTypeAsString() const
|
||||
{
|
||||
switch (attachType) {
|
||||
case AttachTo:
|
||||
return "attach";
|
||||
case TransformInto:
|
||||
return "transform";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
return doesAttach;
|
||||
}
|
||||
bool getCanCreateAnother() const
|
||||
{
|
||||
return !getDoesAttach();
|
||||
return !doesAttach;
|
||||
}
|
||||
bool getIsCreateAllExclusion() const
|
||||
{
|
||||
@@ -519,9 +490,5 @@ public:
|
||||
{
|
||||
return defaultCount;
|
||||
}
|
||||
bool getIsPersistent() const
|
||||
{
|
||||
return isPersistent;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -326,12 +326,12 @@ void CardDatabaseDisplayModel::clearFilterAll()
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void CardDatabaseDisplayModel::setFilterTree(FilterTree *_filterTree)
|
||||
void CardDatabaseDisplayModel::setFilterTree(FilterTree *filterTree)
|
||||
{
|
||||
if (this->filterTree != nullptr)
|
||||
disconnect(this->filterTree, nullptr, this, nullptr);
|
||||
|
||||
this->filterTree = _filterTree;
|
||||
this->filterTree = filterTree;
|
||||
connect(this->filterTree, SIGNAL(changed()), this, SLOT(filterTreeChanged()));
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
|
||||
public:
|
||||
explicit CardDatabaseDisplayModel(QObject *parent = nullptr);
|
||||
void setFilterTree(FilterTree *_filterTree);
|
||||
void setFilterTree(FilterTree *filterTree);
|
||||
void setIsToken(FilterBool _isToken)
|
||||
{
|
||||
isToken = _isToken;
|
||||
|
||||
@@ -23,7 +23,7 @@ bool CockatriceXml3Parser::getCanParseFile(const QString &fileName, QIODevice &d
|
||||
QXmlStreamReader xml(&device);
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
if (xml.name().toString() == COCKATRICE_XML3_TAGNAME) {
|
||||
if (xml.name() == COCKATRICE_XML3_TAGNAME) {
|
||||
int version = xml.attributes().value("version").toString().toInt();
|
||||
if (version == COCKATRICE_XML3_TAGVER) {
|
||||
return true;
|
||||
@@ -52,13 +52,12 @@ void CockatriceXml3Parser::parseFile(QIODevice &device)
|
||||
break;
|
||||
}
|
||||
|
||||
auto name = xml.name().toString();
|
||||
if (name == "sets") {
|
||||
if (xml.name() == "sets") {
|
||||
loadSetsFromXml(xml);
|
||||
} else if (name == "cards") {
|
||||
} else if (xml.name() == "cards") {
|
||||
loadCardsFromXml(xml);
|
||||
} else if (!name.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown item" << name << ", trying to continue anyway";
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
@@ -73,27 +72,26 @@ void CockatriceXml3Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
auto name = xml.name().toString();
|
||||
if (name == "set") {
|
||||
if (xml.name() == "set") {
|
||||
QString shortName, longName, setType;
|
||||
QDate releaseDate;
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
name = xml.name().toString();
|
||||
|
||||
if (name == "name") {
|
||||
if (xml.name() == "name") {
|
||||
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (name == "longname") {
|
||||
} else if (xml.name() == "longname") {
|
||||
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (name == "settype") {
|
||||
} else if (xml.name() == "settype") {
|
||||
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (name == "releasedate") {
|
||||
} else if (xml.name() == "releasedate") {
|
||||
releaseDate =
|
||||
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
||||
} else if (!name.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown set property" << name << ", trying to continue anyway";
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown set property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
@@ -148,14 +146,13 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
auto xmlName = xml.name().toString();
|
||||
if (xmlName == "card") {
|
||||
if (xml.name() == "card") {
|
||||
QString name = QString("");
|
||||
QString text = QString("");
|
||||
QVariantHash properties = QVariantHash();
|
||||
QString colors = QString("");
|
||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||
auto _sets = CardInfoPerSetMap();
|
||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
||||
int tableRow = 0;
|
||||
bool cipt = false;
|
||||
bool isToken = false;
|
||||
@@ -165,39 +162,37 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
xmlName = xml.name().toString();
|
||||
|
||||
// variable - assigned properties
|
||||
if (xmlName == "name") {
|
||||
if (xml.name() == "name") {
|
||||
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xmlName == "text") {
|
||||
} else if (xml.name() == "text") {
|
||||
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xmlName == "color") {
|
||||
} else if (xml.name() == "color") {
|
||||
colors.append(xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xmlName == "token") {
|
||||
} else if (xml.name() == "token") {
|
||||
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
||||
// generic properties
|
||||
} else if (xmlName == "manacost") {
|
||||
} else if (xml.name() == "manacost") {
|
||||
properties.insert("manacost", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xmlName == "cmc") {
|
||||
} else if (xml.name() == "cmc") {
|
||||
properties.insert("cmc", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xmlName == "type") {
|
||||
} else if (xml.name() == "type") {
|
||||
QString type = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
properties.insert("type", type);
|
||||
properties.insert("maintype", getMainCardType(type));
|
||||
} else if (xmlName == "pt") {
|
||||
} else if (xml.name() == "pt") {
|
||||
properties.insert("pt", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xmlName == "loyalty") {
|
||||
} else if (xml.name() == "loyalty") {
|
||||
properties.insert("loyalty", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
// positioning info
|
||||
} else if (xmlName == "tablerow") {
|
||||
} else if (xml.name() == "tablerow") {
|
||||
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
||||
} else if (xmlName == "cipt") {
|
||||
} else if (xml.name() == "cipt") {
|
||||
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
} else if (xmlName == "upsidedown") {
|
||||
} else if (xml.name() == "upsidedown") {
|
||||
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
// sets
|
||||
} else if (xmlName == "set") {
|
||||
} else if (xml.name() == "set") {
|
||||
// NOTE: attributes must be read before readElementText()
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
@@ -221,10 +216,10 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
if (attrs.hasAttribute("rarity")) {
|
||||
setInfo.setProperty("rarity", attrs.value("rarity").toString());
|
||||
}
|
||||
_sets.insert(setName, setInfo);
|
||||
// related cards
|
||||
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||
CardRelation::AttachType attach = CardRelation::DoesNotAttach;
|
||||
sets.insert(setName, setInfo);
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
bool attach = false;
|
||||
bool exclude = false;
|
||||
bool variable = false;
|
||||
int count = 1;
|
||||
@@ -246,7 +241,7 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("attach")) {
|
||||
attach = CardRelation::AttachTo;
|
||||
attach = true;
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("exclude")) {
|
||||
@@ -254,13 +249,13 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||
if (xmlName == "reverse-related") {
|
||||
if (xml.name() == "reverse-related") {
|
||||
reverseRelatedCards << relation;
|
||||
} else {
|
||||
relatedCards << relation;
|
||||
}
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xmlName
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
@@ -268,7 +263,7 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
|
||||
properties.insert("colors", colors);
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, _sets, cipt, tableRow, upsideDown);
|
||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
@@ -412,7 +407,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool CockatriceXml3Parser::saveToFile(SetNameMap _sets,
|
||||
bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl,
|
||||
@@ -439,9 +434,9 @@ bool CockatriceXml3Parser::saveToFile(SetNameMap _sets,
|
||||
xml.writeTextElement("sourceVersion", sourceVersion);
|
||||
xml.writeEndElement();
|
||||
|
||||
if (_sets.count() > 0) {
|
||||
if (sets.count() > 0) {
|
||||
xml.writeStartElement("sets");
|
||||
for (CardSetPtr set : _sets) {
|
||||
for (CardSetPtr set : sets) {
|
||||
xml << set;
|
||||
}
|
||||
xml.writeEndElement();
|
||||
@@ -459,4 +454,4 @@ bool CockatriceXml3Parser::saveToFile(SetNameMap _sets,
|
||||
xml.writeEndDocument();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
~CockatriceXml3Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap _sets,
|
||||
bool saveToFile(SetNameMap sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl = "unknown",
|
||||
|
||||
@@ -23,7 +23,7 @@ bool CockatriceXml4Parser::getCanParseFile(const QString &fileName, QIODevice &d
|
||||
QXmlStreamReader xml(&device);
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
if (xml.name().toString() == COCKATRICE_XML4_TAGNAME) {
|
||||
if (xml.name() == COCKATRICE_XML4_TAGNAME) {
|
||||
int version = xml.attributes().value("version").toString().toInt();
|
||||
if (version == COCKATRICE_XML4_TAGVER) {
|
||||
return true;
|
||||
@@ -52,13 +52,12 @@ void CockatriceXml4Parser::parseFile(QIODevice &device)
|
||||
break;
|
||||
}
|
||||
|
||||
auto xmlName = xml.name().toString();
|
||||
if (xmlName == "sets") {
|
||||
if (xml.name() == "sets") {
|
||||
loadSetsFromXml(xml);
|
||||
} else if (xmlName == "cards") {
|
||||
} else if (xml.name() == "cards") {
|
||||
loadCardsFromXml(xml);
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown item" << xmlName << ", trying to continue anyway";
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
@@ -73,27 +72,25 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
auto xmlName = xml.name().toString();
|
||||
if (xmlName == "set") {
|
||||
if (xml.name() == "set") {
|
||||
QString shortName, longName, setType;
|
||||
QDate releaseDate;
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
xmlName = xml.name().toString();
|
||||
|
||||
if (xmlName == "name") {
|
||||
if (xml.name() == "name") {
|
||||
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xmlName == "longname") {
|
||||
} else if (xml.name() == "longname") {
|
||||
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xmlName == "settype") {
|
||||
} else if (xml.name() == "settype") {
|
||||
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xmlName == "releasedate") {
|
||||
} else if (xml.name() == "releasedate") {
|
||||
releaseDate =
|
||||
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xmlName
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
@@ -112,9 +109,8 @@ QVariantHash CockatriceXml4Parser::loadCardPropertiesFromXml(QXmlStreamReader &x
|
||||
break;
|
||||
}
|
||||
|
||||
auto xmlName = xml.name().toString();
|
||||
if (!xmlName.isEmpty()) {
|
||||
properties.insert(xmlName, xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
if (xml.name() != "") {
|
||||
properties.insert(xml.name().toString(), xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
@@ -127,14 +123,12 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
auto xmlName = xml.name().toString();
|
||||
|
||||
if (xmlName == "card") {
|
||||
if (xml.name() == "card") {
|
||||
QString name = QString("");
|
||||
QString text = QString("");
|
||||
QVariantHash properties = QVariantHash();
|
||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||
auto _sets = CardInfoPerSetMap();
|
||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
||||
int tableRow = 0;
|
||||
bool cipt = false;
|
||||
bool isToken = false;
|
||||
@@ -144,28 +138,25 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
xmlName = xml.name().toString();
|
||||
|
||||
// variable - assigned properties
|
||||
if (xmlName == "name") {
|
||||
if (xml.name() == "name") {
|
||||
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xmlName == "text") {
|
||||
} else if (xml.name() == "text") {
|
||||
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xmlName == "token") {
|
||||
} else if (xml.name() == "token") {
|
||||
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
||||
// generic properties
|
||||
} else if (xmlName == "prop") {
|
||||
} else if (xml.name() == "prop") {
|
||||
properties = loadCardPropertiesFromXml(xml);
|
||||
// positioning info
|
||||
} else if (xmlName == "tablerow") {
|
||||
} else if (xml.name() == "tablerow") {
|
||||
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
||||
} else if (xmlName == "cipt") {
|
||||
} else if (xml.name() == "cipt") {
|
||||
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
} else if (xmlName == "upsidedown") {
|
||||
} else if (xml.name() == "upsidedown") {
|
||||
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
// sets
|
||||
} else if (xmlName == "set") {
|
||||
} else if (xml.name() == "set") {
|
||||
// NOTE: attributes but be read before readElementText()
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
@@ -178,14 +169,13 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
attrName = "picurl";
|
||||
setInfo.setProperty(attrName, attr.value().toString());
|
||||
}
|
||||
_sets.insert(setName, setInfo);
|
||||
sets.insert(setName, setInfo);
|
||||
}
|
||||
// related cards
|
||||
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||
CardRelation::AttachType attachType = CardRelation::DoesNotAttach;
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
bool attach = false;
|
||||
bool exclude = false;
|
||||
bool variable = false;
|
||||
bool persistent = false;
|
||||
int count = 1;
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString cardName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
@@ -205,33 +195,28 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("attach")) {
|
||||
attachType = attrs.value("attach").toString() == "transform" ? CardRelation::TransformInto
|
||||
: CardRelation::AttachTo;
|
||||
attach = true;
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("exclude")) {
|
||||
exclude = true;
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("persistent")) {
|
||||
persistent = true;
|
||||
}
|
||||
|
||||
auto *relation = new CardRelation(cardName, attachType, exclude, variable, count, persistent);
|
||||
if (xmlName == "reverse-related") {
|
||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||
if (xml.name() == "reverse-related") {
|
||||
reverseRelatedCards << relation;
|
||||
} else {
|
||||
relatedCards << relation;
|
||||
}
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown card property" << xmlName
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown card property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, _sets, cipt, tableRow, upsideDown);
|
||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
@@ -295,14 +280,12 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
for (auto i : related) {
|
||||
xml.writeStartElement("related");
|
||||
if (i->getDoesAttach()) {
|
||||
xml.writeAttribute("attach", i->getAttachTypeAsString());
|
||||
xml.writeAttribute("attach", "attach");
|
||||
}
|
||||
if (i->getIsCreateAllExclusion()) {
|
||||
xml.writeAttribute("exclude", "exclude");
|
||||
}
|
||||
if (i->getIsPersistent()) {
|
||||
xml.writeAttribute("persistent", "persistent");
|
||||
}
|
||||
|
||||
if (i->getIsVariable()) {
|
||||
if (1 == i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", "x");
|
||||
@@ -319,16 +302,13 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
for (auto i : reverseRelated) {
|
||||
xml.writeStartElement("reverse-related");
|
||||
if (i->getDoesAttach()) {
|
||||
xml.writeAttribute("attach", i->getAttachTypeAsString());
|
||||
xml.writeAttribute("attach", "attach");
|
||||
}
|
||||
|
||||
if (i->getIsCreateAllExclusion()) {
|
||||
xml.writeAttribute("exclude", "exclude");
|
||||
}
|
||||
|
||||
if (i->getIsPersistent()) {
|
||||
xml.writeAttribute("persistent", "persistent");
|
||||
}
|
||||
if (i->getIsVariable()) {
|
||||
if (1 == i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", "x");
|
||||
@@ -356,7 +336,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool CockatriceXml4Parser::saveToFile(SetNameMap _sets,
|
||||
bool CockatriceXml4Parser::saveToFile(SetNameMap sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl,
|
||||
@@ -383,9 +363,9 @@ bool CockatriceXml4Parser::saveToFile(SetNameMap _sets,
|
||||
xml.writeTextElement("sourceVersion", sourceVersion);
|
||||
xml.writeEndElement();
|
||||
|
||||
if (_sets.count() > 0) {
|
||||
if (sets.count() > 0) {
|
||||
xml.writeStartElement("sets");
|
||||
for (CardSetPtr set : _sets) {
|
||||
for (CardSetPtr set : sets) {
|
||||
xml << set;
|
||||
}
|
||||
xml.writeEndElement();
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
~CockatriceXml4Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap _sets,
|
||||
bool saveToFile(SetNameMap sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl = "unknown",
|
||||
|
||||
@@ -24,7 +24,7 @@ void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
AbstractCardDragItem::paint(painter, option, widget);
|
||||
|
||||
if (occupied)
|
||||
painter->fillPath(shape(), QColor(200, 0, 0, 100));
|
||||
painter->fillRect(boundingRect(), QColor(200, 0, 0, 100));
|
||||
}
|
||||
|
||||
void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
||||
@@ -53,20 +53,8 @@ void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
||||
|
||||
QPointF zonePos = currentZone->scenePos();
|
||||
QPointF cursorPosInZone = cursorScenePos - zonePos;
|
||||
|
||||
// If we are on a Table, we center the card around the cursor, because we
|
||||
// snap it into place and no longer see it being dragged.
|
||||
//
|
||||
// For other zones (where we do display the card under the cursor), we use
|
||||
// the hotspot to feel like the card was dragged at the corresponding
|
||||
// position.
|
||||
TableZone *tableZone = qobject_cast<TableZone *>(cursorZone);
|
||||
QPointF closestGridPoint;
|
||||
if (tableZone)
|
||||
closestGridPoint = tableZone->closestGridPoint(cursorPosInZone);
|
||||
else
|
||||
closestGridPoint = cursorPosInZone - hotSpot;
|
||||
|
||||
QPointF cardTopLeft = cursorPosInZone - hotSpot;
|
||||
QPointF closestGridPoint = cursorZone->closestGridPoint(cardTopLeft);
|
||||
QPointF newPos = zonePos + closestGridPoint;
|
||||
|
||||
if (newPos != pos()) {
|
||||
@@ -95,7 +83,7 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
QList<CardDragItem *> dragItemList;
|
||||
CardZone *startZone = static_cast<CardItem *>(item)->getZone();
|
||||
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone)) && !occupied) {
|
||||
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone))) {
|
||||
dragItemList.append(this);
|
||||
for (int i = 0; i < childDrags.size(); i++) {
|
||||
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
#include "main.h"
|
||||
#include "pictureloader.h"
|
||||
|
||||
#include <QStylePainter>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QWidget>
|
||||
|
||||
CardInfoPicture::CardInfoPicture(QWidget *parent) : QWidget(parent), info(nullptr), pixmapDirty(true)
|
||||
@@ -54,13 +55,6 @@ void CardInfoPicture::paintEvent(QPaintEvent *)
|
||||
if (pixmapDirty)
|
||||
loadPixmap();
|
||||
|
||||
QSize scaledSize = resizedPixmap.size().scaled(size(), Qt::KeepAspectRatio);
|
||||
QPoint topLeft{(width() - scaledSize.width()) / 2, (height() - scaledSize.height()) / 2};
|
||||
qreal radius = 0.05 * scaledSize.width();
|
||||
|
||||
QStylePainter painter(this);
|
||||
QPainterPath shape;
|
||||
shape.addRoundedRect(QRect(topLeft, scaledSize), radius, radius);
|
||||
painter.setClipPath(shape);
|
||||
painter.drawItemPixmap(QRect(topLeft, scaledSize), Qt::AlignCenter, resizedPixmap);
|
||||
QPainter painter(this);
|
||||
style()->drawItemPixmap(&painter, rect(), Qt::AlignHCenter, resizedPixmap);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,13 @@
|
||||
#include "main.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
#include <QVBoxLayout>
|
||||
#include <utility>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||
#include <QScreen>
|
||||
#else
|
||||
#include <QDesktopWidget>
|
||||
#endif
|
||||
#include <QVBoxLayout>
|
||||
|
||||
CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::WindowFlags flags)
|
||||
: QFrame(parent, flags), aspectRatio((qreal)CARD_HEIGHT / (qreal)CARD_WIDTH), info(nullptr)
|
||||
@@ -30,7 +34,12 @@ CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::Win
|
||||
|
||||
setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||
|
||||
int pixmapHeight = QGuiApplication::primaryScreen()->geometry().height() / 3;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||
int pixmapHeight = qApp->primaryScreen()->geometry().height() / 3;
|
||||
#else
|
||||
QDesktopWidget desktopWidget;
|
||||
int pixmapHeight = desktopWidget.screenGeometry().height() / 3;
|
||||
#endif
|
||||
int pixmapWidth = static_cast<int>(pixmapHeight / aspectRatio);
|
||||
pic->setFixedWidth(pixmapWidth);
|
||||
pic->setFixedHeight(pixmapHeight);
|
||||
|
||||
@@ -97,10 +97,10 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QMapIterator<int, int> counterIterator(counters);
|
||||
while (counterIterator.hasNext()) {
|
||||
counterIterator.next();
|
||||
QColor _color;
|
||||
_color.setHsv(counterIterator.key() * 60, 150, 255);
|
||||
QColor color;
|
||||
color.setHsv(counterIterator.key() * 60, 150, 255);
|
||||
|
||||
paintNumberEllipse(counterIterator.value(), 14, _color, i, counters.size(), painter);
|
||||
paintNumberEllipse(counterIterator.value(), 14, color, i, counters.size(), painter);
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -141,19 +141,21 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
}
|
||||
|
||||
if (getBeingPointedAt()) {
|
||||
painter->fillPath(shape(), QBrush(QColor(255, 0, 0, 100)));
|
||||
painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100)));
|
||||
}
|
||||
|
||||
if (doesntUntap) {
|
||||
painter->save();
|
||||
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
transformPainter(painter, translatedSize, tapAngle);
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(Qt::magenta);
|
||||
pen.setWidth(0); // Cosmetic pen
|
||||
const int penWidth = 1;
|
||||
pen.setWidth(penWidth);
|
||||
painter->setPen(pen);
|
||||
painter->drawPath(shape());
|
||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
@@ -233,25 +235,25 @@ void CardItem::resetState()
|
||||
update();
|
||||
}
|
||||
|
||||
void CardItem::processCardInfo(const ServerInfo_Card &_info)
|
||||
void CardItem::processCardInfo(const ServerInfo_Card &info)
|
||||
{
|
||||
counters.clear();
|
||||
const int counterListSize = _info.counter_list_size();
|
||||
const int counterListSize = info.counter_list_size();
|
||||
for (int i = 0; i < counterListSize; ++i) {
|
||||
const ServerInfo_CardCounter &counterInfo = _info.counter_list(i);
|
||||
const ServerInfo_CardCounter &counterInfo = info.counter_list(i);
|
||||
counters.insert(counterInfo.id(), counterInfo.value());
|
||||
}
|
||||
|
||||
setId(_info.id());
|
||||
setName(QString::fromStdString(_info.name()));
|
||||
setAttacking(_info.attacking());
|
||||
setFaceDown(_info.face_down());
|
||||
setPT(QString::fromStdString(_info.pt()));
|
||||
setAnnotation(QString::fromStdString(_info.annotation()));
|
||||
setColor(QString::fromStdString(_info.color()));
|
||||
setTapped(_info.tapped());
|
||||
setDestroyOnZoneChange(_info.destroy_on_zone_change());
|
||||
setDoesntUntap(_info.doesnt_untap());
|
||||
setId(info.id());
|
||||
setName(QString::fromStdString(info.name()));
|
||||
setAttacking(info.attacking());
|
||||
setFaceDown(info.face_down());
|
||||
setPT(QString::fromStdString(info.pt()));
|
||||
setAnnotation(QString::fromStdString(info.annotation()));
|
||||
setColor(QString::fromStdString(info.color()));
|
||||
setTapped(info.tapped());
|
||||
setDestroyOnZoneChange(info.destroy_on_zone_change());
|
||||
setDoesntUntap(info.doesnt_untap());
|
||||
}
|
||||
|
||||
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown)
|
||||
@@ -284,36 +286,15 @@ void CardItem::drawArrow(const QColor &arrowColor)
|
||||
scene()->addItem(arrow);
|
||||
arrow->grabMouse();
|
||||
|
||||
for (const auto &item : scene()->selectedItems()) {
|
||||
CardItem *card = qgraphicsitem_cast<CardItem *>(item);
|
||||
if (card == nullptr || card == this)
|
||||
QListIterator<QGraphicsItem *> itemIterator(scene()->selectedItems());
|
||||
while (itemIterator.hasNext()) {
|
||||
CardItem *c = qgraphicsitem_cast<CardItem *>(itemIterator.next());
|
||||
if (!c || (c == this))
|
||||
continue;
|
||||
if (card->getZone() != zone)
|
||||
if (c->getZone() != zone)
|
||||
continue;
|
||||
|
||||
ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, card, arrowColor);
|
||||
scene()->addItem(childArrow);
|
||||
arrow->addChildArrow(childArrow);
|
||||
}
|
||||
}
|
||||
|
||||
void CardItem::drawAttachArrow()
|
||||
{
|
||||
if (static_cast<TabGame *>(owner->parent())->getSpectator())
|
||||
return;
|
||||
|
||||
auto *arrow = new ArrowAttachItem(this);
|
||||
scene()->addItem(arrow);
|
||||
arrow->grabMouse();
|
||||
|
||||
for (const auto &item : scene()->selectedItems()) {
|
||||
CardItem *card = qgraphicsitem_cast<CardItem *>(item);
|
||||
if (card == nullptr)
|
||||
continue;
|
||||
if (card->getZone() != zone)
|
||||
continue;
|
||||
|
||||
ArrowAttachItem *childArrow = new ArrowAttachItem(card);
|
||||
ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor);
|
||||
scene()->addItem(childArrow);
|
||||
arrow->addChildArrow(childArrow);
|
||||
}
|
||||
@@ -348,24 +329,22 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier);
|
||||
|
||||
// Use the buttonDownPos to align the hot spot with the position when
|
||||
// the user originally clicked
|
||||
createDragItem(id, event->buttonDownPos(Qt::LeftButton), event->scenePos(), facedown || forceFaceDown);
|
||||
createDragItem(id, event->pos(), event->scenePos(), facedown || forceFaceDown);
|
||||
dragItem->grabMouse();
|
||||
|
||||
int childIndex = 0;
|
||||
for (const auto &item : scene()->selectedItems()) {
|
||||
CardItem *card = static_cast<CardItem *>(item);
|
||||
if ((card == this) || (card->getZone() != zone))
|
||||
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
||||
int j = 0;
|
||||
for (int i = 0; i < sel.size(); i++) {
|
||||
CardItem *c = static_cast<CardItem *>(sel.at(i));
|
||||
if ((c == this) || (c->getZone() != zone))
|
||||
continue;
|
||||
++childIndex;
|
||||
++j;
|
||||
QPointF childPos;
|
||||
if (zone->getHasCardAttr())
|
||||
childPos = card->pos() - pos();
|
||||
childPos = c->pos() - pos();
|
||||
else
|
||||
childPos = QPointF(childIndex * CARD_WIDTH / 2, 0);
|
||||
CardDragItem *drag =
|
||||
new CardDragItem(card, card->getId(), childPos, card->getFaceDown() || forceFaceDown, dragItem);
|
||||
childPos = QPointF(j * CARD_WIDTH / 2, 0);
|
||||
CardDragItem *drag = new CardDragItem(c, c->getId(), childPos, c->getFaceDown() || forceFaceDown, dragItem);
|
||||
drag->setPos(dragItem->pos() + childPos);
|
||||
scene()->addItem(drag);
|
||||
}
|
||||
@@ -390,8 +369,7 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
if (cardMenu != nullptr && !cardMenu->isEmpty() && owner != nullptr) {
|
||||
cardMenu->popup(event->screenPos());
|
||||
return;
|
||||
cardMenu->exec(event->screenPos());
|
||||
}
|
||||
} else if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) &&
|
||||
(!SettingsCache::instance().getDoubleClickToPlay())) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define CARDITEM_H
|
||||
|
||||
#include "abstractcarditem.h"
|
||||
#include "server_card.h"
|
||||
|
||||
class CardDatabase;
|
||||
class CardDragItem;
|
||||
@@ -131,14 +130,14 @@ public:
|
||||
}
|
||||
void removeAttachedCard(CardItem *card)
|
||||
{
|
||||
attachedCards.removeOne(card);
|
||||
attachedCards.removeAt(attachedCards.indexOf(card));
|
||||
}
|
||||
const QList<CardItem *> &getAttachedCards() const
|
||||
{
|
||||
return attachedCards;
|
||||
}
|
||||
void resetState();
|
||||
void processCardInfo(const ServerInfo_Card &_info);
|
||||
void processCardInfo(const ServerInfo_Card &info);
|
||||
|
||||
QMenu *getCardMenu() const
|
||||
{
|
||||
@@ -157,7 +156,6 @@ public:
|
||||
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown);
|
||||
void deleteDragItem();
|
||||
void drawArrow(const QColor &arrowColor);
|
||||
void drawAttachArrow();
|
||||
void playCard(bool faceDown);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -187,7 +187,7 @@ CardItem *CardZone::takeCard(int position, int cardId, bool /*canResize*/)
|
||||
|
||||
void CardZone::removeCard(CardItem *card)
|
||||
{
|
||||
cards.removeOne(card);
|
||||
cards.removeAt(cards.indexOf(card));
|
||||
reorganizeCards();
|
||||
emit cardCountChanged();
|
||||
player->deleteCard(card);
|
||||
|
||||
@@ -21,7 +21,7 @@ UserMessagePosition::UserMessagePosition(QTextCursor &cursor)
|
||||
relativePosition = cursor.position() - block.position();
|
||||
}
|
||||
|
||||
ChatView::ChatView(TabSupervisor *_tabSupervisor,
|
||||
ChatView::ChatView(const TabSupervisor *_tabSupervisor,
|
||||
const UserlistProxy *_userlistProxy,
|
||||
TabGame *_game,
|
||||
bool _showTimestamps,
|
||||
@@ -321,7 +321,7 @@ void ChatView::checkTag(QTextCursor &cursor, QString &message)
|
||||
|
||||
void ChatView::checkMention(QTextCursor &cursor, QString &message, const QString &userName, UserLevelFlags userLevel)
|
||||
{
|
||||
const static auto notALetterOrNumber = QRegularExpression("[^a-zA-Z0-9]");
|
||||
const QRegExp notALetterOrNumber = QRegExp("[^a-zA-Z0-9]");
|
||||
|
||||
int firstSpace = message.indexOf(' ');
|
||||
QString fullMentionUpToSpaceOrEnd = (firstSpace == -1) ? message.mid(1) : message.mid(1, firstSpace - 1);
|
||||
@@ -470,23 +470,15 @@ void ChatView::showSystemPopup(const QString &userName)
|
||||
|
||||
QColor ChatView::getCustomMentionColor()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#else
|
||||
QColor customColor;
|
||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#endif
|
||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||
}
|
||||
|
||||
QColor ChatView::getCustomHighlightColor()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#else
|
||||
QColor customColor;
|
||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#endif
|
||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatHighlightColor());
|
||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||
}
|
||||
|
||||
@@ -518,11 +510,7 @@ void ChatView::redactMessages(const QString &userName, int amount)
|
||||
}
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void ChatView::enterEvent(QEnterEvent * /*event*/)
|
||||
#else
|
||||
void ChatView::enterEvent(QEvent * /*event*/)
|
||||
#endif
|
||||
{
|
||||
setMouseTracking(true);
|
||||
}
|
||||
@@ -578,11 +566,7 @@ void ChatView::mousePressEvent(QMouseEvent *event)
|
||||
switch (hoveredItemType) {
|
||||
case HoveredCard: {
|
||||
if ((event->button() == Qt::MiddleButton) || (event->button() == Qt::LeftButton))
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
emit showCardInfoPopup(event->globalPosition().toPoint(), hoveredContent);
|
||||
#else
|
||||
emit showCardInfoPopup(event->globalPos(), hoveredContent);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case HoveredUser: {
|
||||
@@ -592,11 +576,7 @@ void ChatView::mousePressEvent(QMouseEvent *event)
|
||||
switch (event->button()) {
|
||||
case Qt::RightButton: {
|
||||
UserLevelFlags userLevel(hoveredContent.left(delimiterIndex).toInt());
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
userContextMenu->showContextMenu(event->globalPosition().toPoint(), userName, userLevel, this);
|
||||
#else
|
||||
userContextMenu->showContextMenu(event->globalPos(), userName, userLevel, this);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case Qt::LeftButton: {
|
||||
|
||||
@@ -33,7 +33,7 @@ class ChatView : public QTextBrowser
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
TabSupervisor *const tabSupervisor;
|
||||
const TabSupervisor *const tabSupervisor;
|
||||
TabGame *const game;
|
||||
|
||||
private:
|
||||
@@ -65,8 +65,8 @@ private:
|
||||
QTextCursor prepareBlock(bool same = false);
|
||||
void appendCardTag(QTextCursor &cursor, const QString &cardName);
|
||||
void appendUrlTag(QTextCursor &cursor, QString url);
|
||||
static QColor getCustomMentionColor();
|
||||
static QColor getCustomHighlightColor();
|
||||
QColor getCustomMentionColor();
|
||||
QColor getCustomHighlightColor();
|
||||
void showSystemPopup(const QString &userName);
|
||||
bool isModeratorSendingGlobal(QFlags<ServerInfo_User::UserLevelFlag> userLevelFlag, QString message);
|
||||
void checkTag(QTextCursor &cursor, QString &message);
|
||||
@@ -83,7 +83,7 @@ private slots:
|
||||
void actMessageClicked();
|
||||
|
||||
public:
|
||||
ChatView(TabSupervisor *_tabSupervisor,
|
||||
ChatView(const TabSupervisor *_tabSupervisor,
|
||||
const UserlistProxy *_userlistProxy,
|
||||
TabGame *_game,
|
||||
bool _showTimestamps,
|
||||
@@ -103,11 +103,7 @@ public:
|
||||
void redactMessages(const QString &userName, int amount);
|
||||
|
||||
protected:
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void enterEvent(QEnterEvent *event);
|
||||
#else
|
||||
void enterEvent(QEvent *event);
|
||||
#endif
|
||||
void leaveEvent(QEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
29
cockatrice/src/client_metatypes.h
Normal file
29
cockatrice/src/client_metatypes.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef CLIENT_METATYPES_H
|
||||
#define CLIENT_METATYPES_H
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
Q_DECLARE_METATYPE(QVariant)
|
||||
Q_DECLARE_METATYPE(CommandContainer)
|
||||
Q_DECLARE_METATYPE(Response)
|
||||
Q_DECLARE_METATYPE(Response::ResponseCode)
|
||||
Q_DECLARE_METATYPE(ClientStatus)
|
||||
Q_DECLARE_METATYPE(RoomEvent)
|
||||
Q_DECLARE_METATYPE(GameEventContainer)
|
||||
Q_DECLARE_METATYPE(Event_ServerIdentification)
|
||||
Q_DECLARE_METATYPE(Event_ConnectionClosed)
|
||||
Q_DECLARE_METATYPE(Event_ServerShutdown)
|
||||
Q_DECLARE_METATYPE(Event_AddToList)
|
||||
Q_DECLARE_METATYPE(Event_RemoveFromList)
|
||||
Q_DECLARE_METATYPE(Event_UserJoined)
|
||||
Q_DECLARE_METATYPE(Event_UserLeft)
|
||||
Q_DECLARE_METATYPE(Event_ServerMessage)
|
||||
Q_DECLARE_METATYPE(Event_ListRooms)
|
||||
Q_DECLARE_METATYPE(Event_GameJoined)
|
||||
Q_DECLARE_METATYPE(Event_UserMessage)
|
||||
Q_DECLARE_METATYPE(ServerInfo_User)
|
||||
Q_DECLARE_METATYPE(QList<ServerInfo_User>)
|
||||
Q_DECLARE_METATYPE(Event_ReplayAdded)
|
||||
Q_DECLARE_METATYPE(QList<QString>)
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
|
||||
const QStringList DeckLoader::fileNameFilters = QStringList()
|
||||
@@ -209,7 +208,7 @@ void DeckLoader::saveToStream_DeckHeader(QTextStream &out)
|
||||
}
|
||||
|
||||
if (!getComments().isEmpty()) {
|
||||
QStringList commentRows = getComments().split(QRegularExpression("\n|\r\n|\r"));
|
||||
QStringList commentRows = getComments().split(QRegExp("\n|\r\n|\r"));
|
||||
foreach (QString row, commentRows) {
|
||||
out << "// " << row << "\n";
|
||||
}
|
||||
@@ -289,7 +288,7 @@ QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneNam
|
||||
return currentZoneName;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCompleteCardName(const QString &cardName) const
|
||||
QString DeckLoader::getCompleteCardName(const QString cardName) const
|
||||
{
|
||||
if (db) {
|
||||
CardInfoPtr temp = db->guessCard(cardName);
|
||||
|
||||
@@ -57,8 +57,8 @@ protected:
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments = true);
|
||||
[[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override;
|
||||
[[nodiscard]] QString getCompleteCardName(const QString &cardName) const override;
|
||||
virtual QString getCardZoneFromName(QString cardName, QString currentZoneName);
|
||||
virtual QString getCompleteCardName(const QString cardName) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegExp>
|
||||
#include <QUrlQuery>
|
||||
|
||||
DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent)
|
||||
@@ -20,7 +20,7 @@ DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *par
|
||||
void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
||||
{
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
QMessageBox::critical(nullptr, tr("Error"), reply->errorString());
|
||||
QMessageBox::critical(0, tr("Error"), reply->errorString());
|
||||
reply->deleteLater();
|
||||
deleteLater();
|
||||
return;
|
||||
@@ -29,15 +29,14 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
||||
QString data(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
||||
static const QRegularExpression rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
|
||||
auto match = rx.match(data);
|
||||
if (!match.hasMatch()) {
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("The reply from the server could not be parsed."));
|
||||
QRegExp rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
|
||||
if (-1 == rx.indexIn(data)) {
|
||||
QMessageBox::critical(0, tr("Error"), tr("The reply from the server could not be parsed."));
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QString deckUrl = match.captured(1);
|
||||
QString deckUrl = rx.cap(1);
|
||||
QDesktopServices::openUrl(deckUrl);
|
||||
|
||||
deleteLater();
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <QApplication>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QtMath>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item,
|
||||
const QPointF &_hotSpot,
|
||||
@@ -89,8 +89,7 @@ void DeckViewCard::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
||||
painter->setPen(pen);
|
||||
qreal cardRadius = 0.05 * (CARD_WIDTH - 3);
|
||||
painter->drawRoundedRect(QRectF(1.5, 1.5, CARD_WIDTH - 3., CARD_HEIGHT - 3.), cardRadius, cardRadius);
|
||||
painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 2.5));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
@@ -217,7 +216,7 @@ void DeckViewCardContainer::addCard(DeckViewCard *card)
|
||||
|
||||
void DeckViewCardContainer::removeCard(DeckViewCard *card)
|
||||
{
|
||||
cards.removeOne(card);
|
||||
cards.removeAt(cards.indexOf(card));
|
||||
cardsByType.remove(card->getInfo() ? card->getInfo()->getMainCardType() : "", card);
|
||||
}
|
||||
|
||||
@@ -239,9 +238,11 @@ int DeckViewCardContainer::getCardTypeTextWidth() const
|
||||
QFontMetrics fm(f);
|
||||
|
||||
int maxCardTypeWidth = 0;
|
||||
for (const auto &key : cardsByType.keys()) {
|
||||
int cardTypeWidth = fm.size(Qt::TextSingleLine, key).width();
|
||||
maxCardTypeWidth = qMax(maxCardTypeWidth, cardTypeWidth);
|
||||
QMapIterator<QString, DeckViewCard *> i(cardsByType);
|
||||
while (i.hasNext()) {
|
||||
int cardTypeWidth = fm.size(Qt::TextSingleLine, i.next().key()).width();
|
||||
if (cardTypeWidth > maxCardTypeWidth)
|
||||
maxCardTypeWidth = cardTypeWidth;
|
||||
}
|
||||
|
||||
return maxCardTypeWidth + 15;
|
||||
@@ -273,11 +274,16 @@ void DeckViewCardContainer::rearrangeItems(const QList<QPair<int, int>> &rowsAnd
|
||||
{
|
||||
currentRowsAndCols = rowsAndCols;
|
||||
|
||||
int totalCols = 0, totalRows = 0;
|
||||
qreal yUntilNow = separatorY + paddingY;
|
||||
qreal x = (qreal)getCardTypeTextWidth();
|
||||
for (int i = 0; i < rowsAndCols.size(); ++i) {
|
||||
const int tempRows = rowsAndCols[i].first;
|
||||
const int tempCols = rowsAndCols[i].second;
|
||||
totalRows += tempRows;
|
||||
if (tempCols > totalCols)
|
||||
totalCols = tempCols;
|
||||
|
||||
QList<QString> cardTypeList = cardsByType.uniqueKeys();
|
||||
QList<DeckViewCard *> row = cardsByType.values(cardTypeList[i]);
|
||||
std::sort(row.begin(), row.end(), DeckViewCardContainer::sortCardsByName);
|
||||
@@ -434,7 +440,7 @@ void DeckViewScene::rearrangeItems()
|
||||
const int maxRows = rowsAndColsList[maxIndex1][maxIndex2].first;
|
||||
const int maxCardCount = cardCountList[maxIndex1][maxIndex2];
|
||||
rowsAndColsList[maxIndex1][maxIndex2] =
|
||||
QPair<int, int>(maxRows + 1, (int)qCeil((qreal)maxCardCount / (qreal)(maxRows + 1)));
|
||||
QPair<int, int>(maxRows + 1, (int)ceil((qreal)maxCardCount / (qreal)(maxRows + 1)));
|
||||
}
|
||||
|
||||
totalHeight = -spacing;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "dlg_connect.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
#include "userconnection_information.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
@@ -162,7 +162,8 @@ DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
||||
|
||||
previousHostButton->setChecked(true);
|
||||
|
||||
connect(previousHosts, SIGNAL(currentTextChanged(const QString &)), this, SLOT(updateDisplayInfo(const QString &)));
|
||||
connect(previousHosts, SIGNAL(currentIndexChanged(const QString &)), this,
|
||||
SLOT(updateDisplayInfo(const QString &)));
|
||||
|
||||
playernameEdit->setFocus();
|
||||
}
|
||||
@@ -245,22 +246,22 @@ void DlgConnect::updateDisplayInfo(const QString &saveName)
|
||||
}
|
||||
|
||||
UserConnection_Information uci;
|
||||
QStringList _data = uci.getServerInfo(saveName);
|
||||
QStringList data = uci.getServerInfo(saveName);
|
||||
|
||||
bool savePasswordStatus = (_data.at(5) == "1");
|
||||
bool savePasswordStatus = (data.at(5) == "1");
|
||||
|
||||
saveEdit->setText(_data.at(0));
|
||||
hostEdit->setText(_data.at(1));
|
||||
portEdit->setText(_data.at(2));
|
||||
playernameEdit->setText(_data.at(3));
|
||||
saveEdit->setText(data.at(0));
|
||||
hostEdit->setText(data.at(1));
|
||||
portEdit->setText(data.at(2));
|
||||
playernameEdit->setText(data.at(3));
|
||||
savePasswordCheckBox->setChecked(savePasswordStatus);
|
||||
|
||||
if (savePasswordStatus) {
|
||||
passwordEdit->setText(_data.at(4));
|
||||
passwordEdit->setText(data.at(4));
|
||||
}
|
||||
|
||||
if (!_data.at(6).isEmpty()) {
|
||||
QString formattedLink = "<a href=\"" + _data.at(6) + "\">" + _data.at(6) + "</a>";
|
||||
if (!data.at(6).isEmpty()) {
|
||||
QString formattedLink = "<a href=\"" + data.at(6) + "\">" + data.at(6) + "</a>";
|
||||
serverContactLabel->setText(tr("Webpage") + ":");
|
||||
serverContactLink->setText(formattedLink);
|
||||
} else {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "decklist.h"
|
||||
#include "main.h"
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QCloseEvent>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "pb/serverinfo_game.pb.h"
|
||||
#include "pending_command.h"
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
#include "tab_room.h"
|
||||
#include "trice_limits.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
@@ -235,13 +235,13 @@ void DlgCreateGame::actOK()
|
||||
cmd.set_join_as_judge(QApplication::keyboardModifiers() & Qt::ShiftModifier);
|
||||
cmd.set_join_as_spectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
|
||||
QString _gameTypes = QString();
|
||||
QString gameTypes = QString();
|
||||
QMapIterator<int, QRadioButton *> gameTypeCheckBoxIterator(gameTypeCheckBoxes);
|
||||
while (gameTypeCheckBoxIterator.hasNext()) {
|
||||
gameTypeCheckBoxIterator.next();
|
||||
if (gameTypeCheckBoxIterator.value()->isChecked()) {
|
||||
cmd.add_game_type_ids(gameTypeCheckBoxIterator.key());
|
||||
_gameTypes += gameTypeCheckBoxIterator.value()->text() + ", ";
|
||||
gameTypes += gameTypeCheckBoxIterator.value()->text() + ", ";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ void DlgCreateGame::actOK()
|
||||
SettingsCache::instance().setSpectatorsCanTalk(spectatorsCanTalkCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsCanSeeEverything(spectatorsSeeEverythingCheckBox->isChecked());
|
||||
SettingsCache::instance().setCreateGameAsSpectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
SettingsCache::instance().setGameTypes(_gameTypes);
|
||||
SettingsCache::instance().setGameTypes(gameTypes);
|
||||
}
|
||||
PendingCommand *pend = room->prepareRoomCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response)));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "dlg_edit_avatar.h"
|
||||
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
@@ -74,12 +74,13 @@ QByteArray DlgEditAvatar::getImage()
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
for (;;) {
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image.save(&buffer, "JPG");
|
||||
if (ba.length() > MAX_FILE_LENGTH) {
|
||||
ba.clear();
|
||||
image = image.scaledToWidth(image.width() / 2); // divide the amount of pixels in four to get the size down
|
||||
} else {
|
||||
return ba;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "dlg_edit_password.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "carddatabasemodel.h"
|
||||
#include "gettextwithmax.h"
|
||||
#include "main.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QComboBox>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "dlg_edit_user.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "dlg_forgotpasswordchallenge.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "dlg_forgotpasswordrequest.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "dlg_forgotpasswordreset.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "main.h"
|
||||
#include "pictureloader.h"
|
||||
#include "setsmodel.h"
|
||||
#include "settingscache.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
@@ -85,6 +84,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
displayModel->setDynamicSortFilter(false);
|
||||
view = new QTreeView;
|
||||
view->setModel(displayModel);
|
||||
view->setMinimumSize(QSize(500, 250));
|
||||
|
||||
view->setAlternatingRowColors(true);
|
||||
view->setUniformRowHeights(true);
|
||||
@@ -98,6 +98,10 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
view->setDropIndicatorShown(true);
|
||||
view->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
|
||||
view->header()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
view->header()->setSectionResizeMode(SetsModel::EnabledCol, QHeaderView::ResizeToContents);
|
||||
view->header()->setSectionResizeMode(SetsModel::LongNameCol, QHeaderView::ResizeToContents);
|
||||
|
||||
view->sortByColumn(SetsModel::SortKeyCol, Qt::AscendingOrder);
|
||||
view->setColumnHidden(SetsModel::SortKeyCol, true);
|
||||
view->setColumnHidden(SetsModel::IsKnownCol, true);
|
||||
@@ -117,12 +121,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
connect(disableSomeButton, SIGNAL(clicked()), this, SLOT(actDisableSome()));
|
||||
connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this,
|
||||
SLOT(actToggleButtons(const QItemSelection &, const QItemSelection &)));
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
connect(searchField, SIGNAL(textChanged(const QString &)), displayModel,
|
||||
SLOT(setFilterRegularExpression(const QString &)));
|
||||
#else
|
||||
connect(searchField, SIGNAL(textChanged(const QString &)), displayModel, SLOT(setFilterRegExp(const QString &)));
|
||||
#endif
|
||||
connect(view->header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(actDisableSortButtons(int)));
|
||||
connect(searchField, SIGNAL(textChanged(const QString &)), this, SLOT(actDisableResetButton(const QString &)));
|
||||
|
||||
@@ -140,6 +139,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
tr("How to use custom card art") + "</a>"));
|
||||
|
||||
QGridLayout *hintsGrid = new QGridLayout;
|
||||
hintsGrid->setMargin(2);
|
||||
hintsGrid->addWidget(labNotes, 0, 0);
|
||||
hintsGroupBox = new QGroupBox(tr("Hints"));
|
||||
hintsGroupBox->setLayout(hintsGrid);
|
||||
@@ -166,7 +166,7 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
|
||||
mainLayout = new QGridLayout;
|
||||
mainLayout->addLayout(filterBox, 0, 1, 1, 2);
|
||||
mainLayout->addWidget(setsEditToolBar, 1, 0, 4, 1);
|
||||
mainLayout->addWidget(setsEditToolBar, 1, 0, 2, 1);
|
||||
mainLayout->addWidget(view, 1, 1, 1, 2);
|
||||
mainLayout->addWidget(enableAllButton, 2, 1);
|
||||
mainLayout->addWidget(disableAllButton, 2, 2);
|
||||
@@ -186,35 +186,13 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
setWindowTitle(tr("Manage sets"));
|
||||
setMinimumSize(800, 500);
|
||||
auto &geometry = SettingsCache::instance().getSetsDialogGeometry();
|
||||
if (!geometry.isEmpty()) {
|
||||
restoreGeometry(geometry);
|
||||
}
|
||||
auto &headerState = SettingsCache::instance().layouts().getSetsDialogHeaderState();
|
||||
if (!headerState.isEmpty()) {
|
||||
view->header()->restoreState(headerState);
|
||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
||||
} else {
|
||||
view->header()->resizeSections(QHeaderView::ResizeToContents);
|
||||
}
|
||||
connect(view->header(), &QHeaderView::geometriesChanged, this, &WndSets::saveHeaderState);
|
||||
resize(800, 500);
|
||||
}
|
||||
|
||||
WndSets::~WndSets()
|
||||
{
|
||||
}
|
||||
|
||||
void WndSets::closeEvent(QCloseEvent * /*ev*/)
|
||||
{
|
||||
SettingsCache::instance().setSetsDialogGeometry(saveGeometry());
|
||||
}
|
||||
|
||||
void WndSets::saveHeaderState()
|
||||
{
|
||||
SettingsCache::instance().layouts().setSetsDialogHeaderState(view->header()->saveState());
|
||||
}
|
||||
|
||||
void WndSets::rebuildMainLayout(int actionToTake)
|
||||
{
|
||||
if (mainLayout == nullptr)
|
||||
|
||||
@@ -40,8 +40,6 @@ private:
|
||||
QHBoxLayout *filterBox;
|
||||
int sortIndex;
|
||||
Qt::SortOrder sortOrder;
|
||||
void closeEvent(QCloseEvent *ev) override;
|
||||
void saveHeaderState();
|
||||
void rebuildMainLayout(int actionToTake);
|
||||
bool setOrderIsSorted;
|
||||
enum
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "settingscache.h"
|
||||
#include "trice_limits.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
@@ -129,7 +129,6 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
countryEdit->addItem(QPixmap("theme:countries/er"), "er");
|
||||
countryEdit->addItem(QPixmap("theme:countries/es"), "es");
|
||||
countryEdit->addItem(QPixmap("theme:countries/et"), "et");
|
||||
countryEdit->addItem(QPixmap("theme:countries/eu"), "eu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fi"), "fi");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fj"), "fj");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fk"), "fk");
|
||||
@@ -305,7 +304,6 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
countryEdit->addItem(QPixmap("theme:countries/vu"), "vu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/wf"), "wf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ws"), "ws");
|
||||
countryEdit->addItem(QPixmap("theme:countries/xk"), "xk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ye"), "ye");
|
||||
countryEdit->addItem(QPixmap("theme:countries/yt"), "yt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/za"), "za");
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#include "dlg_roll_dice.h"
|
||||
|
||||
#include "trice_limits.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
DlgRollDice::DlgRollDice(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
numberOfSidesLabel = new QLabel(tr("Number of sides:"));
|
||||
numberOfSidesEdit = new QSpinBox(this);
|
||||
numberOfSidesEdit->setValue(DEFAULT_NUMBER_SIDES_DIE);
|
||||
numberOfSidesEdit->setRange(MINIMUM_DIE_SIDES, MAXIMUM_DIE_SIDES);
|
||||
numberOfSidesEdit->setFocus();
|
||||
numberOfSidesLabel->setBuddy(numberOfSidesEdit);
|
||||
|
||||
numberOfDiceLabel = new QLabel(tr("Number of dice:"));
|
||||
numberOfDiceEdit = new QSpinBox(this);
|
||||
numberOfDiceEdit->setValue(DEFAULT_NUMBER_DICE_TO_ROLL);
|
||||
numberOfDiceEdit->setRange(MINIMUM_DICE_TO_ROLL, MAXIMUM_DICE_TO_ROLL);
|
||||
numberOfDiceLabel->setBuddy(numberOfDiceEdit);
|
||||
|
||||
auto *grid = new QGridLayout;
|
||||
grid->addWidget(numberOfSidesLabel, 0, 0);
|
||||
grid->addWidget(numberOfSidesEdit, 0, 1);
|
||||
grid->addWidget(numberOfDiceLabel, 1, 0);
|
||||
grid->addWidget(numberOfDiceEdit, 1, 1);
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addItem(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
setWindowTitle(tr("Roll Dice"));
|
||||
}
|
||||
|
||||
uint DlgRollDice::getDieSideCount() const
|
||||
{
|
||||
return numberOfSidesEdit->text().toUInt();
|
||||
}
|
||||
|
||||
uint DlgRollDice::getDiceToRollCount() const
|
||||
{
|
||||
return numberOfDiceEdit->text().toUInt();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef DLG_ROLL_DICE_H
|
||||
#define DLG_ROLL_DICE_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QSpinBox>
|
||||
|
||||
class DlgRollDice : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
static constexpr uint DEFAULT_NUMBER_SIDES_DIE = 20;
|
||||
static constexpr uint DEFAULT_NUMBER_DICE_TO_ROLL = 1;
|
||||
|
||||
QLabel *numberOfSidesLabel, *numberOfDiceLabel;
|
||||
QSpinBox *numberOfSidesEdit, *numberOfDiceEdit;
|
||||
QDialogButtonBox *buttonBox;
|
||||
|
||||
public:
|
||||
explicit DlgRollDice(QWidget *parent = nullptr);
|
||||
[[nodiscard]] uint getDieSideCount() const;
|
||||
[[nodiscard]] uint getDiceToRollCount() const;
|
||||
};
|
||||
|
||||
#endif // DLG_ROLL_DICE_H
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "carddatabase.h"
|
||||
#include "gettextwithmax.h"
|
||||
#include "main.h"
|
||||
#include "pictureloader.h"
|
||||
#include "releasechannel.h"
|
||||
#include "sequenceEdit/sequenceedit.h"
|
||||
#include "settingscache.h"
|
||||
@@ -18,6 +17,7 @@
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFileDialog>
|
||||
#include <QGridLayout>
|
||||
@@ -44,22 +44,18 @@
|
||||
|
||||
GeneralSettingsPage::GeneralSettingsPage()
|
||||
{
|
||||
QStringList languageCodes = findQmFiles();
|
||||
for (const QString &code : languageCodes) {
|
||||
QString langName = languageName(code);
|
||||
languageBox.addItem(langName, code);
|
||||
}
|
||||
|
||||
QString setLanguage = QCoreApplication::translate("i18n", DEFAULT_LANG_NAME);
|
||||
int index = languageBox.findText(setLanguage, Qt::MatchExactly);
|
||||
if (index == -1) {
|
||||
qWarning() << "could not find language" << setLanguage;
|
||||
} else {
|
||||
languageBox.setCurrentIndex(index);
|
||||
SettingsCache &settings = SettingsCache::instance();
|
||||
QString setLanguage = settings.getLang();
|
||||
QStringList qmFiles = findQmFiles();
|
||||
for (int i = 0; i < qmFiles.size(); i++) {
|
||||
QString langName = languageName(qmFiles[i]);
|
||||
languageBox.addItem(langName, qmFiles[i]);
|
||||
if ((qmFiles[i] == setLanguage) ||
|
||||
(setLanguage.isEmpty() && langName == QCoreApplication::translate("i18n", DEFAULT_LANG_NAME)))
|
||||
languageBox.setCurrentIndex(i);
|
||||
}
|
||||
|
||||
// updates
|
||||
SettingsCache &settings = SettingsCache::instance();
|
||||
QList<ReleaseChannel *> channels = settings.getUpdateReleaseChannels();
|
||||
foreach (ReleaseChannel *chan, channels) {
|
||||
updateReleaseChannelBox.insertItem(chan->getIndex(), tr(chan->getName().toUtf8()));
|
||||
@@ -69,9 +65,18 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||
updateNotificationCheckBox.setChecked(settings.getNotifyAboutUpdates());
|
||||
newVersionOracleCheckBox.setChecked(settings.getNotifyAboutNewVersion());
|
||||
|
||||
// pixmap cache
|
||||
pixmapCacheEdit.setMinimum(PIXMAPCACHE_SIZE_MIN);
|
||||
// 2047 is the max value to avoid overflowing of QPixmapCache::setCacheLimit(int size)
|
||||
pixmapCacheEdit.setMaximum(PIXMAPCACHE_SIZE_MAX);
|
||||
pixmapCacheEdit.setSingleStep(64);
|
||||
pixmapCacheEdit.setValue(settings.getPixmapCacheSize());
|
||||
pixmapCacheEdit.setSuffix(" MB");
|
||||
|
||||
showTipsOnStartup.setChecked(settings.getShowTipsOnStartup());
|
||||
|
||||
connect(&languageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(languageBoxChanged(int)));
|
||||
connect(&pixmapCacheEdit, SIGNAL(valueChanged(int)), &settings, SLOT(setPixmapCacheSize(int)));
|
||||
connect(&updateReleaseChannelBox, SIGNAL(currentIndexChanged(int)), &settings, SLOT(setUpdateReleaseChannel(int)));
|
||||
connect(&updateNotificationCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setNotifyAboutUpdate(int)));
|
||||
connect(&newVersionOracleCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setNotifyAboutNewVersion(int)));
|
||||
@@ -82,6 +87,8 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||
personalGrid->addWidget(&languageBox, 0, 1);
|
||||
personalGrid->addWidget(&updateReleaseChannelLabel, 1, 0);
|
||||
personalGrid->addWidget(&updateReleaseChannelBox, 1, 1);
|
||||
personalGrid->addWidget(&pixmapCacheLabel, 2, 0);
|
||||
personalGrid->addWidget(&pixmapCacheEdit, 2, 1);
|
||||
personalGrid->addWidget(&updateNotificationCheckBox, 3, 0, 1, 2);
|
||||
personalGrid->addWidget(&newVersionOracleCheckBox, 4, 0, 1, 2);
|
||||
personalGrid->addWidget(&showTipsOnStartup, 5, 0, 1, 2);
|
||||
@@ -179,21 +186,19 @@ QStringList GeneralSettingsPage::findQmFiles()
|
||||
{
|
||||
QDir dir(translationPath);
|
||||
QStringList fileNames = dir.entryList(QStringList(translationPrefix + "_*.qm"), QDir::Files, QDir::Name);
|
||||
fileNames.replaceInStrings(QRegularExpression(translationPrefix + "_(.*)\\.qm"), "\\1");
|
||||
fileNames.replaceInStrings(QRegExp(translationPrefix + "_(.*)\\.qm"), "\\1");
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
QString GeneralSettingsPage::languageName(const QString &lang)
|
||||
QString GeneralSettingsPage::languageName(const QString &qmFile)
|
||||
{
|
||||
QTranslator qTranslator;
|
||||
if (qmFile == DEFAULT_LANG_CODE)
|
||||
return DEFAULT_LANG_NAME;
|
||||
|
||||
QString appNameHint = translationPrefix + "_" + lang;
|
||||
bool appTranslationLoaded = qTranslator.load(appNameHint, translationPath);
|
||||
if (!appTranslationLoaded) {
|
||||
qDebug() << "Unable to load" << translationPrefix << "translation" << appNameHint << "at" << translationPath;
|
||||
}
|
||||
QTranslator translator;
|
||||
translator.load(translationPrefix + "_" + qmFile + ".qm", translationPath);
|
||||
|
||||
return qTranslator.translate("i18n", DEFAULT_LANG_NAME);
|
||||
return translator.translate("i18n", DEFAULT_LANG_NAME);
|
||||
}
|
||||
|
||||
void GeneralSettingsPage::deckPathButtonClicked()
|
||||
@@ -291,6 +296,7 @@ void GeneralSettingsPage::retranslateUi()
|
||||
cardDatabasePathLabel.setText(tr("Card database:"));
|
||||
customCardDatabasePathLabel.setText(tr("Custom database directory:"));
|
||||
tokenDatabasePathLabel.setText(tr("Token database:"));
|
||||
pixmapCacheLabel.setText(tr("Picture cache size:"));
|
||||
updateReleaseChannelLabel.setText(tr("Update channel"));
|
||||
updateNotificationCheckBox.setText(tr("Notify if a feature supported by the server is missing in my client"));
|
||||
newVersionOracleCheckBox.setText(tr("Automatically run Oracle when running a new version of Cockatrice"));
|
||||
@@ -299,7 +305,6 @@ void GeneralSettingsPage::retranslateUi()
|
||||
|
||||
AppearanceSettingsPage::AppearanceSettingsPage()
|
||||
{
|
||||
SettingsCache &settings = SettingsCache::instance();
|
||||
QString themeName = SettingsCache::instance().getThemeName();
|
||||
|
||||
QStringList themeDirs = themeManager->getAvailableThemes().keys();
|
||||
@@ -320,31 +325,27 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
||||
themeGroupBox = new QGroupBox;
|
||||
themeGroupBox->setLayout(themeGrid);
|
||||
|
||||
displayCardNamesCheckBox.setChecked(settings.getDisplayCardNames());
|
||||
connect(&displayCardNamesCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setDisplayCardNames(int)));
|
||||
displayCardNamesCheckBox.setChecked(SettingsCache::instance().getDisplayCardNames());
|
||||
connect(&displayCardNamesCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(),
|
||||
SLOT(setDisplayCardNames(int)));
|
||||
|
||||
cardScalingCheckBox.setChecked(settings.getScaleCards());
|
||||
connect(&cardScalingCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setCardScaling(int)));
|
||||
|
||||
verticalCardOverlapPercentBox.setValue(settings.getStackCardOverlapPercent());
|
||||
verticalCardOverlapPercentBox.setRange(0, 80);
|
||||
connect(&verticalCardOverlapPercentBox, SIGNAL(valueChanged(int)), &settings,
|
||||
SLOT(setStackCardOverlapPercent(int)));
|
||||
cardScalingCheckBox.setChecked(SettingsCache::instance().getScaleCards());
|
||||
connect(&cardScalingCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(), SLOT(setCardScaling(int)));
|
||||
|
||||
auto *cardsGrid = new QGridLayout;
|
||||
cardsGrid->addWidget(&displayCardNamesCheckBox, 0, 0, 1, 2);
|
||||
cardsGrid->addWidget(&cardScalingCheckBox, 1, 0, 1, 2);
|
||||
cardsGrid->addWidget(&verticalCardOverlapPercentLabel, 2, 0, 1, 1);
|
||||
cardsGrid->addWidget(&verticalCardOverlapPercentBox, 2, 1, 1, 1);
|
||||
|
||||
cardsGroupBox = new QGroupBox;
|
||||
cardsGroupBox->setLayout(cardsGrid);
|
||||
|
||||
horizontalHandCheckBox.setChecked(settings.getHorizontalHand());
|
||||
connect(&horizontalHandCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setHorizontalHand(int)));
|
||||
horizontalHandCheckBox.setChecked(SettingsCache::instance().getHorizontalHand());
|
||||
connect(&horizontalHandCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(),
|
||||
SLOT(setHorizontalHand(int)));
|
||||
|
||||
leftJustifiedHandCheckBox.setChecked(settings.getLeftJustified());
|
||||
connect(&leftJustifiedHandCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setLeftJustified(int)));
|
||||
leftJustifiedHandCheckBox.setChecked(SettingsCache::instance().getLeftJustified());
|
||||
connect(&leftJustifiedHandCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(),
|
||||
SLOT(setLeftJustified(int)));
|
||||
|
||||
auto *handGrid = new QGridLayout;
|
||||
handGrid->addWidget(&horizontalHandCheckBox, 0, 0, 1, 2);
|
||||
@@ -353,18 +354,18 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
||||
handGroupBox = new QGroupBox;
|
||||
handGroupBox->setLayout(handGrid);
|
||||
|
||||
invertVerticalCoordinateCheckBox.setChecked(settings.getInvertVerticalCoordinate());
|
||||
connect(&invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), &settings,
|
||||
invertVerticalCoordinateCheckBox.setChecked(SettingsCache::instance().getInvertVerticalCoordinate());
|
||||
connect(&invertVerticalCoordinateCheckBox, SIGNAL(stateChanged(int)), &SettingsCache::instance(),
|
||||
SLOT(setInvertVerticalCoordinate(int)));
|
||||
|
||||
minPlayersForMultiColumnLayoutEdit.setMinimum(2);
|
||||
minPlayersForMultiColumnLayoutEdit.setValue(settings.getMinPlayersForMultiColumnLayout());
|
||||
connect(&minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), &settings,
|
||||
minPlayersForMultiColumnLayoutEdit.setValue(SettingsCache::instance().getMinPlayersForMultiColumnLayout());
|
||||
connect(&minPlayersForMultiColumnLayoutEdit, SIGNAL(valueChanged(int)), &SettingsCache::instance(),
|
||||
SLOT(setMinPlayersForMultiColumnLayout(int)));
|
||||
minPlayersForMultiColumnLayoutLabel.setBuddy(&minPlayersForMultiColumnLayoutEdit);
|
||||
|
||||
connect(&maxFontSizeForCardsEdit, SIGNAL(valueChanged(int)), &settings, SLOT(setMaxFontSize(int)));
|
||||
maxFontSizeForCardsEdit.setValue(settings.getMaxFontSize());
|
||||
connect(&maxFontSizeForCardsEdit, SIGNAL(valueChanged(int)), &SettingsCache::instance(), SLOT(setMaxFontSize(int)));
|
||||
maxFontSizeForCardsEdit.setValue(SettingsCache::instance().getMaxFontSize());
|
||||
maxFontSizeForCardsLabel.setBuddy(&maxFontSizeForCardsEdit);
|
||||
maxFontSizeForCardsEdit.setMinimum(9);
|
||||
maxFontSizeForCardsEdit.setMaximum(100);
|
||||
@@ -418,11 +419,9 @@ void AppearanceSettingsPage::retranslateUi()
|
||||
cardsGroupBox->setTitle(tr("Card rendering"));
|
||||
displayCardNamesCheckBox.setText(tr("Display card names on cards having a picture"));
|
||||
cardScalingCheckBox.setText(tr("Scale cards on mouse over"));
|
||||
verticalCardOverlapPercentLabel.setText(
|
||||
tr("Minimum overlap percentage of cards on the stack and in vertical hand"));
|
||||
|
||||
handGroupBox->setTitle(tr("Hand layout"));
|
||||
horizontalHandCheckBox.setText(tr("Display hand horizontally (wastes space)"));
|
||||
horizontalHandCheckBox.setText(tr("Display hand horizontally (requires more space)"));
|
||||
leftJustifiedHandCheckBox.setText(tr("Enable left justification"));
|
||||
|
||||
tableGroupBox->setTitle(tr("Table grid layout"));
|
||||
@@ -587,38 +586,12 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
|
||||
messageListLayout->addWidget(messageToolBar);
|
||||
messageListLayout->addWidget(urlList);
|
||||
|
||||
// pixmap cache
|
||||
pixmapCacheEdit.setMinimum(PIXMAPCACHE_SIZE_MIN);
|
||||
// 2047 is the max value to avoid overflowing of QPixmapCache::setCacheLimit(int size)
|
||||
pixmapCacheEdit.setMaximum(PIXMAPCACHE_SIZE_MAX);
|
||||
pixmapCacheEdit.setSingleStep(64);
|
||||
pixmapCacheEdit.setValue(SettingsCache::instance().getPixmapCacheSize());
|
||||
pixmapCacheEdit.setSuffix(" MB");
|
||||
|
||||
networkCacheEdit.setMinimum(NETWORK_CACHE_SIZE_MIN);
|
||||
networkCacheEdit.setMaximum(NETWORK_CACHE_SIZE_MAX);
|
||||
networkCacheEdit.setSingleStep(1);
|
||||
networkCacheEdit.setValue(SettingsCache::instance().getNetworkCacheSizeInMB());
|
||||
networkCacheEdit.setSuffix(" MB");
|
||||
|
||||
auto networkCacheLayout = new QHBoxLayout;
|
||||
networkCacheLayout->addStretch();
|
||||
networkCacheLayout->addWidget(&networkCacheLabel);
|
||||
networkCacheLayout->addWidget(&networkCacheEdit);
|
||||
|
||||
auto pixmapCacheLayout = new QHBoxLayout;
|
||||
pixmapCacheLayout->addStretch();
|
||||
pixmapCacheLayout->addWidget(&pixmapCacheLabel);
|
||||
pixmapCacheLayout->addWidget(&pixmapCacheEdit);
|
||||
|
||||
// Top Layout
|
||||
lpGeneralGrid->addWidget(&picDownloadCheckBox, 0, 0);
|
||||
lpGeneralGrid->addWidget(&resetDownloadURLs, 0, 1);
|
||||
lpGeneralGrid->addLayout(messageListLayout, 1, 0, 1, 2);
|
||||
lpGeneralGrid->addLayout(networkCacheLayout, 2, 0, 1, 2);
|
||||
lpGeneralGrid->addLayout(pixmapCacheLayout, 3, 0, 1, 2);
|
||||
lpGeneralGrid->addWidget(&urlLinkLabel, 4, 0);
|
||||
lpGeneralGrid->addWidget(&clearDownloadedPicsButton, 4, 1);
|
||||
lpGeneralGrid->addWidget(&urlLinkLabel, 2, 0);
|
||||
lpGeneralGrid->addWidget(&clearDownloadedPicsButton, 2, 1);
|
||||
|
||||
// Spoiler Layout
|
||||
lpSpoilerGrid->addWidget(&mcDownloadSpoilersCheckBox, 0, 0);
|
||||
@@ -633,9 +606,6 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
|
||||
connect(&mcDownloadSpoilersCheckBox, SIGNAL(toggled(bool)), &SettingsCache::instance(),
|
||||
SLOT(setDownloadSpoilerStatus(bool)));
|
||||
connect(&mcDownloadSpoilersCheckBox, SIGNAL(toggled(bool)), this, SLOT(setSpoilersEnabled(bool)));
|
||||
connect(&pixmapCacheEdit, SIGNAL(valueChanged(int)), &SettingsCache::instance(), SLOT(setPixmapCacheSize(int)));
|
||||
connect(&networkCacheEdit, SIGNAL(valueChanged(int)), &SettingsCache::instance(),
|
||||
SLOT(setNetworkCacheSizeInMB(int)));
|
||||
|
||||
mpGeneralGroupBox = new QGroupBox;
|
||||
mpGeneralGroupBox->setLayout(lpGeneralGrid);
|
||||
@@ -660,11 +630,6 @@ void DeckEditorSettingsPage::resetDownloadedURLsButtonClicked()
|
||||
|
||||
void DeckEditorSettingsPage::clearDownloadedPicsButtonClicked()
|
||||
{
|
||||
PictureLoader::clearNetworkCache();
|
||||
|
||||
// These are not used anymore, but we don't delete them automatically, so
|
||||
// we should do it here lest we leave pictures hanging around on users'
|
||||
// machines.
|
||||
QString picsPath = SettingsCache::instance().getPicsPath() + "/downloadedPics/";
|
||||
QStringList dirs = QDir(picsPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||||
bool outerSuccessRemove = true;
|
||||
@@ -692,7 +657,6 @@ void DeckEditorSettingsPage::clearDownloadedPicsButtonClicked()
|
||||
}
|
||||
if (outerSuccessRemove) {
|
||||
QMessageBox::information(this, tr("Success"), tr("Downloaded card pictures have been reset."));
|
||||
QDir(SettingsCache::instance().getPicsPath()).rmdir("downloadedPics");
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("One or more downloaded card pictures could not be cleared."));
|
||||
}
|
||||
@@ -816,10 +780,6 @@ void DeckEditorSettingsPage::retranslateUi()
|
||||
urlLinkLabel.setText(QString("<a href='%1'>%2</a>").arg(WIKI_CUSTOM_PIC_URL).arg(tr("How to add a custom URL")));
|
||||
clearDownloadedPicsButton.setText(tr("Delete Downloaded Images"));
|
||||
resetDownloadURLs.setText(tr("Reset Download URLs"));
|
||||
networkCacheLabel.setText(tr("Downloaded images directory size:"));
|
||||
networkCacheEdit.setToolTip(tr("On-disk cache for downloaded pictures"));
|
||||
pixmapCacheLabel.setText(tr("Picture cache size:"));
|
||||
pixmapCacheEdit.setToolTip(tr("In-memory cache for pictures not currently on screen"));
|
||||
}
|
||||
|
||||
MessagesSettingsPage::MessagesSettingsPage()
|
||||
@@ -831,9 +791,6 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||
connect(&chatMentionCompleterCheckbox, SIGNAL(stateChanged(int)), &SettingsCache::instance(),
|
||||
SLOT(setChatMentionCompleter(int)));
|
||||
|
||||
explainMessagesLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse);
|
||||
explainMessagesLabel.setOpenExternalLinks(true);
|
||||
|
||||
ignoreUnregUsersMainChat.setChecked(SettingsCache::instance().getIgnoreUnregisteredUsers());
|
||||
ignoreUnregUserMessages.setChecked(SettingsCache::instance().getIgnoreUnregisteredUserMessages());
|
||||
connect(&ignoreUnregUsersMainChat, SIGNAL(stateChanged(int)), &SettingsCache::instance(),
|
||||
@@ -848,6 +805,7 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||
connect(&invertHighlightForeground, SIGNAL(stateChanged(int)), this, SLOT(updateTextHighlightColor(int)));
|
||||
|
||||
mentionColor = new QLineEdit();
|
||||
mentionColor->setPlaceholderText(tr("Enter HEX code"));
|
||||
mentionColor->setText(SettingsCache::instance().getChatMentionColor());
|
||||
updateMentionPreview();
|
||||
connect(mentionColor, SIGNAL(textChanged(QString)), this, SLOT(updateColor(QString)));
|
||||
@@ -869,29 +827,36 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||
|
||||
auto *chatGrid = new QGridLayout;
|
||||
chatGrid->addWidget(&chatMentionCheckBox, 0, 0);
|
||||
chatGrid->addWidget(&invertMentionForeground, 0, 1);
|
||||
chatGrid->addWidget(&mentionColorStringLabel, 0, 1, Qt::AlignRight);
|
||||
chatGrid->addWidget(mentionColor, 0, 2);
|
||||
chatGrid->addWidget(&chatMentionCompleterCheckbox, 1, 0);
|
||||
chatGrid->addWidget(&ignoreUnregUsersMainChat, 2, 0);
|
||||
chatGrid->addWidget(&hexLabel, 1, 2);
|
||||
chatGrid->addWidget(&ignoreUnregUserMessages, 3, 0);
|
||||
chatGrid->addWidget(&messagePopups, 4, 0);
|
||||
chatGrid->addWidget(&mentionPopups, 5, 0);
|
||||
chatGrid->addWidget(&roomHistory, 6, 0);
|
||||
chatGrid->addWidget(&invertMentionForeground, 0, 3);
|
||||
chatGrid->addWidget(&chatMentionCompleterCheckbox, 1, 0, 1, -1);
|
||||
chatGrid->addWidget(&ignoreUnregUsersMainChat, 2, 0, 1, -1);
|
||||
chatGrid->addWidget(&ignoreUnregUserMessages, 3, 0, 1, -1);
|
||||
chatGrid->addWidget(&messagePopups, 4, 0, 1, -1);
|
||||
chatGrid->addWidget(&mentionPopups, 5, 0, 1, -1);
|
||||
chatGrid->addWidget(&roomHistory, 6, 0, 1, -1);
|
||||
// Expand first column more than following ones
|
||||
chatGrid->setColumnStretch(0, 3);
|
||||
chatGrid->setColumnStretch(1, 1);
|
||||
chatGroupBox = new QGroupBox;
|
||||
chatGroupBox->setLayout(chatGrid);
|
||||
|
||||
highlightColor = new QLineEdit();
|
||||
highlightColor->setPlaceholderText(tr("Enter HEX code"));
|
||||
highlightColor->setText(SettingsCache::instance().getChatHighlightColor());
|
||||
updateHighlightPreview();
|
||||
connect(highlightColor, SIGNAL(textChanged(QString)), this, SLOT(updateHighlightColor(QString)));
|
||||
|
||||
auto *highlightNotice = new QGridLayout;
|
||||
highlightNotice->addWidget(highlightColor, 0, 2);
|
||||
highlightNotice->addWidget(&invertHighlightForeground, 0, 1);
|
||||
highlightNotice->addWidget(&hexHighlightLabel, 1, 2);
|
||||
highlightNotice->addWidget(customAlertString, 0, 0);
|
||||
highlightNotice->addWidget(&customAlertStringLabel, 1, 0);
|
||||
highlightNotice->addWidget(&highlightColorStringLabel, 0, 1, Qt::AlignRight);
|
||||
highlightNotice->addWidget(highlightColor, 0, 2);
|
||||
highlightNotice->addWidget(&invertHighlightForeground, 0, 3);
|
||||
highlightNotice->addWidget(&customAlertStringLabel, 1, 0, 1, -1);
|
||||
// Expand first column more than following ones
|
||||
highlightNotice->setColumnStretch(0, 3);
|
||||
highlightNotice->setColumnStretch(1, 1);
|
||||
highlightGroupBox = new QGroupBox;
|
||||
highlightGroupBox->setLayout(highlightNotice);
|
||||
|
||||
@@ -925,15 +890,12 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||
messageListLayout->addWidget(messageToolBar);
|
||||
messageListLayout->addWidget(messageList);
|
||||
|
||||
auto *messagesLayout = new QVBoxLayout; // combines the explainer label with the actual messages widget pieces
|
||||
messagesLayout->addLayout(messageListLayout);
|
||||
messagesLayout->addWidget(&explainMessagesLabel);
|
||||
messageShortcuts = new QGroupBox;
|
||||
messageShortcuts->setLayout(messageListLayout);
|
||||
|
||||
messageGroupBox = new QGroupBox; // draws a box around the above layout and allows it to be titled
|
||||
messageGroupBox->setLayout(messagesLayout);
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
|
||||
auto *mainLayout = new QVBoxLayout; // combines the messages groupbox with the rest of the menu
|
||||
mainLayout->addWidget(messageGroupBox);
|
||||
mainLayout->addWidget(messageShortcuts);
|
||||
mainLayout->addWidget(chatGroupBox);
|
||||
mainLayout->addWidget(highlightGroupBox);
|
||||
|
||||
@@ -944,12 +906,8 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||
|
||||
void MessagesSettingsPage::updateColor(const QString &value)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||
QColor colorToSet = QColor::fromString("#" + value);
|
||||
#else
|
||||
QColor colorToSet;
|
||||
colorToSet.setNamedColor("#" + value);
|
||||
#endif
|
||||
if (colorToSet.isValid()) {
|
||||
SettingsCache::instance().setChatMentionColor(value);
|
||||
updateMentionPreview();
|
||||
@@ -958,12 +916,8 @@ void MessagesSettingsPage::updateColor(const QString &value)
|
||||
|
||||
void MessagesSettingsPage::updateHighlightColor(const QString &value)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||
QColor colorToSet = QColor::fromString("#" + value);
|
||||
#else
|
||||
QColor colorToSet;
|
||||
colorToSet.setNamedColor("#" + value);
|
||||
#endif
|
||||
if (colorToSet.isValid()) {
|
||||
SettingsCache::instance().setChatHighlightColor(value);
|
||||
updateHighlightPreview();
|
||||
@@ -1042,18 +996,16 @@ void MessagesSettingsPage::retranslateUi()
|
||||
highlightGroupBox->setTitle(tr("Custom alert words"));
|
||||
chatMentionCheckBox.setText(tr("Enable chat mentions"));
|
||||
chatMentionCompleterCheckbox.setText(tr("Enable mention completer"));
|
||||
messageGroupBox->setTitle(tr("In-game message macros"));
|
||||
explainMessagesLabel.setText(
|
||||
QString("<a href='%1'>%2</a>").arg(WIKI_CUSTOM_SHORTCUTS).arg(tr("How to use in-game message macros")));
|
||||
messageShortcuts->setTitle(tr("In-game message macros"));
|
||||
ignoreUnregUsersMainChat.setText(tr("Ignore chat room messages sent by unregistered users"));
|
||||
ignoreUnregUserMessages.setText(tr("Ignore private messages sent by unregistered users"));
|
||||
invertMentionForeground.setText(tr("Invert text color"));
|
||||
invertHighlightForeground.setText(tr("Invert text color"));
|
||||
mentionColorStringLabel.setText(tr("Color"));
|
||||
highlightColorStringLabel.setText(tr("Color"));
|
||||
messagePopups.setText(tr("Enable desktop notifications for private messages"));
|
||||
mentionPopups.setText(tr("Enable desktop notification for mentions"));
|
||||
roomHistory.setText(tr("Enable room message history on join"));
|
||||
hexLabel.setText(tr("(Color is hexadecimal)"));
|
||||
hexHighlightLabel.setText(tr("(Color is hexadecimal)"));
|
||||
customAlertStringLabel.setText(tr("Separate words with a space, alphanumeric characters only"));
|
||||
}
|
||||
|
||||
@@ -1161,28 +1113,28 @@ ShortcutSettingsPage::ShortcutSettingsPage()
|
||||
btnClearAll->setIcon(QPixmap("theme:icons/clearsearch"));
|
||||
|
||||
// layout
|
||||
auto *_editLayout = new QGridLayout;
|
||||
_editLayout->addWidget(currentActionGroupLabel, 0, 0);
|
||||
_editLayout->addWidget(currentActionGroupName, 0, 1);
|
||||
_editLayout->addWidget(currentActionLabel, 1, 0);
|
||||
_editLayout->addWidget(currentActionName, 1, 1);
|
||||
_editLayout->addWidget(currentShortcutLabel, 2, 0);
|
||||
_editLayout->addWidget(editTextBox, 2, 1);
|
||||
auto *editLayout = new QGridLayout;
|
||||
editLayout->addWidget(currentActionGroupLabel, 0, 0);
|
||||
editLayout->addWidget(currentActionGroupName, 0, 1);
|
||||
editLayout->addWidget(currentActionLabel, 1, 0);
|
||||
editLayout->addWidget(currentActionName, 1, 1);
|
||||
editLayout->addWidget(currentShortcutLabel, 2, 0);
|
||||
editLayout->addWidget(editTextBox, 2, 1);
|
||||
|
||||
editShortcutGroupBox = new QGroupBox;
|
||||
editShortcutGroupBox->setLayout(_editLayout);
|
||||
editShortcutGroupBox->setLayout(editLayout);
|
||||
|
||||
auto *_buttonsLayout = new QHBoxLayout;
|
||||
_buttonsLayout->addWidget(faqLabel);
|
||||
_buttonsLayout->addWidget(btnResetAll);
|
||||
_buttonsLayout->addWidget(btnClearAll);
|
||||
auto *buttonsLayout = new QHBoxLayout;
|
||||
buttonsLayout->addWidget(faqLabel);
|
||||
buttonsLayout->addWidget(btnResetAll);
|
||||
buttonsLayout->addWidget(btnClearAll);
|
||||
|
||||
auto *_mainLayout = new QVBoxLayout;
|
||||
_mainLayout->addWidget(shortcutsTable);
|
||||
_mainLayout->addWidget(editShortcutGroupBox);
|
||||
_mainLayout->addLayout(_buttonsLayout);
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(shortcutsTable);
|
||||
mainLayout->addWidget(editShortcutGroupBox);
|
||||
mainLayout->addLayout(buttonsLayout);
|
||||
|
||||
setLayout(_mainLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
connect(btnResetAll, SIGNAL(clicked()), this, SLOT(resetShortcuts()));
|
||||
connect(btnClearAll, SIGNAL(clicked()), this, SLOT(clearShortcuts()));
|
||||
@@ -1288,13 +1240,17 @@ void ShortcutSettingsPage::retranslateUi()
|
||||
currentShortcutLabel->setText(tr("Shortcut:"));
|
||||
editTextBox->retranslateUi();
|
||||
faqLabel->setText(QString("<a href='%1'>%2</a>").arg(WIKI_CUSTOM_SHORTCUTS).arg(tr("How to set custom shortcuts")));
|
||||
btnResetAll->setText(tr("Restore all default shortcuts"));
|
||||
btnClearAll->setText(tr("Clear all shortcuts"));
|
||||
btnResetAll->setText("Restore all default shortcuts");
|
||||
btnClearAll->setText("Clear all shortcuts");
|
||||
}
|
||||
|
||||
DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
auto rec = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||
auto rec = qApp->primaryScreen()->availableGeometry();
|
||||
#else
|
||||
auto rec = QApplication::desktop()->availableGeometry();
|
||||
#endif
|
||||
this->setMinimumSize(qMin(700, rec.width()), qMin(700, rec.height()));
|
||||
|
||||
connect(&SettingsCache::instance(), SIGNAL(langChanged()), this, SLOT(updateLanguage()));
|
||||
|
||||
@@ -49,7 +49,7 @@ private slots:
|
||||
|
||||
private:
|
||||
QStringList findQmFiles();
|
||||
QString languageName(const QString &lang);
|
||||
QString languageName(const QString &qmFile);
|
||||
QLineEdit *deckPathEdit;
|
||||
QLineEdit *replaysPathEdit;
|
||||
QLineEdit *picsPathEdit;
|
||||
@@ -58,6 +58,7 @@ private:
|
||||
QLineEdit *tokenDatabasePathEdit;
|
||||
QPushButton *resetAllPathsButton;
|
||||
QLabel *allPathsResetLabel;
|
||||
QSpinBox pixmapCacheEdit;
|
||||
QGroupBox *personalGroupBox;
|
||||
QGroupBox *pathsGroupBox;
|
||||
QComboBox languageBox;
|
||||
@@ -65,6 +66,7 @@ private:
|
||||
QCheckBox newVersionOracleCheckBox;
|
||||
QComboBox updateReleaseChannelBox;
|
||||
QLabel languageLabel;
|
||||
QLabel pixmapCacheLabel;
|
||||
QLabel deckPathLabel;
|
||||
QLabel replaysPathLabel;
|
||||
QLabel picsPathLabel;
|
||||
@@ -90,8 +92,6 @@ private:
|
||||
QLabel maxFontSizeForCardsLabel;
|
||||
QCheckBox displayCardNamesCheckBox;
|
||||
QCheckBox cardScalingCheckBox;
|
||||
QLabel verticalCardOverlapPercentLabel;
|
||||
QSpinBox verticalCardOverlapPercentBox;
|
||||
QCheckBox horizontalHandCheckBox;
|
||||
QCheckBox leftJustifiedHandCheckBox;
|
||||
QCheckBox invertVerticalCoordinateCheckBox;
|
||||
@@ -168,10 +168,6 @@ private:
|
||||
QLabel infoOnSpoilersLabel;
|
||||
QPushButton *mpSpoilerPathButton;
|
||||
QPushButton *updateNowButton;
|
||||
QLabel networkCacheLabel;
|
||||
QSpinBox networkCacheEdit;
|
||||
QSpinBox pixmapCacheEdit;
|
||||
QLabel pixmapCacheLabel;
|
||||
};
|
||||
|
||||
class MessagesSettingsPage : public AbstractSettingsPage
|
||||
@@ -206,14 +202,13 @@ private:
|
||||
QCheckBox roomHistory;
|
||||
QGroupBox *chatGroupBox;
|
||||
QGroupBox *highlightGroupBox;
|
||||
QGroupBox *messageGroupBox;
|
||||
QGroupBox *messageShortcuts;
|
||||
QLineEdit *mentionColor;
|
||||
QLineEdit *highlightColor;
|
||||
QLineEdit *customAlertString;
|
||||
QLabel hexLabel;
|
||||
QLabel hexHighlightLabel;
|
||||
QLabel customAlertStringLabel;
|
||||
QLabel explainMessagesLabel;
|
||||
QLabel mentionColorStringLabel;
|
||||
QLabel highlightColorStringLabel;
|
||||
|
||||
void storeSettings();
|
||||
void updateMentionPreview();
|
||||
|
||||
@@ -154,7 +154,7 @@ void DlgTipOfTheDay::updateTip(int tipId)
|
||||
imageLabel->setPixmap(image->scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
}
|
||||
|
||||
date->setText("<i>Tip added on: " + tip.getDate().toString("yyyy-MM-dd") + "</i>");
|
||||
date->setText("<i>Tip added on: " + tip.getDate().toString("yyyy.MM.dd") + "</i>");
|
||||
|
||||
tipNumber->setText("Tip " + QString::number(tipId + 1) + " / " + QString::number(tipDatabase->rowCount()));
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user