mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-21 06:42:41 -08:00
Compare commits
340 Commits
2021-05-28
...
2024-06-16
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7fbc12ac0 | ||
|
|
e2ab8db958 | ||
|
|
34d70980e8 | ||
|
|
e45c4042fe | ||
|
|
ce8092318e | ||
|
|
c95cc1dd9d | ||
|
|
1f72877728 | ||
|
|
93b40343d9 | ||
|
|
ba10108207 | ||
|
|
c28f66d673 | ||
|
|
59f327f97a | ||
|
|
872c92a244 | ||
|
|
2303880b87 | ||
|
|
0e97cc1712 | ||
|
|
d550e42441 | ||
|
|
4279753030 | ||
|
|
2f6c018b7a | ||
|
|
be5d42baba | ||
|
|
f174614496 | ||
|
|
e8c7fba8b0 | ||
|
|
5c49283023 | ||
|
|
ad56b431a3 | ||
|
|
b0d8a33d5f | ||
|
|
1715bcb216 | ||
|
|
96caeaca72 | ||
|
|
c8723ae935 | ||
|
|
94e39c044c | ||
|
|
9776ea53c9 | ||
|
|
675d07dac0 | ||
|
|
1217820288 | ||
|
|
90e1a3cb76 | ||
|
|
7c1095ea50 | ||
|
|
203e916a07 | ||
|
|
7201e34b38 | ||
|
|
6d032c378f | ||
|
|
badd8952f5 | ||
|
|
7209eddb2d | ||
|
|
a7ffd43b29 | ||
|
|
724ba69483 | ||
|
|
1716801437 | ||
|
|
fa727524dc | ||
|
|
28f80e18a0 | ||
|
|
4acc8bfe80 | ||
|
|
9f86ed7887 | ||
|
|
cb18a55338 | ||
|
|
78a928464c | ||
|
|
07a8cd0a5f | ||
|
|
b73ef58567 | ||
|
|
519531f3a0 | ||
|
|
4b8e47d079 | ||
|
|
ed170f7e07 | ||
|
|
6bb559874c | ||
|
|
9cd68e25b3 | ||
|
|
72ac441598 | ||
|
|
f5fe56c85d | ||
|
|
d4fc1be2cc | ||
|
|
7b3617a273 | ||
|
|
3e8adae3de | ||
|
|
9943133d6d | ||
|
|
a5706a47af | ||
|
|
b3b911c64d | ||
|
|
05beb4fcaf | ||
|
|
324b50e381 | ||
|
|
186f4289e9 | ||
|
|
cb90a8356b | ||
|
|
e9c502ab32 | ||
|
|
f728520e97 | ||
|
|
c1b0d50237 | ||
|
|
b9cfc29059 | ||
|
|
6bf7c79891 | ||
|
|
2bd0e58354 | ||
|
|
ee674cb0cf | ||
|
|
dd1b354d48 | ||
|
|
d3e96f4a99 | ||
|
|
90e2eb3db9 | ||
|
|
102be6a350 | ||
|
|
be6152948c | ||
|
|
f14bf4b205 | ||
|
|
123ac2ca25 | ||
|
|
7216b976ec | ||
|
|
7fb698cfbf | ||
|
|
b0470ab678 | ||
|
|
0deb037035 | ||
|
|
064b362d60 | ||
|
|
6bbe228a84 | ||
|
|
a8ba8b6ab5 | ||
|
|
e850f6c2a5 | ||
|
|
e9eb7d6db1 | ||
|
|
56d21321d0 | ||
|
|
3888a74212 | ||
|
|
0035e29f9e | ||
|
|
90679d5669 | ||
|
|
ac5dc2578a | ||
|
|
671e6823be | ||
|
|
0d76662311 | ||
|
|
8dd59cf3cf | ||
|
|
332d25dc00 | ||
|
|
0fa81a77dc | ||
|
|
9a74d8f72d | ||
|
|
8c539351e3 | ||
|
|
e3552fc0ae | ||
|
|
ca308636c3 | ||
|
|
244cb847fb | ||
|
|
176c52daf2 | ||
|
|
ee3525ec64 | ||
|
|
adce921be7 | ||
|
|
20ceb1c284 | ||
|
|
db4364b8f8 | ||
|
|
48d6435e09 | ||
|
|
7c20e9ab34 | ||
|
|
cb52605928 | ||
|
|
bd3100dcda | ||
|
|
afb7c35cfd | ||
|
|
5b694a55d2 | ||
|
|
f750a4cd72 | ||
|
|
eddeaaf52a | ||
|
|
2b42bee424 | ||
|
|
b9706c0cc1 | ||
|
|
800b21b000 | ||
|
|
d1736a25bb | ||
|
|
f269e5fe58 | ||
|
|
45a5296013 | ||
|
|
5f0ab2a177 | ||
|
|
70ab02987a | ||
|
|
421da882d8 | ||
|
|
1a40102f71 | ||
|
|
1fbc10cd77 | ||
|
|
87462398d8 | ||
|
|
b33246b29f | ||
|
|
dbffe30f63 | ||
|
|
9ce450d0b0 | ||
|
|
f5f8acf1fd | ||
|
|
304ed3cd60 | ||
|
|
07248692ce | ||
|
|
cef99cba71 | ||
|
|
cab5f29b57 | ||
|
|
55a2f75d16 | ||
|
|
a416ee8f2b | ||
|
|
c14936c63c | ||
|
|
42e7a8b423 | ||
|
|
4558b1c7ef | ||
|
|
f444ba9665 | ||
|
|
787c8d740b | ||
|
|
ef38a8bb2b | ||
|
|
b5d35d346a | ||
|
|
9a7b15d19b | ||
|
|
ba35a11e82 | ||
|
|
00c9efe541 | ||
|
|
44d1ab348b | ||
|
|
f25e4785ae | ||
|
|
4c290aec57 | ||
|
|
42d1d66d9b | ||
|
|
06c25301a5 | ||
|
|
43dbb45cc6 | ||
|
|
9fb62de5cb | ||
|
|
b282df2e27 | ||
|
|
da8f57f397 | ||
|
|
e9f1992c7f | ||
|
|
2c94a6a64e | ||
|
|
6a5e0a8501 | ||
|
|
26d7fe2ff0 | ||
|
|
5854a635ca | ||
|
|
3d4858b840 | ||
|
|
dec2a252fa | ||
|
|
f619ef23fd | ||
|
|
72743e834e | ||
|
|
8e4ddf366c | ||
|
|
b99bd0176a | ||
|
|
a68b98b245 | ||
|
|
a69d6ff1b4 | ||
|
|
ec679e95fd | ||
|
|
3f78235a74 | ||
|
|
c8a2fd78b0 | ||
|
|
45cf08111a | ||
|
|
527ac36129 | ||
|
|
a7232513a7 | ||
|
|
90f187e885 | ||
|
|
235adbbdf1 | ||
|
|
40c88fe385 | ||
|
|
54b7943d17 | ||
|
|
2f100f2ba3 | ||
|
|
b5305aa5e4 | ||
|
|
a2624e36f3 | ||
|
|
540511befd | ||
|
|
014e73d569 | ||
|
|
e2c256db5b | ||
|
|
28aa473362 | ||
|
|
b79506fbcf | ||
|
|
afbd7252ac | ||
|
|
3e5b7cd392 | ||
|
|
77622095d5 | ||
|
|
8ee71300a2 | ||
|
|
d79971edbc | ||
|
|
273ebb22e4 | ||
|
|
6b86e4d463 | ||
|
|
a8e1dc3b18 | ||
|
|
a95b338c80 | ||
|
|
3e90f109a2 | ||
|
|
b02adccf87 | ||
|
|
accd5e4df7 | ||
|
|
d007196059 | ||
|
|
79501a4af7 | ||
|
|
64c6611ea5 | ||
|
|
a532a63403 | ||
|
|
c10c69d0a9 | ||
|
|
191d5a83a9 | ||
|
|
de69e2c41f | ||
|
|
6d200d17b7 | ||
|
|
4899b6cfef | ||
|
|
0ff59e6d1e | ||
|
|
00a2a8ab71 | ||
|
|
2c702d3579 | ||
|
|
b464fa8d99 | ||
|
|
2b330940e1 | ||
|
|
0d0337f091 | ||
|
|
533045445a | ||
|
|
21f7dd5eba | ||
|
|
f5b973e15c | ||
|
|
baaf261116 | ||
|
|
92ed53e13a | ||
|
|
2a54e9d7d1 | ||
|
|
9577ada171 | ||
|
|
217dc09c0f | ||
|
|
7108eb42c8 | ||
|
|
eb3ce1fd7e | ||
|
|
c88d44e16c | ||
|
|
ec2ad4c713 | ||
|
|
4c04b4ef5a | ||
|
|
88b861d632 | ||
|
|
408a13c937 | ||
|
|
7d0a255a49 | ||
|
|
252883f67e | ||
|
|
bf08a04cda | ||
|
|
6928a2bd98 | ||
|
|
bb16ae09ef | ||
|
|
81d031ca0f | ||
|
|
8203a2fdeb | ||
|
|
75f0d60dff | ||
|
|
992e28797f | ||
|
|
92f941a54c | ||
|
|
4c31527832 | ||
|
|
febe029ed4 | ||
|
|
1d780058c8 | ||
|
|
513fcb0908 | ||
|
|
4bb13677c8 | ||
|
|
a5baf4303c | ||
|
|
7aba404f2e | ||
|
|
1b7e8f3a16 | ||
|
|
5cf93ad61c | ||
|
|
5a52e085a7 | ||
|
|
5d31b70406 | ||
|
|
2885f93fdf | ||
|
|
d225f55e5a | ||
|
|
69edc73585 | ||
|
|
ead1143f2e | ||
|
|
2fc85e0c08 | ||
|
|
fcafcb340a | ||
|
|
ae9b8b8f34 | ||
|
|
994704d353 | ||
|
|
d61c604bf4 | ||
|
|
baaf22d0c4 | ||
|
|
368ff1793f | ||
|
|
3253ad64fd | ||
|
|
1e70989f38 | ||
|
|
f6634de18d | ||
|
|
7903cd520a | ||
|
|
26d1fcc944 | ||
|
|
59d4e64a8d | ||
|
|
1347d88ddb | ||
|
|
6981cca2ae | ||
|
|
4d6c9ede8c | ||
|
|
e845c95816 | ||
|
|
a9f2fc427b | ||
|
|
07e6aadbbe | ||
|
|
86881bbbc3 | ||
|
|
1f15445c69 | ||
|
|
811ee54c76 | ||
|
|
d1a40fd36e | ||
|
|
a3d3aaaca8 | ||
|
|
c5aaa0bc2e | ||
|
|
6dc9f004ce | ||
|
|
6ce346af4a | ||
|
|
37879c4255 | ||
|
|
0683d1aced | ||
|
|
73c5956ece | ||
|
|
7c27e955d5 | ||
|
|
6ef394000b | ||
|
|
755a09bd83 | ||
|
|
8b1daa21ef | ||
|
|
691bcb9338 | ||
|
|
911a303326 | ||
|
|
5652b56b45 | ||
|
|
26acfd5102 | ||
|
|
f789e02096 | ||
|
|
43eee6b32e | ||
|
|
45d86e7ab7 | ||
|
|
b0845837c2 | ||
|
|
a10226d096 | ||
|
|
5e3a524401 | ||
|
|
b095d9b82f | ||
|
|
4cb7240f9a | ||
|
|
a87c66885c | ||
|
|
ac300b0b6d | ||
|
|
013bb8269f | ||
|
|
7712862036 | ||
|
|
656e3230de | ||
|
|
915c14f6cf | ||
|
|
ed32e72dc1 | ||
|
|
d684a9c5fc | ||
|
|
6f360374cc | ||
|
|
bbbf3e2a65 | ||
|
|
b1ef8220ee | ||
|
|
ebebb9c4bb | ||
|
|
586f23cfa9 | ||
|
|
f75ff2a7c8 | ||
|
|
e9ba195d7d | ||
|
|
19333c53f6 | ||
|
|
36e5a399d5 | ||
|
|
dde0f568d9 | ||
|
|
3bc90003b3 | ||
|
|
689f65b38a | ||
|
|
154e1084ba | ||
|
|
6df5cece04 | ||
|
|
c8bb8b0aae | ||
|
|
1e995cd97c | ||
|
|
c25bf491e4 | ||
|
|
affc288144 | ||
|
|
051be37419 | ||
|
|
c0bd49cf13 | ||
|
|
2fe572c398 | ||
|
|
904e740460 | ||
|
|
00add2a527 | ||
|
|
bbe43d4246 | ||
|
|
0280fea3e6 | ||
|
|
a65ce8694c | ||
|
|
c9ddd042fc | ||
|
|
da9222929b | ||
|
|
b858e36183 | ||
|
|
ebe2c494aa | ||
|
|
fac7bfaa92 |
@@ -5,11 +5,14 @@ RUN pacman --sync --refresh --sysupgrade --needed --noconfirm \
|
|||||||
ccache \
|
ccache \
|
||||||
cmake \
|
cmake \
|
||||||
git \
|
git \
|
||||||
|
gtest \
|
||||||
mariadb-libs \
|
mariadb-libs \
|
||||||
protobuf \
|
protobuf \
|
||||||
qt5-base \
|
qt6-base \
|
||||||
qt5-multimedia \
|
qt6-imageformats \
|
||||||
qt5-svg \
|
qt6-multimedia \
|
||||||
qt5-tools \
|
qt6-svg \
|
||||||
qt5-websockets \
|
qt6-tools \
|
||||||
|
qt6-translations \
|
||||||
|
qt6-websockets \
|
||||||
&& pacman --sync --clean --clean --noconfirm
|
&& pacman --sync --clean --clean --noconfirm
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM ubuntu:hirsute
|
FROM debian:11
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
@@ -17,6 +17,7 @@ RUN apt-get update && \
|
|||||||
libqt5svg5-dev \
|
libqt5svg5-dev \
|
||||||
libqt5websockets5-dev \
|
libqt5websockets5-dev \
|
||||||
protobuf-compiler \
|
protobuf-compiler \
|
||||||
|
qt5-image-formats-plugins \
|
||||||
qtmultimedia5-dev \
|
qtmultimedia5-dev \
|
||||||
qttools5-dev \
|
qttools5-dev \
|
||||||
qttools5-dev-tools \
|
qttools5-dev-tools \
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM ubuntu:groovy
|
FROM debian:12
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
@@ -9,17 +9,19 @@ RUN apt-get update && \
|
|||||||
file \
|
file \
|
||||||
g++ \
|
g++ \
|
||||||
git \
|
git \
|
||||||
|
libgl-dev \
|
||||||
liblzma-dev \
|
liblzma-dev \
|
||||||
libmariadb-dev-compat \
|
libmariadb-dev-compat \
|
||||||
libprotobuf-dev \
|
libprotobuf-dev \
|
||||||
libqt5multimedia5-plugins \
|
libqt6multimedia6 \
|
||||||
libqt5sql5-mysql \
|
libqt6sql6-mysql \
|
||||||
libqt5svg5-dev \
|
qt6-svg-dev \
|
||||||
libqt5websockets5-dev \
|
qt6-websockets-dev \
|
||||||
protobuf-compiler \
|
protobuf-compiler \
|
||||||
qt5-default \
|
qt6-image-formats-plugins \
|
||||||
qtmultimedia5-dev \
|
qt6-l10n-tools \
|
||||||
qttools5-dev \
|
qt6-multimedia-dev \
|
||||||
qttools5-dev-tools \
|
qt6-tools-dev \
|
||||||
|
qt6-tools-dev-tools \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
FROM debian:buster
|
|
||||||
|
|
||||||
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/*
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
FROM fedora:33
|
|
||||||
|
|
||||||
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,21 +0,0 @@
|
|||||||
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
|
|
||||||
15
.ci/Fedora39/Dockerfile
Normal file
15
.ci/Fedora39/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
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
|
||||||
15
.ci/Fedora40/Dockerfile
Normal file
15
.ci/Fedora40/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
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,6 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libqt5websockets5-dev \
|
libqt5websockets5-dev \
|
||||||
protobuf-compiler \
|
protobuf-compiler \
|
||||||
qt5-default \
|
qt5-default \
|
||||||
|
qt5-image-formats-plugins \
|
||||||
qtmultimedia5-dev \
|
qtmultimedia5-dev \
|
||||||
qttools5-dev \
|
qttools5-dev \
|
||||||
qttools5-dev-tools \
|
qttools5-dev-tools \
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ RUN apt-get update && \
|
|||||||
libqt5websockets5-dev \
|
libqt5websockets5-dev \
|
||||||
protobuf-compiler \
|
protobuf-compiler \
|
||||||
qt5-default \
|
qt5-default \
|
||||||
|
qt5-image-formats-plugins \
|
||||||
qtmultimedia5-dev \
|
qtmultimedia5-dev \
|
||||||
qttools5-dev \
|
qttools5-dev \
|
||||||
qttools5-dev-tools \
|
qttools5-dev-tools \
|
||||||
|
|||||||
27
.ci/UbuntuJammy/Dockerfile
Normal file
27
.ci/UbuntuJammy/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
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/*
|
||||||
27
.ci/UbuntuNoble/Dockerfile
Normal file
27
.ci/UbuntuNoble/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
FROM ubuntu:noble
|
||||||
|
|
||||||
|
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 \
|
||||||
|
qt6-svg-dev \
|
||||||
|
qt6-websockets-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/*
|
||||||
149
.ci/compile.sh
149
.ci/compile.sh
@@ -2,16 +2,26 @@
|
|||||||
|
|
||||||
# This script is to be used by the ci environment from the project root directory, do not use it from somewhere else.
|
# 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
|
# Read arguments
|
||||||
while [[ "$@" ]]; do
|
while [[ $# != 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
'--')
|
'--')
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
'--format')
|
|
||||||
CHECK_FORMAT=1
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
'--install')
|
'--install')
|
||||||
MAKE_INSTALL=1
|
MAKE_INSTALL=1
|
||||||
shift
|
shift
|
||||||
@@ -19,7 +29,7 @@ while [[ "$@" ]]; do
|
|||||||
'--package')
|
'--package')
|
||||||
MAKE_PACKAGE=1
|
MAKE_PACKAGE=1
|
||||||
shift
|
shift
|
||||||
if [[ $# != 0 && $1 != -* ]]; then
|
if [[ $# != 0 && ${1:0:1} != - ]]; then
|
||||||
PACKAGE_TYPE="$1"
|
PACKAGE_TYPE="$1"
|
||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
@@ -28,7 +38,7 @@ while [[ "$@" ]]; do
|
|||||||
shift
|
shift
|
||||||
if [[ $# == 0 ]]; then
|
if [[ $# == 0 ]]; then
|
||||||
echo "::error file=$0::--suffix expects an argument"
|
echo "::error file=$0::--suffix expects an argument"
|
||||||
exit 1
|
exit 3
|
||||||
fi
|
fi
|
||||||
PACKAGE_SUFFIX="$1"
|
PACKAGE_SUFFIX="$1"
|
||||||
shift
|
shift
|
||||||
@@ -49,94 +59,143 @@ while [[ "$@" ]]; do
|
|||||||
BUILDTYPE="Release"
|
BUILDTYPE="Release"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
*)
|
'--ccache')
|
||||||
if [[ $1 == -* ]]; then
|
USE_CCACHE=1
|
||||||
echo "::error file=$0::unrecognized option: $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
|
exit 3
|
||||||
fi
|
fi
|
||||||
BUILDTYPE="$1"
|
BUILD_DIR="$1"
|
||||||
shift
|
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
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Check formatting using clang-format
|
|
||||||
if [[ $CHECK_FORMAT ]]; then
|
|
||||||
echo "::group::Run linter"
|
|
||||||
source ./.ci/lint.sh
|
|
||||||
echo "::endgroup::"
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
./servatrice/check_schema_version.sh
|
./servatrice/check_schema_version.sh
|
||||||
mkdir -p build
|
if [[ ! $BUILDTYPE ]]; then
|
||||||
cd build
|
BUILDTYPE=Release
|
||||||
|
|
||||||
if [[ ! $CMAKE_BUILD_PARALLEL_LEVEL ]]; then
|
|
||||||
CMAKE_BUILD_PARALLEL_LEVEL=2 # default machines have 2 cores
|
|
||||||
fi
|
fi
|
||||||
|
if [[ ! $BUILD_DIR ]]; then
|
||||||
|
BUILD_DIR="build"
|
||||||
|
fi
|
||||||
|
mkdir -p "$BUILD_DIR"
|
||||||
|
cd "$BUILD_DIR"
|
||||||
|
|
||||||
# Add cmake flags
|
# Add cmake flags
|
||||||
|
flags=("-DCMAKE_BUILD_TYPE=$BUILDTYPE")
|
||||||
if [[ $MAKE_SERVER ]]; then
|
if [[ $MAKE_SERVER ]]; then
|
||||||
flags+=" -DWITH_SERVER=1"
|
flags+=("-DWITH_SERVER=1")
|
||||||
fi
|
fi
|
||||||
if [[ $MAKE_TEST ]]; then
|
if [[ $MAKE_TEST ]]; then
|
||||||
flags+=" -DTEST=1"
|
flags+=("-DTEST=1")
|
||||||
fi
|
fi
|
||||||
if [[ $BUILDTYPE ]]; then
|
if [[ $USE_CCACHE ]]; then
|
||||||
flags+=" -DCMAKE_BUILD_TYPE=$BUILDTYPE"
|
flags+=("-DUSE_CCACHE=1")
|
||||||
|
if [[ $CCACHE_SIZE ]]; then
|
||||||
|
# note, this setting persists after running the script
|
||||||
|
ccache --max-size "$CCACHE_SIZE"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if [[ $PACKAGE_TYPE ]]; then
|
if [[ $PACKAGE_TYPE ]]; then
|
||||||
flags+=" -DCPACK_GENERATOR=$PACKAGE_TYPE"
|
flags+=("-DCPACK_GENERATOR=$PACKAGE_TYPE")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $(uname) == "Darwin" ]]; then
|
# Add cmake --build flags
|
||||||
# prepend ccache compiler binaries to path
|
buildflags=(--config "$BUILDTYPE")
|
||||||
PATH="/usr/local/opt/ccache/libexec:$PATH"
|
if [[ $PARALLEL_COUNT ]]; then
|
||||||
# Add qt install location when using homebrew
|
if [[ $(cmake --build /not_a_dir --parallel 2>&1 | head -1) =~ parallel ]]; then
|
||||||
flags+=" -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5/"
|
# 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")
|
||||||
|
fi
|
||||||
fi
|
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
|
# Compile
|
||||||
echo "::group::Show ccache stats"
|
if [[ $USE_CCACHE ]]; then
|
||||||
ccache --show-stats
|
echo "::group::Show ccache stats"
|
||||||
echo "::endgroup::"
|
ccachestatsverbose
|
||||||
|
echo "::endgroup::"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "::group::Configure cmake"
|
echo "::group::Configure cmake"
|
||||||
cmake --version
|
cmake --version
|
||||||
cmake .. $flags
|
cmake .. "${flags[@]}"
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
echo "::group::Build project"
|
echo "::group::Build project"
|
||||||
cmake --build .
|
if [[ $RUNNER_OS == Windows ]]; then
|
||||||
|
# Enable MTT, see https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||||
|
# and https://devblogs.microsoft.com/cppblog/cpp-build-throughput-investigation-and-tune-up/#multitooltask-mtt
|
||||||
|
cmake --build . "${buildflags[@]}" -- -p:UseMultiToolTask=true -p:EnableClServerMode=true
|
||||||
|
else
|
||||||
|
cmake --build . "${buildflags[@]}"
|
||||||
|
fi
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
echo "::group::Show ccache stats again"
|
if [[ $USE_CCACHE ]]; then
|
||||||
ccache --show-stats
|
echo "::group::Show ccache stats again"
|
||||||
echo "::endgroup::"
|
ccachestatsverbose
|
||||||
|
echo "::endgroup::"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $MAKE_TEST ]]; then
|
if [[ $MAKE_TEST ]]; then
|
||||||
echo "::group::Run tests"
|
echo "::group::Run tests"
|
||||||
cmake --build . --target test
|
ctest -C "$BUILDTYPE" --output-on-failure
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $MAKE_INSTALL ]]; then
|
if [[ $MAKE_INSTALL ]]; then
|
||||||
echo "::group::Install"
|
echo "::group::Install"
|
||||||
cmake --build . --target install
|
cmake --build . --target install --config "$BUILDTYPE"
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $MAKE_PACKAGE ]]; then
|
if [[ $MAKE_PACKAGE ]]; then
|
||||||
echo "::group::Create package"
|
echo "::group::Create package"
|
||||||
cmake --build . --target package
|
cmake --build . --target package --config "$BUILDTYPE"
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
if [[ $PACKAGE_SUFFIX ]]; then
|
if [[ $PACKAGE_SUFFIX ]]; then
|
||||||
echo "::group::Update package name"
|
echo "::group::Update package name"
|
||||||
../.ci/name_build.sh "$PACKAGE_SUFFIX"
|
cd ..
|
||||||
|
BUILD_DIR="$BUILD_DIR" .ci/name_build.sh "$PACKAGE_SUFFIX"
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -3,11 +3,15 @@
|
|||||||
# This script is to be used by the ci environment from the project root directory, do not use it from somewhere else.
|
# 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.
|
# 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
|
# --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
|
# --build builds the image from the Dockerfile in .ci/$NAME
|
||||||
# --save stores the image, if an image was loaded it will not be stored
|
# --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
|
# requires: docker
|
||||||
# uses env: NAME CACHE BUILD GET SAVE (correspond to args: <name> --set-cache <cache> --build --get --save)
|
# uses env: NAME CACHE BUILD GET SAVE INTERACTIVE
|
||||||
|
# (correspond to args: <name> --set-cache <cache> --build --get --save --interactive)
|
||||||
# sets env: RUN CCACHE_DIR IMAGE_NAME RUN_ARGS RUN_OPTS BUILD_SCRIPT
|
# 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
|
# exitcode: 1 for failure, 2 for missing dockerfile, 3 for invalid arguments
|
||||||
export BUILD_SCRIPT=".ci/compile.sh"
|
export BUILD_SCRIPT=".ci/compile.sh"
|
||||||
@@ -18,7 +22,7 @@ image_cache="image"
|
|||||||
ccache_cache=".ccache"
|
ccache_cache=".ccache"
|
||||||
|
|
||||||
# Read arguments
|
# Read arguments
|
||||||
while [[ "$@" ]]; do
|
while [[ $# != 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
'--build')
|
'--build')
|
||||||
BUILD=1
|
BUILD=1
|
||||||
@@ -28,6 +32,10 @@ while [[ "$@" ]]; do
|
|||||||
GET=1
|
GET=1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
'--interactive')
|
||||||
|
INTERACTIVE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
'--save')
|
'--save')
|
||||||
SAVE=1
|
SAVE=1
|
||||||
shift
|
shift
|
||||||
@@ -36,12 +44,12 @@ while [[ "$@" ]]; do
|
|||||||
CACHE=$2
|
CACHE=$2
|
||||||
if ! [[ -d $CACHE ]]; then
|
if ! [[ -d $CACHE ]]; then
|
||||||
echo "could not find cache path: $CACHE" >&2
|
echo "could not find cache path: $CACHE" >&2
|
||||||
exit 3
|
return 3
|
||||||
fi
|
fi
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if [[ $1 == -* ]]; then
|
if [[ ${1:0:1} == - ]]; then
|
||||||
echo "unrecognized option: $1"
|
echo "unrecognized option: $1"
|
||||||
return 3
|
return 3
|
||||||
fi
|
fi
|
||||||
@@ -67,27 +75,27 @@ fi
|
|||||||
|
|
||||||
if ! [[ $CACHE ]]; then
|
if ! [[ $CACHE ]]; then
|
||||||
echo "cache dir is not set!" >&2
|
echo "cache dir is not set!" >&2
|
||||||
else
|
CACHE="$(mktemp -d)"
|
||||||
if ! [[ -d $CACHE ]]; then
|
echo "set cache dir to $CACHE" >&2
|
||||||
echo "could not find cache dir: $CACHE" >&2
|
fi
|
||||||
mkdir -p $CACHE
|
if ! [[ -d $CACHE ]]; then
|
||||||
unset GET # the dir is empty
|
echo "could not find cache dir: $CACHE" >&2
|
||||||
fi
|
mkdir -p "$CACHE"
|
||||||
if [[ $GET || $SAVE ]]; then
|
unset GET # the dir is empty
|
||||||
img_dir="$CACHE/$image_cache"
|
fi
|
||||||
img_save="$img_dir/$IMAGE_NAME$save_extension"
|
if [[ $GET || $SAVE ]]; then
|
||||||
if ! [[ -d $img_dir ]]; then
|
img_dir="$CACHE/$image_cache"
|
||||||
echo "could not find image dir: $img_dir" >&2
|
img_save="$img_dir/$IMAGE_NAME$save_extension"
|
||||||
mkdir -p "$img_dir"
|
if ! [[ -d $img_dir ]]; then
|
||||||
fi
|
echo "could not find image dir: $img_dir" >&2
|
||||||
fi
|
mkdir -p "$img_dir"
|
||||||
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
|
||||||
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
|
# Get the docker image from previously stored save
|
||||||
if [[ $GET ]]; then
|
if [[ $GET ]]; then
|
||||||
@@ -132,15 +140,26 @@ fi
|
|||||||
function RUN ()
|
function RUN ()
|
||||||
{
|
{
|
||||||
echo "running image:"
|
echo "running image:"
|
||||||
if docker images | grep "$IMAGE_NAME"; then
|
if [[ $(docker images) =~ "$IMAGE_NAME" ]]; then
|
||||||
args="--mount type=bind,source=$PWD,target=/src -w=/src"
|
local args=(--mount "type=bind,source=$PWD,target=/src")
|
||||||
|
args+=(--workdir "/src")
|
||||||
|
args+=(--user "$(id -u):$(id -g)")
|
||||||
if [[ $CCACHE_DIR ]]; then
|
if [[ $CCACHE_DIR ]]; then
|
||||||
args+=" --mount type=bind,source=$CCACHE_DIR,target=/.ccache -e CCACHE_DIR=/.ccache"
|
args+=(--mount "type=bind,source=$CCACHE_DIR,target=/.ccache")
|
||||||
|
args+=(--env "CCACHE_DIR=/.ccache")
|
||||||
fi
|
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 $?
|
return $?
|
||||||
else
|
else
|
||||||
echo "could not find docker image: $IMAGE_NAME" >&2
|
echo "could not find docker image: $IMAGE_NAME" >&2
|
||||||
return 3
|
return 3
|
||||||
fi
|
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
|
git fetch --unshallow
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check formatting using clangify
|
# Check formatting using format.sh
|
||||||
echo "Checking your code using clang-format..."
|
echo "Checking your code using clang-format/cmake-format..."
|
||||||
|
|
||||||
diff="$(./clangify.sh --diff --cf-version --branch origin/master)"
|
diff="$(./format.sh --diff --cmake --cf-version --branch origin/master)"
|
||||||
err=$?
|
err=$?
|
||||||
|
|
||||||
case $err in
|
case $err in
|
||||||
@@ -24,7 +24,7 @@ case $err in
|
|||||||
*** ***
|
*** ***
|
||||||
*** Your code does not comply with our style guide. ***
|
*** Your code does not comply with our style guide. ***
|
||||||
*** ***
|
*** ***
|
||||||
*** Please correct it or run the "clangify.sh" script. ***
|
*** Please correct it or run the "format.sh" script. ***
|
||||||
*** Then commit and push those changes to this branch. ***
|
*** Then commit and push those changes to this branch. ***
|
||||||
*** Check our CONTRIBUTING.md file for more details. ***
|
*** Check our CONTRIBUTING.md file for more details. ***
|
||||||
*** ***
|
*** ***
|
||||||
@@ -32,21 +32,23 @@ case $err in
|
|||||||
*** ***
|
*** ***
|
||||||
***********************************************************
|
***********************************************************
|
||||||
|
|
||||||
Used clang-format version:
|
Used version:
|
||||||
${diff%%
|
${diff%%
|
||||||
|
----------
|
||||||
*}
|
*}
|
||||||
|
|
||||||
The following changes should be made:
|
The following changes should be made:
|
||||||
${diff#*
|
${diff#*
|
||||||
|
----------
|
||||||
}
|
}
|
||||||
|
|
||||||
Exiting...
|
Exiting...
|
||||||
EOM
|
EOM
|
||||||
exit 2
|
exit 2
|
||||||
;;
|
;;
|
||||||
|
|
||||||
0)
|
0)
|
||||||
cat <<EOM
|
cat <<EOM
|
||||||
|
|
||||||
***********************************************************
|
***********************************************************
|
||||||
*** ***
|
*** ***
|
||||||
@@ -58,12 +60,10 @@ EOM
|
|||||||
|
|
||||||
Exiting...
|
Exiting...
|
||||||
EOM
|
EOM
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo ""
|
echo "Something went wrong in our formatting checks: format.sh returned $err" >&2
|
||||||
echo "Something went wrong in our formatting checks: clangify returned $err" >&2
|
;;
|
||||||
echo ""
|
esac
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -3,8 +3,9 @@
|
|||||||
# renames the file to [original name][SUFFIX].[original extension]
|
# renames the file to [original name][SUFFIX].[original extension]
|
||||||
# where SUFFIX is either available in the environment or as the first arg
|
# where SUFFIX is either available in the environment or as the first arg
|
||||||
# if MAKE_ZIP is set instead a zip is made
|
# if MAKE_ZIP is set instead a zip is made
|
||||||
# expected to be run in the build directory
|
# expected to be run in the build directory unless BUILD_DIR is set
|
||||||
builddir="."
|
# adds output to GITHUB_OUTPUT
|
||||||
|
builddir="${BUILD_DIR:=.}"
|
||||||
findrx="Cockatrice-*.*"
|
findrx="Cockatrice-*.*"
|
||||||
|
|
||||||
if [[ $1 ]]; then
|
if [[ $1 ]]; then
|
||||||
@@ -27,6 +28,7 @@ if [[ ! $file ]]; then
|
|||||||
echo "::error file=$0::could not find package"
|
echo "::error file=$0::could not find package"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
oldpwd="$PWD"
|
||||||
if ! cd "$path"; then
|
if ! cd "$path"; then
|
||||||
echo "::error file=$0::could not get file path"
|
echo "::error file=$0::could not get file path"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -45,6 +47,9 @@ else
|
|||||||
echo "renaming '$file' to '$filename'"
|
echo "renaming '$file' to '$filename'"
|
||||||
mv "$file" "$filename"
|
mv "$file" "$filename"
|
||||||
fi
|
fi
|
||||||
ls -l "$PWD/$filename"
|
|
||||||
echo "::set-output name=path::$PWD/$filename"
|
cd "$oldpwd"
|
||||||
echo "::set-output name=name::$filename"
|
relative_path="$path/$filename"
|
||||||
|
ls -l "$relative_path"
|
||||||
|
echo "path=$relative_path" >>"$GITHUB_OUTPUT"
|
||||||
|
echo "name=$filename" >>"$GITHUB_OUTPUT"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# the releases are first made as drafts and will be vetted by a human
|
# the releases are first made as drafts and will be vetted by a human
|
||||||
# it just has to provide a template
|
# it just has to provide a template
|
||||||
# this requires the repo to be unshallowed
|
# this requires the repo to be unshallowed
|
||||||
|
# adds output to GITHUB_OUTPUT
|
||||||
template_path=".ci/release_template.md"
|
template_path=".ci/release_template.md"
|
||||||
body_path="/tmp/release.md"
|
body_path="/tmp/release.md"
|
||||||
beta_regex='beta'
|
beta_regex='beta'
|
||||||
@@ -22,22 +23,22 @@ fi
|
|||||||
|
|
||||||
# create title
|
# create title
|
||||||
if [[ $TAG =~ $beta_regex ]]; then
|
if [[ $TAG =~ $beta_regex ]]; then
|
||||||
echo "::set-output name=is_beta::yes"
|
echo "is_beta=yes" >>"$GITHUB_OUTPUT"
|
||||||
title="$TAG"
|
title="$TAG"
|
||||||
echo "creating beta release '$title'"
|
echo "creating beta release '$title'"
|
||||||
elif [[ ! $(cat CMakeLists.txt) =~ $name_regex ]]; then
|
elif [[ ! $(cat CMakeLists.txt) =~ $name_regex ]]; then
|
||||||
echo "::error file=$0::could not find releasename in CMakeLists.txt"
|
echo "::error file=$0::could not find releasename in CMakeLists.txt"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo "::set-output name=is_beta::no"
|
echo "is_beta=no" >>"$GITHUB_OUTPUT"
|
||||||
name="${BASH_REMATCH[1]}"
|
name="${BASH_REMATCH[1]}"
|
||||||
version="${TAG##*-}"
|
version="${TAG##*-}"
|
||||||
title="Cockatrice $version: $name"
|
title="Cockatrice $version: $name"
|
||||||
no_beta=1
|
no_beta=1
|
||||||
echo "::set-output name=friendly_name::$name"
|
echo "friendly_name=$name" >>"$GITHUB_OUTPUT"
|
||||||
echo "creating full release '$title'"
|
echo "creating full release '$title'"
|
||||||
fi
|
fi
|
||||||
echo "::set-output name=title::$title"
|
echo "title=$title" >>"$GITHUB_OUTPUT"
|
||||||
|
|
||||||
# add release notes template
|
# add release notes template
|
||||||
if [[ $no_beta ]]; then
|
if [[ $no_beta ]]; then
|
||||||
@@ -60,9 +61,9 @@ fi
|
|||||||
all_tags="
|
all_tags="
|
||||||
$(git tag)" # tags are ordered alphabetically
|
$(git tag)" # tags are ordered alphabetically
|
||||||
before="${all_tags%%
|
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
|
# 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"
|
echo "::warning file=$0::could not find current tag"
|
||||||
else
|
else
|
||||||
while
|
while
|
||||||
@@ -74,7 +75,7 @@ else
|
|||||||
beta_list+=" $previous" # add to list of skipped betas
|
beta_list+=" $previous" # add to list of skipped betas
|
||||||
next_before="${before%
|
next_before="${before%
|
||||||
*}" # strip the last line
|
*}" # strip the last line
|
||||||
if [[ $next_before == $before ]]; then
|
if [[ $next_before == "$before" ]]; then
|
||||||
unset previous
|
unset previous
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
@@ -108,5 +109,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# write to file
|
# write to file
|
||||||
echo "::set-output name=body_path::$body_path"
|
echo "body_path=$body_path" >>"$GITHUB_OUTPUT"
|
||||||
echo "$body" >"$body_path"
|
echo "$body" >"$body_path"
|
||||||
|
|||||||
@@ -8,26 +8,25 @@ git push -d origin --REPLACE-WITH-BETA-LIST--
|
|||||||
include different targets -->
|
include different targets -->
|
||||||
<pre>
|
<pre>
|
||||||
<b>Pre-compiled binaries we serve:</b>
|
<b>Pre-compiled binaries we serve:</b>
|
||||||
- <kbd>Windows 7/8/10 (32-bit)</kbd></i>
|
- <kbd>Windows 7+</kbd>
|
||||||
- <kbd>Windows 7/8/10 (64-bit)</kbd></i>
|
- <kbd>Windows 10+</kbd>
|
||||||
- <kbd>macOS 10.14</kbd> ("Mojave")</i>
|
- <kbd>macOS 10.15+</kbd> ("Catalina")
|
||||||
- <kbd>macOS 10.15</kbd> ("Catalina")</i>
|
- <kbd>macOS 13+</kbd> ("Ventura")
|
||||||
- <kbd>macOS 11.0</kbd> ("Big Sur")</i>
|
- <kbd>Ubuntu 18.04 LTS</kbd> ("Bionic Beaver")
|
||||||
- <kbd>Ubuntu 18.04</kbd> ("Bionic Beaver")</i>
|
- <kbd>Ubuntu 20.04 LTS</kbd> ("Focal Fossa")
|
||||||
- <kbd>Ubuntu 20.04</kbd> ("Focal Fossa")</i>
|
- <kbd>Ubuntu 22.04 LTS</kbd> ("Jammy Jellyfish")
|
||||||
- <kbd>Ubuntu 20.10</kbd> ("Groovy Gorilla")</i>
|
- <kbd>Ubuntu 24.04 LTS</kbd> ("Noble Numbat")
|
||||||
- <kbd>Ubuntu 21.04</kbd> ("Hirsute Hippo")</i>
|
- <kbd>Debian 11</kbd> ("Bullseye")
|
||||||
- <kbd>Debian 10</kbd> ("Buster")</i>
|
- <kbd>Debian 12</kbd> ("Bookworm")
|
||||||
- <kbd>Fedora 33</kbd></i>
|
- <kbd>Fedora 39</kbd>
|
||||||
- <kbd>Fedora 34</kbd></i>
|
- <kbd>Fedora 40</kbd>
|
||||||
<kbd>We are also packaged in Arch Linux's official community repository, courtesy of @FFY00</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>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
## General Notes
|
## 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'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.
|
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.
|
||||||
@@ -44,7 +43,7 @@ If you'd like to help contribute to Cockatrice in any way, check out our [README
|
|||||||
> ⚠️ **With this release, we no longer provide a ready-to-install binary for:**
|
> ⚠️ **With this release, we no longer provide a ready-to-install binary for:**
|
||||||
> --DEPRECATED-OS-HERE--
|
> --DEPRECATED-OS-HERE--
|
||||||
-->
|
-->
|
||||||
|
|
||||||
- Run the internal software updater: <kbd>Help → Check for Client Updates</kbd>
|
- Run the internal software updater: <kbd>Help → Check for Client Updates</kbd>
|
||||||
|
|
||||||
Don't forget to update your card database right after! (<kbd>Help → Check for Card Updates...</kbd>)
|
Don't forget to update your card database right after! (<kbd>Help → Check for Card Updates...</kbd>)
|
||||||
|
|||||||
58
.ci/update_translation_source_strings.sh
Executable file
58
.ci/update_translation_source_strings.sh
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/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"
|
||||||
14
.ci/update_translation_source_strings_template.md
Normal file
14
.ci/update_translation_source_strings_template.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
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
|
||||||
109
.cmake-format.json
Normal file
109
.cmake-format.json
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
{
|
||||||
|
"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
|
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.
|
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 "Run clangify" step to
|
It's the first job called "linter", you can click the "Check code formatting"
|
||||||
see the output of the test.
|
step to see the output of the test.
|
||||||
|
|
||||||
The message will look like this:
|
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. ***
|
*** Your code does not comply with our style guide. ***
|
||||||
*** ***
|
*** ***
|
||||||
*** Please correct it or run the "clangify.sh" script. ***
|
*** Please correct it or run the "format.sh" script. ***
|
||||||
*** Then commit and push those changes to this branch. ***
|
*** Then commit and push those changes to this branch. ***
|
||||||
*** Check our CONTRIBUTING.md file for more details. ***
|
*** 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
|
almost any environment. A special `.clang-format` configuration file is
|
||||||
included in the project and is used to format your code.
|
included in the project and is used to format your code.
|
||||||
|
|
||||||
We've also included a bash script, `clangify.sh`, that will use clang-format to
|
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 `./clangify.sh --help` to show a
|
format all files in your pr in one go. Use `./format.sh --help` to show a full
|
||||||
full help page.
|
help page.
|
||||||
|
|
||||||
To run clang-format on a single source file simply use the command
|
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
|
`clang-format -i <filename>` to format it in place. (Some systems install
|
||||||
@@ -290,20 +290,21 @@ be included in the next release 👍
|
|||||||
|
|
||||||
Basic workflow for translations:
|
Basic workflow for translations:
|
||||||
1. Developer adds a `tr("foo")` string in the code;
|
1. Developer adds a `tr("foo")` string in the code;
|
||||||
2. Every few days, a maintainer updates the `*_en.ts files` with the new strings;
|
2. CI updates the `*_en@source.ts files` regularly and creates a PR automatically;
|
||||||
3. Transifex picks up the new files from GitHub every 24 hours;
|
3. Maintainer verifies and merges the change;
|
||||||
4. Translators translate the new untranslated strings on Transifex;
|
4. Transifex picks up the new files from GitHub automatically;
|
||||||
5. Before a release, a maintainer fetches the updated translations from Transifex.
|
5. Translators translate the new untranslated strings on Transifex;
|
||||||
|
6. Before a release, a maintainer fetches the updated translations from Transifex.
|
||||||
|
|
||||||
### Using Translations (for developers) ###
|
### Using Translations (for developers) ###
|
||||||
|
|
||||||
All the user-interface strings inside Cockatrice's source code must be written
|
All user interface strings inside Cockatrice's source code must be written
|
||||||
in English(US).
|
in English (US).
|
||||||
Translations to other languages are managed using [Transifex](
|
Translations to other languages are managed using [Transifex](
|
||||||
https://www.transifex.com/projects/p/cockatrice/).
|
https://www.transifex.com/projects/p/cockatrice/).
|
||||||
|
|
||||||
Adding a new string to translate is as easy as adding the string in the
|
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.
|
and translated as needed.
|
||||||
For example, setting the text of a label in the way that the string
|
For example, setting the text of a label in the way that the string
|
||||||
`"My name is:"` can be translated:
|
`"My name is:"` can be translated:
|
||||||
@@ -312,7 +313,7 @@ nameLabel.setText(tr("My name is:"));
|
|||||||
```
|
```
|
||||||
|
|
||||||
To translate a string that would have plural forms you can add the amount to
|
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++
|
```c++
|
||||||
QString message = tr("Everyone draws %n cards", "pop up message", amount);
|
QString message = tr("Everyone draws %n cards", "pop up message", amount);
|
||||||
```
|
```
|
||||||
@@ -321,20 +322,46 @@ 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
|
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
|
string in the code, you don't need to take care of adding the new strings to
|
||||||
the translation files.
|
the translation files.<br>
|
||||||
Every few days, or when a lot of new strings have been added, someone from the
|
We have an automated process to update our language source files on a schedule
|
||||||
development team will take care of extracting all the new strings and adding
|
and provide the translators on Transifex with the new contents.<br>
|
||||||
them to the english translation files and making them available to translators
|
Maintainers can also manually trigger this on demand.
|
||||||
on Transifex.
|
|
||||||
|
|
||||||
### Maintaining Translations (for maintainers) ###
|
### Maintaining Translations (for maintainers) ###
|
||||||
|
|
||||||
When new translatable strings have been added to the code, a maintainer should
|
When new translatable strings have been added to the code, a maintainer has to
|
||||||
make them available to translators on Transifex. Every few days, or when a lot
|
make them available to translators on Transifex.
|
||||||
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 update the english translation files, re-run cmake enabling the appropriate
|
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
|
||||||
parameter and then run make:
|
parameter and then run make:
|
||||||
```sh
|
```sh
|
||||||
cd cockatrice/build
|
cd cockatrice/build
|
||||||
@@ -344,24 +371,26 @@ make
|
|||||||
If the parameter has been enabled correctly, when running "make" you should see
|
If the parameter has been enabled correctly, when running "make" you should see
|
||||||
a line similar to this one (the numbers may vary):
|
a line similar to this one (the numbers may vary):
|
||||||
```sh
|
```sh
|
||||||
[ 76%] Generating ../../cockatrice/translations/cockatrice_en.ts
|
[ 76%] Generating ../../cockatrice/translations/cockatrice_en@source.ts
|
||||||
Updating '../../cockatrice/translations/cockatrice_en.ts'...
|
Updating '../../cockatrice/translations/cockatrice_en@source.ts'...
|
||||||
Found 857 source text(s) (8 new and 849 already existing)
|
Found 857 source text(s) (8 new and 849 already existing)
|
||||||
```
|
```
|
||||||
You should then notice that the following files have uncommitted changes:
|
You should then notice that the following files have uncommitted changes:
|
||||||
|
|
||||||
cockatrice/translations/cockatrice_en.ts
|
cockatrice/translations/cockatrice_en@source.ts
|
||||||
oracle/translations/oracle_en.ts
|
oracle/translations/oracle_en@source.ts
|
||||||
|
|
||||||
It is recommended to disable the parameter afterwards using:
|
It is recommended to disable the parameter afterwards using:
|
||||||
```sh
|
```sh
|
||||||
cmake .. -DUPDATE_TRANSLATIONS=OFF
|
cmake .. -DUPDATE_TRANSLATIONS=OFF
|
||||||
```
|
```
|
||||||
Now you are ready to propose your change.
|
Now you are ready to commit your changes and open a PR.
|
||||||
|
|
||||||
Once your change gets merged, Transifex will pick up the modified files
|
</details>
|
||||||
automatically (checked every 24 hours) and update the interface where
|
|
||||||
translators will be able to translate the new strings.
|
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.
|
||||||
|
|
||||||
### Releasing Translations (for maintainers) ###
|
### Releasing Translations (for maintainers) ###
|
||||||
|
|
||||||
|
|||||||
49
.github/dependabot.yml
vendored
Normal file
49
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# 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
|
||||||
407
.github/workflows/ci-builds.yml
vendored
407
.github/workflows/ci-builds.yml
vendored
@@ -1,407 +0,0 @@
|
|||||||
name: Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
- 'webclient/**'
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
- 'webclient/**'
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
- name: Configure
|
|
||||||
id: configure
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
tag_regex='^refs/tags/'
|
|
||||||
if [[ $GITHUB_EVENT_NAME == pull-request ]]; then # pull request
|
|
||||||
sha="${{github.event.pull_request.head.sha}}"
|
|
||||||
elif [[ $GITHUB_REF =~ $tag_regex ]]; then # release
|
|
||||||
sha="$GITHUB_SHA"
|
|
||||||
tag="${GITHUB_REF/refs\/tags\//}"
|
|
||||||
echo "::set-output name=tag::$tag"
|
|
||||||
else # push to branch
|
|
||||||
sha="$GITHUB_SHA"
|
|
||||||
fi
|
|
||||||
echo "::set-output name=sha::$sha"
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
if: steps.configure.outputs.tag != null
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Prepare release paramaters
|
|
||||||
id: prepare
|
|
||||||
if: steps.configure.outputs.tag != null
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{steps.configure.outputs.tag}}
|
|
||||||
run: .ci/prep_release.sh
|
|
||||||
|
|
||||||
- name: Create release
|
|
||||||
if: steps.configure.outputs.tag != null
|
|
||||||
id: create_release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{github.token}}
|
|
||||||
with:
|
|
||||||
tag_name: ${{github.ref}}
|
|
||||||
release_name: ${{steps.prepare.outputs.title}}
|
|
||||||
body_path: ${{steps.prepare.outputs.body_path}}
|
|
||||||
draft: true
|
|
||||||
prerelease: ${{steps.prepare.outputs.is_beta == 'yes'}}
|
|
||||||
|
|
||||||
build-linux:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
# these names correspond to the files in .ci/$distro
|
|
||||||
include:
|
|
||||||
- distro: UbuntuHirsute
|
|
||||||
package: DEB
|
|
||||||
|
|
||||||
- distro: UbuntuGroovy
|
|
||||||
package: DEB
|
|
||||||
test: skip
|
|
||||||
|
|
||||||
- distro: UbuntuFocal
|
|
||||||
package: DEB
|
|
||||||
test: skip # UbuntuFocal has a broken qt for debug builds
|
|
||||||
|
|
||||||
- distro: UbuntuBionic
|
|
||||||
package: DEB
|
|
||||||
|
|
||||||
- distro: ArchLinux
|
|
||||||
package: skip # we are packaged in arch already
|
|
||||||
allow-failure: yes
|
|
||||||
|
|
||||||
- distro: DebianBuster
|
|
||||||
package: DEB
|
|
||||||
|
|
||||||
- distro: Fedora33
|
|
||||||
package: RPM
|
|
||||||
test: skip # Fedora is our slowest build
|
|
||||||
|
|
||||||
- distro: Fedora34
|
|
||||||
package: RPM
|
|
||||||
test: skip # gtest does not compile for some reason
|
|
||||||
|
|
||||||
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?
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Get cache timestamp
|
|
||||||
id: cache_timestamp
|
|
||||||
shell: bash
|
|
||||||
run: echo "::set-output name=timestamp::$(date -u '+%Y%m%d%H%M%S')"
|
|
||||||
|
|
||||||
- name: Restore cache
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
timestamp: ${{steps.cache_timestamp.outputs.timestamp}}
|
|
||||||
with:
|
|
||||||
path: ${{env.CACHE}}
|
|
||||||
key: docker-${{matrix.distro}}-cache-${{env.timestamp}}
|
|
||||||
restore-keys: |
|
|
||||||
docker-${{matrix.distro}}-cache-
|
|
||||||
|
|
||||||
- name: Build ${{matrix.distro}} Docker image
|
|
||||||
shell: bash
|
|
||||||
run: source .ci/docker.sh --build
|
|
||||||
|
|
||||||
- name: Build debug and test
|
|
||||||
if: matrix.test != 'skip'
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
source .ci/docker.sh
|
|
||||||
RUN --server --debug --test
|
|
||||||
|
|
||||||
- name: Build release package
|
|
||||||
id: package
|
|
||||||
if: matrix.package != 'skip'
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
suffix: '-${{matrix.distro}}'
|
|
||||||
type: '${{matrix.package}}'
|
|
||||||
run: |
|
|
||||||
source .ci/docker.sh
|
|
||||||
RUN --server --release --package "$type" --suffix "$suffix"
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
if: matrix.package != 'skip'
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: ${{matrix.distro}}-package
|
|
||||||
path: ./build/${{steps.package.outputs.name}}
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
- name: Upload to release
|
|
||||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
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.0_Big_Sur
|
|
||||||
include:
|
|
||||||
- target: Debug # tests only
|
|
||||||
os: macos-latest
|
|
||||||
xcode: 11.7
|
|
||||||
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: 11.7
|
|
||||||
type: Release
|
|
||||||
do_tests: 0
|
|
||||||
make_package: true
|
|
||||||
|
|
||||||
- target: 11.0_Big_Sur
|
|
||||||
os: macos-11.0
|
|
||||||
xcode: 12.2
|
|
||||||
type: Release
|
|
||||||
do_tests: 0
|
|
||||||
make_package: true
|
|
||||||
|
|
||||||
name: macOS ${{matrix.target}}
|
|
||||||
|
|
||||||
needs: configure
|
|
||||||
|
|
||||||
runs-on: ${{matrix.os}}
|
|
||||||
|
|
||||||
continue-on-error: ${{matrix.allow-failure == 'yes'}}
|
|
||||||
|
|
||||||
env:
|
|
||||||
CCACHE_DIR: ~/.ccache
|
|
||||||
DEVELOPER_DIR:
|
|
||||||
/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Install dependencies using homebrew
|
|
||||||
shell: bash
|
|
||||||
# cmake cannot find the mysql connector
|
|
||||||
# neither of these works: mariadb-connector-c mysql-connector-c++
|
|
||||||
run: brew install ccache 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: Get ccache timestamp
|
|
||||||
id: ccache_timestamp
|
|
||||||
shell: bash
|
|
||||||
run: echo "::set-output name=timestamp::$(date -u '+%Y%m%d%H%M%S')"
|
|
||||||
|
|
||||||
- name: Restore ccache cache
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
timestamp: ${{steps.ccache_timestamp.outputs.timestamp}}
|
|
||||||
with:
|
|
||||||
path: ${{env.CCACHE_DIR}}
|
|
||||||
key: ${{runner.os}}-xcode-${{matrix.xcode}}-ccache-${{env.timestamp}}
|
|
||||||
restore-keys: |
|
|
||||||
${{runner.os}}-xcode-${{matrix.xcode}}-ccache-
|
|
||||||
|
|
||||||
- name: Build on Xcode ${{matrix.xcode}}
|
|
||||||
shell: bash
|
|
||||||
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@v2
|
|
||||||
with:
|
|
||||||
name: macOS-${{matrix.target}}-xcode-${{matrix.xcode}}-dmg
|
|
||||||
path: ${{steps.package.outputs.path}}
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
- name: Upload to release
|
|
||||||
if: matrix.make_package && needs.configure.outputs.tag != null
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
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:
|
|
||||||
- arch: 64
|
|
||||||
triplet: x64
|
|
||||||
cmake: x64
|
|
||||||
append: _64
|
|
||||||
|
|
||||||
- arch: 32
|
|
||||||
triplet: x86
|
|
||||||
cmake: Win32
|
|
||||||
|
|
||||||
name: Windows ${{matrix.arch}}
|
|
||||||
|
|
||||||
needs: configure
|
|
||||||
|
|
||||||
runs-on: windows-latest
|
|
||||||
|
|
||||||
env:
|
|
||||||
QT_VERSION: '5.12.9'
|
|
||||||
QT_ARCH: msvc2017${{matrix.append}}
|
|
||||||
CMAKE_GENERATOR: 'Visual Studio 16 2019'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Add msbuild to PATH
|
|
||||||
id: add-msbuild
|
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Restore Qt ${{env.QT_VERSION}} ${{matrix.arch}}-bit from cache
|
|
||||||
id: cache-qt
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
key: ${{runner.os}}-QtCache-${{env.QT_VERSION}}-${{matrix.arch}}
|
|
||||||
path: ${{runner.workspace}}/Qt
|
|
||||||
|
|
||||||
- name: Install ${{matrix.arch}}-bit Qt
|
|
||||||
uses: jurplel/install-qt-action@v2
|
|
||||||
with:
|
|
||||||
cached: ${{steps.cache-qt.outputs.cache-hit}}
|
|
||||||
version: ${{env.QT_VERSION}}
|
|
||||||
arch: win${{matrix.arch}}_${{env.QT_ARCH}}
|
|
||||||
|
|
||||||
- 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
|
|
||||||
run: |
|
|
||||||
mkdir -p build
|
|
||||||
cd build
|
|
||||||
export QTDIR="${{runner.workspace}}/Qt/$QT_VERSION/$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@v2
|
|
||||||
with:
|
|
||||||
name: Windows-${{matrix.arch}}bit-installer
|
|
||||||
path: ./build/${{steps.package.outputs.name}}
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
- name: Upload to release
|
|
||||||
if: needs.configure.outputs.tag != null
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
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
|
|
||||||
28
.github/workflows/clangify.yml
vendored
28
.github/workflows/clangify.yml
vendored
@@ -1,28 +0,0 @@
|
|||||||
name: Clangify
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
linter:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: 20 # should be enough to find merge base
|
|
||||||
|
|
||||||
- name: Install clang-format
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y --no-install-recommends clang-format
|
|
||||||
|
|
||||||
- name: Run clangify
|
|
||||||
shell: bash
|
|
||||||
run: ./.ci/lint.sh
|
|
||||||
350
.github/workflows/desktop-build.yml
vendored
Normal file
350
.github/workflows/desktop-build.yml
vendored
Normal file
@@ -0,0 +1,350 @@
|
|||||||
|
name: Build Desktop
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
- 'webclient/**'
|
||||||
|
- '.github/workflows/web-*.yml'
|
||||||
|
- '.github/workflows/translations-*.yml'
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
pull_request:
|
||||||
|
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}}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Configure
|
||||||
|
id: configure
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
tag_regex='^refs/tags/'
|
||||||
|
if [[ $GITHUB_EVENT_NAME == pull-request ]]; then # pull request
|
||||||
|
sha="${{github.event.pull_request.head.sha}}"
|
||||||
|
elif [[ $GITHUB_REF =~ $tag_regex ]]; then # release
|
||||||
|
sha="$GITHUB_SHA"
|
||||||
|
tag="${GITHUB_REF/refs\/tags\//}"
|
||||||
|
echo "tag=$tag" >>"$GITHUB_OUTPUT"
|
||||||
|
else # push to branch
|
||||||
|
sha="$GITHUB_SHA"
|
||||||
|
fi
|
||||||
|
echo "sha=$sha" >>"$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
if: steps.configure.outputs.tag != null
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Prepare release parameters
|
||||||
|
id: prepare
|
||||||
|
if: steps.configure.outputs.tag != null
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
TAG: ${{steps.configure.outputs.tag}}
|
||||||
|
run: .ci/prep_release.sh
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
if: steps.configure.outputs.tag != null
|
||||||
|
id: create_release
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{github.token}}
|
||||||
|
tag_name: ${{steps.configure.outputs.tag}}
|
||||||
|
target: ${{steps.configure.outputs.sha}}
|
||||||
|
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"
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
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
|
||||||
|
package: DEB
|
||||||
|
|
||||||
|
- distro: Debian12
|
||||||
|
package: DEB
|
||||||
|
|
||||||
|
- distro: Fedora39
|
||||||
|
package: RPM
|
||||||
|
|
||||||
|
- distro: Fedora40
|
||||||
|
package: RPM
|
||||||
|
|
||||||
|
- distro: UbuntuBionic
|
||||||
|
package: DEB
|
||||||
|
|
||||||
|
- distro: UbuntuFocal
|
||||||
|
package: DEB
|
||||||
|
test: skip # UbuntuFocal has a broken qt for debug builds
|
||||||
|
|
||||||
|
- distro: UbuntuJammy
|
||||||
|
package: DEB
|
||||||
|
test: skip # running tests on all distros is superfluous
|
||||||
|
|
||||||
|
- distro: UbuntuNoble
|
||||||
|
package: DEB
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
- name: Get cache timestamp
|
||||||
|
id: cache_timestamp
|
||||||
|
shell: bash
|
||||||
|
run: echo "timestamp=$(date -u '+%Y%m%d%H%M%S')" >>"$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Restore cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
env:
|
||||||
|
timestamp: ${{steps.cache_timestamp.outputs.timestamp}}
|
||||||
|
with:
|
||||||
|
path: ${{env.CACHE}}
|
||||||
|
key: docker-${{matrix.distro}}-cache-${{env.timestamp}}
|
||||||
|
restore-keys: |
|
||||||
|
docker-${{matrix.distro}}-cache-
|
||||||
|
|
||||||
|
- name: Build ${{matrix.distro}} Docker image
|
||||||
|
shell: bash
|
||||||
|
run: source .ci/docker.sh --build
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- name: Build release package
|
||||||
|
id: build
|
||||||
|
if: matrix.package != 'skip'
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
BUILD_DIR: build
|
||||||
|
SUFFIX: '-${{matrix.distro}}'
|
||||||
|
distro: '${{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
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
if: matrix.package != 'skip'
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{matrix.distro}}-package
|
||||||
|
path: ${{steps.build.outputs.path}}
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Upload to release
|
||||||
|
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{github.token}}
|
||||||
|
tag_name: ${{needs.configure.outputs.tag}}
|
||||||
|
asset_path: ${{steps.build.outputs.path}}
|
||||||
|
asset_name: ${{steps.build.outputs.name}}
|
||||||
|
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
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"
|
||||||
|
type: Debug
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
if: matrix.make_package
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: macOS-${{matrix.target}}-dmg
|
||||||
|
path: ${{steps.build.outputs.path}}
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Upload to release
|
||||||
|
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{github.token}}
|
||||||
|
tag_name: ${{needs.configure.outputs.tag}}
|
||||||
|
asset_path: ${{steps.build.outputs.path}}
|
||||||
|
asset_name: ${{steps.build.outputs.name}}
|
||||||
|
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- target: 7
|
||||||
|
qt_version: 5.15.*
|
||||||
|
qt_arch: msvc2019_64
|
||||||
|
qt_tools: "tools_opensslv3_x64"
|
||||||
|
|
||||||
|
- target: 10
|
||||||
|
qt_version: 6.5.*
|
||||||
|
qt_arch: msvc2019_64
|
||||||
|
qt_tools: "tools_opensslv3_x64"
|
||||||
|
qt_modules: "qtmultimedia qtwebsockets"
|
||||||
|
|
||||||
|
name: Windows ${{matrix.target}}
|
||||||
|
needs: configure
|
||||||
|
runs-on: windows-2022
|
||||||
|
env:
|
||||||
|
CMAKE_GENERATOR: 'Visual Studio 17 2022'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Add msbuild to PATH
|
||||||
|
id: add-msbuild
|
||||||
|
uses: microsoft/setup-msbuild@v2
|
||||||
|
with:
|
||||||
|
msbuild-architecture: x64
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Install Qt ${{matrix.qt_version}}
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
cache: true
|
||||||
|
setup-python: false
|
||||||
|
version: ${{matrix.qt_version}}
|
||||||
|
arch: win64_${{matrix.qt_arch}}
|
||||||
|
tools: ${{matrix.qt_tools}}
|
||||||
|
modules: ${{matrix.qt_modules}}
|
||||||
|
|
||||||
|
- name: Run vcpkg
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
with:
|
||||||
|
runVcpkgInstall: true
|
||||||
|
doNotCache: false
|
||||||
|
env:
|
||||||
|
VCPKG_DEFAULT_TRIPLET: 'x64-windows'
|
||||||
|
VCPKG_DISABLE_METRICS: 1
|
||||||
|
|
||||||
|
- name: Build Cockatrice
|
||||||
|
id: build
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
PACKAGE_SUFFIX: '-Win${{matrix.target}}'
|
||||||
|
CMAKE_GENERATOR: '${{env.CMAKE_GENERATOR}}'
|
||||||
|
CMAKE_GENERATOR_PLATFORM: 'x64'
|
||||||
|
QTDIR: '${{github.workspace}}\Qt\${{matrix.qt_version}}\win64_${{matrix.qt_arch}}'
|
||||||
|
# No need for --parallel flag, MTT is added in the compile script to let cmake/msbuild manage core count,
|
||||||
|
# project and process parallelism: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||||
|
run: .ci/compile.sh --server --release --test --package
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Windows${{matrix.target}}-installer
|
||||||
|
path: ${{steps.build.outputs.path}}
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Upload to release
|
||||||
|
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{github.token}}
|
||||||
|
tag_name: ${{needs.configure.outputs.tag}}
|
||||||
|
asset_path: ${{steps.build.outputs.path}}
|
||||||
|
asset_name: ${{steps.build.outputs.name}}
|
||||||
|
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||||
29
.github/workflows/desktop-lint.yml
vendored
Normal file
29
.github/workflows/desktop-lint.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Code Style (C++)
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
- 'webclient/**'
|
||||||
|
- '.github/workflows/web-*.yml'
|
||||||
|
- '.github/workflows/translations-*.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
format:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 20 # should be enough to find merge base
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends clang-format cmake-format
|
||||||
|
|
||||||
|
- name: Check code formatting
|
||||||
|
shell: bash
|
||||||
|
run: ./.ci/lint_cpp.sh
|
||||||
72
.github/workflows/translations-pull.yml
vendored
Normal file
72
.github/workflows/translations-pull.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
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
Normal file
87
.github/workflows/translations-push.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
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
|
||||||
52
.github/workflows/web-build.yml
vendored
Normal file
52
.github/workflows/web-build.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
name: Build Web
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/web-*.yml'
|
||||||
|
- 'webclient/**'
|
||||||
|
- '!**.md'
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/web-*.yml'
|
||||||
|
- 'webclient/**'
|
||||||
|
- '!**.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-web:
|
||||||
|
name: React (Node ${{matrix.node_version}})
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: webclient
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
node_version:
|
||||||
|
- 16
|
||||||
|
- lts/*
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{matrix.node_version}}
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: 'webclient/package-lock.json'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm clean-install
|
||||||
|
|
||||||
|
- name: Build app
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Test app
|
||||||
|
run: npm run test
|
||||||
32
.github/workflows/web-lint.yml
vendored
Normal file
32
.github/workflows/web-lint.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: Code Style (TypeScript)
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/web-*.yml'
|
||||||
|
- 'webclient/**'
|
||||||
|
- '!**.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ESLint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: webclient
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: 'webclient/package-lock.json'
|
||||||
|
|
||||||
|
- name: Install ESLint
|
||||||
|
run: npm clean-install --ignore-scripts
|
||||||
|
|
||||||
|
- name: Run ESLint
|
||||||
|
run: npm run lint
|
||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -6,5 +6,10 @@ mysql.cnf
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.idea/
|
.idea/
|
||||||
*.aps
|
*.aps
|
||||||
cmake-build-debug/
|
cmake-build-debug*
|
||||||
preferences
|
preferences
|
||||||
|
compile_commands.json
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
.cache
|
||||||
|
.gdb_history
|
||||||
|
|||||||
7
.husky/pre-commit
Executable file
7
.husky/pre-commit
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
cd webclient
|
||||||
|
npm run translate
|
||||||
|
|
||||||
|
git add src/i18n-default.json
|
||||||
27
.tx/config
27
.tx/config
@@ -1,13 +1,26 @@
|
|||||||
[main]
|
[main]
|
||||||
host = https://www.transifex.com
|
host = https://app.transifex.com
|
||||||
|
|
||||||
[cockatrice.cockatrice]
|
[o:cockatrice:p:cockatrice:r:cockatrice-cockatrice-en-source-ts--master]
|
||||||
|
resource_name = Cockatrice
|
||||||
|
source_lang = en
|
||||||
|
source_file = cockatrice/cockatrice_en@source.ts
|
||||||
file_filter = cockatrice/translations/cockatrice_<lang>.ts
|
file_filter = cockatrice/translations/cockatrice_<lang>.ts
|
||||||
source_file = cockatrice/translations/cockatrice_en.ts
|
type = QT
|
||||||
source_lang = en
|
minimum_perc = 10
|
||||||
|
|
||||||
[cockatrice.oracle]
|
[o:cockatrice:p:cockatrice:r:oracle-oracle-en-source-ts--master]
|
||||||
|
resource_name = Oracle
|
||||||
|
source_lang = en
|
||||||
|
source_file = oracle/oracle_en@source.ts
|
||||||
file_filter = oracle/translations/oracle_<lang>.ts
|
file_filter = oracle/translations/oracle_<lang>.ts
|
||||||
source_file = oracle/translations/oracle_en.ts
|
type = QT
|
||||||
source_lang = en
|
minimum_perc = 10
|
||||||
|
|
||||||
|
[o:cockatrice:p:cockatrice:r:webclient-src-i18n-default-json--master]
|
||||||
|
resource_name = Webclient
|
||||||
|
source_lang = en
|
||||||
|
source_file = webclient/src/i18n-default.json
|
||||||
|
file_filter = webclient/public/locales/<lang>/translation.json
|
||||||
|
type = KEYVALUEJSON
|
||||||
|
minimum_perc = 10
|
||||||
|
|||||||
434
CMakeLists.txt
434
CMakeLists.txt
@@ -5,58 +5,95 @@
|
|||||||
# This file sets all the variables shared between the projects
|
# This file sets all the variables shared between the projects
|
||||||
# like the installation path, compilation flags etc..
|
# like the installation path, compilation flags etc..
|
||||||
|
|
||||||
# Cmake 3.1 is required to enable C++11 support correctly
|
# cmake 3.16 is required if using qt6
|
||||||
cmake_minimum_required(VERSION 3.10)
|
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
|
# Default to "Release" build type
|
||||||
# User-provided value for CMAKE_BUILD_TYPE must be checked before the PROJECT() call
|
# User-provided value for CMAKE_BUILD_TYPE must be checked before the PROJECT() call
|
||||||
IF(DEFINED CMAKE_BUILD_TYPE)
|
if(DEFINED CMAKE_BUILD_TYPE)
|
||||||
SET(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Type of build")
|
set(CMAKE_BUILD_TYPE
|
||||||
ELSE()
|
${CMAKE_BUILD_TYPE}
|
||||||
SET(CMAKE_BUILD_TYPE Release CACHE STRING "Type of build")
|
CACHE STRING "Type of build"
|
||||||
ENDIF()
|
)
|
||||||
|
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)
|
if(USE_CCACHE)
|
||||||
find_program(CCACHE_PROGRAM ccache)
|
find_program(CCACHE_PROGRAM ccache)
|
||||||
if(CCACHE_PROGRAM)
|
if(CCACHE_PROGRAM)
|
||||||
# Support Unix Makefiles and Ninja
|
# Support Unix Makefiles and Ninja
|
||||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||||
MESSAGE(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
message(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
# Use vcpkg toolchain on Windows
|
# Use vcpkg toolchain on Windows
|
||||||
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
set(CMAKE_TOOLCHAIN_FILE
|
||||||
CACHE STRING "Vcpkg toolchain file")
|
${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||||
# Qt path set by user or env var
|
CACHE STRING "Vcpkg toolchain file"
|
||||||
if (QTDIR OR DEFINED ENV{QTDIR} OR DEFINED ENV{QTDIR32} OR DEFINED ENV{QTDIR64})
|
)
|
||||||
else()
|
# Qt path set by user or env var
|
||||||
set(QTDIR "" CACHE PATH "Path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
|
if(QTDIR
|
||||||
message(WARNING "QTDIR variable is missing. Please set this variable to specify path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
|
OR DEFINED ENV{QTDIR}
|
||||||
endif()
|
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()
|
endif()
|
||||||
|
|
||||||
# A project name is needed for CPack
|
# A project name is needed for CPack
|
||||||
# Version can be overriden by git tags, see cmake/getversion.cmake
|
# Version can be overriden by git tags, see cmake/getversion.cmake
|
||||||
PROJECT("Cockatrice" VERSION 2.8.1)
|
project("Cockatrice" VERSION 2.9.1)
|
||||||
|
|
||||||
# Set release name if not provided via env/cmake var
|
# Set release name if not provided via env/cmake var
|
||||||
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
||||||
set(GIT_TAG_RELEASENAME "Prismatic Bridge")
|
set(GIT_TAG_RELEASENAME "Rings of the Wild")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use c++11 for all targets
|
# Use c++17 for all targets
|
||||||
set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ ISO Standard")
|
set(CMAKE_CXX_STANDARD
|
||||||
|
17
|
||||||
|
CACHE STRING "C++ ISO Standard"
|
||||||
|
)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
# Set conventional loops
|
# Set conventional loops
|
||||||
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
|
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
|
||||||
|
|
||||||
# Search path for cmake modules
|
# Search path for cmake modules
|
||||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
set(COCKATRICE_CMAKE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||||
|
list(INSERT CMAKE_MODULE_PATH 0 "${COCKATRICE_CMAKE_PATH}")
|
||||||
|
|
||||||
include(getversion)
|
include(getversion)
|
||||||
|
|
||||||
@@ -65,148 +102,150 @@ include(createversionfile)
|
|||||||
|
|
||||||
# Define a proper install path
|
# Define a proper install path
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
# macOS
|
# macOS
|
||||||
# Due to the special bundle structure ignore
|
# Due to the special bundle structure ignore
|
||||||
# the prefix eventually set by the user.
|
# the prefix eventually set by the user.
|
||||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/release)
|
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/release)
|
||||||
|
|
||||||
# Force ccache usage if available
|
# Force ccache usage if available
|
||||||
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
||||||
if(RULE_LAUNCH_COMPILE)
|
if(RULE_LAUNCH_COMPILE)
|
||||||
MESSAGE(STATUS "Force enabling CCache usage under macOS")
|
message(STATUS "Force enabling CCache usage under macOS")
|
||||||
# Set up wrapper scripts
|
# Set up wrapper scripts
|
||||||
configure_file(${CMAKE_MODULE_PATH}/launch-c.in launch-c)
|
configure_file("${COCKATRICE_CMAKE_PATH}/launch-c.in" launch-c)
|
||||||
configure_file(${CMAKE_MODULE_PATH}/launch-cxx.in launch-cxx)
|
configure_file("${COCKATRICE_CMAKE_PATH}/launch-cxx.in" launch-cxx)
|
||||||
execute_process(COMMAND chmod a+rx
|
execute_process(COMMAND chmod a+rx "${CMAKE_BINARY_DIR}/launch-c" "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||||
"${CMAKE_BINARY_DIR}/launch-c"
|
|
||||||
"${CMAKE_BINARY_DIR}/launch-cxx")
|
|
||||||
|
|
||||||
# Set Xcode project attributes to route compilation through our scripts
|
# Set Xcode project attributes to route compilation through our scripts
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
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()
|
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)
|
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()
|
endif()
|
||||||
|
|
||||||
# Treat warnings as errors (Debug builds only)
|
|
||||||
option(WARNING_AS_ERROR "Treat warnings as errors in debug builds" ON)
|
|
||||||
|
|
||||||
# Define proper compilation flags
|
# Define proper compilation flags
|
||||||
IF(MSVC)
|
if(MSVC)
|
||||||
# Visual Studio: Maximum optimization, disable warning C4251
|
# Visual Studio: Maximum optimization, disable warning C4251, establish C++17 compatibility
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD /wd4251 ")
|
set(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD /wd4251 /Zc:__cplusplus /std:c++17 /permissive- /W4")
|
||||||
# Generate complete debugging information
|
# Generate complete debugging information
|
||||||
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||||
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
|
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
# linux/gcc, bsd/gcc, windows/mingw
|
# linux/gcc, bsd/gcc, windows/mingw
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
||||||
if(WARNING_AS_ERROR)
|
if(WARNING_AS_ERROR)
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -Werror")
|
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -Werror")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra")
|
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}")
|
||||||
endif()
|
endif()
|
||||||
|
endforeach()
|
||||||
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)
|
else()
|
||||||
|
# other: osx/llvm, bsd/llvm
|
||||||
FOREACH(FLAG ${ADDITIONAL_DEBUG_FLAGS})
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||||
CHECK_CXX_COMPILER_FLAG("${FLAG}" CXX_HAS_WARNING_${FLAG})
|
if(WARNING_AS_ERROR)
|
||||||
IF(CXX_HAS_WARNING_${FLAG})
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Werror -Wno-unused-parameter")
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
|
else()
|
||||||
ENDIF()
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra")
|
||||||
ENDFOREACH()
|
endif()
|
||||||
ELSE()
|
endif()
|
||||||
# other: osx/llvm, bsd/llvm
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# GNU systems need to define the Mersenne exponent for the RNG to compile w/o warning
|
# GNU systems need to define the Mersenne exponent for the RNG to compile w/o warning
|
||||||
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
ADD_DEFINITIONS("-DSFMT_MEXP=19937")
|
add_definitions("-DSFMT_MEXP=19937")
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
FIND_PACKAGE(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
# Find Qt5
|
# Determine 32 or 64 bit build
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
set(_lib_suffix 64)
|
set(_lib_suffix 64)
|
||||||
else()
|
else()
|
||||||
set(_lib_suffix 32)
|
set(_lib_suffix 32)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DEFINED QTDIR${_lib_suffix})
|
if(DEFINED QTDIR${_lib_suffix})
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
|
list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
|
||||||
elseif(DEFINED QTDIR)
|
elseif(DEFINED QTDIR)
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR}")
|
list(APPEND CMAKE_PREFIX_PATH "${QTDIR}")
|
||||||
elseif(DEFINED ENV{QTDIR${_lib_suffix}})
|
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})
|
elseif(DEFINED ENV{QTDIR})
|
||||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}")
|
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
FIND_PACKAGE(Qt5Core 5.5.0 REQUIRED)
|
message(STATUS "Update Translations: ${UPDATE_TRANSLATIONS}")
|
||||||
|
|
||||||
IF(Qt5Core_FOUND)
|
include(FindQtRuntime)
|
||||||
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)
|
set(CMAKE_AUTOMOC TRUE)
|
||||||
|
|
||||||
# Find other needed libraries
|
# Find other needed libraries
|
||||||
FIND_PACKAGE(Protobuf REQUIRED)
|
find_package(Protobuf CONFIG)
|
||||||
IF(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
if(NOT Protobuf_FOUND)
|
||||||
MESSAGE(FATAL_ERROR "No protoc command found!")
|
find_package(Protobuf REQUIRED)
|
||||||
ELSE()
|
endif()
|
||||||
MESSAGE(STATUS "Protoc version ${Protobuf_VERSION} found!")
|
|
||||||
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 OpenSSL
|
#Find OpenSSL
|
||||||
IF(WIN32)
|
if(WIN32)
|
||||||
FIND_PACKAGE(Win32SslRuntime)
|
find_package(OpenSSL REQUIRED)
|
||||||
ENDIF()
|
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()
|
||||||
|
|
||||||
#Find VCredist
|
#Find VCredist
|
||||||
IF(MSVC)
|
if(MSVC)
|
||||||
FIND_PACKAGE(VCredistRuntime)
|
find_package(VCredistRuntime)
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
# Package builder
|
# Package builder
|
||||||
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zahalpern+github@gmail.com>")
|
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zach@cockatrice.us>")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME})
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME}")
|
||||||
set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team")
|
set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
|
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||||
@@ -216,82 +255,95 @@ set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
|||||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_VERSION_FILENAME}")
|
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_VERSION_FILENAME}")
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
|
set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
|
||||||
set(CPACK_GENERATOR "DragNDrop")
|
set(CPACK_GENERATOR "DragNDrop")
|
||||||
set(CPACK_DMG_FORMAT "UDBZ")
|
set(CPACK_DMG_FORMAT "UDBZ")
|
||||||
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
||||||
set(CPACK_SYSTEM_NAME "OSX")
|
set(CPACK_SYSTEM_NAME "OSX")
|
||||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns")
|
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
|
||||||
|
)
|
||||||
else()
|
else()
|
||||||
# linux
|
set(CPACK_GENERATOR DEB)
|
||||||
IF(CPACK_GENERATOR STREQUAL "RPM")
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||||
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
|
set(CPACK_DEBIAN_PACKAGE_SECTION "games")
|
||||||
set(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt5-qttools, qt5-qtsvg, qt5-qtmultimedia")
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://github.com/Cockatrice/Cockatrice")
|
||||||
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games")
|
if(Qt6_FOUND)
|
||||||
set(CPACK_RPM_PACKAGE_URL "http://github.com/Cockatrice/Cockatrice")
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt6multimedia6, libqt6svg6, qt6-qpa-plugins")
|
||||||
ELSE()
|
elseif(Qt5_FOUND)
|
||||||
set(CPACK_GENERATOR DEB)
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins, libqt5svg5")
|
||||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
endif()
|
||||||
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()
|
||||||
|
endif()
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
|
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
|
||||||
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "(x64)")
|
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "(x64)")
|
||||||
set(TRICE_IS_64_BIT 1)
|
set(TRICE_IS_64_BIT 1)
|
||||||
else()
|
else()
|
||||||
set(TRICE_IS_64_BIT 0)
|
set(TRICE_IS_64_BIT 0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Configure file with custom definitions for NSIS.
|
# Configure file with custom definitions for NSIS.
|
||||||
configure_file(
|
configure_file("${COCKATRICE_CMAKE_PATH}/NSIS.definitions.nsh.in" "${PROJECT_BINARY_DIR}/NSIS.definitions.nsh")
|
||||||
${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
|
# include vcredist into the package; NSIS will take care of running it
|
||||||
if(VCREDISTRUNTIME_FOUND)
|
if(VCREDISTRUNTIME_FOUND)
|
||||||
INSTALL(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
|
install(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|
||||||
# Compile servatrice (default off)
|
|
||||||
option(WITH_SERVER "build servatrice" OFF)
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
if(WITH_SERVER)
|
if(WITH_SERVER)
|
||||||
add_subdirectory(servatrice)
|
add_subdirectory(servatrice)
|
||||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Servatrice;Servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
set(CPACK_INSTALL_CMAKE_PROJECTS "Servatrice;Servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Compile cockatrice (default on)
|
|
||||||
option(WITH_CLIENT "build cockatrice" ON)
|
|
||||||
if(WITH_CLIENT)
|
if(WITH_CLIENT)
|
||||||
add_subdirectory(cockatrice)
|
add_subdirectory(cockatrice)
|
||||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Cockatrice;Cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
set(CPACK_INSTALL_CMAKE_PROJECTS "Cockatrice;Cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Compile oracle (default on)
|
|
||||||
option(WITH_ORACLE "build oracle" ON)
|
|
||||||
if(WITH_ORACLE)
|
if(WITH_ORACLE)
|
||||||
add_subdirectory(oracle)
|
add_subdirectory(oracle)
|
||||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Oracle;Oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
set(CPACK_INSTALL_CMAKE_PROJECTS "Oracle;Oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Compile dbconverter (default on)
|
|
||||||
option(WITH_DBCONVERTER "build dbconverter" ON)
|
|
||||||
if(WITH_DBCONVERTER)
|
if(WITH_DBCONVERTER)
|
||||||
add_subdirectory(dbconverter)
|
add_subdirectory(dbconverter)
|
||||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Dbconverter;Dbconverter;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
set(CPACK_INSTALL_CMAKE_PROJECTS "Dbconverter;Dbconverter;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Compile tests (default off)
|
|
||||||
option(TEST "build tests" OFF)
|
|
||||||
if(TEST)
|
if(TEST)
|
||||||
include(CTest)
|
include(CTest)
|
||||||
add_subdirectory(tests)
|
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()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
19
README.md
19
README.md
@@ -8,7 +8,7 @@
|
|||||||
<a href="#get-involved--">Get Involved</a> <b>|</b>
|
<a href="#get-involved--">Get Involved</a> <b>|</b>
|
||||||
<a href="#community-resources">Community</a> <b>|</b>
|
<a href="#community-resources">Community</a> <b>|</b>
|
||||||
<a href="#translations-">Translations</a> <b>|</b>
|
<a href="#translations-">Translations</a> <b>|</b>
|
||||||
<a href="#build-">Build</a> <b>|</b>
|
<a href="#build--">Build</a> <b>|</b>
|
||||||
<a href="#run">Run</a> <b>|</b>
|
<a href="#run">Run</a> <b>|</b>
|
||||||
<a href="#license-">License</a>
|
<a href="#license-">License</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<br><pre>
|
<br><pre>
|
||||||
<b>To get started, ⇢ [view our webpage](https://cockatrice.github.io/)</b><br>
|
<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 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>
|
</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)!
|
- 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) [](https://gitter.im/Cockatrice/Cockatrice)
|
# Get Involved [](https://discord.gg/3Z9yzmA)
|
||||||
|
|
||||||
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>
|
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>
|
For support regarding specific servers, please contact that server's admin or forum for support rather than asking here.<br>
|
||||||
@@ -52,8 +52,6 @@ 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.
|
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.
|
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.
|
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.
|
||||||
@@ -67,18 +65,14 @@ Cockatrice uses the [Google Developer Documentation Style Guide](https://develop
|
|||||||
- [reddit r/Cockatrice](https://reddit.com/r/cockatrice)
|
- [reddit r/Cockatrice](https://reddit.com/r/cockatrice)
|
||||||
|
|
||||||
|
|
||||||
# Translations [](https://www.transifex.com/projects/p/cockatrice/)
|
# Translations [](https://transifex.com/cockatrice/cockatrice/)
|
||||||
|
|
||||||
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 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 | 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>
|
Check out our [Translator FAQ](https://github.com/Cockatrice/Cockatrice/wiki/Translation-FAQ) for more information about contributing!<br>
|
||||||
|
|
||||||
|
|
||||||
# Build [](https://github.com/Cockatrice/Cockatrice/actions/workflows/ci-builds.yml?query=branch%3Amaster+event%3Apush)
|
# Build [](https://github.com/Cockatrice/Cockatrice/actions/workflows/desktop-build.yml?query=branch%3Amaster+event%3Apush) [](https://github.com/Cockatrice/Cockatrice/actions/workflows/web-build.yml?query=branch%3Amaster+event%3Apush)
|
||||||
|
|
||||||
**Detailed compiling instructions can be found on the Cockatrice wiki under [Compiling Cockatrice](https://github.com/Cockatrice/Cockatrice/wiki/Compiling-Cockatrice)**
|
**Detailed compiling instructions can be found on the Cockatrice wiki under [Compiling Cockatrice](https://github.com/Cockatrice/Cockatrice/wiki/Compiling-Cockatrice)**
|
||||||
|
|
||||||
@@ -117,6 +111,7 @@ 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).
|
- `-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).
|
- `-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```.
|
- `-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
|
# Run
|
||||||
|
|||||||
55
cmake/CMakeDMGSetup.script
Normal file
55
cmake/CMakeDMGSetup.script
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
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 the LibExecinfo library - FreeBSD only
|
||||||
|
|
||||||
FIND_PATH(LIBEXECINFO_INCLUDE_DIR execinfo.h)
|
find_path(LIBEXECINFO_INCLUDE_DIR execinfo.h)
|
||||||
FIND_LIBRARY(LIBEXECINFO_LIBRARY NAMES execinfo)
|
find_library(LIBEXECINFO_LIBRARY NAMES execinfo)
|
||||||
|
|
||||||
IF(LIBEXECINFO_INCLUDE_DIR AND LIBEXECINFO_LIBRARY)
|
if(LIBEXECINFO_INCLUDE_DIR AND LIBEXECINFO_LIBRARY)
|
||||||
SET(LIBEXECINFO_FOUND TRUE)
|
set(LIBEXECINFO_FOUND TRUE)
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
IF(LIBEXECINFO_FOUND)
|
if(LIBEXECINFO_FOUND)
|
||||||
IF(NOT LIBEXECINFO_FIND_QUIETLY)
|
if(NOT LIBEXECINFO_FIND_QUIETLY)
|
||||||
MESSAGE(STATUS "Found LibExecinfo: ${EXECINFO_LIBRARY}")
|
message(STATUS "Found LibExecinfo: ${EXECINFO_LIBRARY}")
|
||||||
ENDIF()
|
endif()
|
||||||
ELSE()
|
else()
|
||||||
IF(LIBEXECINFO_FIND_REQUIRED)
|
if(LIBEXECINFO_FIND_REQUIRED)
|
||||||
MESSAGE(FATAL_ERROR "Could not find LibExecinfo")
|
message(FATAL_ERROR "Could not find LibExecinfo")
|
||||||
ENDIF()
|
endif()
|
||||||
ENDIF()
|
endif()
|
||||||
|
|||||||
117
cmake/FindQtRuntime.cmake
Normal file
117
cmake/FindQtRuntime.cmake
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# 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,36 +1,42 @@
|
|||||||
# Find the MS Visual Studio VC redistributable package
|
# Find the MS Visual Studio VC redistributable package
|
||||||
|
|
||||||
if (WIN32)
|
if(WIN32)
|
||||||
set(VCREDISTRUNTIME_FOUND "NO")
|
set(VCREDISTRUNTIME_FOUND "NO")
|
||||||
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
|
||||||
set(REDIST_ARCH x64)
|
set(REDIST_ARCH x64)
|
||||||
else()
|
else()
|
||||||
set(REDIST_ARCH x86)
|
set(REDIST_ARCH x86)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(REDIST_FILE vcredist_${REDIST_ARCH}.exe)
|
# 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(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||||
include(InstallRequiredSystemLibraries)
|
include(InstallRequiredSystemLibraries)
|
||||||
|
|
||||||
# Check if the list contains minimum one element, to get the path from
|
# Check if the list contains minimum one element, to get the path from
|
||||||
list(LENGTH CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS libsCount)
|
list(LENGTH CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS libsCount)
|
||||||
if (libsCount GREATER 0)
|
if(libsCount GREATER 0)
|
||||||
list(GET CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS 0 _path)
|
list(GET CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS 0 _path)
|
||||||
|
|
||||||
get_filename_component(_path ${_path} DIRECTORY)
|
get_filename_component(_path ${_path} DIRECTORY)
|
||||||
get_filename_component(_path ${_path}/../../ ABSOLUTE)
|
get_filename_component(_path ${_path}/../../ ABSOLUTE)
|
||||||
|
|
||||||
if (EXISTS "${_path}/${REDIST_FILE}") # VS 2017
|
foreach(redist_file ${REDIST_FILE_NAMES})
|
||||||
set(VCREDISTRUNTIME_FOUND "YES")
|
if(EXISTS "${_path}/${redist_file}")
|
||||||
set(VCREDISTRUNTIME_FILE ${_path}/${REDIST_FILE})
|
set(VCREDISTRUNTIME_FOUND "YES")
|
||||||
endif()
|
set(VCREDISTRUNTIME_FILE ${_path}/${redist_file})
|
||||||
endif()
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(VCREDISTRUNTIME_FOUND)
|
if(VCREDISTRUNTIME_FOUND)
|
||||||
message(STATUS "Found VCredist ${VCREDISTRUNTIME_FILE}")
|
message(STATUS "Found VCredist ${VCREDISTRUNTIME_FILE}")
|
||||||
else()
|
else()
|
||||||
message(WARNING "Could not find VCredist package. It's not required for compiling, but needs to be available at runtime.")
|
message(
|
||||||
endif()
|
WARNING "Could not find VCredist package. It's not required for compiling, but needs to be available at runtime."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
# 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" "VersionMajor" "@CPACK_PACKAGE_VERSION_MAJOR@"
|
||||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "VersionMinor" "@CPACK_PACKAGE_VERSION_MINOR@"
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "VersionMinor" "@CPACK_PACKAGE_VERSION_MINOR@"
|
||||||
|
|
||||||
IfFileExists "$INSTDIR\vcredist_x86.exe" VcRedist86Exists PastVcRedist86Check
|
IfFileExists "$INSTDIR\vc_redist.x86.exe" VcRedist86Exists PastVcRedist86Check
|
||||||
VcRedist86Exists:
|
VcRedist86Exists:
|
||||||
ExecWait '"$INSTDIR\vcredist_x86.exe" /passive /norestart'
|
ExecWait '"$INSTDIR\vc_redist.x86.exe" /passive /norestart'
|
||||||
DetailPrint "Wait to ensure unlock of vc_redist file after installation..."
|
DetailPrint "Wait to ensure unlock of vc_redist file after installation..."
|
||||||
Sleep 3000
|
Sleep 3000
|
||||||
Delete "$INSTDIR\vcredist_x86.exe"
|
Delete "$INSTDIR\vc_redist.x86.exe"
|
||||||
PastVcRedist86Check:
|
PastVcRedist86Check:
|
||||||
|
|
||||||
IfFileExists "$INSTDIR\vcredist_x64.exe" VcRedist64Exists PastVcRedist64Check
|
IfFileExists "$INSTDIR\vc_redist.x64.exe" VcRedist64Exists PastVcRedist64Check
|
||||||
VcRedist64Exists:
|
VcRedist64Exists:
|
||||||
ExecWait '"$INSTDIR\vcredist_x64.exe" /passive /norestart'
|
ExecWait '"$INSTDIR\vc_redist.x64.exe" /passive /norestart'
|
||||||
DetailPrint "Sleep to ensure unlock of vc_redist file after installation..."
|
DetailPrint "Sleep to ensure unlock of vc_redist file after installation..."
|
||||||
Sleep 3000
|
Sleep 3000
|
||||||
Delete "$INSTDIR\vcredist_x64.exe"
|
Delete "$INSTDIR\vc_redist.x64.exe"
|
||||||
PastVcRedist64Check:
|
PastVcRedist64Check:
|
||||||
|
|
||||||
${Else}
|
${Else}
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
set(VERSION_STRING_CPP "${PROJECT_BINARY_DIR}/version_string.cpp")
|
set(VERSION_STRING_CPP "${PROJECT_BINARY_DIR}/version_string.cpp")
|
||||||
set(VERSION_STRING_H "${PROJECT_BINARY_DIR}/version_string.h")
|
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_COMMIT\;
|
||||||
extern const char *VERSION_DATE\;\n" )
|
extern const char *VERSION_DATE\;\n"
|
||||||
set( cppstring "const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
)
|
||||||
|
set(cppstring
|
||||||
|
"const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
||||||
const char *VERSION_COMMIT = \"${GIT_COMMIT_ID}\"\;
|
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} )
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
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}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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}
|
||||||
|
)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${VERSION_STRING_CPP}
|
||||||
|
)
|
||||||
|
|||||||
BIN
cmake/dmgBackground.tif
Normal file
BIN
cmake/dmgBackground.tif
Normal file
Binary file not shown.
@@ -1,154 +1,187 @@
|
|||||||
# HELPER FUNCTIONS
|
# HELPER FUNCTIONS
|
||||||
|
|
||||||
function(get_commit_id)
|
function(get_commit_id)
|
||||||
# get last commit hash
|
# get last commit hash
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h"
|
COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h"
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
RESULT_VARIABLE res_var
|
RESULT_VARIABLE res_var
|
||||||
OUTPUT_VARIABLE GIT_COM_ID
|
OUTPUT_VARIABLE GIT_COM_ID
|
||||||
)
|
)
|
||||||
if(NOT ${res_var} EQUAL 0)
|
if(NOT ${res_var} EQUAL 0)
|
||||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}")
|
string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}")
|
||||||
set(GIT_COMMIT_ID "${GIT_COM_ID}" PARENT_SCOPE)
|
set(GIT_COMMIT_ID
|
||||||
set(PROJECT_VERSION_LABEL "custom(${GIT_COM_ID})" PARENT_SCOPE)
|
"${GIT_COM_ID}"
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
|
set(PROJECT_VERSION_LABEL
|
||||||
|
"custom(${GIT_COM_ID})"
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(get_commit_date)
|
function(get_commit_date)
|
||||||
# get last commit date
|
# get last commit date
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd"
|
COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd"
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
RESULT_VARIABLE res_var
|
RESULT_VARIABLE res_var
|
||||||
OUTPUT_VARIABLE GIT_COM_DATE
|
OUTPUT_VARIABLE GIT_COM_DATE
|
||||||
)
|
)
|
||||||
if(NOT ${res_var} EQUAL 0)
|
if(NOT ${res_var} EQUAL 0)
|
||||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||||
set(GIT_COMMIT_DATE_FRIENDLY "${GIT_COM_DATE}" PARENT_SCOPE)
|
set(GIT_COMMIT_DATE_FRIENDLY
|
||||||
|
"${GIT_COM_DATE}"
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
|
|
||||||
string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||||
set(GIT_COMMIT_DATE "${GIT_COM_DATE}" PARENT_SCOPE)
|
set(GIT_COMMIT_DATE
|
||||||
|
"${GIT_COM_DATE}"
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(get_tag_name commit)
|
function(get_tag_name commit)
|
||||||
if(${commit} STREQUAL "unknown")
|
if(${commit} STREQUAL "unknown")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit}
|
COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit}
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
RESULT_VARIABLE res_var
|
RESULT_VARIABLE res_var
|
||||||
OUTPUT_VARIABLE GIT_TAG
|
OUTPUT_VARIABLE GIT_TAG
|
||||||
ERROR_VARIABLE GIT_TAG_ERR
|
ERROR_VARIABLE GIT_TAG_ERR
|
||||||
)
|
)
|
||||||
|
|
||||||
if((NOT ${res_var} EQUAL 0) OR (${GIT_TAG_ERR} MATCHES "fatal: no tag exactly matches.*"))
|
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)")
|
message(STATUS "Commit is not a release or prerelease (no git tag found)")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}")
|
string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}")
|
||||||
message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}")
|
message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}")
|
||||||
|
|
||||||
# Extract information from tag:
|
# Extract information from tag:
|
||||||
# YYYY-MM-DD-Release-MAJ.MIN.PATCH
|
# YYYY-MM-DD-Release-MAJ.MIN.PATCH
|
||||||
# YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X
|
# YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X
|
||||||
string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}")
|
string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}")
|
||||||
string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}")
|
string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}")
|
||||||
|
|
||||||
# Sanity checks: length
|
# Sanity checks: length
|
||||||
list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT)
|
list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT)
|
||||||
if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 9)
|
if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 9)
|
||||||
message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens")
|
message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Year
|
# Year
|
||||||
list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR)
|
list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR)
|
||||||
if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100)
|
if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100)
|
||||||
message(WARNING "Invalid tag year ${GIT_TAG_YEAR}")
|
message(WARNING "Invalid tag year ${GIT_TAG_YEAR}")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Month
|
# Month
|
||||||
list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH)
|
list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH)
|
||||||
if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12)
|
if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12)
|
||||||
message(WARNING "Invalid tag month ${GIT_TAG_MONTH}")
|
message(WARNING "Invalid tag month ${GIT_TAG_MONTH}")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Day
|
# Day
|
||||||
list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY)
|
list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY)
|
||||||
if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31)
|
if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31)
|
||||||
message(WARNING "Invalid tag day ${GIT_TAG_DAY}")
|
message(WARNING "Invalid tag day ${GIT_TAG_DAY}")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Type
|
# Type
|
||||||
list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE)
|
list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE)
|
||||||
if(NOT(${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development"))
|
if(NOT (${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development"))
|
||||||
message(WARNING "Invalid tag type ${GIT_TAG_TYPE}")
|
message(WARNING "Invalid tag type ${GIT_TAG_TYPE}")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Major
|
# Major
|
||||||
list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR)
|
list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR)
|
||||||
if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99)
|
if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99)
|
||||||
message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}")
|
message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Minor
|
# Minor
|
||||||
list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR)
|
list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR)
|
||||||
if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99)
|
if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99)
|
||||||
message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}")
|
message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Patch
|
# Patch
|
||||||
list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH)
|
list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH)
|
||||||
if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99)
|
if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99)
|
||||||
message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}")
|
message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Label
|
# Label
|
||||||
# 7 = Stable release
|
# 7 = Stable release
|
||||||
# 8 = Dev release, first beta so only "beta" attached
|
# 8 = Dev release, first beta so only "beta" attached
|
||||||
# 9 = Dev release, subsequent beta so "beta.N" attached (N>=2)
|
# 9 = Dev release, subsequent beta so "beta.N" attached (N>=2)
|
||||||
if(${GIT_TAG_LISTCOUNT} EQUAL 8)
|
if(${GIT_TAG_LISTCOUNT} EQUAL 8)
|
||||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||||
elseif(${GIT_TAG_LISTCOUNT} EQUAL 9)
|
elseif(${GIT_TAG_LISTCOUNT} EQUAL 9)
|
||||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||||
list(GET GIT_TAG_EXPLODED 8 GIT_TAG_LABEL_NUM)
|
list(GET GIT_TAG_EXPLODED 8 GIT_TAG_LABEL_NUM)
|
||||||
set(GIT_TAG_LABEL ${GIT_TAG_LABEL} ${GIT_TAG_LABEL_NUM})
|
set(GIT_TAG_LABEL ${GIT_TAG_LABEL} ${GIT_TAG_LABEL_NUM})
|
||||||
string(REPLACE ";" "." GIT_TAG_LABEL "${GIT_TAG_LABEL}")
|
string(REPLACE ";" "." GIT_TAG_LABEL "${GIT_TAG_LABEL}")
|
||||||
else()
|
else()
|
||||||
SET(GIT_TAG_LABEL "")
|
set(GIT_TAG_LABEL "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Override hardcoded version with the informations from the tag
|
# Override hardcoded version with the informations from the tag
|
||||||
set(PROJECT_VERSION_MAJOR ${GIT_TAG_MAJOR} PARENT_SCOPE)
|
set(PROJECT_VERSION_MAJOR
|
||||||
set(PROJECT_VERSION_MINOR ${GIT_TAG_MINOR} PARENT_SCOPE)
|
${GIT_TAG_MAJOR}
|
||||||
set(PROJECT_VERSION_PATCH ${GIT_TAG_PATCH} PARENT_SCOPE)
|
PARENT_SCOPE
|
||||||
set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} 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")
|
if(${GIT_TAG_TYPE} STREQUAL "Development")
|
||||||
set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE)
|
set(PROJECT_VERSION_LABEL
|
||||||
elseif(${GIT_TAG_TYPE} STREQUAL "Release")
|
${GIT_TAG_LABEL}
|
||||||
set(PROJECT_VERSION_LABEL "" PARENT_SCOPE)
|
PARENT_SCOPE
|
||||||
# set release name from env var
|
)
|
||||||
set(PROJECT_VERSION_RELEASENAME "${GIT_TAG_RELEASENAME}" PARENT_SCOPE)
|
elseif(${GIT_TAG_TYPE} STREQUAL "Release")
|
||||||
endif()
|
set(PROJECT_VERSION_LABEL
|
||||||
|
""
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
|
# set release name from env var
|
||||||
|
set(PROJECT_VERSION_RELEASENAME
|
||||||
|
"${GIT_TAG_RELEASENAME}"
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
@@ -163,16 +196,16 @@ set(PROJECT_VERSION_RELEASENAME "")
|
|||||||
|
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
if(GIT_FOUND)
|
if(GIT_FOUND)
|
||||||
get_commit_id()
|
get_commit_id()
|
||||||
get_commit_date()
|
get_commit_date()
|
||||||
get_tag_name(${GIT_COMMIT_ID})
|
get_tag_name(${GIT_COMMIT_ID})
|
||||||
else()
|
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()
|
endif()
|
||||||
|
|
||||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||||
if(PROJECT_VERSION_LABEL)
|
if(PROJECT_VERSION_LABEL)
|
||||||
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}")
|
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})")
|
set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})")
|
||||||
@@ -180,7 +213,7 @@ set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})")
|
|||||||
# Format: <program name>[-ReleaseName]-MAJ.MIN.PATCH[-prerelease_label]
|
# Format: <program name>[-ReleaseName]-MAJ.MIN.PATCH[-prerelease_label]
|
||||||
set(PROJECT_VERSION_FILENAME "${PROJECT_NAME}")
|
set(PROJECT_VERSION_FILENAME "${PROJECT_NAME}")
|
||||||
if(PROJECT_VERSION_RELEASENAME)
|
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()
|
endif()
|
||||||
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION}")
|
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION}")
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ project(gtest-download LANGUAGES NONE)
|
|||||||
|
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
ExternalProject_Add(googletest
|
ExternalProject_Add(googletest
|
||||||
URL https://github.com/google/googletest/archive/release-1.7.0.zip
|
URL https://github.com/google/googletest/archive/release-1.11.0.zip
|
||||||
URL_HASH SHA1=f89bc9f55477df2fde082481e2d709bfafdb057b
|
URL_HASH SHA1=9ffb7b5923f4a8fcdabf2f42c6540cce299f44c0
|
||||||
SOURCE_DIR "${CMAKE_BINARY_DIR}/gtest-src"
|
SOURCE_DIR "${CMAKE_BINARY_DIR}/gtest-src"
|
||||||
BINARY_DIR "${CMAKE_BINARY_DIR}/gtest-build"
|
BINARY_DIR "${CMAKE_BINARY_DIR}/gtest-build"
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
TEST_COMMAND ""
|
TEST_COMMAND ""
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,284 +2,386 @@
|
|||||||
#
|
#
|
||||||
# provides the cockatrice binary
|
# 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
|
||||||
src/abstractcounter.cpp
|
src/abstractcounter.cpp
|
||||||
|
src/abstractgraphicsitem.cpp
|
||||||
|
src/arrowitem.cpp
|
||||||
|
src/arrowtarget.cpp
|
||||||
|
src/carddatabase.cpp
|
||||||
|
src/carddatabasemodel.cpp
|
||||||
|
src/carddbparser/carddatabaseparser.cpp
|
||||||
|
src/carddbparser/cockatricexml3.cpp
|
||||||
|
src/carddbparser/cockatricexml4.cpp
|
||||||
|
src/carddragitem.cpp
|
||||||
|
src/cardfilter.cpp
|
||||||
|
src/cardframe.cpp
|
||||||
|
src/cardinfopicture.cpp
|
||||||
|
src/cardinfotext.cpp
|
||||||
|
src/cardinfowidget.cpp
|
||||||
|
src/carditem.cpp
|
||||||
|
src/cardlist.cpp
|
||||||
|
src/cardzone.cpp
|
||||||
|
src/chatview/chatview.cpp
|
||||||
src/counter_general.cpp
|
src/counter_general.cpp
|
||||||
src/dlg_creategame.cpp
|
src/customlineedit.cpp
|
||||||
src/dlg_filter_games.cpp
|
src/deck_loader.cpp
|
||||||
|
src/decklistmodel.cpp
|
||||||
|
src/deckstats_interface.cpp
|
||||||
|
src/deckview.cpp
|
||||||
src/dlg_connect.cpp
|
src/dlg_connect.cpp
|
||||||
src/dlg_create_token.cpp
|
src/dlg_create_token.cpp
|
||||||
|
src/dlg_creategame.cpp
|
||||||
src/dlg_edit_avatar.cpp
|
src/dlg_edit_avatar.cpp
|
||||||
src/dlg_edit_password.cpp
|
src/dlg_edit_password.cpp
|
||||||
src/dlg_edit_tokens.cpp
|
src/dlg_edit_tokens.cpp
|
||||||
src/dlg_edit_user.cpp
|
src/dlg_edit_user.cpp
|
||||||
|
src/dlg_filter_games.cpp
|
||||||
|
src/dlg_forgotpasswordchallenge.cpp
|
||||||
src/dlg_forgotpasswordrequest.cpp
|
src/dlg_forgotpasswordrequest.cpp
|
||||||
src/dlg_forgotpasswordreset.cpp
|
src/dlg_forgotpasswordreset.cpp
|
||||||
src/dlg_forgotpasswordchallenge.cpp
|
|
||||||
src/dlg_manage_sets.cpp
|
|
||||||
src/dlg_register.cpp
|
|
||||||
src/dlg_tip_of_the_day.cpp
|
|
||||||
src/tip_of_the_day.cpp
|
|
||||||
src/dlg_update.cpp
|
|
||||||
src/dlg_viewlog.cpp
|
|
||||||
src/abstractclient.cpp
|
|
||||||
src/remoteclient.cpp
|
|
||||||
src/main.cpp
|
|
||||||
src/window_main.cpp
|
|
||||||
src/gamesmodel.cpp
|
|
||||||
src/player.cpp
|
|
||||||
src/playertarget.cpp
|
|
||||||
src/cardzone.cpp
|
|
||||||
src/selectzone.cpp
|
|
||||||
src/cardlist.cpp
|
|
||||||
src/abstractcarditem.cpp
|
|
||||||
src/carditem.cpp
|
|
||||||
src/tablezone.cpp
|
|
||||||
src/handzone.cpp
|
|
||||||
src/handcounter.cpp
|
|
||||||
src/carddatabase.cpp
|
|
||||||
src/keysignals.cpp
|
|
||||||
src/gameview.cpp
|
|
||||||
src/gameselector.cpp
|
|
||||||
src/decklistmodel.cpp
|
|
||||||
src/deck_loader.cpp
|
|
||||||
src/dlg_load_deck_from_clipboard.cpp
|
src/dlg_load_deck_from_clipboard.cpp
|
||||||
src/dlg_load_remote_deck.cpp
|
src/dlg_load_remote_deck.cpp
|
||||||
src/cardinfowidget.cpp
|
src/dlg_manage_sets.cpp
|
||||||
src/cardframe.cpp
|
src/dlg_register.cpp
|
||||||
src/cardinfopicture.cpp
|
src/dlg_roll_dice.cpp
|
||||||
src/cardinfotext.cpp
|
|
||||||
src/filterbuilder.cpp
|
|
||||||
src/cardfilter.cpp
|
|
||||||
src/filtertreemodel.cpp
|
|
||||||
src/filtertree.cpp
|
|
||||||
src/messagelogwidget.cpp
|
|
||||||
src/zoneviewzone.cpp
|
|
||||||
src/zoneviewwidget.cpp
|
|
||||||
src/pilezone.cpp
|
|
||||||
src/stackzone.cpp
|
|
||||||
src/carddragitem.cpp
|
|
||||||
src/carddatabasemodel.cpp
|
|
||||||
src/setsmodel.cpp
|
|
||||||
src/abstractgraphicsitem.cpp
|
|
||||||
src/abstractcarddragitem.cpp
|
|
||||||
src/dlg_settings.cpp
|
src/dlg_settings.cpp
|
||||||
src/phasestoolbar.cpp
|
src/dlg_tip_of_the_day.cpp
|
||||||
|
src/dlg_update.cpp
|
||||||
|
src/dlg_viewlog.cpp
|
||||||
|
src/filter_string.cpp
|
||||||
|
src/filterbuilder.cpp
|
||||||
|
src/filtertree.cpp
|
||||||
|
src/filtertreemodel.cpp
|
||||||
src/gamescene.cpp
|
src/gamescene.cpp
|
||||||
src/arrowitem.cpp
|
src/gameselector.cpp
|
||||||
src/arrowtarget.cpp
|
src/gamesmodel.cpp
|
||||||
src/tab.cpp
|
src/gameview.cpp
|
||||||
src/tab_server.cpp
|
src/gettextwithmax.cpp
|
||||||
src/tab_room.cpp
|
src/handcounter.cpp
|
||||||
src/tab_message.cpp
|
src/handle_public_servers.cpp
|
||||||
src/tab_game.cpp
|
src/handzone.cpp
|
||||||
src/tab_deck_storage.cpp
|
src/keysignals.cpp
|
||||||
src/tab_replays.cpp
|
src/lineeditcompleter.cpp
|
||||||
src/tab_supervisor.cpp
|
src/localclient.cpp
|
||||||
src/tab_admin.cpp
|
|
||||||
src/tab_account.cpp
|
|
||||||
src/tab_deck_editor.cpp
|
|
||||||
src/tab_logs.cpp
|
|
||||||
src/replay_timeline_widget.cpp
|
|
||||||
src/deckstats_interface.cpp
|
|
||||||
src/tappedout_interface.cpp
|
|
||||||
src/chatview/chatview.cpp
|
|
||||||
src/userlist.cpp
|
|
||||||
src/userinfobox.cpp
|
|
||||||
src/user_context_menu.cpp
|
|
||||||
src/remotedecklist_treewidget.cpp
|
|
||||||
src/remotereplaylist_treewidget.cpp
|
|
||||||
src/deckview.cpp
|
|
||||||
src/playerlistwidget.cpp
|
|
||||||
src/pixmapgenerator.cpp
|
|
||||||
src/settingscache.cpp
|
|
||||||
src/thememanager.cpp
|
|
||||||
src/localserver.cpp
|
src/localserver.cpp
|
||||||
src/localserverinterface.cpp
|
src/localserverinterface.cpp
|
||||||
src/localclient.cpp
|
src/logger.cpp
|
||||||
src/soundengine.cpp
|
src/main.cpp
|
||||||
|
src/messagelogwidget.cpp
|
||||||
src/pending_command.cpp
|
src/pending_command.cpp
|
||||||
|
src/phase.cpp
|
||||||
|
src/phasestoolbar.cpp
|
||||||
src/pictureloader.cpp
|
src/pictureloader.cpp
|
||||||
src/shortcutssettings.cpp
|
src/pilezone.cpp
|
||||||
|
src/pixmapgenerator.cpp
|
||||||
|
src/player.cpp
|
||||||
|
src/playerlistwidget.cpp
|
||||||
|
src/playertarget.cpp
|
||||||
|
src/releasechannel.cpp
|
||||||
|
src/remoteclient.cpp
|
||||||
|
src/remotedecklist_treewidget.cpp
|
||||||
|
src/remotereplaylist_treewidget.cpp
|
||||||
|
src/replay_timeline_widget.cpp
|
||||||
|
src/selectzone.cpp
|
||||||
src/sequenceEdit/sequenceedit.cpp
|
src/sequenceEdit/sequenceedit.cpp
|
||||||
src/lineeditcompleter.cpp
|
src/setsmodel.cpp
|
||||||
src/settings/settingsmanager.cpp
|
|
||||||
src/settings/carddatabasesettings.cpp
|
src/settings/carddatabasesettings.cpp
|
||||||
src/settings/serverssettings.cpp
|
src/settings/downloadsettings.cpp
|
||||||
src/settings/messagesettings.cpp
|
|
||||||
src/settings/gamefilterssettings.cpp
|
src/settings/gamefilterssettings.cpp
|
||||||
src/settings/layoutssettings.cpp
|
src/settings/layoutssettings.cpp
|
||||||
src/settings/downloadsettings.cpp
|
src/settings/messagesettings.cpp
|
||||||
src/update_downloader.cpp
|
src/settings/serverssettings.cpp
|
||||||
src/logger.cpp
|
src/settings/settingsmanager.cpp
|
||||||
src/releasechannel.cpp
|
src/settingscache.cpp
|
||||||
src/userconnection_information.cpp
|
src/shortcutssettings.cpp
|
||||||
|
src/soundengine.cpp
|
||||||
src/spoilerbackgroundupdater.cpp
|
src/spoilerbackgroundupdater.cpp
|
||||||
src/handle_public_servers.cpp
|
src/stackzone.cpp
|
||||||
src/carddbparser/carddatabaseparser.cpp
|
src/tab.cpp
|
||||||
src/carddbparser/cockatricexml3.cpp
|
src/tab_account.cpp
|
||||||
src/carddbparser/cockatricexml4.cpp
|
src/tab_admin.cpp
|
||||||
src/filter_string.cpp
|
src/tab_deck_editor.cpp
|
||||||
src/phase.cpp
|
src/tab_deck_storage.cpp
|
||||||
src/customlineedit.cpp
|
src/tab_game.cpp
|
||||||
|
src/tab_logs.cpp
|
||||||
|
src/tab_message.cpp
|
||||||
|
src/tab_replays.cpp
|
||||||
|
src/tab_room.cpp
|
||||||
|
src/tab_server.cpp
|
||||||
|
src/tab_supervisor.cpp
|
||||||
|
src/tablezone.cpp
|
||||||
|
src/tappedout_interface.cpp
|
||||||
|
src/thememanager.cpp
|
||||||
|
src/tip_of_the_day.cpp
|
||||||
src/translatecountername.cpp
|
src/translatecountername.cpp
|
||||||
|
src/update_downloader.cpp
|
||||||
|
src/user_context_menu.cpp
|
||||||
|
src/userconnection_information.cpp
|
||||||
|
src/userinfobox.cpp
|
||||||
|
src/userlist.cpp
|
||||||
|
src/window_main.cpp
|
||||||
|
src/zoneviewwidget.cpp
|
||||||
|
src/zoneviewzone.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(sounds)
|
add_subdirectory(sounds)
|
||||||
add_subdirectory(themes)
|
add_subdirectory(themes)
|
||||||
|
|
||||||
set(cockatrice_RESOURCES cockatrice.qrc)
|
set(cockatrice_RESOURCES cockatrice.qrc)
|
||||||
|
|
||||||
IF(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_cockatrice_SRCS ${CMAKE_SOURCE_DIR}/cockatrice/src/*.cpp
|
||||||
FILE(GLOB_RECURSE translate_common_SRCS ${CMAKE_SOURCE_DIR}/common/*.cpp ${CMAKE_SOURCE_DIR}/common/*.h)
|
${CMAKE_SOURCE_DIR}/cockatrice/src/*.h
|
||||||
SET(translate_SRCS ${translate_cockatrice_SRCS} ${translate_common_SRCS})
|
)
|
||||||
SET(cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/cockatrice_en.ts")
|
file(GLOB_RECURSE translate_common_SRCS ${CMAKE_SOURCE_DIR}/common/*.cpp ${CMAKE_SOURCE_DIR}/common/*.h)
|
||||||
ELSE()
|
set(translate_SRCS ${translate_cockatrice_SRCS} ${translate_common_SRCS})
|
||||||
FILE(GLOB cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts")
|
set(cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice_en@source.ts")
|
||||||
ENDIF(UPDATE_TRANSLATIONS)
|
else()
|
||||||
|
file(GLOB cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts")
|
||||||
|
endif(UPDATE_TRANSLATIONS)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} cockatrice.rc)
|
set(cockatrice_SOURCES ${cockatrice_SOURCES} cockatrice.rc)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(MACOSX_BUNDLE_ICON_FILE appicon.icns)
|
set(MACOSX_BUNDLE_ICON_FILE appicon.icns)
|
||||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
set_source_files_properties(
|
||||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
|
${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources
|
||||||
ENDIF(APPLE)
|
)
|
||||||
|
set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
|
||||||
|
endif(APPLE)
|
||||||
|
|
||||||
# Qt5
|
if(Qt6_FOUND)
|
||||||
find_package(Qt5 COMPONENTS Concurrent Multimedia Network PrintSupport Svg WebSockets Widgets REQUIRED)
|
qt6_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||||
set(COCKATRICE_QT_MODULES Qt5::Concurrent Qt5::Multimedia Qt5::Network Qt5::PrintSupport Qt5::Svg Qt5::Widgets Qt5::WebSockets)
|
elseif(Qt5_FOUND)
|
||||||
|
qt5_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||||
# 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()
|
endif()
|
||||||
|
|
||||||
QT5_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
|
||||||
|
|
||||||
# Declare path variables
|
# Declare path variables
|
||||||
set(ICONDIR share/icons CACHE STRING "icon dir")
|
set(ICONDIR
|
||||||
set(DESKTOPDIR share/applications CACHE STRING "desktop file destination")
|
share/icons
|
||||||
|
CACHE STRING "icon dir"
|
||||||
|
)
|
||||||
|
set(DESKTOPDIR
|
||||||
|
share/applications
|
||||||
|
CACHE STRING "desktop file destination"
|
||||||
|
)
|
||||||
|
|
||||||
# Include directories
|
# Include directories
|
||||||
INCLUDE_DIRECTORIES(../common)
|
include_directories(../common)
|
||||||
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
|
include_directories(${PROTOBUF_INCLUDE_DIR})
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common)
|
include_directories(${CMAKE_BINARY_DIR}/common)
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
# Build cockatrice binary and link it
|
set(COCKATRICE_MAC_QM_INSTALL_DIR "cockatrice.app/Contents/Resources/translations")
|
||||||
ADD_EXECUTABLE(cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_SOURCES} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC} ${cockatrice_MOC_SRCS})
|
set(COCKATRICE_UNIX_QM_INSTALL_DIR "share/cockatrice/translations")
|
||||||
|
set(COCKATRICE_WIN32_QM_INSTALL_DIR "translations")
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${COCKATRICE_QT_MODULES})
|
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()
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
|
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
|
||||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}")
|
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}")
|
||||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}")
|
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}")
|
||||||
set(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}")
|
set(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}")
|
||||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION})
|
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION})
|
||||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${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 ./)
|
install(TARGETS cockatrice BUNDLE DESTINATION ./)
|
||||||
INSTALL(FILES ${cockatrice_QM} DESTINATION ./cockatrice.app/Contents/Resources/translations)
|
else()
|
||||||
else()
|
# Assume linux
|
||||||
# Assume linux
|
install(TARGETS cockatrice RUNTIME DESTINATION bin/)
|
||||||
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.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}/resources/cockatrice.svg DESTINATION ${ICONDIR}/hicolor/scalable/apps)
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cockatrice.desktop DESTINATION ${DESKTOPDIR})
|
||||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cockatrice.desktop DESTINATION ${DESKTOPDIR})
|
endif()
|
||||||
INSTALL(FILES ${cockatrice_QM} DESTINATION share/cockatrice/translations)
|
|
||||||
endif()
|
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
INSTALL(TARGETS cockatrice RUNTIME DESTINATION ./)
|
install(TARGETS cockatrice RUNTIME DESTINATION ./)
|
||||||
INSTALL(FILES ${cockatrice_QM} DESTINATION ./translations)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||||
set(plugin_dest_dir cockatrice.app/Contents/Plugins)
|
set(plugin_dest_dir cockatrice.app/Contents/Plugins)
|
||||||
set(qtconf_dest_dir cockatrice.app/Contents/Resources)
|
set(qtconf_dest_dir cockatrice.app/Contents/Resources)
|
||||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/.." ABSOLUTE)
|
|
||||||
|
|
||||||
# qt5 plugins: audio, iconengines, imageformats, platforms, printsupport
|
# Qt plugins: audio (Qt5), iconengines, imageformats, platforms, printsupport (Qt5), styles, tls (Qt6)
|
||||||
install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime
|
install(
|
||||||
FILES_MATCHING
|
DIRECTORY "${QT_PLUGINS_DIR}/"
|
||||||
PATTERN "*.dSYM" EXCLUDE
|
DESTINATION ${plugin_dest_dir}
|
||||||
PATTERN "*_debug.dylib" EXCLUDE
|
COMPONENT Runtime
|
||||||
PATTERN "audio/*.dylib"
|
FILES_MATCHING
|
||||||
PATTERN "iconengines/*.dylib"
|
PATTERN "*.dSYM" EXCLUDE
|
||||||
PATTERN "imageformats/*.dylib"
|
PATTERN "*_debug.dylib" EXCLUDE
|
||||||
PATTERN "platforms/*.dylib"
|
PATTERN "audio/*.dylib"
|
||||||
PATTERN "printsupport/*.dylib"
|
PATTERN "iconengines/*.dylib"
|
||||||
PATTERN "styles/*.dylib"
|
PATTERN "imageformats/*.dylib"
|
||||||
)
|
PATTERN "platforms/*.dylib"
|
||||||
|
PATTERN "printsupport/*.dylib"
|
||||||
|
PATTERN "styles/*.dylib"
|
||||||
|
PATTERN "tls/*.dylib"
|
||||||
|
)
|
||||||
|
|
||||||
install(CODE "
|
install(
|
||||||
|
CODE "
|
||||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
||||||
Plugins = Plugins
|
Plugins = Plugins
|
||||||
Translations = Resources/translations
|
Translations = Resources/translations
|
||||||
Data = Resources\")
|
Data = Resources\")
|
||||||
" COMPONENT Runtime)
|
"
|
||||||
|
COMPONENT Runtime
|
||||||
|
)
|
||||||
|
|
||||||
install(CODE "
|
install(
|
||||||
|
CODE "
|
||||||
file(GLOB_RECURSE QTPLUGINS
|
file(GLOB_RECURSE QTPLUGINS
|
||||||
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dylib\")
|
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dylib\")
|
||||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||||
include(BundleUtilities)
|
include(BundleUtilities)
|
||||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
||||||
" COMPONENT Runtime)
|
"
|
||||||
|
COMPONENT Runtime
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||||
set(plugin_dest_dir Plugins)
|
set(plugin_dest_dir Plugins)
|
||||||
set(qtconf_dest_dir .)
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
# qt5 plugins: audio, iconengines, imageformats, platforms, printsupport
|
# Qt plugins: audio (Qt5), iconengines, imageformats, platforms, printsupport (Qt5), styles, tls (Qt6)
|
||||||
install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime
|
install(
|
||||||
FILES_MATCHING REGEX "(audio|iconengines|imageformats|platforms|printsupport|styles)/.*[^d]\\.dll")
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
install(CODE "
|
install(
|
||||||
|
CODE "
|
||||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
||||||
Plugins = Plugins
|
Plugins = Plugins
|
||||||
Translations = Resources/translations
|
Translations = Resources/translations
|
||||||
Data = Resources\")
|
Data = Resources\")
|
||||||
" COMPONENT Runtime)
|
"
|
||||||
|
COMPONENT Runtime
|
||||||
|
)
|
||||||
|
|
||||||
install(CODE "
|
install(
|
||||||
|
CODE "
|
||||||
file(GLOB_RECURSE QTPLUGINS
|
file(GLOB_RECURSE QTPLUGINS
|
||||||
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dll\")
|
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dll\")
|
||||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||||
include(BundleUtilities)
|
include(BundleUtilities)
|
||||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/Cockatrice.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/Cockatrice.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
||||||
" COMPONENT Runtime)
|
"
|
||||||
|
COMPONENT Runtime
|
||||||
|
)
|
||||||
|
|
||||||
if(WIN32SSLRUNTIME_FOUND)
|
if(OPENSSL_FOUND)
|
||||||
install(FILES ${WIN32SSLRUNTIME_LIBRARIES} DESTINATION ./)
|
install(FILES ${OPENSSL_INCLUDE_DIRS} DESTINATION ./)
|
||||||
endif()
|
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})
|
||||||
|
endif()
|
||||||
|
elseif(WIN32)
|
||||||
|
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_WIN32_QM_INSTALL_DIR})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(Qt6_FOUND)
|
||||||
|
qt6_finalize_target(cockatrice)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -126,6 +126,7 @@
|
|||||||
<file>resources/countries/er.svg</file>
|
<file>resources/countries/er.svg</file>
|
||||||
<file>resources/countries/es.svg</file>
|
<file>resources/countries/es.svg</file>
|
||||||
<file>resources/countries/et.svg</file>
|
<file>resources/countries/et.svg</file>
|
||||||
|
<file>resources/countries/eu.svg</file>
|
||||||
<file>resources/countries/fi.svg</file>
|
<file>resources/countries/fi.svg</file>
|
||||||
<file>resources/countries/fj.svg</file>
|
<file>resources/countries/fj.svg</file>
|
||||||
<file>resources/countries/fk.svg</file>
|
<file>resources/countries/fk.svg</file>
|
||||||
@@ -301,16 +302,13 @@
|
|||||||
<file>resources/countries/vu.svg</file>
|
<file>resources/countries/vu.svg</file>
|
||||||
<file>resources/countries/wf.svg</file>
|
<file>resources/countries/wf.svg</file>
|
||||||
<file>resources/countries/ws.svg</file>
|
<file>resources/countries/ws.svg</file>
|
||||||
|
<file>resources/countries/xk.svg</file>
|
||||||
<file>resources/countries/ye.svg</file>
|
<file>resources/countries/ye.svg</file>
|
||||||
<file>resources/countries/yt.svg</file>
|
<file>resources/countries/yt.svg</file>
|
||||||
<file>resources/countries/za.svg</file>
|
<file>resources/countries/za.svg</file>
|
||||||
<file>resources/countries/zm.svg</file>
|
<file>resources/countries/zm.svg</file>
|
||||||
<file>resources/countries/zw.svg</file>
|
<file>resources/countries/zw.svg</file>
|
||||||
|
|
||||||
<file>resources/genders/male.svg</file>
|
|
||||||
<file>resources/genders/female.svg</file>
|
|
||||||
<file>resources/genders/unknown.svg</file>
|
|
||||||
|
|
||||||
<file>resources/phases/untap.svg</file>
|
<file>resources/phases/untap.svg</file>
|
||||||
<file>resources/phases/upkeep.svg</file>
|
<file>resources/phases/upkeep.svg</file>
|
||||||
<file>resources/phases/draw.svg</file>
|
<file>resources/phases/draw.svg</file>
|
||||||
@@ -353,10 +351,10 @@
|
|||||||
<file>resources/tips/images/cockatrice_wiki.png</file>
|
<file>resources/tips/images/cockatrice_wiki.png</file>
|
||||||
<file>resources/tips/images/coin_flip.png</file>
|
<file>resources/tips/images/coin_flip.png</file>
|
||||||
<file>resources/tips/images/counter_expression.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/face_down.png</file>
|
||||||
<file>resources/tips/images/filter_games.png</file>
|
<file>resources/tips/images/filter_games.png</file>
|
||||||
<file>resources/tips/images/github_logo.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/setpt.png</file>
|
||||||
<file>resources/tips/images/shortcuts.png</file>
|
<file>resources/tips/images/shortcuts.png</file>
|
||||||
<file>resources/tips/images/themes.png</file>
|
<file>resources/tips/images/themes.png</file>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
92
cockatrice/resources/countries/xk.svg
Normal file
92
cockatrice/resources/countries/xk.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.3 KiB |
@@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
<svg
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
version="1.0"
|
|
||||||
width="75"
|
|
||||||
height="75"
|
|
||||||
id="svg34864">
|
|
||||||
<defs
|
|
||||||
id="defs34866" />
|
|
||||||
<g
|
|
||||||
transform="translate(-348.7552,-478.0905)"
|
|
||||||
id="layer1">
|
|
||||||
<g
|
|
||||||
transform="matrix(1.071197,0,0,1.075147,-13.30677,-36.99488)"
|
|
||||||
id="g3773">
|
|
||||||
<path
|
|
||||||
d="M 176 33 A 11 11 0 1 1 154,33 A 11 11 0 1 1 176 33 z"
|
|
||||||
transform="matrix(1.540096,0,0,1.5384,118.8893,454.0543)"
|
|
||||||
style="color:black;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
|
||||||
id="path3939" />
|
|
||||||
<path
|
|
||||||
d="M 373.00525,521.74399 L 373.00525,543.28159"
|
|
||||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:4.61774349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
id="path3941" />
|
|
||||||
<path
|
|
||||||
d="M 363.76467,534.05119 L 382.24582,534.05119"
|
|
||||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:4.61774349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
id="path4816" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="75" height="75" id="svg34864">
|
|
||||||
<defs id="defs34866"/>
|
|
||||||
<g transform="translate(-348.755, -478.091)" id="layer1">
|
|
||||||
<g transform="matrix(1.94812, 0, 0, 1.93731, -342.43, -460.01)" id="g1872">
|
|
||||||
<path d="M 387.95009,489.60348 L 378.66214,498.89143" style="opacity: 1; color: black; fill: none; fill-opacity: 0.75; fill-rule: evenodd; stroke: black; stroke-width: 3; stroke-linecap: butt; stroke-linejoin: miter; marker: none; stroke-miterlimit: 4; stroke-dasharray: none; stroke-dashoffset: 0pt; stroke-opacity: 1; visibility: visible; display: inline; overflow: visible;" id="path26867"/>
|
|
||||||
<path d="M 49.396475 36.70454 A 15.623922 16.319134 0 1 1 18.14863,36.70454 A 15.623922 16.319134 0 1 1 49.396475 36.70454 z" transform="matrix(0.48802, 0.48802, -0.467594, 0.467594, 371.609, 473.136)" style="opacity: 1; color: black; fill: none; fill-opacity: 1; fill-rule: evenodd; stroke: black; stroke-width: 4.44072; stroke-linecap: butt; stroke-linejoin: miter; marker: none; stroke-miterlimit: 4; stroke-dasharray: none; stroke-dashoffset: 0pt; stroke-opacity: 1; visibility: visible; display: inline; overflow: visible;" id="path26871"/>
|
|
||||||
<path d="M 379.92823,489.70212 C 387.842,489.70212 387.842,489.70212 387.842,489.70212 L 387.842,497.61589" style="fill: none; fill-rule: evenodd; stroke: black; stroke-width: 3; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path27759"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Intersexual/Transgendered symbol by Gregory Maxwell. Copyright 2005. GFDL-1.2 only -->
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
version="1.1"
|
|
||||||
width="210"
|
|
||||||
height="280">
|
|
||||||
<path d="M 188,38 v 20 l 14,-8 v -42 h -42 l -8,14 h 20 l -37,37 a 79,79 0 1,0 -59,141 v 22 h -27 v 23 h 27 v 27 h 23 v -27 h 27 v -23 h -27 v -22 a 79,79 0 0,0 52,-125 zm -100,27 a 57,57 0 1,1 0,114 a 57,57 0 1,1 0,-114 z"/>
|
|
||||||
<!-- 88,65 // -63,-10 -->
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 500 B |
@@ -1,6 +1,7 @@
|
|||||||
## Syntax Help
|
## Search Syntax Help
|
||||||
-----
|
-----
|
||||||
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.
|
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.
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Name:</dt>
|
<dt>Name:</dt>
|
||||||
<dd>[birds of paradise](#birds of paradise) <small>(Any card name containing the words birds, of, and paradise)</small></dd>
|
<dd>[birds of paradise](#birds of paradise) <small>(Any card name containing the words birds, of, and paradise)</small></dd>
|
||||||
@@ -30,10 +31,10 @@ The search bar recognizes a set of special commands similar to some other card d
|
|||||||
<dd>[c:c](#c:c) <small>(Any colorless card)</small></dd>
|
<dd>[c:c](#c:c) <small>(Any colorless card)</small></dd>
|
||||||
<dd>[ci:w](#ci:w) <small>(Any card that has white in it's color identity)</small></dd>
|
<dd>[ci:w](#ci:w) <small>(Any card that has white in it's color identity)</small></dd>
|
||||||
|
|
||||||
<dt><u>Pow</u>er, <u>Tou</u>ghness, <u>C</u>onverted <u>M</u>ana <u>C</u>ost:</dt>
|
<dt><u>Pow</u>er, <u>Tou</u>ghness, <u>M</u>ana <u>V</u>alue:</dt>
|
||||||
<dd>[tou:1](#tou:1) <small>(Any card with a toughness of 1)</small></dd>
|
<dd>[tou:1](#tou:1) <small>(Any card with a toughness of 1)</small></dd>
|
||||||
<dd>[pow>=8](#pow>=8) <small>(Any card with a power greater than or equal to 8)</small></dd>
|
<dd>[pow>=8](#pow>=8) <small>(Any card with a power greater than or equal to 8)</small></dd>
|
||||||
<dd>[cmc=7](#cmc=7) <small>(Any card with a converted mana cost equal to 7)</small></dd>
|
<dd>[mv=7](#mv=7) <small>(Any card with a mana value equal to 7)</small></dd>
|
||||||
|
|
||||||
<dt><u>R</u>arity:</dt>
|
<dt><u>R</u>arity:</dt>
|
||||||
<dd>[r:mythic](#r:mythic) <small>(Any card that has the mythic-rare rarity)</small></dd>
|
<dd>[r:mythic](#r:mythic) <small>(Any card that has the mythic-rare rarity)</small></dd>
|
||||||
@@ -46,8 +47,7 @@ The search bar recognizes a set of special commands similar to some other card d
|
|||||||
|
|
||||||
<dt><u>E</u>dition:</dt>
|
<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>[set:lea](#set:lea) <small>(Cards that appear in Alpha, which has the set code LEA)</small></dd>
|
||||||
<dd>[e:lea,leb](#e:lea,leb) <small>(Cards that appear in Alpha or Beta)</small></dd>
|
<dd>[e:lea or e:leb](#e:lea or e: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>
|
<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>
|
<dd>[c:wu -c:m](#c:wu -c:m) <small>(Any card that is white or blue, but not multicolored)</small></dd>
|
||||||
|
|||||||
BIN
cockatrice/resources/tips/images/discord.png
Normal file
BIN
cockatrice/resources/tips/images/discord.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.9 KiB |
@@ -7,9 +7,9 @@
|
|||||||
</tip>
|
</tip>
|
||||||
<tip>
|
<tip>
|
||||||
<title>Suggesting New Tips</title>
|
<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://gitter.im/cockatrice/cockatrice">Gitter</a>!</text>
|
<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>gitter.png</image>
|
<image>discord.png</image>
|
||||||
<date>2018-03-01</date>
|
<date>2023-10-18</date>
|
||||||
</tip>
|
</tip>
|
||||||
<tip>
|
<tip>
|
||||||
<title>Reporting Bugs</title>
|
<title>Reporting Bugs</title>
|
||||||
|
|||||||
@@ -2,18 +2,15 @@
|
|||||||
#
|
#
|
||||||
# add sounds subfolders
|
# add sounds subfolders
|
||||||
|
|
||||||
SET(defsounds
|
set(defsounds Default Legacy)
|
||||||
Default
|
|
||||||
Legacy
|
|
||||||
)
|
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
INSTALL(DIRECTORY ${defsounds} DESTINATION Cockatrice.app/Contents/Resources/sounds/)
|
install(DIRECTORY ${defsounds} DESTINATION Cockatrice.app/Contents/Resources/sounds/)
|
||||||
else()
|
else()
|
||||||
# Assume linux
|
# Assume linux
|
||||||
INSTALL(DIRECTORY ${defsounds} DESTINATION share/cockatrice/sounds/)
|
install(DIRECTORY ${defsounds} DESTINATION share/cockatrice/sounds/)
|
||||||
endif()
|
endif()
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
INSTALL(DIRECTORY ${defsounds} DESTINATION sounds/)
|
install(DIRECTORY ${defsounds} DESTINATION sounds/)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -20,13 +20,8 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item,
|
|||||||
parentDrag->addChildDrag(this);
|
parentDrag->addChildDrag(this);
|
||||||
setZValue(2000000007 + hotSpot.x() * 1000000 + hotSpot.y() * 1000 + 1000);
|
setZValue(2000000007 + hotSpot.x() * 1000000 + hotSpot.y() * 1000 + 1000);
|
||||||
} else {
|
} else {
|
||||||
if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) {
|
hotSpot = QPointF{qBound(0.0, hotSpot.x(), static_cast<qreal>(CARD_WIDTH - 1)),
|
||||||
qDebug() << "CardDragItem: coordinate overflow: x =" << hotSpot.x() << ", y =" << hotSpot.y();
|
qBound(0.0, hotSpot.y(), static_cast<qreal>(CARD_HEIGHT - 1))};
|
||||||
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);
|
setCursor(Qt::ClosedHandCursor);
|
||||||
setZValue(2000000007);
|
setZValue(2000000007);
|
||||||
}
|
}
|
||||||
@@ -45,12 +40,19 @@ AbstractCardDragItem::~AbstractCardDragItem()
|
|||||||
delete childDrags[i];
|
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)
|
void AbstractCardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||||
{
|
{
|
||||||
item->paint(painter, option, widget);
|
item->paint(painter, option, widget);
|
||||||
|
|
||||||
// adds a mask to the card so it looks like the card hasnt been placed yet
|
// adds a mask to the card so it looks like the card hasnt been placed yet
|
||||||
painter->fillRect(boundingRect(), GHOST_MASK);
|
painter->fillPath(shape(), GHOST_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
void AbstractCardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
|||||||
@@ -21,17 +21,18 @@ public:
|
|||||||
{
|
{
|
||||||
Type = typeCardDrag
|
Type = typeCardDrag
|
||||||
};
|
};
|
||||||
int type() const
|
int type() const override
|
||||||
{
|
{
|
||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
AbstractCardDragItem(AbstractCardItem *_item, const QPointF &_hotSpot, AbstractCardDragItem *parentDrag = 0);
|
AbstractCardDragItem(AbstractCardItem *_item, const QPointF &_hotSpot, AbstractCardDragItem *parentDrag = 0);
|
||||||
~AbstractCardDragItem();
|
~AbstractCardDragItem();
|
||||||
QRectF boundingRect() const
|
QRectF boundingRect() const override
|
||||||
{
|
{
|
||||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||||
}
|
}
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
QPainterPath shape() const override;
|
||||||
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||||
AbstractCardItem *getItem() const
|
AbstractCardItem *getItem() const
|
||||||
{
|
{
|
||||||
return item;
|
return item;
|
||||||
@@ -44,7 +45,7 @@ public:
|
|||||||
virtual void updatePosition(const QPointF &cursorScenePos) = 0;
|
virtual void updatePosition(const QPointF &cursorScenePos) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
#include <QCursor>
|
|
||||||
#include <QGraphicsScene>
|
|
||||||
#include <QGraphicsSceneMouseEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cmath>
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include "round.h"
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
#include "abstractcarditem.h"
|
#include "abstractcarditem.h"
|
||||||
|
|
||||||
#include "carddatabase.h"
|
#include "carddatabase.h"
|
||||||
#include "gamescene.h"
|
#include "gamescene.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "pictureloader.h"
|
#include "pictureloader.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
|
||||||
|
#include <QCursor>
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, int _id, QGraphicsItem *parent)
|
AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, int _id, QGraphicsItem *parent)
|
||||||
: ArrowTarget(_owner, parent), id(_id), name(_name), tapped(false), facedown(false), tapAngle(0),
|
: ArrowTarget(_owner, parent), id(_id), name(_name), tapped(false), facedown(false), tapAngle(0),
|
||||||
bgColor(Qt::transparent), isHovered(false), realZValue(0)
|
bgColor(Qt::transparent), isHovered(false), realZValue(0)
|
||||||
@@ -36,6 +34,13 @@ QRectF AbstractCardItem::boundingRect() const
|
|||||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
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()
|
void AbstractCardItem::pixmapUpdated()
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
@@ -115,24 +120,14 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
|
|||||||
|
|
||||||
if (paintImage) {
|
if (paintImage) {
|
||||||
painter->save();
|
painter->save();
|
||||||
transformPainter(painter, translatedSize, angle);
|
painter->setClipPath(shape());
|
||||||
painter->drawPixmap(QPointF(1, 1), translatedPixmap);
|
painter->drawPixmap(boundingRect(), translatedPixmap, QRectF({0, 0}, translatedPixmap.size()));
|
||||||
painter->restore();
|
painter->restore();
|
||||||
} else {
|
} else {
|
||||||
painter->setBrush(bgColor);
|
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) {
|
if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) {
|
||||||
painter->save();
|
painter->save();
|
||||||
transformPainter(painter, translatedSize, angle);
|
transformPainter(painter, translatedSize, angle);
|
||||||
@@ -160,9 +155,7 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
|||||||
QSizeF translatedSize = getTranslatedSize(painter);
|
QSizeF translatedSize = getTranslatedSize(painter);
|
||||||
paintPicture(painter, translatedSize, tapAngle);
|
paintPicture(painter, translatedSize, tapAngle);
|
||||||
|
|
||||||
painter->save();
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||||
transformPainter(painter, translatedSize, tapAngle);
|
|
||||||
|
|
||||||
if (isSelected() || isHovered) {
|
if (isSelected() || isHovered) {
|
||||||
QPen pen;
|
QPen pen;
|
||||||
@@ -170,15 +163,12 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
|||||||
pen.setColor(Qt::yellow);
|
pen.setColor(Qt::yellow);
|
||||||
if (isSelected())
|
if (isSelected())
|
||||||
pen.setColor(Qt::red);
|
pen.setColor(Qt::red);
|
||||||
const int penWidth = 1;
|
pen.setWidth(0); // Cosmetic pen
|
||||||
pen.setWidth(penWidth);
|
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
painter->drawPath(shape());
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCardItem::setName(const QString &_name)
|
void AbstractCardItem::setName(const QString &_name)
|
||||||
@@ -272,7 +262,6 @@ void AbstractCardItem::setFaceDown(bool _facedown)
|
|||||||
{
|
{
|
||||||
facedown = _facedown;
|
facedown = _facedown;
|
||||||
update();
|
update();
|
||||||
emit updateCardMenu(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
void AbstractCardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ signals:
|
|||||||
void hovered(AbstractCardItem *card);
|
void hovered(AbstractCardItem *card);
|
||||||
void showCardInfoPopup(QPoint pos, QString cardName);
|
void showCardInfoPopup(QPoint pos, QString cardName);
|
||||||
void deleteCardInfoPopup(QString cardName);
|
void deleteCardInfoPopup(QString cardName);
|
||||||
void updateCardMenu(AbstractCardItem *card);
|
|
||||||
void sigPixmapUpdated();
|
void sigPixmapUpdated();
|
||||||
void cardShiftClicked(QString cardName);
|
void cardShiftClicked(QString cardName);
|
||||||
|
|
||||||
@@ -45,7 +44,7 @@ public:
|
|||||||
{
|
{
|
||||||
Type = typeCard
|
Type = typeCard
|
||||||
};
|
};
|
||||||
int type() const
|
int type() const override
|
||||||
{
|
{
|
||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
@@ -54,10 +53,11 @@ public:
|
|||||||
int _id = -1,
|
int _id = -1,
|
||||||
QGraphicsItem *parent = nullptr);
|
QGraphicsItem *parent = nullptr);
|
||||||
~AbstractCardItem();
|
~AbstractCardItem();
|
||||||
QRectF boundingRect() const;
|
QRectF boundingRect() const override;
|
||||||
|
QPainterPath shape() const override;
|
||||||
QSizeF getTranslatedSize(QPainter *painter) const;
|
QSizeF getTranslatedSize(QPainter *painter) const;
|
||||||
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
|
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||||
CardInfoPtr getInfo() const
|
CardInfoPtr getInfo() const
|
||||||
{
|
{
|
||||||
return info;
|
return info;
|
||||||
@@ -104,9 +104,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle);
|
void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
|
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
||||||
void cacheBgColor();
|
void cacheBgColor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "abstractclient.h"
|
#include "abstractclient.h"
|
||||||
|
|
||||||
#include "client_metatypes.h"
|
|
||||||
#include "featureset.h"
|
#include "featureset.h"
|
||||||
#include "get_pb_extension.h"
|
#include "get_pb_extension.h"
|
||||||
#include "pb/commands.pb.h"
|
#include "pb/commands.pb.h"
|
||||||
@@ -22,7 +21,8 @@
|
|||||||
|
|
||||||
#include <google/protobuf/descriptor.h>
|
#include <google/protobuf/descriptor.h>
|
||||||
|
|
||||||
AbstractClient::AbstractClient(QObject *parent) : QObject(parent), nextCmdId(0), status(StatusDisconnected)
|
AbstractClient::AbstractClient(QObject *parent)
|
||||||
|
: QObject(parent), nextCmdId(0), status(StatusDisconnected), serverSupportsPasswordHash(false)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<QVariant>("QVariant");
|
qRegisterMetaType<QVariant>("QVariant");
|
||||||
qRegisterMetaType<CommandContainer>("CommandContainer");
|
qRegisterMetaType<CommandContainer>("CommandContainer");
|
||||||
@@ -47,6 +47,7 @@ AbstractClient::AbstractClient(QObject *parent) : QObject(parent), nextCmdId(0),
|
|||||||
qRegisterMetaType<QList<ServerInfo_User>>("QList<ServerInfo_User>");
|
qRegisterMetaType<QList<ServerInfo_User>>("QList<ServerInfo_User>");
|
||||||
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
|
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
|
||||||
qRegisterMetaType<QList<QString>>("missingFeatures");
|
qRegisterMetaType<QList<QString>>("missingFeatures");
|
||||||
|
qRegisterMetaType<PendingCommand *>("pendingCommand");
|
||||||
|
|
||||||
FeatureSet features;
|
FeatureSet features;
|
||||||
features.initalizeFeatureList(clientFeatures);
|
features.initalizeFeatureList(clientFeatures);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ enum ClientStatus
|
|||||||
StatusRequestingForgotPassword,
|
StatusRequestingForgotPassword,
|
||||||
StatusSubmitForgotPasswordReset,
|
StatusSubmitForgotPasswordReset,
|
||||||
StatusSubmitForgotPasswordChallenge,
|
StatusSubmitForgotPasswordChallenge,
|
||||||
|
StatusGettingPasswordSalt,
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbstractClient : public QObject
|
class AbstractClient : public QObject
|
||||||
@@ -87,7 +88,7 @@ protected slots:
|
|||||||
protected:
|
protected:
|
||||||
QMap<int, PendingCommand *> pendingCommands;
|
QMap<int, PendingCommand *> pendingCommands;
|
||||||
QString userName, password, email, country, realName, token;
|
QString userName, password, email, country, realName, token;
|
||||||
int gender;
|
bool serverSupportsPasswordHash;
|
||||||
void setStatus(ClientStatus _status);
|
void setStatus(ClientStatus _status);
|
||||||
int getNewCmdId()
|
int getNewCmdId()
|
||||||
{
|
{
|
||||||
@@ -107,7 +108,11 @@ public:
|
|||||||
void sendCommand(const CommandContainer &cont);
|
void sendCommand(const CommandContainer &cont);
|
||||||
void sendCommand(PendingCommand *pend);
|
void sendCommand(PendingCommand *pend);
|
||||||
|
|
||||||
const QString getUserName()
|
bool getServerSupportsPasswordHash() const
|
||||||
|
{
|
||||||
|
return serverSupportsPasswordHash;
|
||||||
|
}
|
||||||
|
const QString &getUserName() const
|
||||||
{
|
{
|
||||||
return userName;
|
return userName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <cmath>
|
#include <QtMath>
|
||||||
|
|
||||||
ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &_color)
|
ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &_color)
|
||||||
: QGraphicsItem(), player(_player), id(_id), startItem(_startItem), targetItem(_targetItem), color(_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 arrowWidth = 15.0;
|
||||||
const double headWidth = 40.0;
|
const double headWidth = 40.0;
|
||||||
const double headLength =
|
const double headLength =
|
||||||
headWidth / pow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++
|
headWidth / qPow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++
|
||||||
const double phi = 15;
|
const double phi = 15;
|
||||||
|
|
||||||
if (!startItem)
|
if (!startItem)
|
||||||
@@ -86,7 +86,7 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
|||||||
if (lineLength < 30)
|
if (lineLength < 30)
|
||||||
path = QPainterPath();
|
path = QPainterPath();
|
||||||
else {
|
else {
|
||||||
QPointF c(lineLength / 2, tan(phi * M_PI / 180) * lineLength);
|
QPointF c(lineLength / 2, qTan(phi * M_PI / 180) * lineLength);
|
||||||
|
|
||||||
QPainterPath centerLine;
|
QPainterPath centerLine;
|
||||||
centerLine.moveTo(0, 0);
|
centerLine.moveTo(0, 0);
|
||||||
@@ -97,22 +97,22 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
|||||||
QLineF testLine(arrowBodyEndPoint, centerLine.pointAtPercent(percentage + 0.001));
|
QLineF testLine(arrowBodyEndPoint, centerLine.pointAtPercent(percentage + 0.001));
|
||||||
qreal alpha = testLine.angle() - 90;
|
qreal alpha = testLine.angle() - 90;
|
||||||
QPointF endPoint1 =
|
QPointF endPoint1 =
|
||||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180));
|
arrowBodyEndPoint + arrowWidth / 2 * QPointF(qCos(alpha * M_PI / 180), -qSin(alpha * M_PI / 180));
|
||||||
QPointF endPoint2 =
|
QPointF endPoint2 =
|
||||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180));
|
arrowBodyEndPoint + arrowWidth / 2 * QPointF(-qCos(alpha * M_PI / 180), qSin(alpha * M_PI / 180));
|
||||||
QPointF point1 =
|
QPointF point1 =
|
||||||
endPoint1 + (headWidth - arrowWidth) / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180));
|
endPoint1 + (headWidth - arrowWidth) / 2 * QPointF(qCos(alpha * M_PI / 180), -qSin(alpha * M_PI / 180));
|
||||||
QPointF point2 =
|
QPointF point2 =
|
||||||
endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180));
|
endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-qCos(alpha * M_PI / 180), qSin(alpha * M_PI / 180));
|
||||||
|
|
||||||
path = QPainterPath(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
path = QPainterPath(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||||
path.quadTo(c, endPoint1);
|
path.quadTo(c, endPoint1);
|
||||||
path.lineTo(point1);
|
path.lineTo(point1);
|
||||||
path.lineTo(QPointF(lineLength, 0));
|
path.lineTo(QPointF(lineLength, 0));
|
||||||
path.lineTo(point2);
|
path.lineTo(point2);
|
||||||
path.lineTo(endPoint2);
|
path.lineTo(endPoint2);
|
||||||
path.quadTo(c, arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
path.quadTo(c, arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||||
path.lineTo(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
path.lineTo(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||||
}
|
}
|
||||||
|
|
||||||
setPos(startPoint);
|
setPos(startPoint);
|
||||||
@@ -138,8 +138,8 @@ void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QList<QGraphicsItem *> colliding = scene()->items(event->scenePos());
|
QList<QGraphicsItem *> colliding = scene()->items(event->scenePos());
|
||||||
for (int i = 0; i < colliding.size(); ++i) {
|
for (QGraphicsItem *item : colliding) {
|
||||||
if (qgraphicsitem_cast<CardItem *>(colliding[i])) {
|
if (qgraphicsitem_cast<CardItem *>(item)) {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -205,8 +205,8 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
|
||||||
for (int i = 0; i < childArrows.size(); ++i) {
|
for (ArrowDragItem *child : childArrows) {
|
||||||
childArrows[i]->mouseMoveEvent(event);
|
child->mouseMoveEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +251,9 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
}
|
}
|
||||||
delArrow();
|
delArrow();
|
||||||
|
|
||||||
for (int i = 0; i < childArrows.size(); ++i)
|
for (ArrowDragItem *child : childArrows) {
|
||||||
childArrows[i]->mouseReleaseEvent(event);
|
child->mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
|
ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
|
||||||
@@ -260,6 +261,11 @@ ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArrowAttachItem::addChildArrow(ArrowAttachItem *childArrow)
|
||||||
|
{
|
||||||
|
childArrows.append(childArrow);
|
||||||
|
}
|
||||||
|
|
||||||
void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (!startItem)
|
if (!startItem)
|
||||||
@@ -295,9 +301,13 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
updatePath();
|
updatePath();
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
for (ArrowAttachItem *child : childArrows) {
|
||||||
|
child->mouseMoveEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
|
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (!startItem)
|
if (!startItem)
|
||||||
return;
|
return;
|
||||||
@@ -319,4 +329,8 @@ void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
delArrow();
|
delArrow();
|
||||||
|
|
||||||
|
for (ArrowAttachItem *child : childArrows) {
|
||||||
|
child->mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,8 +85,12 @@ protected:
|
|||||||
class ArrowAttachItem : public ArrowItem
|
class ArrowAttachItem : public ArrowItem
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QList<ArrowAttachItem *> childArrows;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ArrowAttachItem(ArrowTarget *_startItem);
|
ArrowAttachItem(ArrowTarget *_startItem);
|
||||||
|
void addChildArrow(ArrowAttachItem *childArrow);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||||
|
|||||||
@@ -43,9 +43,8 @@ public:
|
|||||||
}
|
}
|
||||||
void removeArrowFrom(ArrowItem *arrow)
|
void removeArrowFrom(ArrowItem *arrow)
|
||||||
{
|
{
|
||||||
arrowsFrom.removeAt(arrowsFrom.indexOf(arrow));
|
arrowsFrom.removeOne(arrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<ArrowItem *> &getArrowsTo() const
|
const QList<ArrowItem *> &getArrowsTo() const
|
||||||
{
|
{
|
||||||
return arrowsTo;
|
return arrowsTo;
|
||||||
@@ -56,8 +55,7 @@ public:
|
|||||||
}
|
}
|
||||||
void removeArrowTo(ArrowItem *arrow)
|
void removeArrowTo(ArrowItem *arrow)
|
||||||
{
|
{
|
||||||
arrowsTo.removeAt(arrowsTo.indexOf(arrow));
|
arrowsTo.removeOne(arrow);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -266,9 +266,14 @@ CardInfoPtr CardInfo::newInstance(const QString &_name,
|
|||||||
|
|
||||||
QString CardInfo::getCorrectedName() const
|
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;
|
QString result = name;
|
||||||
// Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
|
// Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
|
||||||
return result.remove(" // ").remove(':').remove('"').remove('?').replace('/', ' ');
|
return result.remove(rmrx).replace(spacerx, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
||||||
@@ -587,9 +592,9 @@ void CardDatabase::refreshCachedReverseRelatedCards()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *newCardRelation = new CardRelation(card->getName(), cardRelation->getDoesAttach(),
|
auto *newCardRelation = new CardRelation(
|
||||||
cardRelation->getIsCreateAllExclusion(),
|
card->getName(), cardRelation->getAttachType(), cardRelation->getIsCreateAllExclusion(),
|
||||||
cardRelation->getIsVariable(), cardRelation->getDefaultCount());
|
cardRelation->getIsVariable(), cardRelation->getDefaultCount(), cardRelation->getIsPersistent());
|
||||||
cards.value(targetCard)->addReverseRelatedCards2Me(newCardRelation);
|
cards.value(targetCard)->addReverseRelatedCards2Me(newCardRelation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -607,22 +612,22 @@ QStringList CardDatabase::getAllMainCardTypes() const
|
|||||||
|
|
||||||
void CardDatabase::checkUnknownSets()
|
void CardDatabase::checkUnknownSets()
|
||||||
{
|
{
|
||||||
SetList sets = getSetList();
|
auto _sets = getSetList();
|
||||||
|
|
||||||
if (sets.getEnabledSetsNum()) {
|
if (_sets.getEnabledSetsNum()) {
|
||||||
// if some sets are first found on this run, ask the user
|
// if some sets are first found on this run, ask the user
|
||||||
int numUnknownSets = sets.getUnknownSetsNum();
|
int numUnknownSets = _sets.getUnknownSetsNum();
|
||||||
QStringList unknownSetNames = sets.getUnknownSetsNames();
|
QStringList unknownSetNames = _sets.getUnknownSetsNames();
|
||||||
if (numUnknownSets > 0) {
|
if (numUnknownSets > 0) {
|
||||||
emit cardDatabaseNewSetsFound(numUnknownSets, unknownSetNames);
|
emit cardDatabaseNewSetsFound(numUnknownSets, unknownSetNames);
|
||||||
} else {
|
} else {
|
||||||
sets.markAllAsKnown();
|
_sets.markAllAsKnown();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No set enabled. Probably this is the first time running trice
|
// No set enabled. Probably this is the first time running trice
|
||||||
sets.guessSortKeys();
|
_sets.guessSortKeys();
|
||||||
sets.sortByKey();
|
_sets.sortByKey();
|
||||||
sets.enableAll();
|
_sets.enableAll();
|
||||||
notifyEnabledSetsChanged();
|
notifyEnabledSetsChanged();
|
||||||
|
|
||||||
emit cardDatabaseAllNewSetsEnabled();
|
emit cardDatabaseAllNewSetsEnabled();
|
||||||
@@ -631,14 +636,14 @@ void CardDatabase::checkUnknownSets()
|
|||||||
|
|
||||||
void CardDatabase::enableAllUnknownSets()
|
void CardDatabase::enableAllUnknownSets()
|
||||||
{
|
{
|
||||||
SetList sets = getSetList();
|
auto _sets = getSetList();
|
||||||
sets.enableAllUnknown();
|
_sets.enableAllUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabase::markAllSetsAsKnown()
|
void CardDatabase::markAllSetsAsKnown()
|
||||||
{
|
{
|
||||||
SetList sets = getSetList();
|
auto _sets = getSetList();
|
||||||
sets.markAllAsKnown();
|
_sets.markAllAsKnown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabase::notifyEnabledSetsChanged()
|
void CardDatabase::notifyEnabledSetsChanged()
|
||||||
@@ -672,12 +677,13 @@ bool CardDatabase::saveCustomTokensToFile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CardRelation::CardRelation(const QString &_name,
|
CardRelation::CardRelation(const QString &_name,
|
||||||
bool _doesAttach,
|
AttachType _attachType,
|
||||||
bool _isCreateAllExclusion,
|
bool _isCreateAllExclusion,
|
||||||
bool _isVariableCount,
|
bool _isVariableCount,
|
||||||
int _defaultCount)
|
int _defaultCount,
|
||||||
: name(_name), doesAttach(_doesAttach), isCreateAllExclusion(_isCreateAllExclusion),
|
bool _isPersistent)
|
||||||
isVariableCount(_isVariableCount), defaultCount(_defaultCount)
|
: name(_name), attachType(_attachType), isCreateAllExclusion(_isCreateAllExclusion),
|
||||||
|
isVariableCount(_isVariableCount), defaultCount(_defaultCount), isPersistent(_isPersistent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -452,31 +452,60 @@ signals:
|
|||||||
class CardRelation : public QObject
|
class CardRelation : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum AttachType
|
||||||
|
{
|
||||||
|
DoesNotAttach = 0,
|
||||||
|
AttachTo = 1,
|
||||||
|
TransformInto = 2,
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
bool doesAttach;
|
AttachType attachType;
|
||||||
bool isCreateAllExclusion;
|
bool isCreateAllExclusion;
|
||||||
bool isVariableCount;
|
bool isVariableCount;
|
||||||
int defaultCount;
|
int defaultCount;
|
||||||
|
bool isPersistent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CardRelation(const QString &_name = QString(),
|
explicit CardRelation(const QString &_name = QString(),
|
||||||
bool _doesAttach = false,
|
AttachType _attachType = DoesNotAttach,
|
||||||
bool _isCreateAllExclusion = false,
|
bool _isCreateAllExclusion = false,
|
||||||
bool _isVariableCount = false,
|
bool _isVariableCount = false,
|
||||||
int _defaultCount = 1);
|
int _defaultCount = 1,
|
||||||
|
bool _isPersistent = false);
|
||||||
|
|
||||||
inline const QString &getName() const
|
inline const QString &getName() const
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
AttachType getAttachType() const
|
||||||
|
{
|
||||||
|
return attachType;
|
||||||
|
}
|
||||||
bool getDoesAttach() const
|
bool getDoesAttach() const
|
||||||
{
|
{
|
||||||
return doesAttach;
|
return attachType != DoesNotAttach;
|
||||||
|
}
|
||||||
|
bool getDoesTransform() const
|
||||||
|
{
|
||||||
|
return attachType == TransformInto;
|
||||||
|
}
|
||||||
|
QString getAttachTypeAsString() const
|
||||||
|
{
|
||||||
|
switch (attachType) {
|
||||||
|
case AttachTo:
|
||||||
|
return "attach";
|
||||||
|
case TransformInto:
|
||||||
|
return "transform";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool getCanCreateAnother() const
|
bool getCanCreateAnother() const
|
||||||
{
|
{
|
||||||
return !doesAttach;
|
return !getDoesAttach();
|
||||||
}
|
}
|
||||||
bool getIsCreateAllExclusion() const
|
bool getIsCreateAllExclusion() const
|
||||||
{
|
{
|
||||||
@@ -490,5 +519,9 @@ public:
|
|||||||
{
|
{
|
||||||
return defaultCount;
|
return defaultCount;
|
||||||
}
|
}
|
||||||
|
bool getIsPersistent() const
|
||||||
|
{
|
||||||
|
return isPersistent;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -326,12 +326,12 @@ void CardDatabaseDisplayModel::clearFilterAll()
|
|||||||
invalidateFilter();
|
invalidateFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDatabaseDisplayModel::setFilterTree(FilterTree *filterTree)
|
void CardDatabaseDisplayModel::setFilterTree(FilterTree *_filterTree)
|
||||||
{
|
{
|
||||||
if (this->filterTree != nullptr)
|
if (this->filterTree != nullptr)
|
||||||
disconnect(this->filterTree, nullptr, this, nullptr);
|
disconnect(this->filterTree, nullptr, this, nullptr);
|
||||||
|
|
||||||
this->filterTree = filterTree;
|
this->filterTree = _filterTree;
|
||||||
connect(this->filterTree, SIGNAL(changed()), this, SLOT(filterTreeChanged()));
|
connect(this->filterTree, SIGNAL(changed()), this, SLOT(filterTreeChanged()));
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CardDatabaseDisplayModel(QObject *parent = nullptr);
|
explicit CardDatabaseDisplayModel(QObject *parent = nullptr);
|
||||||
void setFilterTree(FilterTree *filterTree);
|
void setFilterTree(FilterTree *_filterTree);
|
||||||
void setIsToken(FilterBool _isToken)
|
void setIsToken(FilterBool _isToken)
|
||||||
{
|
{
|
||||||
isToken = _isToken;
|
isToken = _isToken;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ bool CockatriceXml3Parser::getCanParseFile(const QString &fileName, QIODevice &d
|
|||||||
QXmlStreamReader xml(&device);
|
QXmlStreamReader xml(&device);
|
||||||
while (!xml.atEnd()) {
|
while (!xml.atEnd()) {
|
||||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||||
if (xml.name() == COCKATRICE_XML3_TAGNAME) {
|
if (xml.name().toString() == COCKATRICE_XML3_TAGNAME) {
|
||||||
int version = xml.attributes().value("version").toString().toInt();
|
int version = xml.attributes().value("version").toString().toInt();
|
||||||
if (version == COCKATRICE_XML3_TAGVER) {
|
if (version == COCKATRICE_XML3_TAGVER) {
|
||||||
return true;
|
return true;
|
||||||
@@ -52,12 +52,13 @@ void CockatriceXml3Parser::parseFile(QIODevice &device)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml.name() == "sets") {
|
auto name = xml.name().toString();
|
||||||
|
if (name == "sets") {
|
||||||
loadSetsFromXml(xml);
|
loadSetsFromXml(xml);
|
||||||
} else if (xml.name() == "cards") {
|
} else if (name == "cards") {
|
||||||
loadCardsFromXml(xml);
|
loadCardsFromXml(xml);
|
||||||
} else if (xml.name() != "") {
|
} else if (!name.isEmpty()) {
|
||||||
qDebug() << "[CockatriceXml3Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
qDebug() << "[CockatriceXml3Parser] Unknown item" << name << ", trying to continue anyway";
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,26 +73,27 @@ void CockatriceXml3Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml.name() == "set") {
|
auto name = xml.name().toString();
|
||||||
|
if (name == "set") {
|
||||||
QString shortName, longName, setType;
|
QString shortName, longName, setType;
|
||||||
QDate releaseDate;
|
QDate releaseDate;
|
||||||
while (!xml.atEnd()) {
|
while (!xml.atEnd()) {
|
||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
name = xml.name().toString();
|
||||||
|
|
||||||
if (xml.name() == "name") {
|
if (name == "name") {
|
||||||
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "longname") {
|
} else if (name == "longname") {
|
||||||
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "settype") {
|
} else if (name == "settype") {
|
||||||
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "releasedate") {
|
} else if (name == "releasedate") {
|
||||||
releaseDate =
|
releaseDate =
|
||||||
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
||||||
} else if (xml.name() != "") {
|
} else if (!name.isEmpty()) {
|
||||||
qDebug() << "[CockatriceXml3Parser] Unknown set property" << xml.name()
|
qDebug() << "[CockatriceXml3Parser] Unknown set property" << name << ", trying to continue anyway";
|
||||||
<< ", trying to continue anyway";
|
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,13 +148,14 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml.name() == "card") {
|
auto xmlName = xml.name().toString();
|
||||||
|
if (xmlName == "card") {
|
||||||
QString name = QString("");
|
QString name = QString("");
|
||||||
QString text = QString("");
|
QString text = QString("");
|
||||||
QVariantHash properties = QVariantHash();
|
QVariantHash properties = QVariantHash();
|
||||||
QString colors = QString("");
|
QString colors = QString("");
|
||||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
auto _sets = CardInfoPerSetMap();
|
||||||
int tableRow = 0;
|
int tableRow = 0;
|
||||||
bool cipt = false;
|
bool cipt = false;
|
||||||
bool isToken = false;
|
bool isToken = false;
|
||||||
@@ -162,37 +165,39 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
xmlName = xml.name().toString();
|
||||||
|
|
||||||
// variable - assigned properties
|
// variable - assigned properties
|
||||||
if (xml.name() == "name") {
|
if (xmlName == "name") {
|
||||||
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "text") {
|
} else if (xmlName == "text") {
|
||||||
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "color") {
|
} else if (xmlName == "color") {
|
||||||
colors.append(xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
colors.append(xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||||
} else if (xml.name() == "token") {
|
} else if (xmlName == "token") {
|
||||||
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
||||||
// generic properties
|
// generic properties
|
||||||
} else if (xml.name() == "manacost") {
|
} else if (xmlName == "manacost") {
|
||||||
properties.insert("manacost", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
properties.insert("manacost", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||||
} else if (xml.name() == "cmc") {
|
} else if (xmlName == "cmc") {
|
||||||
properties.insert("cmc", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
properties.insert("cmc", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||||
} else if (xml.name() == "type") {
|
} else if (xmlName == "type") {
|
||||||
QString type = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
QString type = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
properties.insert("type", type);
|
properties.insert("type", type);
|
||||||
properties.insert("maintype", getMainCardType(type));
|
properties.insert("maintype", getMainCardType(type));
|
||||||
} else if (xml.name() == "pt") {
|
} else if (xmlName == "pt") {
|
||||||
properties.insert("pt", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
properties.insert("pt", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||||
} else if (xml.name() == "loyalty") {
|
} else if (xmlName == "loyalty") {
|
||||||
properties.insert("loyalty", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
properties.insert("loyalty", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||||
// positioning info
|
// positioning info
|
||||||
} else if (xml.name() == "tablerow") {
|
} else if (xmlName == "tablerow") {
|
||||||
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
||||||
} else if (xml.name() == "cipt") {
|
} else if (xmlName == "cipt") {
|
||||||
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||||
} else if (xml.name() == "upsidedown") {
|
} else if (xmlName == "upsidedown") {
|
||||||
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||||
// sets
|
// sets
|
||||||
} else if (xml.name() == "set") {
|
} else if (xmlName == "set") {
|
||||||
// NOTE: attributes must be read before readElementText()
|
// NOTE: attributes must be read before readElementText()
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
QXmlStreamAttributes attrs = xml.attributes();
|
||||||
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
@@ -216,10 +221,10 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
if (attrs.hasAttribute("rarity")) {
|
if (attrs.hasAttribute("rarity")) {
|
||||||
setInfo.setProperty("rarity", attrs.value("rarity").toString());
|
setInfo.setProperty("rarity", attrs.value("rarity").toString());
|
||||||
}
|
}
|
||||||
sets.insert(setName, setInfo);
|
_sets.insert(setName, setInfo);
|
||||||
// relatd cards
|
// related cards
|
||||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||||
bool attach = false;
|
CardRelation::AttachType attach = CardRelation::DoesNotAttach;
|
||||||
bool exclude = false;
|
bool exclude = false;
|
||||||
bool variable = false;
|
bool variable = false;
|
||||||
int count = 1;
|
int count = 1;
|
||||||
@@ -241,7 +246,7 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.hasAttribute("attach")) {
|
if (attrs.hasAttribute("attach")) {
|
||||||
attach = true;
|
attach = CardRelation::AttachTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.hasAttribute("exclude")) {
|
if (attrs.hasAttribute("exclude")) {
|
||||||
@@ -249,13 +254,13 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||||
if (xml.name() == "reverse-related") {
|
if (xmlName == "reverse-related") {
|
||||||
reverseRelatedCards << relation;
|
reverseRelatedCards << relation;
|
||||||
} else {
|
} else {
|
||||||
relatedCards << relation;
|
relatedCards << relation;
|
||||||
}
|
}
|
||||||
} else if (xml.name() != "") {
|
} else if (!xmlName.isEmpty()) {
|
||||||
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xml.name()
|
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xmlName
|
||||||
<< ", trying to continue anyway";
|
<< ", trying to continue anyway";
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
@@ -263,7 +268,7 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
|
|
||||||
properties.insert("colors", colors);
|
properties.insert("colors", colors);
|
||||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
reverseRelatedCards, _sets, cipt, tableRow, upsideDown);
|
||||||
emit addCard(newCard);
|
emit addCard(newCard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -407,7 +412,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
|||||||
return xml;
|
return xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
|
bool CockatriceXml3Parser::saveToFile(SetNameMap _sets,
|
||||||
CardNameMap cards,
|
CardNameMap cards,
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
const QString &sourceUrl,
|
const QString &sourceUrl,
|
||||||
@@ -434,9 +439,9 @@ bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
|
|||||||
xml.writeTextElement("sourceVersion", sourceVersion);
|
xml.writeTextElement("sourceVersion", sourceVersion);
|
||||||
xml.writeEndElement();
|
xml.writeEndElement();
|
||||||
|
|
||||||
if (sets.count() > 0) {
|
if (_sets.count() > 0) {
|
||||||
xml.writeStartElement("sets");
|
xml.writeStartElement("sets");
|
||||||
for (CardSetPtr set : sets) {
|
for (CardSetPtr set : _sets) {
|
||||||
xml << set;
|
xml << set;
|
||||||
}
|
}
|
||||||
xml.writeEndElement();
|
xml.writeEndElement();
|
||||||
@@ -454,4 +459,4 @@ bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
|
|||||||
xml.writeEndDocument();
|
xml.writeEndDocument();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public:
|
|||||||
~CockatriceXml3Parser() override = default;
|
~CockatriceXml3Parser() override = default;
|
||||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||||
void parseFile(QIODevice &device) override;
|
void parseFile(QIODevice &device) override;
|
||||||
bool saveToFile(SetNameMap sets,
|
bool saveToFile(SetNameMap _sets,
|
||||||
CardNameMap cards,
|
CardNameMap cards,
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
const QString &sourceUrl = "unknown",
|
const QString &sourceUrl = "unknown",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ bool CockatriceXml4Parser::getCanParseFile(const QString &fileName, QIODevice &d
|
|||||||
QXmlStreamReader xml(&device);
|
QXmlStreamReader xml(&device);
|
||||||
while (!xml.atEnd()) {
|
while (!xml.atEnd()) {
|
||||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||||
if (xml.name() == COCKATRICE_XML4_TAGNAME) {
|
if (xml.name().toString() == COCKATRICE_XML4_TAGNAME) {
|
||||||
int version = xml.attributes().value("version").toString().toInt();
|
int version = xml.attributes().value("version").toString().toInt();
|
||||||
if (version == COCKATRICE_XML4_TAGVER) {
|
if (version == COCKATRICE_XML4_TAGVER) {
|
||||||
return true;
|
return true;
|
||||||
@@ -52,12 +52,13 @@ void CockatriceXml4Parser::parseFile(QIODevice &device)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml.name() == "sets") {
|
auto xmlName = xml.name().toString();
|
||||||
|
if (xmlName == "sets") {
|
||||||
loadSetsFromXml(xml);
|
loadSetsFromXml(xml);
|
||||||
} else if (xml.name() == "cards") {
|
} else if (xmlName == "cards") {
|
||||||
loadCardsFromXml(xml);
|
loadCardsFromXml(xml);
|
||||||
} else if (xml.name() != "") {
|
} else if (!xmlName.isEmpty()) {
|
||||||
qDebug() << "[CockatriceXml4Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
qDebug() << "[CockatriceXml4Parser] Unknown item" << xmlName << ", trying to continue anyway";
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,25 +73,27 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml.name() == "set") {
|
auto xmlName = xml.name().toString();
|
||||||
|
if (xmlName == "set") {
|
||||||
QString shortName, longName, setType;
|
QString shortName, longName, setType;
|
||||||
QDate releaseDate;
|
QDate releaseDate;
|
||||||
while (!xml.atEnd()) {
|
while (!xml.atEnd()) {
|
||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
xmlName = xml.name().toString();
|
||||||
|
|
||||||
if (xml.name() == "name") {
|
if (xmlName == "name") {
|
||||||
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "longname") {
|
} else if (xmlName == "longname") {
|
||||||
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "settype") {
|
} else if (xmlName == "settype") {
|
||||||
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "releasedate") {
|
} else if (xmlName == "releasedate") {
|
||||||
releaseDate =
|
releaseDate =
|
||||||
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
||||||
} else if (xml.name() != "") {
|
} else if (!xmlName.isEmpty()) {
|
||||||
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xml.name()
|
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xmlName
|
||||||
<< ", trying to continue anyway";
|
<< ", trying to continue anyway";
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
@@ -109,8 +112,9 @@ QVariantHash CockatriceXml4Parser::loadCardPropertiesFromXml(QXmlStreamReader &x
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml.name() != "") {
|
auto xmlName = xml.name().toString();
|
||||||
properties.insert(xml.name().toString(), xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
if (!xmlName.isEmpty()) {
|
||||||
|
properties.insert(xmlName, xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return properties;
|
return properties;
|
||||||
@@ -123,12 +127,14 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xml.name() == "card") {
|
auto xmlName = xml.name().toString();
|
||||||
|
|
||||||
|
if (xmlName == "card") {
|
||||||
QString name = QString("");
|
QString name = QString("");
|
||||||
QString text = QString("");
|
QString text = QString("");
|
||||||
QVariantHash properties = QVariantHash();
|
QVariantHash properties = QVariantHash();
|
||||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
auto _sets = CardInfoPerSetMap();
|
||||||
int tableRow = 0;
|
int tableRow = 0;
|
||||||
bool cipt = false;
|
bool cipt = false;
|
||||||
bool isToken = false;
|
bool isToken = false;
|
||||||
@@ -138,25 +144,28 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmlName = xml.name().toString();
|
||||||
|
|
||||||
// variable - assigned properties
|
// variable - assigned properties
|
||||||
if (xml.name() == "name") {
|
if (xmlName == "name") {
|
||||||
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "text") {
|
} else if (xmlName == "text") {
|
||||||
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
} else if (xml.name() == "token") {
|
} else if (xmlName == "token") {
|
||||||
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
||||||
// generic properties
|
// generic properties
|
||||||
} else if (xml.name() == "prop") {
|
} else if (xmlName == "prop") {
|
||||||
properties = loadCardPropertiesFromXml(xml);
|
properties = loadCardPropertiesFromXml(xml);
|
||||||
// positioning info
|
// positioning info
|
||||||
} else if (xml.name() == "tablerow") {
|
} else if (xmlName == "tablerow") {
|
||||||
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
||||||
} else if (xml.name() == "cipt") {
|
} else if (xmlName == "cipt") {
|
||||||
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||||
} else if (xml.name() == "upsidedown") {
|
} else if (xmlName == "upsidedown") {
|
||||||
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||||
// sets
|
// sets
|
||||||
} else if (xml.name() == "set") {
|
} else if (xmlName == "set") {
|
||||||
// NOTE: attributes but be read before readElementText()
|
// NOTE: attributes but be read before readElementText()
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
QXmlStreamAttributes attrs = xml.attributes();
|
||||||
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
@@ -169,13 +178,14 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
attrName = "picurl";
|
attrName = "picurl";
|
||||||
setInfo.setProperty(attrName, attr.value().toString());
|
setInfo.setProperty(attrName, attr.value().toString());
|
||||||
}
|
}
|
||||||
sets.insert(setName, setInfo);
|
_sets.insert(setName, setInfo);
|
||||||
}
|
}
|
||||||
// relatd cards
|
// related cards
|
||||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||||
bool attach = false;
|
CardRelation::AttachType attachType = CardRelation::DoesNotAttach;
|
||||||
bool exclude = false;
|
bool exclude = false;
|
||||||
bool variable = false;
|
bool variable = false;
|
||||||
|
bool persistent = false;
|
||||||
int count = 1;
|
int count = 1;
|
||||||
QXmlStreamAttributes attrs = xml.attributes();
|
QXmlStreamAttributes attrs = xml.attributes();
|
||||||
QString cardName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
QString cardName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||||
@@ -195,28 +205,33 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.hasAttribute("attach")) {
|
if (attrs.hasAttribute("attach")) {
|
||||||
attach = true;
|
attachType = attrs.value("attach").toString() == "transform" ? CardRelation::TransformInto
|
||||||
|
: CardRelation::AttachTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.hasAttribute("exclude")) {
|
if (attrs.hasAttribute("exclude")) {
|
||||||
exclude = true;
|
exclude = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
if (attrs.hasAttribute("persistent")) {
|
||||||
if (xml.name() == "reverse-related") {
|
persistent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *relation = new CardRelation(cardName, attachType, exclude, variable, count, persistent);
|
||||||
|
if (xmlName == "reverse-related") {
|
||||||
reverseRelatedCards << relation;
|
reverseRelatedCards << relation;
|
||||||
} else {
|
} else {
|
||||||
relatedCards << relation;
|
relatedCards << relation;
|
||||||
}
|
}
|
||||||
} else if (xml.name() != "") {
|
} else if (!xmlName.isEmpty()) {
|
||||||
qDebug() << "[CockatriceXml4Parser] Unknown card property" << xml.name()
|
qDebug() << "[CockatriceXml4Parser] Unknown card property" << xmlName
|
||||||
<< ", trying to continue anyway";
|
<< ", trying to continue anyway";
|
||||||
xml.skipCurrentElement();
|
xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
reverseRelatedCards, _sets, cipt, tableRow, upsideDown);
|
||||||
emit addCard(newCard);
|
emit addCard(newCard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,12 +295,14 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
|||||||
for (auto i : related) {
|
for (auto i : related) {
|
||||||
xml.writeStartElement("related");
|
xml.writeStartElement("related");
|
||||||
if (i->getDoesAttach()) {
|
if (i->getDoesAttach()) {
|
||||||
xml.writeAttribute("attach", "attach");
|
xml.writeAttribute("attach", i->getAttachTypeAsString());
|
||||||
}
|
}
|
||||||
if (i->getIsCreateAllExclusion()) {
|
if (i->getIsCreateAllExclusion()) {
|
||||||
xml.writeAttribute("exclude", "exclude");
|
xml.writeAttribute("exclude", "exclude");
|
||||||
}
|
}
|
||||||
|
if (i->getIsPersistent()) {
|
||||||
|
xml.writeAttribute("persistent", "persistent");
|
||||||
|
}
|
||||||
if (i->getIsVariable()) {
|
if (i->getIsVariable()) {
|
||||||
if (1 == i->getDefaultCount()) {
|
if (1 == i->getDefaultCount()) {
|
||||||
xml.writeAttribute("count", "x");
|
xml.writeAttribute("count", "x");
|
||||||
@@ -302,13 +319,16 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
|||||||
for (auto i : reverseRelated) {
|
for (auto i : reverseRelated) {
|
||||||
xml.writeStartElement("reverse-related");
|
xml.writeStartElement("reverse-related");
|
||||||
if (i->getDoesAttach()) {
|
if (i->getDoesAttach()) {
|
||||||
xml.writeAttribute("attach", "attach");
|
xml.writeAttribute("attach", i->getAttachTypeAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i->getIsCreateAllExclusion()) {
|
if (i->getIsCreateAllExclusion()) {
|
||||||
xml.writeAttribute("exclude", "exclude");
|
xml.writeAttribute("exclude", "exclude");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i->getIsPersistent()) {
|
||||||
|
xml.writeAttribute("persistent", "persistent");
|
||||||
|
}
|
||||||
if (i->getIsVariable()) {
|
if (i->getIsVariable()) {
|
||||||
if (1 == i->getDefaultCount()) {
|
if (1 == i->getDefaultCount()) {
|
||||||
xml.writeAttribute("count", "x");
|
xml.writeAttribute("count", "x");
|
||||||
@@ -336,7 +356,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
|||||||
return xml;
|
return xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CockatriceXml4Parser::saveToFile(SetNameMap sets,
|
bool CockatriceXml4Parser::saveToFile(SetNameMap _sets,
|
||||||
CardNameMap cards,
|
CardNameMap cards,
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
const QString &sourceUrl,
|
const QString &sourceUrl,
|
||||||
@@ -363,9 +383,9 @@ bool CockatriceXml4Parser::saveToFile(SetNameMap sets,
|
|||||||
xml.writeTextElement("sourceVersion", sourceVersion);
|
xml.writeTextElement("sourceVersion", sourceVersion);
|
||||||
xml.writeEndElement();
|
xml.writeEndElement();
|
||||||
|
|
||||||
if (sets.count() > 0) {
|
if (_sets.count() > 0) {
|
||||||
xml.writeStartElement("sets");
|
xml.writeStartElement("sets");
|
||||||
for (CardSetPtr set : sets) {
|
for (CardSetPtr set : _sets) {
|
||||||
xml << set;
|
xml << set;
|
||||||
}
|
}
|
||||||
xml.writeEndElement();
|
xml.writeEndElement();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public:
|
|||||||
~CockatriceXml4Parser() override = default;
|
~CockatriceXml4Parser() override = default;
|
||||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||||
void parseFile(QIODevice &device) override;
|
void parseFile(QIODevice &device) override;
|
||||||
bool saveToFile(SetNameMap sets,
|
bool saveToFile(SetNameMap _sets,
|
||||||
CardNameMap cards,
|
CardNameMap cards,
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
const QString &sourceUrl = "unknown",
|
const QString &sourceUrl = "unknown",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
|||||||
AbstractCardDragItem::paint(painter, option, widget);
|
AbstractCardDragItem::paint(painter, option, widget);
|
||||||
|
|
||||||
if (occupied)
|
if (occupied)
|
||||||
painter->fillRect(boundingRect(), QColor(200, 0, 0, 100));
|
painter->fillPath(shape(), QColor(200, 0, 0, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
||||||
@@ -53,8 +53,20 @@ void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
|||||||
|
|
||||||
QPointF zonePos = currentZone->scenePos();
|
QPointF zonePos = currentZone->scenePos();
|
||||||
QPointF cursorPosInZone = cursorScenePos - zonePos;
|
QPointF cursorPosInZone = cursorScenePos - zonePos;
|
||||||
QPointF cardTopLeft = cursorPosInZone - hotSpot;
|
|
||||||
QPointF closestGridPoint = cursorZone->closestGridPoint(cardTopLeft);
|
// 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 newPos = zonePos + closestGridPoint;
|
QPointF newPos = zonePos + closestGridPoint;
|
||||||
|
|
||||||
if (newPos != pos()) {
|
if (newPos != pos()) {
|
||||||
@@ -83,7 +95,7 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
|
|
||||||
QList<CardDragItem *> dragItemList;
|
QList<CardDragItem *> dragItemList;
|
||||||
CardZone *startZone = static_cast<CardItem *>(item)->getZone();
|
CardZone *startZone = static_cast<CardItem *>(item)->getZone();
|
||||||
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone))) {
|
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone)) && !occupied) {
|
||||||
dragItemList.append(this);
|
dragItemList.append(this);
|
||||||
for (int i = 0; i < childDrags.size(); i++) {
|
for (int i = 0; i < childDrags.size(); i++) {
|
||||||
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
|
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const QString CardFilter::attrName(Attr a)
|
|||||||
case AttrManaCost:
|
case AttrManaCost:
|
||||||
return tr("Mana Cost");
|
return tr("Mana Cost");
|
||||||
case AttrCmc:
|
case AttrCmc:
|
||||||
return tr("CMC");
|
return tr("Mana Value");
|
||||||
case AttrRarity:
|
case AttrRarity:
|
||||||
return tr("Rarity");
|
return tr("Rarity");
|
||||||
case AttrPow:
|
case AttrPow:
|
||||||
|
|||||||
@@ -4,8 +4,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "pictureloader.h"
|
#include "pictureloader.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QStylePainter>
|
||||||
#include <QStyle>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
CardInfoPicture::CardInfoPicture(QWidget *parent) : QWidget(parent), info(nullptr), pixmapDirty(true)
|
CardInfoPicture::CardInfoPicture(QWidget *parent) : QWidget(parent), info(nullptr), pixmapDirty(true)
|
||||||
@@ -55,6 +54,13 @@ void CardInfoPicture::paintEvent(QPaintEvent *)
|
|||||||
if (pixmapDirty)
|
if (pixmapDirty)
|
||||||
loadPixmap();
|
loadPixmap();
|
||||||
|
|
||||||
QPainter painter(this);
|
QSize scaledSize = resizedPixmap.size().scaled(size(), Qt::KeepAspectRatio);
|
||||||
style()->drawItemPixmap(&painter, rect(), Qt::AlignHCenter, resizedPixmap);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,9 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <utility>
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#else
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
#endif
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::WindowFlags flags)
|
CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::WindowFlags flags)
|
||||||
: QFrame(parent, flags), aspectRatio((qreal)CARD_HEIGHT / (qreal)CARD_WIDTH), info(nullptr)
|
: QFrame(parent, flags), aspectRatio((qreal)CARD_HEIGHT / (qreal)CARD_WIDTH), info(nullptr)
|
||||||
@@ -34,12 +30,7 @@ CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::Win
|
|||||||
|
|
||||||
setFrameStyle(QFrame::Panel | QFrame::Raised);
|
setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
int pixmapHeight = QGuiApplication::primaryScreen()->geometry().height() / 3;
|
||||||
int pixmapHeight = qApp->primaryScreen()->geometry().height() / 3;
|
|
||||||
#else
|
|
||||||
QDesktopWidget desktopWidget;
|
|
||||||
int pixmapHeight = desktopWidget.screenGeometry().height() / 3;
|
|
||||||
#endif
|
|
||||||
int pixmapWidth = static_cast<int>(pixmapHeight / aspectRatio);
|
int pixmapWidth = static_cast<int>(pixmapHeight / aspectRatio);
|
||||||
pic->setFixedWidth(pixmapWidth);
|
pic->setFixedWidth(pixmapWidth);
|
||||||
pic->setFixedHeight(pixmapHeight);
|
pic->setFixedHeight(pixmapHeight);
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ CardItem::CardItem(Player *_owner,
|
|||||||
int _cardid,
|
int _cardid,
|
||||||
bool _revealedCard,
|
bool _revealedCard,
|
||||||
QGraphicsItem *parent,
|
QGraphicsItem *parent,
|
||||||
CardZone *_zone,
|
CardZone *_zone)
|
||||||
bool updateMenu)
|
|
||||||
: AbstractCardItem(_name, _owner, _cardid, parent), zone(_zone), revealedCard(_revealedCard), attacking(false),
|
: AbstractCardItem(_name, _owner, _cardid, parent), zone(_zone), revealedCard(_revealedCard), attacking(false),
|
||||||
destroyOnZoneChange(false), doesntUntap(false), dragItem(nullptr), attachedTo(nullptr)
|
destroyOnZoneChange(false), doesntUntap(false), dragItem(nullptr), attachedTo(nullptr)
|
||||||
{
|
{
|
||||||
@@ -35,9 +34,6 @@ CardItem::CardItem(Player *_owner,
|
|||||||
moveMenu = new QMenu;
|
moveMenu = new QMenu;
|
||||||
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
if (updateMenu) { // avoid updating card menu too often
|
|
||||||
emit updateCardMenu(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CardItem::~CardItem()
|
CardItem::~CardItem()
|
||||||
@@ -84,7 +80,6 @@ void CardItem::deleteLater()
|
|||||||
void CardItem::setZone(CardZone *_zone)
|
void CardItem::setZone(CardZone *_zone)
|
||||||
{
|
{
|
||||||
zone = _zone;
|
zone = _zone;
|
||||||
emit updateCardMenu(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardItem::retranslateUi()
|
void CardItem::retranslateUi()
|
||||||
@@ -102,10 +97,10 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|||||||
QMapIterator<int, int> counterIterator(counters);
|
QMapIterator<int, int> counterIterator(counters);
|
||||||
while (counterIterator.hasNext()) {
|
while (counterIterator.hasNext()) {
|
||||||
counterIterator.next();
|
counterIterator.next();
|
||||||
QColor color;
|
QColor _color;
|
||||||
color.setHsv(counterIterator.key() * 60, 150, 255);
|
_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;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,21 +141,19 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (getBeingPointedAt()) {
|
if (getBeingPointedAt()) {
|
||||||
painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100)));
|
painter->fillPath(shape(), QBrush(QColor(255, 0, 0, 100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doesntUntap) {
|
if (doesntUntap) {
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||||
transformPainter(painter, translatedSize, tapAngle);
|
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setColor(Qt::magenta);
|
pen.setColor(Qt::magenta);
|
||||||
const int penWidth = 1;
|
pen.setWidth(0); // Cosmetic pen
|
||||||
pen.setWidth(penWidth);
|
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
painter->drawPath(shape());
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
@@ -203,23 +196,25 @@ void CardItem::setPT(const QString &_pt)
|
|||||||
|
|
||||||
void CardItem::setAttachedTo(CardItem *_attachedTo)
|
void CardItem::setAttachedTo(CardItem *_attachedTo)
|
||||||
{
|
{
|
||||||
if (attachedTo)
|
if (attachedTo != nullptr) {
|
||||||
attachedTo->removeAttachedCard(this);
|
attachedTo->removeAttachedCard(this);
|
||||||
|
}
|
||||||
|
|
||||||
gridPoint.setX(-1);
|
gridPoint.setX(-1);
|
||||||
attachedTo = _attachedTo;
|
attachedTo = _attachedTo;
|
||||||
if (attachedTo) {
|
if (attachedTo != nullptr) {
|
||||||
setParentItem(attachedTo->getZone());
|
setParentItem(attachedTo->getZone());
|
||||||
attachedTo->addAttachedCard(this);
|
attachedTo->addAttachedCard(this);
|
||||||
if (zone != attachedTo->getZone())
|
if (zone != attachedTo->getZone()) {
|
||||||
attachedTo->getZone()->reorganizeCards();
|
attachedTo->getZone()->reorganizeCards();
|
||||||
} else
|
}
|
||||||
|
} else {
|
||||||
setParentItem(zone);
|
setParentItem(zone);
|
||||||
|
}
|
||||||
|
|
||||||
if (zone)
|
if (zone != nullptr) {
|
||||||
zone->reorganizeCards();
|
zone->reorganizeCards();
|
||||||
|
}
|
||||||
emit updateCardMenu(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardItem::resetState()
|
void CardItem::resetState()
|
||||||
@@ -238,25 +233,25 @@ void CardItem::resetState()
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardItem::processCardInfo(const ServerInfo_Card &info)
|
void CardItem::processCardInfo(const ServerInfo_Card &_info)
|
||||||
{
|
{
|
||||||
counters.clear();
|
counters.clear();
|
||||||
const int counterListSize = info.counter_list_size();
|
const int counterListSize = _info.counter_list_size();
|
||||||
for (int i = 0; i < counterListSize; ++i) {
|
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());
|
counters.insert(counterInfo.id(), counterInfo.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
setId(info.id());
|
setId(_info.id());
|
||||||
setName(QString::fromStdString(info.name()));
|
setName(QString::fromStdString(_info.name()));
|
||||||
setAttacking(info.attacking());
|
setAttacking(_info.attacking());
|
||||||
setFaceDown(info.face_down());
|
setFaceDown(_info.face_down());
|
||||||
setPT(QString::fromStdString(info.pt()));
|
setPT(QString::fromStdString(_info.pt()));
|
||||||
setAnnotation(QString::fromStdString(info.annotation()));
|
setAnnotation(QString::fromStdString(_info.annotation()));
|
||||||
setColor(QString::fromStdString(info.color()));
|
setColor(QString::fromStdString(_info.color()));
|
||||||
setTapped(info.tapped());
|
setTapped(_info.tapped());
|
||||||
setDestroyOnZoneChange(info.destroy_on_zone_change());
|
setDestroyOnZoneChange(_info.destroy_on_zone_change());
|
||||||
setDoesntUntap(info.doesnt_untap());
|
setDoesntUntap(_info.doesnt_untap());
|
||||||
}
|
}
|
||||||
|
|
||||||
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown)
|
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown)
|
||||||
@@ -289,15 +284,36 @@ void CardItem::drawArrow(const QColor &arrowColor)
|
|||||||
scene()->addItem(arrow);
|
scene()->addItem(arrow);
|
||||||
arrow->grabMouse();
|
arrow->grabMouse();
|
||||||
|
|
||||||
QListIterator<QGraphicsItem *> itemIterator(scene()->selectedItems());
|
for (const auto &item : scene()->selectedItems()) {
|
||||||
while (itemIterator.hasNext()) {
|
CardItem *card = qgraphicsitem_cast<CardItem *>(item);
|
||||||
CardItem *c = qgraphicsitem_cast<CardItem *>(itemIterator.next());
|
if (card == nullptr || card == this)
|
||||||
if (!c || (c == this))
|
|
||||||
continue;
|
continue;
|
||||||
if (c->getZone() != zone)
|
if (card->getZone() != zone)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor);
|
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);
|
||||||
scene()->addItem(childArrow);
|
scene()->addItem(childArrow);
|
||||||
arrow->addChildArrow(childArrow);
|
arrow->addChildArrow(childArrow);
|
||||||
}
|
}
|
||||||
@@ -332,22 +348,24 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
|
|
||||||
bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier);
|
bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier);
|
||||||
|
|
||||||
createDragItem(id, event->pos(), event->scenePos(), facedown || forceFaceDown);
|
// 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);
|
||||||
dragItem->grabMouse();
|
dragItem->grabMouse();
|
||||||
|
|
||||||
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
int childIndex = 0;
|
||||||
int j = 0;
|
for (const auto &item : scene()->selectedItems()) {
|
||||||
for (int i = 0; i < sel.size(); i++) {
|
CardItem *card = static_cast<CardItem *>(item);
|
||||||
CardItem *c = static_cast<CardItem *>(sel.at(i));
|
if ((card == this) || (card->getZone() != zone))
|
||||||
if ((c == this) || (c->getZone() != zone))
|
|
||||||
continue;
|
continue;
|
||||||
++j;
|
++childIndex;
|
||||||
QPointF childPos;
|
QPointF childPos;
|
||||||
if (zone->getHasCardAttr())
|
if (zone->getHasCardAttr())
|
||||||
childPos = c->pos() - pos();
|
childPos = card->pos() - pos();
|
||||||
else
|
else
|
||||||
childPos = QPointF(j * CARD_WIDTH / 2, 0);
|
childPos = QPointF(childIndex * CARD_WIDTH / 2, 0);
|
||||||
CardDragItem *drag = new CardDragItem(c, c->getId(), childPos, c->getFaceDown() || forceFaceDown, dragItem);
|
CardDragItem *drag =
|
||||||
|
new CardDragItem(card, card->getId(), childPos, card->getFaceDown() || forceFaceDown, dragItem);
|
||||||
drag->setPos(dragItem->pos() + childPos);
|
drag->setPos(dragItem->pos() + childPos);
|
||||||
scene()->addItem(drag);
|
scene()->addItem(drag);
|
||||||
}
|
}
|
||||||
@@ -371,9 +389,9 @@ void CardItem::playCard(bool faceDown)
|
|||||||
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (event->button() == Qt::RightButton) {
|
if (event->button() == Qt::RightButton) {
|
||||||
if (cardMenu && !cardMenu->isEmpty() && owner != nullptr) {
|
if (cardMenu != nullptr && !cardMenu->isEmpty() && owner != nullptr) {
|
||||||
owner->updateCardMenu(this);
|
cardMenu->popup(event->screenPos());
|
||||||
cardMenu->exec(event->screenPos());
|
return;
|
||||||
}
|
}
|
||||||
} else if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) &&
|
} else if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) &&
|
||||||
(!SettingsCache::instance().getDoubleClickToPlay())) {
|
(!SettingsCache::instance().getDoubleClickToPlay())) {
|
||||||
@@ -437,13 +455,13 @@ bool CardItem::animationEvent()
|
|||||||
|
|
||||||
QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
QVariant CardItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||||
{
|
{
|
||||||
if ((change == ItemSelectedHasChanged) && owner) {
|
if ((change == ItemSelectedHasChanged) && owner != nullptr) {
|
||||||
if (value == true) {
|
if (value == true) {
|
||||||
owner->setCardMenu(cardMenu);
|
owner->setCardMenu(cardMenu);
|
||||||
owner->getGame()->setActiveCard(this);
|
owner->getGame()->setActiveCard(this);
|
||||||
} else if (owner->getCardMenu() == cardMenu) {
|
} else if (owner->getCardMenu() == cardMenu) {
|
||||||
owner->setCardMenu(0);
|
owner->setCardMenu(nullptr);
|
||||||
owner->getGame()->setActiveCard(0);
|
owner->getGame()->setActiveCard(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QGraphicsItem::itemChange(change, value);
|
return QGraphicsItem::itemChange(change, value);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define CARDITEM_H
|
#define CARDITEM_H
|
||||||
|
|
||||||
#include "abstractcarditem.h"
|
#include "abstractcarditem.h"
|
||||||
|
#include "server_card.h"
|
||||||
|
|
||||||
class CardDatabase;
|
class CardDatabase;
|
||||||
class CardDragItem;
|
class CardDragItem;
|
||||||
@@ -53,8 +54,7 @@ public:
|
|||||||
int _cardid = -1,
|
int _cardid = -1,
|
||||||
bool revealedCard = false,
|
bool revealedCard = false,
|
||||||
QGraphicsItem *parent = nullptr,
|
QGraphicsItem *parent = nullptr,
|
||||||
CardZone *_zone = nullptr,
|
CardZone *_zone = nullptr);
|
||||||
bool updateMenu = false);
|
|
||||||
~CardItem();
|
~CardItem();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
CardZone *getZone() const
|
CardZone *getZone() const
|
||||||
@@ -131,14 +131,14 @@ public:
|
|||||||
}
|
}
|
||||||
void removeAttachedCard(CardItem *card)
|
void removeAttachedCard(CardItem *card)
|
||||||
{
|
{
|
||||||
attachedCards.removeAt(attachedCards.indexOf(card));
|
attachedCards.removeOne(card);
|
||||||
}
|
}
|
||||||
const QList<CardItem *> &getAttachedCards() const
|
const QList<CardItem *> &getAttachedCards() const
|
||||||
{
|
{
|
||||||
return attachedCards;
|
return attachedCards;
|
||||||
}
|
}
|
||||||
void resetState();
|
void resetState();
|
||||||
void processCardInfo(const ServerInfo_Card &info);
|
void processCardInfo(const ServerInfo_Card &_info);
|
||||||
|
|
||||||
QMenu *getCardMenu() const
|
QMenu *getCardMenu() const
|
||||||
{
|
{
|
||||||
@@ -157,6 +157,7 @@ public:
|
|||||||
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown);
|
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown);
|
||||||
void deleteDragItem();
|
void deleteDragItem();
|
||||||
void drawArrow(const QColor &arrowColor);
|
void drawArrow(const QColor &arrowColor);
|
||||||
|
void drawAttachArrow();
|
||||||
void playCard(bool faceDown);
|
void playCard(bool faceDown);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ CardItem *CardZone::takeCard(int position, int cardId, bool /*canResize*/)
|
|||||||
|
|
||||||
void CardZone::removeCard(CardItem *card)
|
void CardZone::removeCard(CardItem *card)
|
||||||
{
|
{
|
||||||
cards.removeAt(cards.indexOf(card));
|
cards.removeOne(card);
|
||||||
reorganizeCards();
|
reorganizeCards();
|
||||||
emit cardCountChanged();
|
emit cardCountChanged();
|
||||||
player->deleteCard(card);
|
player->deleteCard(card);
|
||||||
|
|||||||
@@ -12,11 +12,16 @@
|
|||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QTextEdit>
|
|
||||||
|
|
||||||
const QColor DEFAULT_MENTION_COLOR = QColor(194, 31, 47);
|
const QColor DEFAULT_MENTION_COLOR = QColor(194, 31, 47);
|
||||||
|
|
||||||
ChatView::ChatView(const TabSupervisor *_tabSupervisor,
|
UserMessagePosition::UserMessagePosition(QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
block = cursor.block();
|
||||||
|
relativePosition = cursor.position() - block.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatView::ChatView(TabSupervisor *_tabSupervisor,
|
||||||
const UserlistProxy *_userlistProxy,
|
const UserlistProxy *_userlistProxy,
|
||||||
TabGame *_game,
|
TabGame *_game,
|
||||||
bool _showTimestamps,
|
bool _showTimestamps,
|
||||||
@@ -43,8 +48,8 @@ ChatView::ChatView(const TabSupervisor *_tabSupervisor,
|
|||||||
userContextMenu = new UserContextMenu(tabSupervisor, this, game);
|
userContextMenu = new UserContextMenu(tabSupervisor, this, game);
|
||||||
connect(userContextMenu, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
connect(userContextMenu, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||||
|
|
||||||
userName = userlistProxy->getOwnUsername();
|
ownUserName = userlistProxy->getOwnUsername();
|
||||||
mention = "@" + userName;
|
mention = "@" + ownUserName;
|
||||||
|
|
||||||
mentionFormat.setFontWeight(QFont::Bold);
|
mentionFormat.setFontWeight(QFont::Bold);
|
||||||
|
|
||||||
@@ -68,7 +73,7 @@ QTextCursor ChatView::prepareBlock(bool same)
|
|||||||
{
|
{
|
||||||
lastSender.clear();
|
lastSender.clear();
|
||||||
|
|
||||||
QTextCursor cursor(document()->lastBlock());
|
QTextCursor cursor(document());
|
||||||
cursor.movePosition(QTextCursor::End);
|
cursor.movePosition(QTextCursor::End);
|
||||||
if (same) {
|
if (same) {
|
||||||
cursor.insertHtml("<br>");
|
cursor.insertHtml("<br>");
|
||||||
@@ -145,76 +150,86 @@ void ChatView::appendUrlTag(QTextCursor &cursor, QString url)
|
|||||||
|
|
||||||
void ChatView::appendMessage(QString message,
|
void ChatView::appendMessage(QString message,
|
||||||
RoomMessageTypeFlags messageType,
|
RoomMessageTypeFlags messageType,
|
||||||
QString sender,
|
const QString &userName,
|
||||||
UserLevelFlags userLevel,
|
UserLevelFlags userLevel,
|
||||||
QString UserPrivLevel,
|
QString UserPrivLevel,
|
||||||
bool playerBold)
|
bool playerBold)
|
||||||
{
|
{
|
||||||
bool atBottom = verticalScrollBar()->value() >= verticalScrollBar()->maximum();
|
bool atBottom = verticalScrollBar()->value() >= verticalScrollBar()->maximum();
|
||||||
bool sameSender = (sender == lastSender) && !lastSender.isEmpty();
|
// messageType should be Event_RoomSay::UserMessage though we don't actually check
|
||||||
|
bool isUserMessage = !(userName.toLower() == "servatrice" || userName.isEmpty());
|
||||||
|
bool sameSender = isUserMessage && userName == lastSender;
|
||||||
QTextCursor cursor = prepareBlock(sameSender);
|
QTextCursor cursor = prepareBlock(sameSender);
|
||||||
lastSender = sender;
|
lastSender = userName;
|
||||||
|
|
||||||
// timestamp
|
// timestamp
|
||||||
if (showTimestamps && (!sameSender || sender.toLower() == "servatrice") && !sender.isEmpty()) {
|
if (showTimestamps && ((!sameSender && isUserMessage) || userName.toLower() == "servatrice")) {
|
||||||
QTextCharFormat timeFormat;
|
QTextCharFormat timeFormat;
|
||||||
timeFormat.setForeground(serverMessageColor);
|
timeFormat.setForeground(serverMessageColor);
|
||||||
if (sender.isEmpty())
|
timeFormat.setFontWeight(QFont::Bold);
|
||||||
timeFormat.setFontWeight(QFont::Bold);
|
|
||||||
cursor.setCharFormat(timeFormat);
|
cursor.setCharFormat(timeFormat);
|
||||||
cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm:ss] "));
|
cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm:ss] "));
|
||||||
}
|
}
|
||||||
|
|
||||||
// nickname
|
// nickname
|
||||||
if (sender.toLower() != "servatrice") {
|
if (isUserMessage) {
|
||||||
QTextCharFormat senderFormat;
|
QTextCharFormat senderFormat;
|
||||||
if (sender == userName) {
|
if (userName == ownUserName) {
|
||||||
senderFormat.setForeground(QBrush(getCustomMentionColor()));
|
senderFormat.setForeground(QBrush(getCustomMentionColor()));
|
||||||
senderFormat.setFontWeight(QFont::Bold);
|
senderFormat.setFontWeight(QFont::Bold);
|
||||||
} else {
|
} else {
|
||||||
senderFormat.setForeground(QBrush(otherUserColor));
|
senderFormat.setForeground(QBrush(otherUserColor));
|
||||||
if (playerBold)
|
if (playerBold) {
|
||||||
senderFormat.setFontWeight(QFont::Bold);
|
senderFormat.setFontWeight(QFont::Bold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
senderFormat.setAnchor(true);
|
senderFormat.setAnchor(true);
|
||||||
senderFormat.setAnchorHref("user://" + QString::number(userLevel) + "_" + sender);
|
senderFormat.setAnchorHref("user://" + QString::number(userLevel) + "_" + userName);
|
||||||
if (sameSender) {
|
if (sameSender) {
|
||||||
cursor.insertText(" ");
|
cursor.insertText(" ");
|
||||||
} else {
|
} else {
|
||||||
if (!sender.isEmpty()) {
|
const int pixelSize = QFontInfo(cursor.charFormat().font()).pixelSize();
|
||||||
const int pixelSize = QFontInfo(cursor.charFormat().font()).pixelSize();
|
bool isBuddy = userlistProxy->isUserBuddy(userName);
|
||||||
bool isBuddy = userlistProxy->isUserBuddy(sender);
|
cursor.insertImage(
|
||||||
cursor.insertImage(
|
UserLevelPixmapGenerator::generatePixmap(pixelSize, userLevel, isBuddy, UserPrivLevel).toImage());
|
||||||
UserLevelPixmapGenerator::generatePixmap(pixelSize, userLevel, isBuddy, UserPrivLevel).toImage());
|
cursor.insertText(" ");
|
||||||
cursor.insertText(" ");
|
|
||||||
}
|
|
||||||
cursor.setCharFormat(senderFormat);
|
cursor.setCharFormat(senderFormat);
|
||||||
if (!sender.isEmpty())
|
cursor.insertText(userName);
|
||||||
sender.append(": ");
|
cursor.insertText(": ");
|
||||||
cursor.insertText(sender);
|
userMessagePositions[userName].append(cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// use different color for server messages
|
// use different color for server messages
|
||||||
defaultFormat = QTextCharFormat();
|
defaultFormat = QTextCharFormat();
|
||||||
if (sender.isEmpty()) {
|
if (!isUserMessage) {
|
||||||
switch (messageType) {
|
if (messageType == Event_RoomSay::ChatHistory) {
|
||||||
case Event_RoomSay::Welcome:
|
defaultFormat.setForeground(Qt::gray); // FIXME : hardcoded color
|
||||||
defaultFormat.setForeground(Qt::darkGreen);
|
defaultFormat.setFontWeight(QFont::Light);
|
||||||
defaultFormat.setFontWeight(QFont::Bold);
|
defaultFormat.setFontItalic(true);
|
||||||
break;
|
static const QRegularExpression userNameRegex("^(\\[[^\\]]*\\]\\s)(\\S+):\\s");
|
||||||
case Event_RoomSay::ChatHistory:
|
auto match = userNameRegex.match(message);
|
||||||
defaultFormat.setForeground(Qt::gray);
|
if (match.hasMatch()) {
|
||||||
defaultFormat.setFontWeight(QFont::Light);
|
cursor.setCharFormat(defaultFormat);
|
||||||
defaultFormat.setFontItalic(true);
|
UserMessagePosition pos(cursor);
|
||||||
break;
|
pos.relativePosition = match.captured(0).length(); // set message start
|
||||||
default:
|
auto before = match.captured(1);
|
||||||
defaultFormat.setForeground(Qt::darkGreen);
|
auto sentBy = match.captured(2);
|
||||||
defaultFormat.setFontWeight(QFont::Bold);
|
cursor.insertText(before); // add message timestamp
|
||||||
|
QTextCharFormat senderFormat(defaultFormat);
|
||||||
|
senderFormat.setAnchor(true);
|
||||||
|
// this underscore is important, it is used to add the user level, but in this case the level is
|
||||||
|
// unknown, if the name contains an underscore it would split up the name
|
||||||
|
senderFormat.setAnchorHref("user://_" + sentBy);
|
||||||
|
cursor.setCharFormat(senderFormat);
|
||||||
|
cursor.insertText(sentBy); // add username with href so it shows the menu
|
||||||
|
userMessagePositions[sentBy].append(pos); // save message position
|
||||||
|
message.remove(0, pos.relativePosition - 2); // do not remove semicolon
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
defaultFormat.setForeground(Qt::darkGreen); // FIXME : hardcoded color
|
||||||
|
defaultFormat.setFontWeight(QFont::Bold);
|
||||||
}
|
}
|
||||||
} else if (sender.toLower() == "servatrice") {
|
|
||||||
defaultFormat.setForeground(Qt::darkGreen);
|
|
||||||
defaultFormat.setFontWeight(QFont::Bold);
|
|
||||||
}
|
}
|
||||||
cursor.setCharFormat(defaultFormat);
|
cursor.setCharFormat(defaultFormat);
|
||||||
|
|
||||||
@@ -234,7 +249,7 @@ void ChatView::appendMessage(QString message,
|
|||||||
break;
|
break;
|
||||||
case '@':
|
case '@':
|
||||||
if (mentionEnabled) {
|
if (mentionEnabled) {
|
||||||
checkMention(cursor, message, sender, userLevel);
|
checkMention(cursor, message, userName, userLevel);
|
||||||
} else {
|
} else {
|
||||||
cursor.insertText(c, defaultFormat);
|
cursor.insertText(c, defaultFormat);
|
||||||
message = message.mid(1);
|
message = message.mid(1);
|
||||||
@@ -304,9 +319,9 @@ void ChatView::checkTag(QTextCursor &cursor, QString &message)
|
|||||||
checkWord(cursor, message);
|
checkWord(cursor, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatView::checkMention(QTextCursor &cursor, QString &message, QString &sender, UserLevelFlags userLevel)
|
void ChatView::checkMention(QTextCursor &cursor, QString &message, const QString &userName, UserLevelFlags userLevel)
|
||||||
{
|
{
|
||||||
const QRegExp notALetterOrNumber = QRegExp("[^a-zA-Z0-9]");
|
const static auto notALetterOrNumber = QRegularExpression("[^a-zA-Z0-9]");
|
||||||
|
|
||||||
int firstSpace = message.indexOf(' ');
|
int firstSpace = message.indexOf(' ');
|
||||||
QString fullMentionUpToSpaceOrEnd = (firstSpace == -1) ? message.mid(1) : message.mid(1, firstSpace - 1);
|
QString fullMentionUpToSpaceOrEnd = (firstSpace == -1) ? message.mid(1) : message.mid(1, firstSpace - 1);
|
||||||
@@ -316,7 +331,7 @@ void ChatView::checkMention(QTextCursor &cursor, QString &message, QString &send
|
|||||||
const ServerInfo_User *onlineUser = userlistProxy->getOnlineUser(fullMentionUpToSpaceOrEnd);
|
const ServerInfo_User *onlineUser = userlistProxy->getOnlineUser(fullMentionUpToSpaceOrEnd);
|
||||||
if (onlineUser) // Is there a user online named this?
|
if (onlineUser) // Is there a user online named this?
|
||||||
{
|
{
|
||||||
if (userName.toLower() == fullMentionUpToSpaceOrEnd.toLower()) // Is this user you?
|
if (ownUserName.toLower() == fullMentionUpToSpaceOrEnd.toLower()) // Is this user you?
|
||||||
{
|
{
|
||||||
// You have received a valid mention!!
|
// You have received a valid mention!!
|
||||||
soundEngine->playSound("chat_mention");
|
soundEngine->playSound("chat_mention");
|
||||||
@@ -325,7 +340,7 @@ void ChatView::checkMention(QTextCursor &cursor, QString &message, QString &send
|
|||||||
: QBrush(Qt::black));
|
: QBrush(Qt::black));
|
||||||
cursor.insertText(mention, mentionFormat);
|
cursor.insertText(mention, mentionFormat);
|
||||||
message = message.mid(mention.size());
|
message = message.mid(mention.size());
|
||||||
showSystemPopup(sender);
|
showSystemPopup(userName);
|
||||||
} else {
|
} else {
|
||||||
QString correctUserName = QString::fromStdString(onlineUser->name());
|
QString correctUserName = QString::fromStdString(onlineUser->name());
|
||||||
mentionFormatOtherUser.setAnchorHref("user://" + QString::number(onlineUser->user_level()) + "_" +
|
mentionFormatOtherUser.setAnchorHref("user://" + QString::number(onlineUser->user_level()) + "_" +
|
||||||
@@ -347,7 +362,7 @@ void ChatView::checkMention(QTextCursor &cursor, QString &message, QString &send
|
|||||||
: QBrush(Qt::black));
|
: QBrush(Qt::black));
|
||||||
cursor.insertText("@" + fullMentionUpToSpaceOrEnd, mentionFormat);
|
cursor.insertText("@" + fullMentionUpToSpaceOrEnd, mentionFormat);
|
||||||
message = message.mid(fullMentionUpToSpaceOrEnd.size() + 1);
|
message = message.mid(fullMentionUpToSpaceOrEnd.size() + 1);
|
||||||
showSystemPopup(sender);
|
showSystemPopup(userName);
|
||||||
|
|
||||||
cursor.setCharFormat(defaultFormat);
|
cursor.setCharFormat(defaultFormat);
|
||||||
return;
|
return;
|
||||||
@@ -445,26 +460,33 @@ void ChatView::actMessageClicked()
|
|||||||
emit messageClickedSignal();
|
emit messageClickedSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatView::showSystemPopup(QString &sender)
|
void ChatView::showSystemPopup(const QString &userName)
|
||||||
{
|
{
|
||||||
QApplication::alert(this);
|
QApplication::alert(this);
|
||||||
if (SettingsCache::instance().getShowMentionPopup()) {
|
if (SettingsCache::instance().getShowMentionPopup()) {
|
||||||
QString ref = sender.left(sender.length() - 2);
|
emit showMentionPopup(userName);
|
||||||
emit showMentionPopup(ref);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor ChatView::getCustomMentionColor()
|
QColor ChatView::getCustomMentionColor()
|
||||||
{
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||||
|
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||||
|
#else
|
||||||
QColor customColor;
|
QColor customColor;
|
||||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatMentionColor());
|
customColor.setNamedColor("#" + SettingsCache::instance().getChatMentionColor());
|
||||||
|
#endif
|
||||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor ChatView::getCustomHighlightColor()
|
QColor ChatView::getCustomHighlightColor()
|
||||||
{
|
{
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||||
|
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||||
|
#else
|
||||||
QColor customColor;
|
QColor customColor;
|
||||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatHighlightColor());
|
customColor.setNamedColor("#" + SettingsCache::instance().getChatMentionColor());
|
||||||
|
#endif
|
||||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +496,33 @@ void ChatView::clearChat()
|
|||||||
lastSender = "";
|
lastSender = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatView::redactMessages(const QString &userName, int amount)
|
||||||
|
{
|
||||||
|
auto &messagePositions = userMessagePositions[userName];
|
||||||
|
bool removedLastMessage = false;
|
||||||
|
QTextCursor cursor(document());
|
||||||
|
for (; !messagePositions.isEmpty() && amount != 0; --amount) {
|
||||||
|
auto position = messagePositions.takeLast(); // go backwards from last message
|
||||||
|
cursor.setPosition(position.block.position()); // move to start of block, then continue to start of message
|
||||||
|
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, position.relativePosition);
|
||||||
|
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); // select until end of block
|
||||||
|
cursor.removeSelectedText();
|
||||||
|
// if the cursor is at the end of the text it is possible to add text to this block still
|
||||||
|
removedLastMessage |= cursor.atEnd();
|
||||||
|
// we will readd this position later
|
||||||
|
}
|
||||||
|
if (removedLastMessage) {
|
||||||
|
cursor.movePosition(QTextCursor::End);
|
||||||
|
messagePositions.append(cursor);
|
||||||
|
// note that this message might stay empty, this is not harmful as it will simply remove nothing the next time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
|
void ChatView::enterEvent(QEnterEvent * /*event*/)
|
||||||
|
#else
|
||||||
void ChatView::enterEvent(QEvent * /*event*/)
|
void ChatView::enterEvent(QEvent * /*event*/)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
@@ -530,7 +578,11 @@ void ChatView::mousePressEvent(QMouseEvent *event)
|
|||||||
switch (hoveredItemType) {
|
switch (hoveredItemType) {
|
||||||
case HoveredCard: {
|
case HoveredCard: {
|
||||||
if ((event->button() == Qt::MiddleButton) || (event->button() == Qt::LeftButton))
|
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);
|
emit showCardInfoPopup(event->globalPos(), hoveredContent);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HoveredUser: {
|
case HoveredUser: {
|
||||||
@@ -540,7 +592,11 @@ void ChatView::mousePressEvent(QMouseEvent *event)
|
|||||||
switch (event->button()) {
|
switch (event->button()) {
|
||||||
case Qt::RightButton: {
|
case Qt::RightButton: {
|
||||||
UserLevelFlags userLevel(hoveredContent.left(delimiterIndex).toInt());
|
UserLevelFlags userLevel(hoveredContent.left(delimiterIndex).toInt());
|
||||||
userContextMenu->showContextMenu(event->globalPos(), userName, userLevel);
|
#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;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::LeftButton: {
|
case Qt::LeftButton: {
|
||||||
|
|||||||
@@ -18,11 +18,22 @@ class QMouseEvent;
|
|||||||
class UserContextMenu;
|
class UserContextMenu;
|
||||||
class TabGame;
|
class TabGame;
|
||||||
|
|
||||||
|
class UserMessagePosition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
|
||||||
|
UserMessagePosition() = default; // older qt versions require a default constructor to use in containers
|
||||||
|
#endif
|
||||||
|
UserMessagePosition(QTextCursor &cursor);
|
||||||
|
int relativePosition;
|
||||||
|
QTextBlock block;
|
||||||
|
};
|
||||||
|
|
||||||
class ChatView : public QTextBrowser
|
class ChatView : public QTextBrowser
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
protected:
|
protected:
|
||||||
const TabSupervisor *const tabSupervisor;
|
TabSupervisor *const tabSupervisor;
|
||||||
TabGame *const game;
|
TabGame *const game;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -36,7 +47,7 @@ private:
|
|||||||
const UserlistProxy *const userlistProxy;
|
const UserlistProxy *const userlistProxy;
|
||||||
UserContextMenu *userContextMenu;
|
UserContextMenu *userContextMenu;
|
||||||
QString lastSender;
|
QString lastSender;
|
||||||
QString userName;
|
QString ownUserName;
|
||||||
QString mention;
|
QString mention;
|
||||||
QTextCharFormat mentionFormat;
|
QTextCharFormat mentionFormat;
|
||||||
QTextCharFormat highlightFormat;
|
QTextCharFormat highlightFormat;
|
||||||
@@ -48,16 +59,18 @@ private:
|
|||||||
HoveredItemType hoveredItemType;
|
HoveredItemType hoveredItemType;
|
||||||
QString hoveredContent;
|
QString hoveredContent;
|
||||||
QAction *messageClicked;
|
QAction *messageClicked;
|
||||||
|
QMap<QString, QVector<UserMessagePosition>> userMessagePositions;
|
||||||
|
|
||||||
QTextFragment getFragmentUnderMouse(const QPoint &pos) const;
|
QTextFragment getFragmentUnderMouse(const QPoint &pos) const;
|
||||||
QTextCursor prepareBlock(bool same = false);
|
QTextCursor prepareBlock(bool same = false);
|
||||||
void appendCardTag(QTextCursor &cursor, const QString &cardName);
|
void appendCardTag(QTextCursor &cursor, const QString &cardName);
|
||||||
void appendUrlTag(QTextCursor &cursor, QString url);
|
void appendUrlTag(QTextCursor &cursor, QString url);
|
||||||
QColor getCustomMentionColor();
|
static QColor getCustomMentionColor();
|
||||||
QColor getCustomHighlightColor();
|
static QColor getCustomHighlightColor();
|
||||||
void showSystemPopup(QString &sender);
|
void showSystemPopup(const QString &userName);
|
||||||
bool isModeratorSendingGlobal(QFlags<ServerInfo_User::UserLevelFlag> userLevelFlag, QString message);
|
bool isModeratorSendingGlobal(QFlags<ServerInfo_User::UserLevelFlag> userLevelFlag, QString message);
|
||||||
void checkTag(QTextCursor &cursor, QString &message);
|
void checkTag(QTextCursor &cursor, QString &message);
|
||||||
void checkMention(QTextCursor &cursor, QString &message, QString &sender, UserLevelFlags userLevel);
|
void checkMention(QTextCursor &cursor, QString &message, const QString &userName, UserLevelFlags userLevel);
|
||||||
void checkWord(QTextCursor &cursor, QString &message);
|
void checkWord(QTextCursor &cursor, QString &message);
|
||||||
QString extractNextWord(QString &message, QString &rest);
|
QString extractNextWord(QString &message, QString &rest);
|
||||||
|
|
||||||
@@ -70,7 +83,7 @@ private slots:
|
|||||||
void actMessageClicked();
|
void actMessageClicked();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChatView(const TabSupervisor *_tabSupervisor,
|
ChatView(TabSupervisor *_tabSupervisor,
|
||||||
const UserlistProxy *_userlistProxy,
|
const UserlistProxy *_userlistProxy,
|
||||||
TabGame *_game,
|
TabGame *_game,
|
||||||
bool _showTimestamps,
|
bool _showTimestamps,
|
||||||
@@ -82,14 +95,19 @@ public:
|
|||||||
QString optionalFontColor = QString());
|
QString optionalFontColor = QString());
|
||||||
void appendMessage(QString message,
|
void appendMessage(QString message,
|
||||||
RoomMessageTypeFlags messageType = {},
|
RoomMessageTypeFlags messageType = {},
|
||||||
QString sender = QString(),
|
const QString &userName = QString(),
|
||||||
UserLevelFlags userLevel = UserLevelFlags(),
|
UserLevelFlags userLevel = UserLevelFlags(),
|
||||||
QString UserPrivLevel = "NONE",
|
QString UserPrivLevel = "NONE",
|
||||||
bool playerBold = false);
|
bool playerBold = false);
|
||||||
void clearChat();
|
void clearChat();
|
||||||
|
void redactMessages(const QString &userName, int amount);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
|
void enterEvent(QEnterEvent *event);
|
||||||
|
#else
|
||||||
void enterEvent(QEvent *event);
|
void enterEvent(QEvent *event);
|
||||||
|
#endif
|
||||||
void leaveEvent(QEvent *event);
|
void leaveEvent(QEvent *event);
|
||||||
void mouseMoveEvent(QMouseEvent *event);
|
void mouseMoveEvent(QMouseEvent *event);
|
||||||
void mousePressEvent(QMouseEvent *event);
|
void mousePressEvent(QMouseEvent *event);
|
||||||
@@ -101,7 +119,7 @@ signals:
|
|||||||
void deleteCardInfoPopup(QString cardName);
|
void deleteCardInfoPopup(QString cardName);
|
||||||
void addMentionTag(QString mentionTag);
|
void addMentionTag(QString mentionTag);
|
||||||
void messageClickedSignal();
|
void messageClickedSignal();
|
||||||
void showMentionPopup(QString &sender);
|
void showMentionPopup(const QString &userName);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
#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
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#include "customlineedit.h"
|
#include "customlineedit.h"
|
||||||
|
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
@@ -38,8 +37,8 @@ bool LineEditUnfocusable::isUnfocusShortcut(QKeyEvent *event)
|
|||||||
QKeySequence key(modifier + keyNoMod);
|
QKeySequence key(modifier + keyNoMod);
|
||||||
QList<QKeySequence> unfocusShortcut = SettingsCache::instance().shortcuts().getShortcut("Textbox/unfocusTextBox");
|
QList<QKeySequence> unfocusShortcut = SettingsCache::instance().shortcuts().getShortcut("Textbox/unfocusTextBox");
|
||||||
|
|
||||||
for (QList<QKeySequence>::iterator i = unfocusShortcut.begin(); i != unfocusShortcut.end(); ++i) {
|
for (const auto &unfocusKey : unfocusShortcut) {
|
||||||
if (key.matches(*i) == QKeySequence::ExactMatch)
|
if (key.matches(unfocusKey) == QKeySequence::ExactMatch)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ class QString;
|
|||||||
// shortcuts and other shortcuts
|
// shortcuts and other shortcuts
|
||||||
class LineEditUnfocusable : public QLineEdit
|
class LineEditUnfocusable : public QLineEdit
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
LineEditUnfocusable(QWidget *parent = nullptr);
|
explicit LineEditUnfocusable(QWidget *parent = nullptr);
|
||||||
LineEditUnfocusable(const QString &contents, QWidget *parent = nullptr);
|
explicit LineEditUnfocusable(const QString &contents, QWidget *parent = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isUnfocusShortcut(QKeyEvent *key);
|
static bool isUnfocusShortcut(QKeyEvent *key);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QRegularExpression>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
const QStringList DeckLoader::fileNameFilters = QStringList()
|
const QStringList DeckLoader::fileNameFilters = QStringList()
|
||||||
@@ -208,7 +209,7 @@ void DeckLoader::saveToStream_DeckHeader(QTextStream &out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!getComments().isEmpty()) {
|
if (!getComments().isEmpty()) {
|
||||||
QStringList commentRows = getComments().split(QRegExp("\n|\r\n|\r"));
|
QStringList commentRows = getComments().split(QRegularExpression("\n|\r\n|\r"));
|
||||||
foreach (QString row, commentRows) {
|
foreach (QString row, commentRows) {
|
||||||
out << "// " << row << "\n";
|
out << "// " << row << "\n";
|
||||||
}
|
}
|
||||||
@@ -288,7 +289,7 @@ QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneNam
|
|||||||
return currentZoneName;
|
return currentZoneName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DeckLoader::getCompleteCardName(const QString cardName) const
|
QString DeckLoader::getCompleteCardName(const QString &cardName) const
|
||||||
{
|
{
|
||||||
if (db) {
|
if (db) {
|
||||||
CardInfoPtr temp = db->guessCard(cardName);
|
CardInfoPtr temp = db->guessCard(cardName);
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ protected:
|
|||||||
const InnerDecklistNode *zoneNode,
|
const InnerDecklistNode *zoneNode,
|
||||||
QList<DecklistCardNode *> cards,
|
QList<DecklistCardNode *> cards,
|
||||||
bool addComments = true);
|
bool addComments = true);
|
||||||
virtual QString getCardZoneFromName(QString cardName, QString currentZoneName);
|
[[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override;
|
||||||
virtual QString getCompleteCardName(const QString cardName) const;
|
[[nodiscard]] QString getCompleteCardName(const QString &cardName) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QRegExp>
|
#include <QRegularExpression>
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
|
|
||||||
DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent)
|
DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent)
|
||||||
@@ -20,7 +20,7 @@ DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *par
|
|||||||
void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
||||||
{
|
{
|
||||||
if (reply->error() != QNetworkReply::NoError) {
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
QMessageBox::critical(0, tr("Error"), reply->errorString());
|
QMessageBox::critical(nullptr, tr("Error"), reply->errorString());
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
@@ -29,14 +29,15 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
|||||||
QString data(reply->readAll());
|
QString data(reply->readAll());
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
||||||
QRegExp rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
|
static const QRegularExpression rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
|
||||||
if (-1 == rx.indexIn(data)) {
|
auto match = rx.match(data);
|
||||||
QMessageBox::critical(0, tr("Error"), tr("The reply from the server could not be parsed."));
|
if (!match.hasMatch()) {
|
||||||
|
QMessageBox::critical(nullptr, tr("Error"), tr("The reply from the server could not be parsed."));
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString deckUrl = rx.cap(1);
|
QString deckUrl = match.captured(1);
|
||||||
QDesktopServices::openUrl(deckUrl);
|
QDesktopServices::openUrl(deckUrl);
|
||||||
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QtMath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item,
|
DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item,
|
||||||
const QPointF &_hotSpot,
|
const QPointF &_hotSpot,
|
||||||
@@ -89,7 +89,8 @@ void DeckViewCard::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
|||||||
pen.setJoinStyle(Qt::MiterJoin);
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 2.5));
|
qreal cardRadius = 0.05 * (CARD_WIDTH - 3);
|
||||||
|
painter->drawRoundedRect(QRectF(1.5, 1.5, CARD_WIDTH - 3., CARD_HEIGHT - 3.), cardRadius, cardRadius);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +217,7 @@ void DeckViewCardContainer::addCard(DeckViewCard *card)
|
|||||||
|
|
||||||
void DeckViewCardContainer::removeCard(DeckViewCard *card)
|
void DeckViewCardContainer::removeCard(DeckViewCard *card)
|
||||||
{
|
{
|
||||||
cards.removeAt(cards.indexOf(card));
|
cards.removeOne(card);
|
||||||
cardsByType.remove(card->getInfo() ? card->getInfo()->getMainCardType() : "", card);
|
cardsByType.remove(card->getInfo() ? card->getInfo()->getMainCardType() : "", card);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,11 +239,9 @@ int DeckViewCardContainer::getCardTypeTextWidth() const
|
|||||||
QFontMetrics fm(f);
|
QFontMetrics fm(f);
|
||||||
|
|
||||||
int maxCardTypeWidth = 0;
|
int maxCardTypeWidth = 0;
|
||||||
QMapIterator<QString, DeckViewCard *> i(cardsByType);
|
for (const auto &key : cardsByType.keys()) {
|
||||||
while (i.hasNext()) {
|
int cardTypeWidth = fm.size(Qt::TextSingleLine, key).width();
|
||||||
int cardTypeWidth = fm.size(Qt::TextSingleLine, i.next().key()).width();
|
maxCardTypeWidth = qMax(maxCardTypeWidth, cardTypeWidth);
|
||||||
if (cardTypeWidth > maxCardTypeWidth)
|
|
||||||
maxCardTypeWidth = cardTypeWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxCardTypeWidth + 15;
|
return maxCardTypeWidth + 15;
|
||||||
@@ -274,16 +273,11 @@ void DeckViewCardContainer::rearrangeItems(const QList<QPair<int, int>> &rowsAnd
|
|||||||
{
|
{
|
||||||
currentRowsAndCols = rowsAndCols;
|
currentRowsAndCols = rowsAndCols;
|
||||||
|
|
||||||
int totalCols = 0, totalRows = 0;
|
|
||||||
qreal yUntilNow = separatorY + paddingY;
|
qreal yUntilNow = separatorY + paddingY;
|
||||||
qreal x = (qreal)getCardTypeTextWidth();
|
qreal x = (qreal)getCardTypeTextWidth();
|
||||||
for (int i = 0; i < rowsAndCols.size(); ++i) {
|
for (int i = 0; i < rowsAndCols.size(); ++i) {
|
||||||
const int tempRows = rowsAndCols[i].first;
|
const int tempRows = rowsAndCols[i].first;
|
||||||
const int tempCols = rowsAndCols[i].second;
|
const int tempCols = rowsAndCols[i].second;
|
||||||
totalRows += tempRows;
|
|
||||||
if (tempCols > totalCols)
|
|
||||||
totalCols = tempCols;
|
|
||||||
|
|
||||||
QList<QString> cardTypeList = cardsByType.uniqueKeys();
|
QList<QString> cardTypeList = cardsByType.uniqueKeys();
|
||||||
QList<DeckViewCard *> row = cardsByType.values(cardTypeList[i]);
|
QList<DeckViewCard *> row = cardsByType.values(cardTypeList[i]);
|
||||||
std::sort(row.begin(), row.end(), DeckViewCardContainer::sortCardsByName);
|
std::sort(row.begin(), row.end(), DeckViewCardContainer::sortCardsByName);
|
||||||
@@ -440,7 +434,7 @@ void DeckViewScene::rearrangeItems()
|
|||||||
const int maxRows = rowsAndColsList[maxIndex1][maxIndex2].first;
|
const int maxRows = rowsAndColsList[maxIndex1][maxIndex2].first;
|
||||||
const int maxCardCount = cardCountList[maxIndex1][maxIndex2];
|
const int maxCardCount = cardCountList[maxIndex1][maxIndex2];
|
||||||
rowsAndColsList[maxIndex1][maxIndex2] =
|
rowsAndColsList[maxIndex1][maxIndex2] =
|
||||||
QPair<int, int>(maxRows + 1, (int)ceil((qreal)maxCardCount / (qreal)(maxRows + 1)));
|
QPair<int, int>(maxRows + 1, (int)qCeil((qreal)maxCardCount / (qreal)(maxRows + 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
totalHeight = -spacing;
|
totalHeight = -spacing;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "dlg_connect.h"
|
#include "dlg_connect.h"
|
||||||
|
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
#include "userconnection_information.h"
|
#include "userconnection_information.h"
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
@@ -39,22 +40,27 @@ DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
|||||||
|
|
||||||
saveLabel = new QLabel(tr("Name:"));
|
saveLabel = new QLabel(tr("Name:"));
|
||||||
saveEdit = new QLineEdit;
|
saveEdit = new QLineEdit;
|
||||||
|
saveEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
saveLabel->setBuddy(saveEdit);
|
saveLabel->setBuddy(saveEdit);
|
||||||
|
|
||||||
hostLabel = new QLabel(tr("&Host:"));
|
hostLabel = new QLabel(tr("&Host:"));
|
||||||
hostEdit = new QLineEdit;
|
hostEdit = new QLineEdit;
|
||||||
|
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
hostLabel->setBuddy(hostEdit);
|
hostLabel->setBuddy(hostEdit);
|
||||||
|
|
||||||
portLabel = new QLabel(tr("&Port:"));
|
portLabel = new QLabel(tr("&Port:"));
|
||||||
portEdit = new QLineEdit;
|
portEdit = new QLineEdit;
|
||||||
|
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||||
portLabel->setBuddy(portEdit);
|
portLabel->setBuddy(portEdit);
|
||||||
|
|
||||||
playernameLabel = new QLabel(tr("Player &name:"));
|
playernameLabel = new QLabel(tr("Player &name:"));
|
||||||
playernameEdit = new QLineEdit;
|
playernameEdit = new QLineEdit;
|
||||||
|
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
playernameLabel->setBuddy(playernameEdit);
|
playernameLabel->setBuddy(playernameEdit);
|
||||||
|
|
||||||
passwordLabel = new QLabel(tr("P&assword:"));
|
passwordLabel = new QLabel(tr("P&assword:"));
|
||||||
passwordEdit = new QLineEdit;
|
passwordEdit = new QLineEdit;
|
||||||
|
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
passwordLabel->setBuddy(passwordEdit);
|
passwordLabel->setBuddy(passwordEdit);
|
||||||
passwordEdit->setEchoMode(QLineEdit::Password);
|
passwordEdit->setEchoMode(QLineEdit::Password);
|
||||||
|
|
||||||
@@ -156,8 +162,7 @@ DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
|||||||
|
|
||||||
previousHostButton->setChecked(true);
|
previousHostButton->setChecked(true);
|
||||||
|
|
||||||
connect(previousHosts, SIGNAL(currentIndexChanged(const QString &)), this,
|
connect(previousHosts, SIGNAL(currentTextChanged(const QString &)), this, SLOT(updateDisplayInfo(const QString &)));
|
||||||
SLOT(updateDisplayInfo(const QString &)));
|
|
||||||
|
|
||||||
playernameEdit->setFocus();
|
playernameEdit->setFocus();
|
||||||
}
|
}
|
||||||
@@ -240,22 +245,22 @@ void DlgConnect::updateDisplayInfo(const QString &saveName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserConnection_Information uci;
|
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));
|
saveEdit->setText(_data.at(0));
|
||||||
hostEdit->setText(data.at(1));
|
hostEdit->setText(_data.at(1));
|
||||||
portEdit->setText(data.at(2));
|
portEdit->setText(_data.at(2));
|
||||||
playernameEdit->setText(data.at(3));
|
playernameEdit->setText(_data.at(3));
|
||||||
savePasswordCheckBox->setChecked(savePasswordStatus);
|
savePasswordCheckBox->setChecked(savePasswordStatus);
|
||||||
|
|
||||||
if (savePasswordStatus) {
|
if (savePasswordStatus) {
|
||||||
passwordEdit->setText(data.at(4));
|
passwordEdit->setText(_data.at(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.at(6).isEmpty()) {
|
if (!_data.at(6).isEmpty()) {
|
||||||
QString formattedLink = "<a href=\"" + data.at(6) + "\">" + data.at(6) + "</a>";
|
QString formattedLink = "<a href=\"" + _data.at(6) + "\">" + _data.at(6) + "</a>";
|
||||||
serverContactLabel->setText(tr("Webpage") + ":");
|
serverContactLabel->setText(tr("Webpage") + ":");
|
||||||
serverContactLink->setText(formattedLink);
|
serverContactLink->setText(formattedLink);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "decklist.h"
|
#include "decklist.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
@@ -28,6 +29,7 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa
|
|||||||
|
|
||||||
nameLabel = new QLabel(tr("&Name:"));
|
nameLabel = new QLabel(tr("&Name:"));
|
||||||
nameEdit = new QLineEdit(tr("Token"));
|
nameEdit = new QLineEdit(tr("Token"));
|
||||||
|
nameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
nameEdit->selectAll();
|
nameEdit->selectAll();
|
||||||
connect(nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateSearch(const QString &)));
|
connect(nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateSearch(const QString &)));
|
||||||
nameLabel->setBuddy(nameEdit);
|
nameLabel->setBuddy(nameEdit);
|
||||||
@@ -45,10 +47,12 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa
|
|||||||
|
|
||||||
ptLabel = new QLabel(tr("&P/T:"));
|
ptLabel = new QLabel(tr("&P/T:"));
|
||||||
ptEdit = new QLineEdit;
|
ptEdit = new QLineEdit;
|
||||||
|
ptEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
ptLabel->setBuddy(ptEdit);
|
ptLabel->setBuddy(ptEdit);
|
||||||
|
|
||||||
annotationLabel = new QLabel(tr("&Annotation:"));
|
annotationLabel = new QLabel(tr("&Annotation:"));
|
||||||
annotationEdit = new QLineEdit;
|
annotationEdit = new QLineEdit;
|
||||||
|
annotationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
annotationLabel->setBuddy(annotationEdit);
|
annotationLabel->setBuddy(annotationEdit);
|
||||||
|
|
||||||
destroyCheckBox = new QCheckBox(tr("&Destroy token when it leaves the table"));
|
destroyCheckBox = new QCheckBox(tr("&Destroy token when it leaves the table"));
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "pending_command.h"
|
#include "pending_command.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
#include "tab_room.h"
|
#include "tab_room.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
@@ -24,8 +25,8 @@ void DlgCreateGame::sharedCtor()
|
|||||||
rememberGameSettings = new QCheckBox(tr("Re&member settings"));
|
rememberGameSettings = new QCheckBox(tr("Re&member settings"));
|
||||||
descriptionLabel = new QLabel(tr("&Description:"));
|
descriptionLabel = new QLabel(tr("&Description:"));
|
||||||
descriptionEdit = new QLineEdit;
|
descriptionEdit = new QLineEdit;
|
||||||
|
descriptionEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
descriptionLabel->setBuddy(descriptionEdit);
|
descriptionLabel->setBuddy(descriptionEdit);
|
||||||
descriptionEdit->setMaxLength(60);
|
|
||||||
|
|
||||||
maxPlayersLabel = new QLabel(tr("P&layers:"));
|
maxPlayersLabel = new QLabel(tr("P&layers:"));
|
||||||
maxPlayersEdit = new QSpinBox();
|
maxPlayersEdit = new QSpinBox();
|
||||||
@@ -57,6 +58,7 @@ void DlgCreateGame::sharedCtor()
|
|||||||
|
|
||||||
passwordLabel = new QLabel(tr("&Password:"));
|
passwordLabel = new QLabel(tr("&Password:"));
|
||||||
passwordEdit = new QLineEdit;
|
passwordEdit = new QLineEdit;
|
||||||
|
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
passwordLabel->setBuddy(passwordEdit);
|
passwordLabel->setBuddy(passwordEdit);
|
||||||
|
|
||||||
onlyBuddiesCheckBox = new QCheckBox(tr("Only &buddies can join"));
|
onlyBuddiesCheckBox = new QCheckBox(tr("Only &buddies can join"));
|
||||||
@@ -233,13 +235,13 @@ void DlgCreateGame::actOK()
|
|||||||
cmd.set_join_as_judge(QApplication::keyboardModifiers() & Qt::ShiftModifier);
|
cmd.set_join_as_judge(QApplication::keyboardModifiers() & Qt::ShiftModifier);
|
||||||
cmd.set_join_as_spectator(createGameAsSpectatorCheckBox->isChecked());
|
cmd.set_join_as_spectator(createGameAsSpectatorCheckBox->isChecked());
|
||||||
|
|
||||||
QString gameTypes = QString();
|
QString _gameTypes = QString();
|
||||||
QMapIterator<int, QRadioButton *> gameTypeCheckBoxIterator(gameTypeCheckBoxes);
|
QMapIterator<int, QRadioButton *> gameTypeCheckBoxIterator(gameTypeCheckBoxes);
|
||||||
while (gameTypeCheckBoxIterator.hasNext()) {
|
while (gameTypeCheckBoxIterator.hasNext()) {
|
||||||
gameTypeCheckBoxIterator.next();
|
gameTypeCheckBoxIterator.next();
|
||||||
if (gameTypeCheckBoxIterator.value()->isChecked()) {
|
if (gameTypeCheckBoxIterator.value()->isChecked()) {
|
||||||
cmd.add_game_type_ids(gameTypeCheckBoxIterator.key());
|
cmd.add_game_type_ids(gameTypeCheckBoxIterator.key());
|
||||||
gameTypes += gameTypeCheckBoxIterator.value()->text() + ", ";
|
_gameTypes += gameTypeCheckBoxIterator.value()->text() + ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +256,7 @@ void DlgCreateGame::actOK()
|
|||||||
SettingsCache::instance().setSpectatorsCanTalk(spectatorsCanTalkCheckBox->isChecked());
|
SettingsCache::instance().setSpectatorsCanTalk(spectatorsCanTalkCheckBox->isChecked());
|
||||||
SettingsCache::instance().setSpectatorsCanSeeEverything(spectatorsSeeEverythingCheckBox->isChecked());
|
SettingsCache::instance().setSpectatorsCanSeeEverything(spectatorsSeeEverythingCheckBox->isChecked());
|
||||||
SettingsCache::instance().setCreateGameAsSpectator(createGameAsSpectatorCheckBox->isChecked());
|
SettingsCache::instance().setCreateGameAsSpectator(createGameAsSpectatorCheckBox->isChecked());
|
||||||
SettingsCache::instance().setGameTypes(gameTypes);
|
SettingsCache::instance().setGameTypes(_gameTypes);
|
||||||
}
|
}
|
||||||
PendingCommand *pend = room->prepareRoomCommand(cmd);
|
PendingCommand *pend = room->prepareRoomCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response)));
|
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response)));
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "dlg_edit_avatar.h"
|
#include "dlg_edit_avatar.h"
|
||||||
|
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
@@ -72,9 +74,15 @@ QByteArray DlgEditAvatar::getImage()
|
|||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ba;
|
for (;;) {
|
||||||
QBuffer buffer(&ba);
|
QByteArray ba;
|
||||||
buffer.open(QIODevice::WriteOnly);
|
QBuffer buffer(&ba);
|
||||||
image.save(&buffer, "JPG");
|
buffer.open(QIODevice::WriteOnly);
|
||||||
return ba;
|
image.save(&buffer, "JPG");
|
||||||
|
if (ba.length() > MAX_FILE_LENGTH) {
|
||||||
|
image = image.scaledToWidth(image.width() / 2); // divide the amount of pixels in four to get the size down
|
||||||
|
} else {
|
||||||
|
return ba;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "dlg_edit_password.h"
|
#include "dlg_edit_password.h"
|
||||||
|
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
@@ -12,6 +13,7 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
|||||||
{
|
{
|
||||||
oldPasswordLabel = new QLabel(tr("Old password:"));
|
oldPasswordLabel = new QLabel(tr("Old password:"));
|
||||||
oldPasswordEdit = new QLineEdit();
|
oldPasswordEdit = new QLineEdit();
|
||||||
|
oldPasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
|
|
||||||
auto &servers = SettingsCache::instance().servers();
|
auto &servers = SettingsCache::instance().servers();
|
||||||
if (servers.getSavePassword()) {
|
if (servers.getSavePassword()) {
|
||||||
@@ -23,11 +25,13 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
|||||||
|
|
||||||
newPasswordLabel = new QLabel(tr("New password:"));
|
newPasswordLabel = new QLabel(tr("New password:"));
|
||||||
newPasswordEdit = new QLineEdit();
|
newPasswordEdit = new QLineEdit();
|
||||||
|
newPasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
newPasswordLabel->setBuddy(newPasswordLabel);
|
newPasswordLabel->setBuddy(newPasswordLabel);
|
||||||
newPasswordEdit->setEchoMode(QLineEdit::Password);
|
newPasswordEdit->setEchoMode(QLineEdit::Password);
|
||||||
|
|
||||||
newPasswordLabel2 = new QLabel(tr("Confirm new password:"));
|
newPasswordLabel2 = new QLabel(tr("Confirm new password:"));
|
||||||
newPasswordEdit2 = new QLineEdit();
|
newPasswordEdit2 = new QLineEdit();
|
||||||
|
newPasswordEdit2->setMaxLength(MAX_NAME_LENGTH);
|
||||||
newPasswordLabel2->setBuddy(newPasswordLabel2);
|
newPasswordLabel2->setBuddy(newPasswordLabel2);
|
||||||
newPasswordEdit2->setEchoMode(QLineEdit::Password);
|
newPasswordEdit2->setEchoMode(QLineEdit::Password);
|
||||||
|
|
||||||
@@ -55,7 +59,11 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
|||||||
|
|
||||||
void DlgEditPassword::actOk()
|
void DlgEditPassword::actOk()
|
||||||
{
|
{
|
||||||
if (newPasswordEdit->text() != newPasswordEdit2->text()) {
|
// TODO this stuff should be using qvalidators
|
||||||
|
if (newPasswordEdit->text().length() < 8) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Your password is too short."));
|
||||||
|
return;
|
||||||
|
} else if (newPasswordEdit->text() != newPasswordEdit2->text()) {
|
||||||
QMessageBox::warning(this, tr("Error"), tr("The new passwords don't match."));
|
QMessageBox::warning(this, tr("Error"), tr("The new passwords don't match."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
#include "carddatabase.h"
|
#include "carddatabase.h"
|
||||||
#include "carddatabasemodel.h"
|
#include "carddatabasemodel.h"
|
||||||
|
#include "gettextwithmax.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
@@ -23,6 +25,7 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nul
|
|||||||
{
|
{
|
||||||
nameLabel = new QLabel(tr("&Name:"));
|
nameLabel = new QLabel(tr("&Name:"));
|
||||||
nameEdit = new QLineEdit;
|
nameEdit = new QLineEdit;
|
||||||
|
nameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
nameEdit->setEnabled(false);
|
nameEdit->setEnabled(false);
|
||||||
nameLabel->setBuddy(nameEdit);
|
nameLabel->setBuddy(nameEdit);
|
||||||
|
|
||||||
@@ -40,11 +43,13 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nul
|
|||||||
|
|
||||||
ptLabel = new QLabel(tr("&P/T:"));
|
ptLabel = new QLabel(tr("&P/T:"));
|
||||||
ptEdit = new QLineEdit;
|
ptEdit = new QLineEdit;
|
||||||
|
ptEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
ptLabel->setBuddy(ptEdit);
|
ptLabel->setBuddy(ptEdit);
|
||||||
connect(ptEdit, SIGNAL(textChanged(QString)), this, SLOT(ptChanged(QString)));
|
connect(ptEdit, SIGNAL(textChanged(QString)), this, SLOT(ptChanged(QString)));
|
||||||
|
|
||||||
annotationLabel = new QLabel(tr("&Annotation:"));
|
annotationLabel = new QLabel(tr("&Annotation:"));
|
||||||
annotationEdit = new QLineEdit;
|
annotationEdit = new QLineEdit;
|
||||||
|
annotationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
annotationLabel->setBuddy(annotationEdit);
|
annotationLabel->setBuddy(annotationEdit);
|
||||||
connect(annotationEdit, SIGNAL(textChanged(QString)), this, SLOT(annotationChanged(QString)));
|
connect(annotationEdit, SIGNAL(textChanged(QString)), this, SLOT(annotationChanged(QString)));
|
||||||
|
|
||||||
@@ -142,9 +147,8 @@ void DlgEditTokens::tokenSelectionChanged(const QModelIndex ¤t, const QMod
|
|||||||
void DlgEditTokens::actAddToken()
|
void DlgEditTokens::actAddToken()
|
||||||
{
|
{
|
||||||
QString name;
|
QString name;
|
||||||
bool askAgain = true;
|
for (;;) {
|
||||||
do {
|
name = getTextWithMax(this, tr("Add token"), tr("Please enter the name of the token:"));
|
||||||
name = QInputDialog::getText(this, tr("Add token"), tr("Please enter the name of the token:"));
|
|
||||||
if (name.isEmpty())
|
if (name.isEmpty())
|
||||||
return;
|
return;
|
||||||
if (databaseModel->getDatabase()->getCard(name)) {
|
if (databaseModel->getDatabase()->getCard(name)) {
|
||||||
@@ -152,9 +156,9 @@ void DlgEditTokens::actAddToken()
|
|||||||
tr("The chosen name conflicts with an existing card or token.\nMake sure to enable "
|
tr("The chosen name conflicts with an existing card or token.\nMake sure to enable "
|
||||||
"the 'Token' set in the \"Manage sets\" dialog to display them correctly."));
|
"the 'Token' set in the \"Manage sets\" dialog to display them correctly."));
|
||||||
} else {
|
} else {
|
||||||
askAgain = false;
|
break;
|
||||||
}
|
}
|
||||||
} while (askAgain);
|
}
|
||||||
|
|
||||||
QString setName = CardDatabase::TOKENS_SETNAME;
|
QString setName = CardDatabase::TOKENS_SETNAME;
|
||||||
CardInfoPerSetMap sets;
|
CardInfoPerSetMap sets;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "dlg_edit_user.h"
|
#include "dlg_edit_user.h"
|
||||||
|
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
@@ -12,6 +13,7 @@ DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QStrin
|
|||||||
{
|
{
|
||||||
emailLabel = new QLabel(tr("Email:"));
|
emailLabel = new QLabel(tr("Email:"));
|
||||||
emailEdit = new QLineEdit();
|
emailEdit = new QLineEdit();
|
||||||
|
emailEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
emailLabel->setBuddy(emailEdit);
|
emailLabel->setBuddy(emailEdit);
|
||||||
emailEdit->setText(email);
|
emailEdit->setText(email);
|
||||||
|
|
||||||
@@ -33,6 +35,7 @@ DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QStrin
|
|||||||
|
|
||||||
realnameLabel = new QLabel(tr("Real name:"));
|
realnameLabel = new QLabel(tr("Real name:"));
|
||||||
realnameEdit = new QLineEdit();
|
realnameEdit = new QLineEdit();
|
||||||
|
realnameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
realnameLabel->setBuddy(realnameEdit);
|
realnameLabel->setBuddy(realnameEdit);
|
||||||
realnameEdit->setText(realName);
|
realnameEdit->setText(realName);
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ public:
|
|||||||
{
|
{
|
||||||
return emailEdit->text();
|
return emailEdit->text();
|
||||||
}
|
}
|
||||||
int getGender() const
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
} // This will return GenderUnknown for protocol purposes.
|
|
||||||
QString getCountry() const
|
QString getCountry() const
|
||||||
{
|
{
|
||||||
return countryEdit->currentIndex() == 0 ? "" : countryEdit->currentText();
|
return countryEdit->currentIndex() == 0 ? "" : countryEdit->currentText();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user