mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-14 22:42:14 -07:00
Merge branch 'master' into feat/release-docker-images
This commit is contained in:
commit
8e502efc0a
283 changed files with 8522 additions and 2934 deletions
|
|
@ -41,7 +41,7 @@ If you ever encounter a bug, have a suggestion or idea, or feel a need for a dev
|
||||||
|
|
||||||
For basic information related to the app and getting started, please take a look at our official site: **https://cockatrice.github.io**
|
For basic information related to the app and getting started, please take a look at our official site: **https://cockatrice.github.io**
|
||||||
|
|
||||||
If you'd like to help and contribute to Cockatrice in any way, check out our [README](https://github.com/Cockatrice/Cockatrice#get-involved-).
|
If you'd like to help and contribute to Cockatrice in any way, check out our [README](https://github.com/Cockatrice/Cockatrice#contribute).
|
||||||
We're always available to answer questions you may have on how the program works and how you can provide a meaningful contribution.
|
We're always available to answer questions you may have on how the program works and how you can provide a meaningful contribution.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -2,7 +2,8 @@
|
||||||
name: "🐛 Bug Report"
|
name: "🐛 Bug Report"
|
||||||
about: Report an issue encountered while using Cockatrice
|
about: Report an issue encountered while using Cockatrice
|
||||||
title: ''
|
title: ''
|
||||||
labels: 'Bug'
|
type: 'Bug'
|
||||||
|
labels: ''
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
5
.github/ISSUE_TEMPLATE/feature_request.md
vendored
5
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
|
@ -1,8 +1,9 @@
|
||||||
---
|
---
|
||||||
name: "💡 Feature Request"
|
name: "💡 Feature Request"
|
||||||
about: Request a new feature
|
about: Request a new feature for Cockatrice
|
||||||
title: ''
|
title: ''
|
||||||
labels: 'Feature Request'
|
type: 'Feature'
|
||||||
|
labels: ''
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
207
README.md
207
README.md
|
|
@ -5,159 +5,154 @@
|
||||||
<p align='center'>
|
<p align='center'>
|
||||||
<a href="#cockatrice"><b>Cockatrice</b></a> <b>|</b>
|
<a href="#cockatrice"><b>Cockatrice</b></a> <b>|</b>
|
||||||
<a href="#download-">Download</a> <b>|</b>
|
<a href="#download-">Download</a> <b>|</b>
|
||||||
<a href="#get-involved-">Get Involved</a> <b>|</b>
|
<a href="#related-repositories">Related</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="#contribute">Contribute</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>
|
||||||
<a href="#license-">License</a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<br><pre>
|
<br><pre><p align='center'>
|
||||||
<b>To get started, ⇢ [view our webpage](https://cockatrice.github.io/)</b><br>
|
<b>To get started with Cockatrice ⇢ [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 to the app ⇢ [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 ⇢ learn [how to contribute](#contribute-)</b>
|
||||||
</pre><br>
|
</pre><p><br>
|
||||||
|
|
||||||
|
|
||||||
# Cockatrice
|
# Cockatrice
|
||||||
|
|
||||||
Cockatrice is an open-source, multiplatform program for playing tabletop card games over a network. The program's server design prevents users from manipulating the game for unfair advantage. The client also provides a single-player mode, which allows users to brew while offline. This project uses C++ and the Qt5 libraries.<br>
|
Cockatrice is an open-source, multiplatform application for playing tabletop card games over a network. The program's server design prevents users from manipulating the game for unfair advantage. The client also provides a single-player mode, which allows users to brew while offline.<br><br>
|
||||||
|
This project uses <kbd>C++</kbd> and the <kbd>Qt</kbd> libraries.<br>
|
||||||
|
First work on a webclient with <kbd>Typescript</kbd> was started as well.<br>
|
||||||
|
|
||||||
|
|
||||||
# Download [](https://tooomm.github.io/github-release-stats/?username=Cockatrice&repository=Cockatrice)
|
# Download [](https://tooomm.github.io/github-release-stats/?username=Cockatrice&repository=Cockatrice&search=0)
|
||||||
|
|
||||||
Downloads are available for full releases and the current beta version in development. There is no strict release schedule for either of them.
|
Downloads are available for **stable releases** and the current **beta version** in development.
|
||||||
|
There is no strict release schedule for either of them.
|
||||||
|
<br><pre>
|
||||||
|
Latest <kbd>stable</kbd> release:
|
||||||
|
[](https://github.com/cockatrice/cockatrice/releases/latest)  [](https://tooomm.github.io/github-release-stats/?username=Cockatrice&repository=Cockatrice&search=0)
|
||||||
|
</pre><pre>
|
||||||
|
Latest <kbd>beta</kbd> version:
|
||||||
|
[](https://github.com/cockatrice/cockatrice/releases)  [](https://tooomm.github.io/github-release-stats/?username=Cockatrice&repository=Cockatrice&search=0) [](https://github.com/Cockatrice/Cockatrice/pulls?q=is%3Apr+is%3Aclosed)
|
||||||
|
<sub><i>While incorporating the latest fixes and features, beta builds may not be stable and/or contain new bugs!</i></sub>
|
||||||
|
<sub><b><i>Please report any findings when testing them!</i></b></sub>
|
||||||
|
</pre>
|
||||||
|
|
||||||
- Latest `stable` release: [](https://github.com/cockatrice/cockatrice/releases/latest) [](https://tooomm.github.io/github-release-stats/?username=Cockatrice&repository=Cockatrice)<br>
|
# Related Repositories
|
||||||
- Stable versions are checkpoints featuring major feature and UI enhancements.
|
|
||||||
- **Recommended for most users!**
|
|
||||||
|
|
||||||
- Latest `beta` release: [](https://github.com/cockatrice/cockatrice/releases) [](https://tooomm.github.io/github-release-stats/?username=Cockatrice&repository=Cockatrice)
|
- [Magic-Token](https://github.com/Cockatrice/Magic-Token): MtG token data to use in Cockatrice
|
||||||
- Beta versions include the most recently added features and bugfixes, but can be unstable.
|
- [Magic-Spoiler](https://github.com/Cockatrice/Magic-Spoiler): Script to generate MtG spoiler data from [MTGJSON](https://github.com/mtgjson/mtgjson) to use in Cockatrice
|
||||||
- To be a Cockatrice Beta Tester, use this version. Find more information [here](https://github.com/Cockatrice/Cockatrice/wiki/Release-Channels)!
|
- [cockatrice.github.io](https://github.com/Cockatrice/cockatrice.github.io): Code of the official webpage of the Cockatrice project
|
||||||
|
|
||||||
|
|
||||||
# Get Involved [](https://discord.gg/3Z9yzmA)
|
# Community Resources [](https://discord.gg/3Z9yzmA)
|
||||||
|
|
||||||
Join our [Discord community](https://discord.gg/3Z9yzmA) to connect with the project, contributors or fellow users of the app. 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 other projet contributors (`#dev` channel) or fellow users of the app. Come here to talk about the application, features, or just to hang out.
|
||||||
For support regarding specific servers, please contact that server's admin or forum for support rather than asking here.<br>
|
- [Official Website](https://cockatrice.github.io)
|
||||||
|
- [Official Wiki](https://github.com/Cockatrice/Cockatrice/wiki)
|
||||||
To contribute code to the project, please review [the guidelines](https://github.com/Cockatrice/Cockatrice/blob/master/.github/CONTRIBUTING.md).
|
- [Official Discord](https://discord.gg/3Z9yzmA)
|
||||||
We maintain two tags for contributors to find issues to work on:
|
|
||||||
- [Good first issue](https://github.com/Cockatrice/Cockatrice/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22Good%20first%20issue%22%20): issues tagged in this way provide a simple way to get started. They don't require much experience to be worked on.
|
|
||||||
- [Help wanted](https://github.com/Cockatrice/Cockatrice/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22Help%20Wanted%22%20): This tag is used for issues that we are looking for a contributor to work on. Often this is for feature suggestions we are willing to accept, but don't have the time to work on ourselves.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
# Community Resources
|
|
||||||
|
|
||||||
- [Cockatrice Official Site](https://cockatrice.github.io)
|
|
||||||
- [Cockatrice Official Wiki](https://github.com/Cockatrice/Cockatrice/wiki)
|
|
||||||
- [Cockatrice Official Discord](https://discord.gg/3Z9yzmA)
|
|
||||||
- [reddit r/Cockatrice](https://reddit.com/r/cockatrice)
|
- [reddit r/Cockatrice](https://reddit.com/r/cockatrice)
|
||||||
|
|
||||||
|
>[!IMPORTANT]
|
||||||
|
>For support regarding specific servers, please contact that server's admin/mods and use their dedicated communication channels rather than contacting the team building the software.
|
||||||
|
|
||||||
# Translations [](https://transifex.com/cockatrice/cockatrice/)
|
|
||||||
|
|
||||||
Cockatrice uses Transifex for translations. You can help us bring Cockatrice, Oracle and Webatrice to your language or just adjust single wordings right from within your browser by visiting our [Transifex project page](https://transifex.com/cockatrice/cockatrice/).<br>
|
# Contribute
|
||||||
|
|
||||||
Check out our [Translator FAQ](https://github.com/Cockatrice/Cockatrice/wiki/Translation-FAQ) for more information about contributing!<br>
|
### Code
|
||||||
|
|
||||||
|
To contribute code to the project, please review our [guidelines](https://github.com/Cockatrice/Cockatrice/blob/master/.github/CONTRIBUTING.md) first.<br>
|
||||||
|
We maintain two tags for contributors to easier find issues to potentially work on:
|
||||||
|
- [](https://github.com/Cockatrice/Cockatrice/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22Good%20first%20issue%22%20)<br>
|
||||||
|
Issues tagged in this way provide a simple way to get started. They don't require much experience to be worked on.
|
||||||
|
- [](https://github.com/Cockatrice/Cockatrice/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22Help%20Wanted%22%20)<br>
|
||||||
|
This tag is used for issues that we are looking for somebody to pick up. Often this is for feature suggestions we support, but don't have the time to work on ourselves.
|
||||||
|
|
||||||
|
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 reviews for submitted changes.<br>
|
||||||
|
We'll happily advice on how best to implement a feature, or we can show you where the codebase is doing something similar before you get too far along - put a note on an issue you want to discuss more on!
|
||||||
|
|
||||||
|
Cockatrice tries to use the [Google Developer Documentation Style Guide](https://developers.google.com/style/) to ensure consistent documentation. We encourage you to improve the documentation by suggesting edits based on this guide.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Kudos to our amazing contributors ❤️</b></summary>
|
||||||
|
<a href="https://github.com/Cockatrice/Cockatrice/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=Cockatrice/Cockatrice" />
|
||||||
|
</a><br>
|
||||||
|
<sub><i>Made with <a href="https://contrib.rocks">contrib.rocks</a>.</i></sub>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Translations [](https://transifex.com/cockatrice/cockatrice/)
|
||||||
|
|
||||||
|
Cockatrice uses Transifex to manage translations. You can help us bring <kbd>Cockatrice</kbd>, <kbd>Oracle</kbd> and <kbd>Webatrice</kbd> to your language and just adjust single wordings right from within your browser by visiting our [Transifex project page](https://transifex.com/cockatrice/cockatrice/).<br>
|
||||||
|
|
||||||
|
Check out our [Translator FAQ](https://github.com/Cockatrice/Cockatrice/wiki/Translation-FAQ) for more information about getting invovled, and join a group of hundreds of others!<br>
|
||||||
|
|
||||||
|
|
||||||
# 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)
|
# 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)**
|
Dependencies: *(for minimum versions search our [CMake file](https://github.com/Cockatrice/Cockatrice/blob/master/CMakeLists.txt))*
|
||||||
|
|
||||||
Dependencies: *(for minimum requirements search our [CMake file](https://github.com/Cockatrice/Cockatrice/blob/master/CMakeLists.txt))*
|
|
||||||
- [Qt](https://www.qt.io/developers/)
|
- [Qt](https://www.qt.io/developers/)
|
||||||
- [protobuf](https://github.com/protocolbuffers/protobuf)
|
- [protobuf](https://github.com/protocolbuffers/protobuf)
|
||||||
- [CMake](https://www.cmake.org/)
|
- [CMake](https://www.cmake.org/)
|
||||||
|
|
||||||
Oracle can optionally use zlib and xz to load compressed files:
|
Oracle can *optionally* use some packages to load compressed card files:
|
||||||
- [xz](https://tukaani.org/xz/)
|
- [xz](https://tukaani.org/xz/)
|
||||||
- [zlib](https://www.zlib.net/)
|
- [zlib](https://www.zlib.net/)
|
||||||
|
|
||||||
To compile:
|
<br>
|
||||||
|
|
||||||
mkdir build
|
**Basic compilation steps:**
|
||||||
cd build
|
```bash
|
||||||
cmake ..
|
mkdir build
|
||||||
make
|
cd build
|
||||||
|
cmake ..
|
||||||
You can then run
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then
|
||||||
|
- Create a Cockatrice installation inside the `release` folder:
|
||||||
|
```bash
|
||||||
make install
|
make install
|
||||||
|
```
|
||||||
to get a cockatrice installation inside the `release` folder, or:
|
- Or make an installation package specific to your system:
|
||||||
|
```bash
|
||||||
make package
|
make package
|
||||||
|
```
|
||||||
|
|
||||||
to create a system-specific installation package.
|
>[!NOTE]
|
||||||
|
>Detailed compiling instructions can be found in the Cockatrice wiki at [Compiling Cockatrice](https://github.com/Cockatrice/Cockatrice/wiki/Compiling-Cockatrice)
|
||||||
|
|
||||||
The following flags can be passed to `cmake`:
|
<br>
|
||||||
|
|
||||||
- `-DWITH_SERVER=1` Whether to build the server (default 0 = no).
|
The following flags (with their non-default values) can be passed to `cmake`:
|
||||||
- `-DWITH_CLIENT=0` Whether to build the client (default 1 = yes).
|
| Flag | Description |
|
||||||
- `-DWITH_ORACLE=0` Whether to build oracle (default 1 = yes).
|
| --- | --- |
|
||||||
- `-DCMAKE_BUILD_TYPE=Debug` Compile in debug mode. Enables extra logging output, debug symbols, and much more verbose compiler warnings (default `Release`).
|
| `-DWITH_SERVER=1` | Build <kbd>Servatrice</kbd> server |
|
||||||
- `-DWARNING_AS_ERROR=0` Whether to treat compilation warnings as errors in debug mode (default 1 = yes).
|
| `-DWITH_CLIENT=0` | Don't build <kbd>Cockatrice</kbd> client |
|
||||||
- `-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).
|
| `-DWITH_ORACLE=0` | Don't build <kbd>Oracle</kbd> card database tool |
|
||||||
- `-DTEST=1` Enable regression tests (default 0 = no). Note: needs googletest, will be downloaded on the fly if unavailable. To run tests: ```make test```.
|
| `-DCMAKE_BUILD_TYPE=Debug` | Compile in debug mode<br> Enables extra logging output, debug symbols, and much more verbose compiler warnings |
|
||||||
- `-DFORCE_USE_QT5=1` Skip looking for Qt6 before trying to find Qt5
|
| `-DWARNING_AS_ERROR=0` | Don't treat compilation warnings as errors in debug mode |
|
||||||
|
| `-DUPDATE_TRANSLATIONS=1` | Configure `make` to update the translation .ts files for new strings in the source code<br> **Note:** `make clean` will remove the .ts files |
|
||||||
|
| `-DTEST=1` | Enable regression tests<br> **Note:** `make test` to run tests, *googletest* will be downloaded if not available |
|
||||||
|
| `-DFORCE_USE_QT5=1` | Skip looking for Qt6 before trying to find Qt5 |
|
||||||
|
|
||||||
|
|
||||||
# Run
|
# Run
|
||||||
|
|
||||||
`Cockatrice` is the game client<br>
|
<kbd>Cockatrice</kbd> is the game client<br>
|
||||||
`Oracle` fetches card data<br>
|
<kbd>Oracle</kbd> fetches card data<br>
|
||||||
`Servatrice` is the server<br>
|
<kbd>Servatrice</kbd> is the server<br>
|
||||||
|
|
||||||
**Servatrice Docker container**
|
#### Docker
|
||||||
|
|
||||||
You can run an instance of Servatrice (the Cockatrice server) using [Docker](https://www.docker.com/what-docker) and the Cockatrice Dockerfile.<br>
|
You can run an instance of <kbd>Servatrice</kbd> (the Cockatrice server) using [Docker](https://www.docker.com/resources/what-container/) and our Dockerfile.<br>
|
||||||
|
|
||||||
First, create an image from the Dockerfile<br>
|
For more information, have a look in our wiki section on [Setting up Servatrice](https://github.com/Cockatrice/Cockatrice/wiki/Setting-up-Servatrice#using-docker).<br>
|
||||||
`cd /path/to/Cockatrice-Repo/`
|
There, you'll also find more hints on our **docker-compose** file which will configure and run both a MySQL server and Servatrice.
|
||||||
`docker build -t servatrice .`<br>
|
|
||||||
And then run it<br>
|
|
||||||
`docker run -i -p 4748:4748 -t servatrice:latest`<br>
|
|
||||||
|
|
||||||
For versions after 2.10.2, there is also an official image available on the GitHub container registry. You can pull it using<br>
|
|
||||||
`docker pull ghcr.io/cockatrice/servatrice:latest`<br>
|
|
||||||
And then run it<br>
|
|
||||||
`docker run -i -p 4748:4748 -t ghcr.io/cockatrice/servatrice:latest`<br>
|
|
||||||
|
|
||||||
>Note: Running this command exposes the port 4748 of the docker container<br>
|
|
||||||
to permit connections to the server.
|
|
||||||
|
|
||||||
Find more information on how to use Servatrice with Docker in our [wiki](https://github.com/Cockatrice/Cockatrice/wiki/Setting-up-Servatrice#using-docker).
|
|
||||||
|
|
||||||
**Docker compose**
|
|
||||||
|
|
||||||
There is also a docker-compose file available which will configure and run both a MySQL server and Servatrice. The docker-compose setup scripts can be found in the `servatrice/docker` folder and vary only slightly from the default sql and server .ini files. The setup scripts can either be modified in place, or docker-compose can mount alternative files into the images, as you prefer.
|
|
||||||
|
|
||||||
To run Servatrice via docker-compose, first install docker-compose following the [install instructions](https://docs.docker.com/compose/install/). Once installed, run the following from the root of the repository:
|
|
||||||
```bash
|
|
||||||
docker-compose build # Build the Servatrice image using the same Dockerfile as above.
|
|
||||||
docker-compose up # Setup and run both the MySQL server and Servatrice.
|
|
||||||
```
|
|
||||||
|
|
||||||
>Note: Similar to the above Docker setup, this will expose port 4748.
|
|
||||||
|
|
||||||
>Note: The first time running the docker-compose setup, the MySQL server will take a little time to run the initial setup scripts. Due to this, the Servatrice instance may fail the first few attempts to connect to the database. Servatrice is set to `restart: always` in the docker-compose.yml, which will allow it to continue attempting to start up. Once the MySQL scripts have completed, Servatrice should then connect automatically on the next attempt.
|
|
||||||
|
|
||||||
**Docker compose in Windows**
|
|
||||||
A out of box working docker-compose file has been added to help setup in Windows.
|
|
||||||
|
|
||||||
Docker in Windows requires additional steps in form of using Docker Desktop to allow resource sharing from the drive the volumes are mapped from, as well as potential workarounds needed to get file sharing working in Windows. This [StackOverflow discussion sheds some light on it](https://stackoverflow.com/questions/42203488/settings-to-windows-firewall-to-allow-docker-for-windows-to-share-drive)
|
|
||||||
|
|
||||||
|
|
||||||
# License [](https://github.com/Cockatrice/Cockatrice/blob/master/LICENSE)
|
# License [](https://github.com/Cockatrice/Cockatrice/blob/master/LICENSE)
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,245 @@
|
||||||
|
|
||||||
project(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
project(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||||
|
|
||||||
file(GLOB_RECURSE cockatrice_CPP_FILES CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/cockatrice/src/*.cpp)
|
set(cockatrice_SOURCES
|
||||||
|
${VERSION_STRING_CPP}
|
||||||
set(cockatrice_SOURCES ${cockatrice_CPP_FILES} ${VERSION_STRING_CPP})
|
# sort by alphabetical order, so that there is no debate about where to add new sources to the list
|
||||||
|
src/client/game_logic/abstract_client.cpp
|
||||||
|
src/client/game_logic/key_signals.cpp
|
||||||
|
src/client/get_text_with_max.cpp
|
||||||
|
src/client/menus/deck_editor/deck_editor_menu.cpp
|
||||||
|
src/client/network/client_update_checker.cpp
|
||||||
|
src/client/network/release_channel.cpp
|
||||||
|
src/client/network/replay_timeline_widget.cpp
|
||||||
|
src/client/network/sets_model.cpp
|
||||||
|
src/client/network/spoiler_background_updater.cpp
|
||||||
|
src/client/sound_engine.cpp
|
||||||
|
src/client/tabs/abstract_tab_deck_editor.cpp
|
||||||
|
src/client/tabs/api/edhrec/tab_edhrec.cpp
|
||||||
|
src/client/tabs/api/edhrec/tab_edhrec_main.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/commander/edhrec_commander_api_response_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/display/top_tags/edhrec_top_tags_api_response_display_widget.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/archidekt_links/edhrec_api_response_archidekt_links.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response_average_deck_statistics.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_details.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_list.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/cards/edhrec_api_response_card_container.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/card_prices/edhrec_api_response_card_prices.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/cards/edhrec_commander_api_response_commander_details.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/commander/edhrec_commander_api_response.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/average_deck/edhrec_average_deck_api_response.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/average_deck/edhrec_deck_api_response.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/top_cards/edhrec_top_cards_api_response.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/top_commanders/edhrec_top_commanders_api_response.cpp
|
||||||
|
src/client/tabs/api/edhrec/api_response/top_tags/edhrec_top_tags_api_response.cpp
|
||||||
|
src/client/tabs/tab.cpp
|
||||||
|
src/client/tabs/tab_account.cpp
|
||||||
|
src/client/tabs/tab_admin.cpp
|
||||||
|
src/client/tabs/tab_deck_editor.cpp
|
||||||
|
src/client/tabs/tab_deck_storage.cpp
|
||||||
|
src/client/tabs/tab_game.cpp
|
||||||
|
src/client/tabs/tab_logs.cpp
|
||||||
|
src/client/tabs/tab_message.cpp
|
||||||
|
src/client/tabs/tab_replays.cpp
|
||||||
|
src/client/tabs/tab_room.cpp
|
||||||
|
src/client/tabs/tab_server.cpp
|
||||||
|
src/client/tabs/tab_supervisor.cpp
|
||||||
|
src/client/tabs/tab_visual_database_display.cpp
|
||||||
|
src/client/tabs/visual_deck_editor/tab_deck_editor_visual.cpp
|
||||||
|
src/client/tabs/visual_deck_editor/tab_deck_editor_visual_tab_widget.cpp
|
||||||
|
src/client/tabs/visual_deck_storage/tab_deck_storage_visual.cpp
|
||||||
|
src/client/tapped_out_interface.cpp
|
||||||
|
src/client/translate_counter_name.cpp
|
||||||
|
src/client/ui/layouts/flow_layout.cpp
|
||||||
|
src/client/ui/layouts/overlap_layout.cpp
|
||||||
|
src/client/ui/line_edit_completer.cpp
|
||||||
|
src/client/ui/phases_toolbar.cpp
|
||||||
|
src/client/ui/picture_loader/picture_loader.cpp
|
||||||
|
src/client/ui/picture_loader/picture_loader_worker.cpp
|
||||||
|
src/client/ui/picture_loader/picture_to_load.cpp
|
||||||
|
src/client/ui/pixel_map_generator.cpp
|
||||||
|
src/client/ui/theme_manager.cpp
|
||||||
|
src/client/ui/tip_of_the_day.cpp
|
||||||
|
src/client/ui/widgets/cards/additional_info/color_identity_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/additional_info/mana_cost_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/additional_info/mana_symbol_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_group_display_widgets/card_group_display_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_group_display_widgets/flat_card_group_display_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_group_display_widgets/overlapped_card_group_display_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_info_display_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_info_frame_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_info_picture_enlarged_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_info_picture_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_info_picture_with_text_overlay_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_info_text_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/card_size_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/deck_card_zone_display_widget.cpp
|
||||||
|
src/client/ui/widgets/cards/deck_preview_card_picture_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_analytics/deck_analytics_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_analytics/mana_base_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_analytics/mana_curve_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_analytics/mana_devotion_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_database_display_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_deck_dock_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_filter_dock_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp
|
||||||
|
src/client/ui/widgets/general/display/banner_widget.cpp
|
||||||
|
src/client/ui/widgets/general/display/bar_widget.cpp
|
||||||
|
src/client/ui/widgets/general/display/dynamic_font_size_label.cpp
|
||||||
|
src/client/ui/widgets/general/display/dynamic_font_size_push_button.cpp
|
||||||
|
src/client/ui/widgets/general/display/labeled_input.cpp
|
||||||
|
src/client/ui/widgets/general/display/shadow_background_label.cpp
|
||||||
|
src/client/ui/widgets/general/layout_containers/flow_widget.cpp
|
||||||
|
src/client/ui/widgets/general/layout_containers/overlap_control_widget.cpp
|
||||||
|
src/client/ui/widgets/general/layout_containers/overlap_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/all_zones_card_amount_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/card_amount_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/printing_selector.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/printing_selector_card_display_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/printing_selector_card_overlay_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/printing_selector_card_search_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/printing_selector_card_selection_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/printing_selector_card_sorting_widget.cpp
|
||||||
|
src/client/ui/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp
|
||||||
|
src/client/ui/widgets/quick_settings/settings_button_widget.cpp
|
||||||
|
src/client/ui/widgets/quick_settings/settings_popup_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_display_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_display_name_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_display_main_type_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_display_set_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_database_display/visual_database_filter_display_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_editor/visual_deck_editor_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_addition_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_dialog.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_display_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_tag_item_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
|
||||||
|
src/client/ui/window_main.cpp
|
||||||
|
src/client/update_downloader.cpp
|
||||||
|
src/deck/custom_line_edit.cpp
|
||||||
|
src/deck/deck_list_model.cpp
|
||||||
|
src/deck/deck_loader.cpp
|
||||||
|
src/deck/deck_stats_interface.cpp
|
||||||
|
src/dialogs/dlg_connect.cpp
|
||||||
|
src/dialogs/dlg_convert_deck_to_cod_format.cpp
|
||||||
|
src/dialogs/dlg_create_game.cpp
|
||||||
|
src/dialogs/dlg_create_token.cpp
|
||||||
|
src/dialogs/dlg_edit_avatar.cpp
|
||||||
|
src/dialogs/dlg_edit_password.cpp
|
||||||
|
src/dialogs/dlg_edit_tokens.cpp
|
||||||
|
src/dialogs/dlg_edit_user.cpp
|
||||||
|
src/dialogs/dlg_filter_games.cpp
|
||||||
|
src/dialogs/dlg_forgot_password_challenge.cpp
|
||||||
|
src/dialogs/dlg_forgot_password_request.cpp
|
||||||
|
src/dialogs/dlg_forgot_password_reset.cpp
|
||||||
|
src/dialogs/dlg_load_deck.cpp
|
||||||
|
src/dialogs/dlg_load_deck_from_clipboard.cpp
|
||||||
|
src/dialogs/dlg_load_remote_deck.cpp
|
||||||
|
src/dialogs/dlg_manage_sets.cpp
|
||||||
|
src/dialogs/dlg_move_top_cards_until.cpp
|
||||||
|
src/dialogs/dlg_register.cpp
|
||||||
|
src/dialogs/dlg_roll_dice.cpp
|
||||||
|
src/dialogs/dlg_settings.cpp
|
||||||
|
src/dialogs/dlg_tip_of_the_day.cpp
|
||||||
|
src/dialogs/dlg_update.cpp
|
||||||
|
src/dialogs/dlg_view_log.cpp
|
||||||
|
src/game/board/abstract_counter.cpp
|
||||||
|
src/game/board/abstract_graphics_item.cpp
|
||||||
|
src/game/board/arrow_item.cpp
|
||||||
|
src/game/board/arrow_target.cpp
|
||||||
|
src/game/board/counter_general.cpp
|
||||||
|
src/game/cards/abstract_card_drag_item.cpp
|
||||||
|
src/game/cards/abstract_card_item.cpp
|
||||||
|
src/game/cards/card_completer_proxy_model.cpp
|
||||||
|
src/game/cards/card_database.cpp
|
||||||
|
src/game/cards/card_database_manager.cpp
|
||||||
|
src/game/cards/card_database_model.cpp
|
||||||
|
src/game/cards/card_database_parser/card_database_parser.cpp
|
||||||
|
src/game/cards/card_database_parser/cockatrice_xml_3.cpp
|
||||||
|
src/game/cards/card_database_parser/cockatrice_xml_4.cpp
|
||||||
|
src/game/cards/card_drag_item.cpp
|
||||||
|
src/game/cards/card_info.cpp
|
||||||
|
src/game/cards/card_item.cpp
|
||||||
|
src/game/cards/card_list.cpp
|
||||||
|
src/game/cards/card_search_model.cpp
|
||||||
|
src/game/deckview/deck_view.cpp
|
||||||
|
src/game/deckview/deck_view_container.cpp
|
||||||
|
src/game/filters/filter_builder.cpp
|
||||||
|
src/game/filters/filter_card.cpp
|
||||||
|
src/game/filters/filter_string.cpp
|
||||||
|
src/game/filters/filter_tree.cpp
|
||||||
|
src/game/filters/filter_tree_model.cpp
|
||||||
|
src/game/filters/syntax_help.cpp
|
||||||
|
src/game/game_scene.cpp
|
||||||
|
src/game/game_selector.cpp
|
||||||
|
src/game/game_view.cpp
|
||||||
|
src/game/games_model.cpp
|
||||||
|
src/game/hand_counter.cpp
|
||||||
|
src/game/phase.cpp
|
||||||
|
src/game/player/player.cpp
|
||||||
|
src/game/player/player_list_widget.cpp
|
||||||
|
src/game/player/player_target.cpp
|
||||||
|
src/game/zones/card_zone.cpp
|
||||||
|
src/game/zones/hand_zone.cpp
|
||||||
|
src/game/zones/pile_zone.cpp
|
||||||
|
src/game/zones/select_zone.cpp
|
||||||
|
src/game/zones/stack_zone.cpp
|
||||||
|
src/game/zones/table_zone.cpp
|
||||||
|
src/game/zones/view_zone.cpp
|
||||||
|
src/game/zones/view_zone_widget.cpp
|
||||||
|
src/main.cpp
|
||||||
|
src/server/chat_view/chat_view.cpp
|
||||||
|
src/server/handle_public_servers.cpp
|
||||||
|
src/server/local_client.cpp
|
||||||
|
src/server/local_server.cpp
|
||||||
|
src/server/local_server_interface.cpp
|
||||||
|
src/server/message_log_widget.cpp
|
||||||
|
src/server/pending_command.cpp
|
||||||
|
src/server/remote/remote_client.cpp
|
||||||
|
src/server/remote/remote_decklist_tree_widget.cpp
|
||||||
|
src/server/remote/remote_replay_list_tree_widget.cpp
|
||||||
|
src/server/user/user_context_menu.cpp
|
||||||
|
src/server/user/user_info_box.cpp
|
||||||
|
src/server/user/user_info_connection.cpp
|
||||||
|
src/server/user/user_list_manager.cpp
|
||||||
|
src/server/user/user_list_widget.cpp
|
||||||
|
src/settings/cache_settings.cpp
|
||||||
|
src/settings/card_database_settings.cpp
|
||||||
|
src/settings/card_override_settings.cpp
|
||||||
|
src/settings/debug_settings.cpp
|
||||||
|
src/settings/download_settings.cpp
|
||||||
|
src/settings/game_filters_settings.cpp
|
||||||
|
src/settings/layouts_settings.cpp
|
||||||
|
src/settings/message_settings.cpp
|
||||||
|
src/settings/recents_settings.cpp
|
||||||
|
src/settings/servers_settings.cpp
|
||||||
|
src/settings/settings_manager.cpp
|
||||||
|
src/settings/shortcut_treeview.cpp
|
||||||
|
src/settings/shortcuts_settings.cpp
|
||||||
|
src/utility/card_info_comparator.cpp
|
||||||
|
src/utility/levenshtein.cpp
|
||||||
|
src/utility/logger.cpp
|
||||||
|
src/utility/sequence_edit.cpp
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(sounds)
|
add_subdirectory(sounds)
|
||||||
add_subdirectory(themes)
|
add_subdirectory(themes)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
# servers_settings = false
|
# servers_settings = false
|
||||||
# shortcuts_settings = false
|
# shortcuts_settings = false
|
||||||
|
|
||||||
|
# local_client = false
|
||||||
# remote_client = false
|
# remote_client = false
|
||||||
|
|
||||||
# player = false
|
# player = false
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,13 @@
|
||||||
#include "../../../settings/cache_settings.h"
|
#include "../../../settings/cache_settings.h"
|
||||||
#include "../../../settings/shortcuts_settings.h"
|
#include "../../../settings/shortcuts_settings.h"
|
||||||
|
|
||||||
DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEditor)
|
DeckEditorMenu::DeckEditorMenu(AbstractTabDeckEditor *parent) : QMenu(parent), deckEditor(parent)
|
||||||
: QMenu(parent), deckEditor(_deckEditor)
|
|
||||||
{
|
{
|
||||||
aNewDeck = new QAction(QString(), this);
|
aNewDeck = new QAction(QString(), this);
|
||||||
connect(aNewDeck, SIGNAL(triggered()), deckEditor, SLOT(actNewDeck()));
|
connect(aNewDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actNewDeck);
|
||||||
|
|
||||||
aLoadDeck = new QAction(QString(), this);
|
aLoadDeck = new QAction(QString(), this);
|
||||||
connect(aLoadDeck, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeck()));
|
connect(aLoadDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actLoadDeck);
|
||||||
|
|
||||||
loadRecentDeckMenu = new QMenu(this);
|
loadRecentDeckMenu = new QMenu(this);
|
||||||
connect(&SettingsCache::instance().recents(), &RecentsSettings::recentlyOpenedDeckPathsChanged, this,
|
connect(&SettingsCache::instance().recents(), &RecentsSettings::recentlyOpenedDeckPathsChanged, this,
|
||||||
|
|
@ -22,47 +21,50 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit
|
||||||
updateRecentlyOpened();
|
updateRecentlyOpened();
|
||||||
|
|
||||||
aSaveDeck = new QAction(QString(), this);
|
aSaveDeck = new QAction(QString(), this);
|
||||||
connect(aSaveDeck, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeck()));
|
connect(aSaveDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actSaveDeck);
|
||||||
|
|
||||||
aSaveDeckAs = new QAction(QString(), this);
|
aSaveDeckAs = new QAction(QString(), this);
|
||||||
connect(aSaveDeckAs, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckAs()));
|
connect(aSaveDeckAs, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actSaveDeckAs);
|
||||||
|
|
||||||
aLoadDeckFromClipboard = new QAction(QString(), this);
|
aLoadDeckFromClipboard = new QAction(QString(), this);
|
||||||
connect(aLoadDeckFromClipboard, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeckFromClipboard()));
|
connect(aLoadDeckFromClipboard, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actLoadDeckFromClipboard);
|
||||||
|
|
||||||
aEditDeckInClipboard = new QAction(QString(), this);
|
aEditDeckInClipboard = new QAction(QString(), this);
|
||||||
connect(aEditDeckInClipboard, SIGNAL(triggered()), deckEditor, SLOT(actEditDeckInClipboard()));
|
connect(aEditDeckInClipboard, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actEditDeckInClipboard);
|
||||||
|
|
||||||
aEditDeckInClipboardRaw = new QAction(QString(), this);
|
aEditDeckInClipboardRaw = new QAction(QString(), this);
|
||||||
connect(aEditDeckInClipboardRaw, SIGNAL(triggered()), deckEditor, SLOT(actEditDeckInClipboardRaw()));
|
connect(aEditDeckInClipboardRaw, &QAction::triggered, deckEditor,
|
||||||
|
&AbstractTabDeckEditor::actEditDeckInClipboardRaw);
|
||||||
|
|
||||||
aSaveDeckToClipboard = new QAction(QString(), this);
|
aSaveDeckToClipboard = new QAction(QString(), this);
|
||||||
connect(aSaveDeckToClipboard, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboard()));
|
connect(aSaveDeckToClipboard, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actSaveDeckToClipboard);
|
||||||
|
|
||||||
aSaveDeckToClipboardNoSetInfo = new QAction(QString(), this);
|
aSaveDeckToClipboardNoSetInfo = new QAction(QString(), this);
|
||||||
connect(aSaveDeckToClipboardNoSetInfo, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboardNoSetInfo()));
|
connect(aSaveDeckToClipboardNoSetInfo, &QAction::triggered, deckEditor,
|
||||||
|
&AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo);
|
||||||
|
|
||||||
aSaveDeckToClipboardRaw = new QAction(QString(), this);
|
aSaveDeckToClipboardRaw = new QAction(QString(), this);
|
||||||
connect(aSaveDeckToClipboardRaw, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboardRaw()));
|
connect(aSaveDeckToClipboardRaw, &QAction::triggered, deckEditor,
|
||||||
|
&AbstractTabDeckEditor::actSaveDeckToClipboardRaw);
|
||||||
|
|
||||||
aSaveDeckToClipboardRawNoSetInfo = new QAction(QString(), this);
|
aSaveDeckToClipboardRawNoSetInfo = new QAction(QString(), this);
|
||||||
connect(aSaveDeckToClipboardRawNoSetInfo, SIGNAL(triggered()), deckEditor,
|
connect(aSaveDeckToClipboardRawNoSetInfo, &QAction::triggered, deckEditor,
|
||||||
SLOT(actSaveDeckToClipboardRawNoSetInfo()));
|
&AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo);
|
||||||
|
|
||||||
aPrintDeck = new QAction(QString(), this);
|
aPrintDeck = new QAction(QString(), this);
|
||||||
connect(aPrintDeck, SIGNAL(triggered()), deckEditor, SLOT(actPrintDeck()));
|
connect(aPrintDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actPrintDeck);
|
||||||
|
|
||||||
aExportDeckDecklist = new QAction(QString(), this);
|
aExportDeckDecklist = new QAction(QString(), this);
|
||||||
connect(aExportDeckDecklist, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklist()));
|
connect(aExportDeckDecklist, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actExportDeckDecklist);
|
||||||
|
|
||||||
aExportDeckDecklistXyz = new QAction(QString(), this);
|
aExportDeckDecklistXyz = new QAction(QString(), this);
|
||||||
connect(aExportDeckDecklistXyz, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklistXyz()));
|
connect(aExportDeckDecklistXyz, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actExportDeckDecklistXyz);
|
||||||
|
|
||||||
aAnalyzeDeckDeckstats = new QAction(QString(), this);
|
aAnalyzeDeckDeckstats = new QAction(QString(), this);
|
||||||
connect(aAnalyzeDeckDeckstats, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckDeckstats()));
|
connect(aAnalyzeDeckDeckstats, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actAnalyzeDeckDeckstats);
|
||||||
|
|
||||||
aAnalyzeDeckTappedout = new QAction(QString(), this);
|
aAnalyzeDeckTappedout = new QAction(QString(), this);
|
||||||
connect(aAnalyzeDeckTappedout, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckTappedout()));
|
connect(aAnalyzeDeckTappedout, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actAnalyzeDeckTappedout);
|
||||||
|
|
||||||
analyzeDeckMenu = new QMenu(this);
|
analyzeDeckMenu = new QMenu(this);
|
||||||
analyzeDeckMenu->addAction(aExportDeckDecklist);
|
analyzeDeckMenu->addAction(aExportDeckDecklist);
|
||||||
|
|
@ -103,7 +105,8 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit
|
||||||
addAction(aClose);
|
addAction(aClose);
|
||||||
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||||
|
&DeckEditorMenu::refreshShortcuts);
|
||||||
refreshShortcuts();
|
refreshShortcuts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ class DeckEditorMenu : public QMenu
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *deckEditor);
|
explicit DeckEditorMenu(AbstractTabDeckEditor *parent);
|
||||||
|
|
||||||
AbstractTabDeckEditor *deckEditor;
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPrintPreviewDialog>
|
#include <QPrintPreviewDialog>
|
||||||
|
#include <QPrinter>
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
@ -65,7 +66,8 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
||||||
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
||||||
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
||||||
|
|
||||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||||
|
&AbstractTabDeckEditor::refreshShortcuts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractTabDeckEditor::updateCard(CardInfoPtr _card)
|
void AbstractTabDeckEditor::updateCard(CardInfoPtr _card)
|
||||||
|
|
@ -124,8 +126,13 @@ void AbstractTabDeckEditor::actSwapCard(CardInfoPtr info, QString zoneName)
|
||||||
{
|
{
|
||||||
QString providerId = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("uuid");
|
QString providerId = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("uuid");
|
||||||
QString collectorNumber = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("num");
|
QString collectorNumber = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("num");
|
||||||
deckDockWidget->swapCard(
|
|
||||||
deckDockWidget->deckModel->findCard(info->getName(), zoneName, providerId, collectorNumber));
|
QModelIndex foundCard = deckDockWidget->deckModel->findCard(info->getName(), zoneName, providerId, collectorNumber);
|
||||||
|
if (!foundCard.isValid()) {
|
||||||
|
foundCard = deckDockWidget->deckModel->findCard(info->getName(), zoneName);
|
||||||
|
}
|
||||||
|
|
||||||
|
deckDockWidget->swapCard(foundCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -332,8 +339,7 @@ bool AbstractTabDeckEditor::actSaveDeck()
|
||||||
cmd.set_deck_list(deckString.toStdString());
|
cmd.set_deck_list(deckString.toStdString());
|
||||||
|
|
||||||
PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd);
|
PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &AbstractTabDeckEditor::saveDeckRemoteFinished);
|
||||||
SLOT(saveDeckRemoteFinished(Response)));
|
|
||||||
tabSupervisor->getClient()->sendCommand(pend);
|
tabSupervisor->getClient()->sendCommand(pend);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -357,6 +363,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
|
||||||
dialog.setDefaultSuffix("cod");
|
dialog.setDefaultSuffix("cod");
|
||||||
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);
|
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);
|
||||||
dialog.selectFile(getDeckList()->getName().trimmed());
|
dialog.selectFile(getDeckList()->getName().trimmed());
|
||||||
|
|
||||||
if (!dialog.exec())
|
if (!dialog.exec())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -451,7 +458,7 @@ void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo()
|
||||||
void AbstractTabDeckEditor::actPrintDeck()
|
void AbstractTabDeckEditor::actPrintDeck()
|
||||||
{
|
{
|
||||||
auto *dlg = new QPrintPreviewDialog(this);
|
auto *dlg = new QPrintPreviewDialog(this);
|
||||||
connect(dlg, SIGNAL(paintRequested(QPrinter *)), deckDockWidget->deckModel, SLOT(printDeckList(QPrinter *)));
|
connect(dlg, &QPrintPreviewDialog::paintRequested, deckDockWidget->deckModel, &DeckListModel::printDeckList);
|
||||||
dlg->exec();
|
dlg->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
||||||
#define TAB_GENERIC_DECK_EDITOR_H
|
#define TAB_GENERIC_DECK_EDITOR_H
|
||||||
|
|
||||||
#include "../../game/cards/card_database.h"
|
#include "../../game/cards/card_info.h"
|
||||||
#include "../menus/deck_editor/deck_editor_menu.h"
|
#include "../menus/deck_editor/deck_editor_menu.h"
|
||||||
#include "../ui/widgets/deck_editor/deck_editor_card_info_dock_widget.h"
|
#include "../ui/widgets/deck_editor/deck_editor_card_info_dock_widget.h"
|
||||||
#include "../ui/widgets/deck_editor/deck_editor_database_display_widget.h"
|
#include "../ui/widgets/deck_editor/deck_editor_database_display_widget.h"
|
||||||
|
|
@ -44,6 +44,8 @@ class AbstractTabDeckEditor : public Tab
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
friend class DeckEditorMenu;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||||
|
|
||||||
|
|
@ -67,7 +69,7 @@ public:
|
||||||
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget;
|
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onDeckChanged();
|
virtual void onDeckChanged();
|
||||||
void updateCard(CardInfoPtr _card);
|
void updateCard(CardInfoPtr _card);
|
||||||
void actAddCard(CardInfoPtr info);
|
void actAddCard(CardInfoPtr info);
|
||||||
void actAddCardToSideboard(CardInfoPtr info);
|
void actAddCardToSideboard(CardInfoPtr info);
|
||||||
|
|
@ -90,7 +92,7 @@ protected slots:
|
||||||
void cleanDeckAndResetModified();
|
void cleanDeckAndResetModified();
|
||||||
virtual void actLoadDeck();
|
virtual void actLoadDeck();
|
||||||
bool actSaveDeck();
|
bool actSaveDeck();
|
||||||
bool actSaveDeckAs();
|
virtual bool actSaveDeckAs();
|
||||||
virtual void actLoadDeckFromClipboard();
|
virtual void actLoadDeckFromClipboard();
|
||||||
void actEditDeckInClipboard();
|
void actEditDeckInClipboard();
|
||||||
void actEditDeckInClipboardRaw();
|
void actEditDeckInClipboardRaw();
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
#include "edhrec_commander_api_response_archidekt_links.h"
|
#include "edhrec_api_response_archidekt_links.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseArchidektLink::fromJson(const QJsonObject &json)
|
void EdhrecApiResponseArchidektLink::fromJson(const QJsonObject &json)
|
||||||
{
|
{
|
||||||
c = json.value("c").toString();
|
c = json.value("c").toString();
|
||||||
f = json.value("f").toInt(0);
|
f = json.value("f").toInt(0);
|
||||||
|
|
@ -13,7 +13,7 @@ void EdhrecCommanderApiResponseArchidektLink::fromJson(const QJsonObject &json)
|
||||||
u = json.value("u").toString();
|
u = json.value("u").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseArchidektLink::debugPrint() const
|
void EdhrecApiResponseArchidektLink::debugPrint() const
|
||||||
{
|
{
|
||||||
qDebug() << " C:" << c;
|
qDebug() << " C:" << c;
|
||||||
qDebug() << " F:" << f;
|
qDebug() << " F:" << f;
|
||||||
|
|
@ -27,7 +27,7 @@ void EdhrecCommanderApiResponseArchidektLinks::fromJson(const QJsonArray &json)
|
||||||
for (const QJsonValue &value : json) {
|
for (const QJsonValue &value : json) {
|
||||||
if (value.isObject()) {
|
if (value.isObject()) {
|
||||||
QJsonObject entryJson = value.toObject();
|
QJsonObject entryJson = value.toObject();
|
||||||
EdhrecCommanderApiResponseArchidektLink entry;
|
EdhrecApiResponseArchidektLink entry;
|
||||||
entry.fromJson(entryJson);
|
entry.fromJson(entryJson);
|
||||||
entries.append(entry);
|
entries.append(entry);
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
// Represents a single Archidekt entry
|
// Represents a single Archidekt entry
|
||||||
class EdhrecCommanderApiResponseArchidektLink
|
class EdhrecApiResponseArchidektLink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString c;
|
QString c;
|
||||||
|
|
@ -23,7 +23,7 @@ public:
|
||||||
class EdhrecCommanderApiResponseArchidektLinks
|
class EdhrecCommanderApiResponseArchidektLinks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QVector<EdhrecCommanderApiResponseArchidektLink> entries;
|
QVector<EdhrecApiResponseArchidektLink> entries;
|
||||||
|
|
||||||
void fromJson(const QJsonArray &json);
|
void fromJson(const QJsonArray &json);
|
||||||
void debugPrint() const;
|
void debugPrint() const;
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "edhrec_average_deck_api_response.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
void EdhrecAverageDeckApiResponse::fromJson(const QJsonObject &json)
|
||||||
|
{
|
||||||
|
// Parse the collapsed DeckStatistics
|
||||||
|
deckStats.fromJson(json);
|
||||||
|
|
||||||
|
// Parse Archidekt section
|
||||||
|
QJsonArray archidektJson = json.value("archidekt").toArray();
|
||||||
|
archidekt.fromJson(archidektJson);
|
||||||
|
|
||||||
|
// Parse other fields
|
||||||
|
similar = json.value("similar").toObject();
|
||||||
|
header = json.value("header").toString();
|
||||||
|
panels = json.value("panels").toObject();
|
||||||
|
description = json.value("description").toString();
|
||||||
|
QJsonObject containerJson = json.value("container").toObject();
|
||||||
|
container.fromJson(containerJson);
|
||||||
|
QJsonArray cardsJson = json.value("deck").toArray();
|
||||||
|
deck.fromJson(cardsJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecAverageDeckApiResponse::debugPrint() const
|
||||||
|
{
|
||||||
|
qDebug() << "Deck Statistics:";
|
||||||
|
qDebug() << " Creature:" << deckStats.creature;
|
||||||
|
qDebug() << " Instant:" << deckStats.instant;
|
||||||
|
qDebug() << " Sorcery:" << deckStats.sorcery;
|
||||||
|
qDebug() << " Artifact:" << deckStats.artifact;
|
||||||
|
qDebug() << " Enchantment:" << deckStats.enchantment;
|
||||||
|
qDebug() << " Battle:" << deckStats.battle;
|
||||||
|
qDebug() << " Planeswalker:" << deckStats.planeswalker;
|
||||||
|
qDebug() << " Land:" << deckStats.land;
|
||||||
|
qDebug() << " Basic:" << deckStats.basic;
|
||||||
|
qDebug() << " Nonbasic:" << deckStats.nonbasic;
|
||||||
|
|
||||||
|
archidekt.debugPrint();
|
||||||
|
|
||||||
|
qDebug() << "Similar:" << similar;
|
||||||
|
qDebug() << "Header:" << header;
|
||||||
|
qDebug() << "Panels:" << panels;
|
||||||
|
qDebug() << "Description:" << description;
|
||||||
|
container.debugPrint();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef EDHREC_AVERAGE_DECK_API_RESPONSE_H
|
||||||
|
#define EDHREC_AVERAGE_DECK_API_RESPONSE_H
|
||||||
|
|
||||||
|
#include "../archidekt_links/edhrec_api_response_archidekt_links.h"
|
||||||
|
#include "../cards/edhrec_api_response_card_container.h"
|
||||||
|
#include "../commander/edhrec_commander_api_response_average_deck_statistics.h"
|
||||||
|
#include "edhrec_deck_api_response.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
// Represents the main structure of the JSON
|
||||||
|
class EdhrecAverageDeckApiResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EdhrecCommanderApiResponseAverageDeckStatistics deckStats;
|
||||||
|
EdhrecCommanderApiResponseArchidektLinks archidekt;
|
||||||
|
QJsonObject similar;
|
||||||
|
QString header;
|
||||||
|
QJsonObject panels;
|
||||||
|
QString description;
|
||||||
|
EdhrecApiResponseCardContainer container;
|
||||||
|
EdhrecDeckApiResponse deck;
|
||||||
|
|
||||||
|
void fromJson(const QJsonObject &json);
|
||||||
|
void debugPrint() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_AVERAGE_DECK_API_RESPONSE_H
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "edhrec_deck_api_response.h"
|
||||||
|
|
||||||
|
#include "../../../../../../deck/deck_loader.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
void EdhrecDeckApiResponse::fromJson(const QJsonArray &json)
|
||||||
|
{
|
||||||
|
QString deckList;
|
||||||
|
for (const QJsonValue &cardlistValue : json) {
|
||||||
|
deckList += cardlistValue.toString() + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
deckLoader = new DeckLoader();
|
||||||
|
|
||||||
|
QTextStream stream(&deckList);
|
||||||
|
deckLoader->loadFromStream_Plain(stream, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecDeckApiResponse::debugPrint() const
|
||||||
|
{
|
||||||
|
qDebug() << "Breadcrumb:";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef EDHREC_DECK_API_RESPONSE_H
|
||||||
|
#define EDHREC_DECK_API_RESPONSE_H
|
||||||
|
|
||||||
|
#include "../../../../../../deck/deck_loader.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
class EdhrecDeckApiResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
EdhrecDeckApiResponse() = default;
|
||||||
|
|
||||||
|
// Parse deck-related data from JSON
|
||||||
|
void fromJson(const QJsonArray &json);
|
||||||
|
|
||||||
|
// Debug method for logging
|
||||||
|
void debugPrint() const;
|
||||||
|
|
||||||
|
DeckLoader *deckLoader;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_DECK_API_RESPONSE_H
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include "edhrec_commander_api_response_card_prices.h"
|
#include "edhrec_api_response_card_prices.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
@ -18,14 +18,14 @@ void CardPrices::fromJson(const QJsonObject &json)
|
||||||
|
|
||||||
void CardPrices::debugPrint() const
|
void CardPrices::debugPrint() const
|
||||||
{
|
{
|
||||||
qDebug() << "Card Prices:";
|
qInfo() << "Card Prices:";
|
||||||
qDebug() << "Cardhoarder:" << cardhoarder;
|
qInfo() << "Cardhoarder:" << cardhoarder;
|
||||||
qDebug() << "Cardkingdom:" << cardkingdom;
|
qInfo() << "Cardkingdom:" << cardkingdom;
|
||||||
qDebug() << "Cardmarket:" << cardmarket;
|
qInfo() << "Cardmarket:" << cardmarket;
|
||||||
qDebug() << "Face2Face:" << face2face;
|
qInfo() << "Face2Face:" << face2face;
|
||||||
qDebug() << "Manapool:" << manapool;
|
qInfo() << "Manapool:" << manapool;
|
||||||
qDebug() << "Mtgstocks:" << mtgstocks;
|
qInfo() << "Mtgstocks:" << mtgstocks;
|
||||||
qDebug() << "SCG:" << scg;
|
qInfo() << "SCG:" << scg;
|
||||||
qDebug() << "TCGL:" << tcgl;
|
qInfo() << "TCGL:" << tcgl;
|
||||||
qDebug() << "Tcgplayer:" << tcgplayer;
|
qInfo() << "Tcgplayer:" << tcgplayer;
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#include "edhrec_commander_api_response_card_container.h"
|
#include "edhrec_api_response_card_container.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseCardContainer::fromJson(const QJsonObject &json)
|
void EdhrecApiResponseCardContainer::fromJson(const QJsonObject &json)
|
||||||
{
|
{
|
||||||
// Parse breadcrumb
|
// Parse breadcrumb
|
||||||
QJsonArray breadcrumbArray = json.value("breadcrumb").toArray();
|
QJsonArray breadcrumbArray = json.value("breadcrumb").toArray();
|
||||||
|
|
@ -20,7 +20,7 @@ void EdhrecCommanderApiResponseCardContainer::fromJson(const QJsonObject &json)
|
||||||
for (const QJsonValue &cardlistValue : cardlistsArray) {
|
for (const QJsonValue &cardlistValue : cardlistsArray) {
|
||||||
QJsonObject cardlistObj = cardlistValue.toObject();
|
QJsonObject cardlistObj = cardlistValue.toObject();
|
||||||
QJsonArray cardviewsArray = cardlistObj.value("cardviews").toArray();
|
QJsonArray cardviewsArray = cardlistObj.value("cardviews").toArray();
|
||||||
EdhrecCommanderApiResponseCardList cardView;
|
EdhrecApiResponseCardList cardView;
|
||||||
cardView.fromJson(cardlistValue.toObject());
|
cardView.fromJson(cardlistValue.toObject());
|
||||||
cardlists.push_back(cardView);
|
cardlists.push_back(cardView);
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ void EdhrecCommanderApiResponseCardContainer::fromJson(const QJsonObject &json)
|
||||||
title = json.value("title").toString();
|
title = json.value("title").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseCardContainer::debugPrint() const
|
void EdhrecApiResponseCardContainer::debugPrint() const
|
||||||
{
|
{
|
||||||
qDebug() << "Breadcrumb:";
|
qDebug() << "Breadcrumb:";
|
||||||
for (const auto &breadcrumbEntry : breadcrumb) {
|
for (const auto &breadcrumbEntry : breadcrumb) {
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef CONTAINER_ENTRY_H
|
#ifndef CONTAINER_ENTRY_H
|
||||||
#define CONTAINER_ENTRY_H
|
#define CONTAINER_ENTRY_H
|
||||||
|
|
||||||
#include "edhrec_commander_api_response_card_list.h"
|
#include "edhrec_api_response_card_list.h"
|
||||||
#include "edhrec_commander_api_response_commander_details.h"
|
#include "edhrec_commander_api_response_commander_details.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
@ -10,11 +10,11 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
class EdhrecCommanderApiResponseCardContainer
|
class EdhrecApiResponseCardContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
EdhrecCommanderApiResponseCardContainer() = default;
|
EdhrecApiResponseCardContainer() = default;
|
||||||
|
|
||||||
// Parse deck-related data from JSON
|
// Parse deck-related data from JSON
|
||||||
void fromJson(const QJsonObject &json);
|
void fromJson(const QJsonObject &json);
|
||||||
|
|
@ -35,7 +35,7 @@ public:
|
||||||
{
|
{
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
const QVector<EdhrecCommanderApiResponseCardList> &getCardlists() const
|
const QVector<EdhrecApiResponseCardList> &getCardlists() const
|
||||||
{
|
{
|
||||||
return cardlists;
|
return cardlists;
|
||||||
}
|
}
|
||||||
|
|
@ -52,7 +52,7 @@ private:
|
||||||
QString description;
|
QString description;
|
||||||
QVector<QJsonObject> breadcrumb;
|
QVector<QJsonObject> breadcrumb;
|
||||||
EdhrecCommanderApiResponseCommanderDetails card;
|
EdhrecCommanderApiResponseCommanderDetails card;
|
||||||
QVector<EdhrecCommanderApiResponseCardList> cardlists;
|
QVector<EdhrecApiResponseCardList> cardlists;
|
||||||
QString keywords;
|
QString keywords;
|
||||||
QString title;
|
QString title;
|
||||||
};
|
};
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
#include "edhrec_commander_api_response_card_details.h"
|
#include "edhrec_api_response_card_details.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
EdhrecCommanderApiResponseCardDetails::EdhrecCommanderApiResponseCardDetails()
|
EdhrecApiResponseCardDetails::EdhrecApiResponseCardDetails()
|
||||||
: synergy(0.0), inclusion(0), numDecks(0), potentialDecks(0)
|
: synergy(0.0), inclusion(0), numDecks(0), potentialDecks(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseCardDetails::fromJson(const QJsonObject &json)
|
void EdhrecApiResponseCardDetails::fromJson(const QJsonObject &json)
|
||||||
{
|
{
|
||||||
// Parse the fields from the JSON object
|
// Parse the fields from the JSON object
|
||||||
name = json.value("name").toString();
|
name = json.value("name").toString();
|
||||||
|
|
@ -21,7 +21,7 @@ void EdhrecCommanderApiResponseCardDetails::fromJson(const QJsonObject &json)
|
||||||
potentialDecks = json.value("potential_decks").toInt(0);
|
potentialDecks = json.value("potential_decks").toInt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseCardDetails::debugPrint() const
|
void EdhrecApiResponseCardDetails::debugPrint() const
|
||||||
{
|
{
|
||||||
// Print out all the fields for debugging
|
// Print out all the fields for debugging
|
||||||
qDebug() << "Name:" << name;
|
qDebug() << "Name:" << name;
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class EdhrecCommanderApiResponseCardDetails
|
class EdhrecApiResponseCardDetails
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString name;
|
QString name;
|
||||||
|
|
@ -17,7 +17,7 @@ public:
|
||||||
int numDecks;
|
int numDecks;
|
||||||
int potentialDecks;
|
int potentialDecks;
|
||||||
|
|
||||||
EdhrecCommanderApiResponseCardDetails();
|
EdhrecApiResponseCardDetails();
|
||||||
|
|
||||||
// Method to populate the object from a JSON object
|
// Method to populate the object from a JSON object
|
||||||
void fromJson(const QJsonObject &json);
|
void fromJson(const QJsonObject &json);
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
#include "edhrec_commander_api_response_card_list.h"
|
#include "edhrec_api_response_card_list.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
EdhrecCommanderApiResponseCardList::EdhrecCommanderApiResponseCardList()
|
EdhrecApiResponseCardList::EdhrecApiResponseCardList()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseCardList::fromJson(const QJsonObject &json)
|
void EdhrecApiResponseCardList::fromJson(const QJsonObject &json)
|
||||||
{
|
{
|
||||||
// Parse the header from the JSON object
|
// Parse the header from the JSON object
|
||||||
header = json.value("header").toString();
|
header = json.value("header").toString();
|
||||||
|
|
@ -15,19 +15,19 @@ void EdhrecCommanderApiResponseCardList::fromJson(const QJsonObject &json)
|
||||||
QJsonArray cardviewsArray = json.value("cardviews").toArray();
|
QJsonArray cardviewsArray = json.value("cardviews").toArray();
|
||||||
for (const QJsonValue &value : cardviewsArray) {
|
for (const QJsonValue &value : cardviewsArray) {
|
||||||
QJsonObject cardviewObj = value.toObject();
|
QJsonObject cardviewObj = value.toObject();
|
||||||
EdhrecCommanderApiResponseCardDetails cardView;
|
EdhrecApiResponseCardDetails cardView;
|
||||||
cardView.fromJson(cardviewObj);
|
cardView.fromJson(cardviewObj);
|
||||||
cardViews.append(cardView);
|
cardViews.append(cardView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseCardList::debugPrint() const
|
void EdhrecApiResponseCardList::debugPrint() const
|
||||||
{
|
{
|
||||||
// Print out the header
|
// Print out the header
|
||||||
qDebug() << "Header:" << header;
|
qDebug() << "Header:" << header;
|
||||||
|
|
||||||
// Print out all the CardView objects
|
// Print out all the CardView objects
|
||||||
for (const EdhrecCommanderApiResponseCardDetails &cardView : cardViews) {
|
for (const EdhrecApiResponseCardDetails &cardView : cardViews) {
|
||||||
cardView.debugPrint();
|
cardView.debugPrint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
#ifndef CARD_LIST_H
|
#ifndef CARD_LIST_H
|
||||||
#define CARD_LIST_H
|
#define CARD_LIST_H
|
||||||
|
|
||||||
#include "edhrec_commander_api_response_card_details.h"
|
#include "edhrec_api_response_card_details.h"
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class EdhrecCommanderApiResponseCardList
|
class EdhrecApiResponseCardList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString header;
|
QString header;
|
||||||
QList<EdhrecCommanderApiResponseCardDetails> cardViews;
|
QList<EdhrecApiResponseCardDetails> cardViews;
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
EdhrecCommanderApiResponseCardList();
|
EdhrecApiResponseCardList();
|
||||||
|
|
||||||
// Method to populate the object from a JSON object
|
// Method to populate the object from a JSON object
|
||||||
void fromJson(const QJsonObject &json);
|
void fromJson(const QJsonObject &json);
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
|
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
|
||||||
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
|
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
|
||||||
|
|
||||||
#include "edhrec_commander_api_response_card_prices.h"
|
#include "../card_prices/edhrec_api_response_card_prices.h"
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#ifndef DECKDATA_H
|
#ifndef DECKDATA_H
|
||||||
#define DECKDATA_H
|
#define DECKDATA_H
|
||||||
|
|
||||||
#include "edhrec_commander_api_response_archidekt_links.h"
|
#include "../archidekt_links//edhrec_api_response_archidekt_links.h"
|
||||||
|
#include "../cards/edhrec_api_response_card_container.h"
|
||||||
#include "edhrec_commander_api_response_average_deck_statistics.h"
|
#include "edhrec_commander_api_response_average_deck_statistics.h"
|
||||||
#include "edhrec_commander_api_response_card_container.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
@ -19,7 +19,7 @@ public:
|
||||||
QString header;
|
QString header;
|
||||||
QJsonObject panels;
|
QJsonObject panels;
|
||||||
QString description;
|
QString description;
|
||||||
EdhrecCommanderApiResponseCardContainer container;
|
EdhrecApiResponseCardContainer container;
|
||||||
|
|
||||||
void fromJson(const QJsonObject &json);
|
void fromJson(const QJsonObject &json);
|
||||||
void debugPrint() const;
|
void debugPrint() const;
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "edhrec_top_cards_api_response.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
void EdhrecTopCardsApiResponse::fromJson(const QJsonObject &json)
|
||||||
|
{
|
||||||
|
header = json.value("header").toString();
|
||||||
|
description = json.value("description").toString();
|
||||||
|
QJsonObject containerJson = json.value("container").toObject();
|
||||||
|
container.fromJson(containerJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecTopCardsApiResponse::debugPrint() const
|
||||||
|
{
|
||||||
|
qDebug() << "Header:" << header;
|
||||||
|
qDebug() << "Description:" << description;
|
||||||
|
container.debugPrint();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef EDHREC_TOP_CARDS_API_RESPONSE_H
|
||||||
|
#define EDHREC_TOP_CARDS_API_RESPONSE_H
|
||||||
|
|
||||||
|
#include "../cards/edhrec_api_response_card_container.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class EdhrecTopCardsApiResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString header;
|
||||||
|
QString description;
|
||||||
|
EdhrecApiResponseCardContainer container;
|
||||||
|
|
||||||
|
void fromJson(const QJsonObject &json);
|
||||||
|
void debugPrint() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_TOP_CARDS_API_RESPONSE_H
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "edhrec_top_commanders_api_response.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
void EdhrecTopCommandersApiResponse::fromJson(const QJsonObject &json)
|
||||||
|
{
|
||||||
|
header = json.value("header").toString();
|
||||||
|
description = json.value("description").toString();
|
||||||
|
QJsonObject containerJson = json.value("container").toObject();
|
||||||
|
container.fromJson(containerJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecTopCommandersApiResponse::debugPrint() const
|
||||||
|
{
|
||||||
|
qDebug() << "Header:" << header;
|
||||||
|
qDebug() << "Description:" << description;
|
||||||
|
container.debugPrint();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef EDHREC_TOP_COMMANDERS_API_RESPONSE_H
|
||||||
|
#define EDHREC_TOP_COMMANDERS_API_RESPONSE_H
|
||||||
|
|
||||||
|
#include "../cards/edhrec_api_response_card_container.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class EdhrecTopCommandersApiResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString header;
|
||||||
|
QString description;
|
||||||
|
EdhrecApiResponseCardContainer container;
|
||||||
|
|
||||||
|
void fromJson(const QJsonObject &json);
|
||||||
|
void debugPrint() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_TOP_COMMANDERS_API_RESPONSE_H
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "edhrec_top_tags_api_response.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
void EdhrecTopTagsApiResponse::fromJson(const QJsonObject &json)
|
||||||
|
{
|
||||||
|
header = json.value("header").toString();
|
||||||
|
description = json.value("description").toString();
|
||||||
|
QJsonObject containerJson = json.value("container").toObject();
|
||||||
|
container.fromJson(containerJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecTopTagsApiResponse::debugPrint() const
|
||||||
|
{
|
||||||
|
qDebug() << "Header:" << header;
|
||||||
|
qDebug() << "Description:" << description;
|
||||||
|
container.debugPrint();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef EDHREC_TOP_TAGS_API_RESPONSE_H
|
||||||
|
#define EDHREC_TOP_TAGS_API_RESPONSE_H
|
||||||
|
|
||||||
|
#include "../cards/edhrec_api_response_card_container.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class EdhrecTopTagsApiResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString header;
|
||||||
|
QString description;
|
||||||
|
EdhrecApiResponseCardContainer container;
|
||||||
|
|
||||||
|
void fromJson(const QJsonObject &json);
|
||||||
|
void debugPrint() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_TOP_TAGS_API_RESPONSE_H
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "edhrec_api_response_card_prices_display_widget.h"
|
||||||
|
|
||||||
|
EdhrecApiResponseCardPricesDisplayWidget::EdhrecApiResponseCardPricesDisplayWidget(QWidget *parent,
|
||||||
|
const CardPrices &_cardPrices)
|
||||||
|
: QWidget(parent), cardPrices(_cardPrices)
|
||||||
|
{
|
||||||
|
layout = new QGridLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
cardHoarderLabel = new QLabel(this);
|
||||||
|
cardHoarderPrice = new QLabel(QString::number(cardPrices.getCardhoarder().value("price").toDouble()), this);
|
||||||
|
cardKingdomLabel = new QLabel(this);
|
||||||
|
cardKingdomPrice = new QLabel(QString::number(cardPrices.getCardkingdom().value("price").toDouble()), this);
|
||||||
|
cardMarketLabel = new QLabel(this);
|
||||||
|
cardMarketPrice = new QLabel(QString::number(cardPrices.getCardmarket().value("price").toDouble()), this);
|
||||||
|
face2faceLabel = new QLabel(this);
|
||||||
|
face2facePrice = new QLabel(QString::number(cardPrices.getFace2face().value("price").toDouble()), this);
|
||||||
|
manaPoolLabel = new QLabel(this);
|
||||||
|
manaPoolPrice = new QLabel(QString::number(cardPrices.getManapool().value("price").toDouble()), this);
|
||||||
|
mtgStocksLabel = new QLabel(this);
|
||||||
|
mtgStocksPrice = new QLabel(QString::number(cardPrices.getMtgstocks().value("price").toDouble()), this);
|
||||||
|
scgLabel = new QLabel(this);
|
||||||
|
scgPrice = new QLabel(QString::number(cardPrices.getScg().value("price").toDouble()), this);
|
||||||
|
tcglLabel = new QLabel(this);
|
||||||
|
tcglPrice = new QLabel(QString::number(cardPrices.getTcgl().value("price").toDouble()), this);
|
||||||
|
tcgplayerLabel = new QLabel(this);
|
||||||
|
tcgplayerPrice = new QLabel(QString::number(cardPrices.getTcgplayer().value("price").toDouble()), this);
|
||||||
|
|
||||||
|
layout->addWidget(cardHoarderLabel, 0, 0);
|
||||||
|
layout->addWidget(cardHoarderPrice, 0, 1);
|
||||||
|
layout->addWidget(cardKingdomLabel, 0, 2);
|
||||||
|
layout->addWidget(cardKingdomPrice, 0, 3);
|
||||||
|
|
||||||
|
layout->addWidget(cardMarketLabel, 1, 0);
|
||||||
|
layout->addWidget(cardMarketPrice, 1, 1);
|
||||||
|
layout->addWidget(face2faceLabel, 1, 2);
|
||||||
|
layout->addWidget(face2facePrice, 1, 3);
|
||||||
|
|
||||||
|
layout->addWidget(manaPoolLabel, 2, 0);
|
||||||
|
layout->addWidget(manaPoolPrice, 2, 1);
|
||||||
|
layout->addWidget(mtgStocksLabel, 2, 2);
|
||||||
|
layout->addWidget(mtgStocksPrice, 2, 3);
|
||||||
|
|
||||||
|
layout->addWidget(scgLabel, 3, 0);
|
||||||
|
layout->addWidget(scgPrice, 3, 1);
|
||||||
|
layout->addWidget(tcglLabel, 3, 2);
|
||||||
|
layout->addWidget(tcglPrice, 3, 3);
|
||||||
|
|
||||||
|
layout->addWidget(tcgplayerLabel, 4, 0);
|
||||||
|
layout->addWidget(tcgplayerPrice, 4, 1);
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecApiResponseCardPricesDisplayWidget::retranslateUi()
|
||||||
|
{
|
||||||
|
cardHoarderLabel->setText(tr("Card Hoarder"));
|
||||||
|
cardKingdomLabel->setText(tr("Card Kingdom"));
|
||||||
|
cardMarketLabel->setText(tr("Card Market"));
|
||||||
|
face2faceLabel->setText(tr("Face 2-Face"));
|
||||||
|
manaPoolLabel->setText(tr("Mana Pool"));
|
||||||
|
mtgStocksLabel->setText(tr("MTG Stocks"));
|
||||||
|
scgLabel->setText(tr("Scg"));
|
||||||
|
tcglLabel->setText(tr("Tcgl"));
|
||||||
|
tcgplayerLabel->setText(tr("Tcgplayer"));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef EDHREC_API_RESPONSE_CARD_PRICES_DISPLAY_WIDGET_H
|
||||||
|
#define EDHREC_API_RESPONSE_CARD_PRICES_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../api_response/card_prices/edhrec_api_response_card_prices.h"
|
||||||
|
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class EdhrecApiResponseCardPricesDisplayWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
EdhrecApiResponseCardPricesDisplayWidget(QWidget *parent, const CardPrices &cardPrices);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void retranslateUi();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CardPrices cardPrices;
|
||||||
|
QGridLayout *layout;
|
||||||
|
QLabel *cardHoarderLabel;
|
||||||
|
QLabel *cardHoarderPrice;
|
||||||
|
QLabel *cardKingdomLabel;
|
||||||
|
QLabel *cardKingdomPrice;
|
||||||
|
QLabel *cardMarketLabel;
|
||||||
|
QLabel *cardMarketPrice;
|
||||||
|
QLabel *face2faceLabel;
|
||||||
|
QLabel *face2facePrice;
|
||||||
|
QLabel *manaPoolLabel;
|
||||||
|
QLabel *manaPoolPrice;
|
||||||
|
QLabel *mtgStocksLabel;
|
||||||
|
QLabel *mtgStocksPrice;
|
||||||
|
QLabel *scgLabel;
|
||||||
|
QLabel *scgPrice;
|
||||||
|
QLabel *tcglLabel;
|
||||||
|
QLabel *tcglPrice;
|
||||||
|
QLabel *tcgplayerLabel;
|
||||||
|
QLabel *tcgplayerPrice;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_API_RESPONSE_CARD_PRICES_DISPLAY_WIDGET_H
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include "edhrec_api_response_card_details_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../tab_edhrec_main.h"
|
||||||
|
|
||||||
|
EdhrecApiResponseCardDetailsDisplayWidget::EdhrecApiResponseCardDetailsDisplayWidget(
|
||||||
|
QWidget *parent,
|
||||||
|
const EdhrecApiResponseCardDetails &_toDisplay)
|
||||||
|
: QWidget(parent), toDisplay(_toDisplay)
|
||||||
|
{
|
||||||
|
layout = new QVBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
cardPictureWidget = new CardInfoPictureWidget(this);
|
||||||
|
cardPictureWidget->setCard(CardDatabaseManager::getInstance()->guessCard(toDisplay.sanitized));
|
||||||
|
|
||||||
|
label = new QLabel(this);
|
||||||
|
label->setText(toDisplay.name + "\n" + toDisplay.label);
|
||||||
|
label->setAlignment(Qt::AlignHCenter);
|
||||||
|
|
||||||
|
int inclusionRate = 0;
|
||||||
|
// Set label color based on inclusion rate
|
||||||
|
if (toDisplay.potentialDecks != 0) {
|
||||||
|
inclusionRate = (toDisplay.numDecks * 100) / toDisplay.potentialDecks;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor labelColor;
|
||||||
|
if (inclusionRate <= 30) {
|
||||||
|
labelColor = QColor(255, 0, 0); // Red
|
||||||
|
} else if (inclusionRate <= 60) {
|
||||||
|
int red = 255 - ((inclusionRate - 30) * 2);
|
||||||
|
int green = (inclusionRate - 30) * 4; // Adjust green to make the transition smoother
|
||||||
|
labelColor = QColor(red, green, 0); // purple-ish
|
||||||
|
} else if (inclusionRate <= 90) {
|
||||||
|
int green = (inclusionRate - 60) * 5; // Increase green
|
||||||
|
labelColor = QColor(100, green, 100); // Green shades
|
||||||
|
} else {
|
||||||
|
labelColor = QColor(100, 200, 100); // Dark Green
|
||||||
|
}
|
||||||
|
|
||||||
|
label->setStyleSheet(QString("color: %1").arg(labelColor.name()));
|
||||||
|
|
||||||
|
layout->addWidget(cardPictureWidget);
|
||||||
|
layout->addWidget(label);
|
||||||
|
|
||||||
|
QWidget *currentParent = parentWidget();
|
||||||
|
TabEdhRecMain *parentTab = nullptr;
|
||||||
|
|
||||||
|
while (currentParent) {
|
||||||
|
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentParent = currentParent->parentWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parentTab) {
|
||||||
|
connect(cardPictureWidget, &CardInfoPictureWidget::cardClicked, this,
|
||||||
|
&EdhrecApiResponseCardDetailsDisplayWidget::actRequestPageNavigation);
|
||||||
|
connect(this, &EdhrecApiResponseCardDetailsDisplayWidget::requestUrl, parentTab,
|
||||||
|
&TabEdhRecMain::actNavigatePage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecApiResponseCardDetailsDisplayWidget::actRequestPageNavigation()
|
||||||
|
{
|
||||||
|
emit requestUrl(toDisplay.url);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||||
|
#define EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||||
|
#include "../../api_response/cards/edhrec_api_response_card_details.h"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class EdhrecApiResponseCardDetailsDisplayWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit EdhrecApiResponseCardDetailsDisplayWidget(QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay);
|
||||||
|
public slots:
|
||||||
|
void actRequestPageNavigation();
|
||||||
|
signals:
|
||||||
|
void requestUrl(QString url);
|
||||||
|
|
||||||
|
private:
|
||||||
|
EdhrecApiResponseCardDetails toDisplay;
|
||||||
|
QVBoxLayout *layout;
|
||||||
|
CardInfoPictureWidget *cardPictureWidget;
|
||||||
|
QLabel *label;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "edhrec_api_response_card_list_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../../ui/widgets/general/display/banner_widget.h"
|
||||||
|
#include "edhrec_api_response_card_details_display_widget.h"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
EdhrecApiResponseCardListDisplayWidget::EdhrecApiResponseCardListDisplayWidget(QWidget *parent,
|
||||||
|
EdhrecApiResponseCardList toDisplay)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
layout = new QVBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
header = new BannerWidget(this, toDisplay.header);
|
||||||
|
|
||||||
|
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
|
||||||
|
header->setBuddy(flowWidget);
|
||||||
|
|
||||||
|
foreach (EdhrecApiResponseCardDetails card_detail, toDisplay.cardViews) {
|
||||||
|
auto widget = new EdhrecApiResponseCardDetailsDisplayWidget(flowWidget, card_detail);
|
||||||
|
flowWidget->addWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->addWidget(header);
|
||||||
|
layout->addWidget(flowWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecApiResponseCardListDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
qDebug() << event->size();
|
||||||
|
}
|
||||||
|
|
@ -1,20 +1,19 @@
|
||||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
||||||
#define EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
#define EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
#include "../../../ui/widgets/general/display/banner_widget.h"
|
#include "../../../../../ui/widgets/general/display/banner_widget.h"
|
||||||
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
#include "../../../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||||
#include "api_response/edhrec_commander_api_response_card_list.h"
|
#include "../../api_response/cards/edhrec_api_response_card_list.h"
|
||||||
|
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class EdhrecCommanderApiResponseCardListDisplayWidget : public QWidget
|
class EdhrecApiResponseCardListDisplayWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit EdhrecCommanderApiResponseCardListDisplayWidget(QWidget *parent,
|
explicit EdhrecApiResponseCardListDisplayWidget(QWidget *parent, EdhrecApiResponseCardList toDisplay);
|
||||||
EdhrecCommanderApiResponseCardList toDisplay);
|
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
[[nodiscard]] QString getBannerText() const
|
[[nodiscard]] QString getBannerText() const
|
||||||
{
|
{
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
#include "edhrec_commander_api_response_commander_details_display_widget.h"
|
#include "edhrec_api_response_commander_details_display_widget.h"
|
||||||
|
|
||||||
#include "../../../../game/cards/card_database_manager.h"
|
#include "../../../../../../game/cards/card_database_manager.h"
|
||||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||||
|
#include "../card_prices/edhrec_api_response_card_prices_display_widget.h"
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails)
|
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
|
||||||
|
QString baseUrl)
|
||||||
: QWidget(parent), commanderDetails(_commanderDetails)
|
: QWidget(parent), commanderDetails(_commanderDetails)
|
||||||
{
|
{
|
||||||
layout = new QVBoxLayout(this);
|
layout = new QVBoxLayout(this);
|
||||||
|
|
@ -23,9 +23,16 @@ EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCom
|
||||||
salt = new QLabel(this);
|
salt = new QLabel(this);
|
||||||
salt->setAlignment(Qt::AlignCenter);
|
salt->setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
|
cardPricesDisplayWidget = new EdhrecApiResponseCardPricesDisplayWidget(this, commanderDetails.getPrices());
|
||||||
|
|
||||||
|
navigationWidget = new EdhrecCommanderApiResponseNavigationWidget(this, commanderDetails, baseUrl);
|
||||||
|
|
||||||
layout->addWidget(commanderPicture);
|
layout->addWidget(commanderPicture);
|
||||||
layout->addWidget(label);
|
layout->addWidget(label);
|
||||||
layout->addWidget(salt);
|
layout->addWidget(salt);
|
||||||
|
layout->addWidget(cardPricesDisplayWidget);
|
||||||
|
layout->addWidget(navigationWidget);
|
||||||
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,28 +1,34 @@
|
||||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||||
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||||
#include "api_response/edhrec_commander_api_response_commander_details.h"
|
#include "../../api_response/cards/edhrec_commander_api_response_commander_details.h"
|
||||||
|
#include "../card_prices/edhrec_api_response_card_prices_display_widget.h"
|
||||||
|
#include "edhrec_commander_api_response_navigation_widget.h"
|
||||||
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
class EdhrecCommanderApiResponseNavigationWidget;
|
||||||
class EdhrecCommanderResponseCommanderDetailsDisplayWidget : public QWidget
|
class EdhrecCommanderResponseCommanderDetailsDisplayWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
explicit EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails);
|
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
|
||||||
|
QString baseUrl);
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel *label;
|
EdhrecCommanderApiResponseCommanderDetails commanderDetails;
|
||||||
QLabel *salt;
|
|
||||||
QVBoxLayout *layout;
|
QVBoxLayout *layout;
|
||||||
CardInfoPictureWidget *commanderPicture;
|
CardInfoPictureWidget *commanderPicture;
|
||||||
EdhrecCommanderApiResponseCommanderDetails commanderDetails;
|
QLabel *label;
|
||||||
|
QLabel *salt;
|
||||||
|
EdhrecApiResponseCardPricesDisplayWidget *cardPricesDisplayWidget;
|
||||||
|
EdhrecCommanderApiResponseNavigationWidget *navigationWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
#endif // EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#include "edhrec_commander_api_response_display_widget.h"
|
#include "edhrec_commander_api_response_display_widget.h"
|
||||||
|
|
||||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||||
#include "api_response/edhrec_commander_api_response.h"
|
#include "../../api_response/commander/edhrec_commander_api_response.h"
|
||||||
#include "edhrec_commander_api_response_card_list_display_widget.h"
|
#include "../cards/edhrec_api_response_card_list_display_widget.h"
|
||||||
#include "edhrec_commander_api_response_commander_details_display_widget.h"
|
#include "edhrec_api_response_commander_details_display_widget.h"
|
||||||
|
|
||||||
#include <QListView>
|
#include <QListView>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
|
|
||||||
EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
|
EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
|
||||||
EdhrecCommanderApiResponse response)
|
EdhrecCommanderApiResponse response,
|
||||||
|
QString baseUrl)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
layout = new QHBoxLayout(this);
|
layout = new QHBoxLayout(this);
|
||||||
|
|
@ -31,15 +32,15 @@ EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget
|
||||||
QStringList widgetNames;
|
QStringList widgetNames;
|
||||||
|
|
||||||
// Add commander details
|
// Add commander details
|
||||||
auto commanderPicture =
|
auto commanderPicture = new EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
||||||
new EdhrecCommanderResponseCommanderDetailsDisplayWidget(this, response.container.getCommanderDetails());
|
this, response.container.getCommanderDetails(), baseUrl);
|
||||||
cardDisplayLayout->addWidget(commanderPicture);
|
cardDisplayLayout->addWidget(commanderPicture);
|
||||||
widgetNames.append("Commander Details");
|
widgetNames.append("Commander Details");
|
||||||
|
|
||||||
// Add card list widgets
|
// Add card list widgets
|
||||||
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||||
for (const EdhrecCommanderApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||||
auto cardListDisplayWidget = new EdhrecCommanderApiResponseCardListDisplayWidget(this, card_list);
|
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
|
||||||
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||||
widgetNames.append(cardListDisplayWidget->getBannerText());
|
widgetNames.append(cardListDisplayWidget->getBannerText());
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
#ifndef EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
#define EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
#define EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
#include "api_response/edhrec_commander_api_response.h"
|
#include "../../api_response/commander/edhrec_commander_api_response.h"
|
||||||
|
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
@ -12,7 +12,9 @@ class EdhrecCommanderApiResponseDisplayWidget : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EdhrecCommanderApiResponseDisplayWidget(QWidget *parent, EdhrecCommanderApiResponse response);
|
explicit EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
|
||||||
|
EdhrecCommanderApiResponse response,
|
||||||
|
QString baseUrl);
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
#include "edhrec_commander_api_response_navigation_widget.h"
|
||||||
|
|
||||||
|
#include "../../tab_edhrec_main.h"
|
||||||
|
|
||||||
|
EdhrecCommanderApiResponseNavigationWidget::EdhrecCommanderApiResponseNavigationWidget(
|
||||||
|
QWidget *parent,
|
||||||
|
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
|
||||||
|
QString baseUrl)
|
||||||
|
: QWidget(parent), commanderDetails(_commanderDetails)
|
||||||
|
{
|
||||||
|
layout = new QGridLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
gameChangerLabel = new QLabel(this);
|
||||||
|
budgetLabel = new QLabel(this);
|
||||||
|
|
||||||
|
comboPushButton = new QPushButton(this);
|
||||||
|
averageDeckPushButton = new QPushButton(this);
|
||||||
|
|
||||||
|
layout->addWidget(comboPushButton, 0, 0, 1, 1);
|
||||||
|
layout->addWidget(averageDeckPushButton, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
layout->addWidget(gameChangerLabel, 1, 0, 1, 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < gameChangerOptions.length(); i++) {
|
||||||
|
QString option = gameChangerOptions.at(i);
|
||||||
|
QString label = option.isEmpty() ? "All" : option.at(0).toUpper() + option.mid(1);
|
||||||
|
QPushButton *optionButton = new QPushButton(label, this);
|
||||||
|
gameChangerButtons[option] = optionButton;
|
||||||
|
layout->addWidget(optionButton, 2, i);
|
||||||
|
connect(optionButton, &QPushButton::clicked, this, [=, this]() {
|
||||||
|
selectedGameChanger = option;
|
||||||
|
updateOptionButtonSelection(gameChangerButtons, option);
|
||||||
|
actRequestCommanderNavigation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->addWidget(budgetLabel, 3, 0, 1, 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < budgetOptions.length(); i++) {
|
||||||
|
QString option = budgetOptions.at(i);
|
||||||
|
QString label = option.isEmpty() ? "Any" : option.at(0).toUpper() + option.mid(1);
|
||||||
|
QPushButton *btn = new QPushButton(label, this);
|
||||||
|
budgetButtons[option] = btn;
|
||||||
|
layout->addWidget(btn, 4, i);
|
||||||
|
connect(btn, &QPushButton::clicked, this, [=, this]() {
|
||||||
|
selectedBudget = option;
|
||||||
|
updateOptionButtonSelection(budgetButtons, option);
|
||||||
|
actRequestCommanderNavigation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOptionButtonSelection(gameChangerButtons, "");
|
||||||
|
updateOptionButtonSelection(budgetButtons, "");
|
||||||
|
|
||||||
|
QWidget *currentParent = parentWidget();
|
||||||
|
TabEdhRecMain *parentTab = nullptr;
|
||||||
|
|
||||||
|
while (currentParent) {
|
||||||
|
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentParent = currentParent->parentWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parentTab) {
|
||||||
|
connect(comboPushButton, &QPushButton::clicked, this,
|
||||||
|
&EdhrecCommanderApiResponseNavigationWidget::actRequestComboNavigation);
|
||||||
|
connect(averageDeckPushButton, &QPushButton::clicked, this,
|
||||||
|
&EdhrecCommanderApiResponseNavigationWidget::actRequestAverageDeckNavigation);
|
||||||
|
connect(this, &EdhrecCommanderApiResponseNavigationWidget::requestUrl, parentTab,
|
||||||
|
&TabEdhRecMain::actNavigatePage);
|
||||||
|
}
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
applyOptionsFromUrl(baseUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecCommanderApiResponseNavigationWidget::retranslateUi()
|
||||||
|
{
|
||||||
|
comboPushButton->setText(tr("Combos"));
|
||||||
|
averageDeckPushButton->setText(tr("Average Deck"));
|
||||||
|
gameChangerLabel->setText(tr("Game Changers"));
|
||||||
|
budgetLabel->setText(tr("Budget"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecCommanderApiResponseNavigationWidget::applyOptionsFromUrl(const QString &url)
|
||||||
|
{
|
||||||
|
QString cleanedUrl = url;
|
||||||
|
|
||||||
|
// Remove base and file extension
|
||||||
|
if (cleanedUrl.startsWith("https://json.edhrec.com/pages/")) {
|
||||||
|
cleanedUrl = cleanedUrl.mid(QString("https://json.edhrec.com/pages/").length());
|
||||||
|
}
|
||||||
|
if (cleanedUrl.endsWith(".json")) {
|
||||||
|
cleanedUrl.chop(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expecting something like: "commanders/the-ur-dragon/core/expensive"
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||||
|
QStringList parts = cleanedUrl.split('/', Qt::SkipEmptyParts);
|
||||||
|
#else
|
||||||
|
QStringList parts = cleanedUrl.split('/', QString::SkipEmptyParts);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (parts.size() < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString commanderName = parts[1];
|
||||||
|
QString gameChangerOpt, budgetOpt;
|
||||||
|
|
||||||
|
// Define valid sets
|
||||||
|
QSet<QString> validGameChangers = {"core", "upgraded", "optimized"};
|
||||||
|
QSet<QString> validBudgets = {"budget", "expensive"};
|
||||||
|
|
||||||
|
// Check remaining parts after commander
|
||||||
|
for (int i = 2; i < parts.size(); ++i) {
|
||||||
|
QString part = parts[i].toLower();
|
||||||
|
if (validGameChangers.contains(part)) {
|
||||||
|
gameChangerOpt = part;
|
||||||
|
} else if (validBudgets.contains(part)) {
|
||||||
|
budgetOpt = part;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate and apply
|
||||||
|
if (!gameChangerButtons.contains(gameChangerOpt)) {
|
||||||
|
gameChangerOpt.clear();
|
||||||
|
}
|
||||||
|
if (!budgetButtons.contains(budgetOpt)) {
|
||||||
|
budgetOpt.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedGameChanger = gameChangerOpt;
|
||||||
|
selectedBudget = budgetOpt;
|
||||||
|
|
||||||
|
updateOptionButtonSelection(gameChangerButtons, selectedGameChanger);
|
||||||
|
updateOptionButtonSelection(budgetButtons, selectedBudget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecCommanderApiResponseNavigationWidget::updateOptionButtonSelection(QMap<QString, QPushButton *> &buttons,
|
||||||
|
const QString &selectedKey)
|
||||||
|
{
|
||||||
|
for (auto it = buttons.begin(); it != buttons.end(); ++it) {
|
||||||
|
it.value()->setStyleSheet(it.key() == selectedKey ? "background-color: lightblue; font-weight: bold;" : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EdhrecCommanderApiResponseNavigationWidget::addNavigationOptionsToUrl(QString baseUrl)
|
||||||
|
{
|
||||||
|
if (!selectedGameChanger.isEmpty()) {
|
||||||
|
baseUrl += "/" + selectedGameChanger;
|
||||||
|
}
|
||||||
|
if (!selectedBudget.isEmpty()) {
|
||||||
|
baseUrl += "/" + selectedBudget;
|
||||||
|
}
|
||||||
|
return baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecCommanderApiResponseNavigationWidget::actRequestCommanderNavigation()
|
||||||
|
{
|
||||||
|
emit requestUrl(addNavigationOptionsToUrl("/commanders/" + commanderDetails.getSanitized()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecCommanderApiResponseNavigationWidget::actRequestComboNavigation()
|
||||||
|
{
|
||||||
|
emit requestUrl("/combos/" + commanderDetails.getSanitized());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecCommanderApiResponseNavigationWidget::actRequestAverageDeckNavigation()
|
||||||
|
{
|
||||||
|
emit requestUrl(addNavigationOptionsToUrl("/average-decks/" + commanderDetails.getSanitized()));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H
|
||||||
|
#define EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H
|
||||||
|
|
||||||
|
#include "edhrec_api_response_commander_details_display_widget.h"
|
||||||
|
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class EdhrecCommanderApiResponseNavigationWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit EdhrecCommanderApiResponseNavigationWidget(
|
||||||
|
QWidget *parent,
|
||||||
|
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
|
||||||
|
QString baseUrl);
|
||||||
|
void retranslateUi();
|
||||||
|
void applyOptionsFromUrl(const QString &url);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void actRequestCommanderNavigation();
|
||||||
|
void actRequestComboNavigation();
|
||||||
|
void actRequestAverageDeckNavigation();
|
||||||
|
signals:
|
||||||
|
void requestUrl(QString url);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QGridLayout *layout;
|
||||||
|
|
||||||
|
QLabel *gameChangerLabel;
|
||||||
|
QLabel *budgetLabel;
|
||||||
|
|
||||||
|
QStringList gameChangerOptions = {"", "core", "upgraded", "optimized"};
|
||||||
|
QStringList budgetOptions = {"", "budget", "expensive"};
|
||||||
|
|
||||||
|
QString selectedGameChanger;
|
||||||
|
QString selectedBudget;
|
||||||
|
|
||||||
|
QMap<QString, QPushButton *> gameChangerButtons;
|
||||||
|
QMap<QString, QPushButton *> budgetButtons;
|
||||||
|
|
||||||
|
QPushButton *comboPushButton;
|
||||||
|
QPushButton *averageDeckPushButton;
|
||||||
|
|
||||||
|
EdhrecCommanderApiResponseCommanderDetails commanderDetails;
|
||||||
|
|
||||||
|
void updateOptionButtonSelection(QMap<QString, QPushButton *> &buttons, const QString &selectedKey);
|
||||||
|
QString addNavigationOptionsToUrl(QString baseUrl);
|
||||||
|
QString buildComboUrl() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "edhrec_top_cards_api_response_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../api_response/top_cards/edhrec_top_cards_api_response.h"
|
||||||
|
#include "../cards/edhrec_api_response_card_list_display_widget.h"
|
||||||
|
|
||||||
|
EdhrecTopCardsApiResponseDisplayWidget::EdhrecTopCardsApiResponseDisplayWidget(QWidget *parent,
|
||||||
|
EdhrecTopCardsApiResponse response)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
layout = new QHBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
cardDisplayLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
// Add card list widgets
|
||||||
|
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||||
|
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||||
|
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
|
||||||
|
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a QScrollArea to hold the card display widgets
|
||||||
|
scrollArea = new QScrollArea(this);
|
||||||
|
scrollArea->setWidgetResizable(true);
|
||||||
|
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||||
|
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
|
// Set the cardDisplayLayout inside the scroll area
|
||||||
|
auto scrollWidget = new QWidget(scrollArea);
|
||||||
|
scrollWidget->setLayout(cardDisplayLayout);
|
||||||
|
scrollArea->setWidget(scrollWidget);
|
||||||
|
|
||||||
|
layout->addWidget(scrollArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecTopCardsApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
layout->invalidate();
|
||||||
|
layout->activate();
|
||||||
|
layout->update();
|
||||||
|
if (scrollArea && scrollArea->widget()) {
|
||||||
|
scrollArea->widget()->resize(event->size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
#define EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../api_response/top_cards/edhrec_top_cards_api_response.h"
|
||||||
|
|
||||||
|
#include <QResizeEvent>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class EdhrecTopCardsApiResponseDisplayWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EdhrecTopCardsApiResponseDisplayWidget(QWidget *parent, EdhrecTopCardsApiResponse response);
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *layout;
|
||||||
|
QVBoxLayout *cardDisplayLayout;
|
||||||
|
QScrollArea *scrollArea;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "edhrec_top_commanders_api_response_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h"
|
||||||
|
#include "../cards/edhrec_api_response_card_list_display_widget.h"
|
||||||
|
|
||||||
|
EdhrecTopCommandersApiResponseDisplayWidget::EdhrecTopCommandersApiResponseDisplayWidget(
|
||||||
|
QWidget *parent,
|
||||||
|
EdhrecTopCommandersApiResponse response)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
layout = new QHBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
cardDisplayLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
// Add card list widgets
|
||||||
|
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||||
|
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||||
|
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
|
||||||
|
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a QScrollArea to hold the card display widgets
|
||||||
|
scrollArea = new QScrollArea(this);
|
||||||
|
scrollArea->setWidgetResizable(true);
|
||||||
|
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||||
|
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
|
// Set the cardDisplayLayout inside the scroll area
|
||||||
|
auto scrollWidget = new QWidget(scrollArea);
|
||||||
|
scrollWidget->setLayout(cardDisplayLayout);
|
||||||
|
scrollArea->setWidget(scrollWidget);
|
||||||
|
|
||||||
|
layout->addWidget(scrollArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecTopCommandersApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
qDebug() << event->size();
|
||||||
|
layout->invalidate();
|
||||||
|
layout->activate();
|
||||||
|
layout->update();
|
||||||
|
if (scrollArea && scrollArea->widget()) {
|
||||||
|
scrollArea->widget()->resize(event->size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
#define EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h"
|
||||||
|
|
||||||
|
#include <QResizeEvent>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class EdhrecTopCommandersApiResponseDisplayWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EdhrecTopCommandersApiResponseDisplayWidget(QWidget *parent, EdhrecTopCommandersApiResponse response);
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *layout;
|
||||||
|
QVBoxLayout *cardDisplayLayout;
|
||||||
|
QScrollArea *scrollArea;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "edhrec_top_tags_api_response_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../api_response/top_tags/edhrec_top_tags_api_response.h"
|
||||||
|
#include "../cards/edhrec_api_response_card_list_display_widget.h"
|
||||||
|
|
||||||
|
EdhrecTopTagsApiResponseDisplayWidget::EdhrecTopTagsApiResponseDisplayWidget(QWidget *parent,
|
||||||
|
EdhrecTopTagsApiResponse response)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
layout = new QHBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
cardDisplayLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
// Add card list widgets
|
||||||
|
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||||
|
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||||
|
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
|
||||||
|
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a QScrollArea to hold the card display widgets
|
||||||
|
scrollArea = new QScrollArea(this);
|
||||||
|
scrollArea->setWidgetResizable(true);
|
||||||
|
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||||
|
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
|
// Set the cardDisplayLayout inside the scroll area
|
||||||
|
auto scrollWidget = new QWidget(scrollArea);
|
||||||
|
scrollWidget->setLayout(cardDisplayLayout);
|
||||||
|
scrollArea->setWidget(scrollWidget);
|
||||||
|
|
||||||
|
layout->addWidget(scrollArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EdhrecTopTagsApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
layout->invalidate();
|
||||||
|
layout->activate();
|
||||||
|
layout->update();
|
||||||
|
if (scrollArea && scrollArea->widget()) {
|
||||||
|
scrollArea->widget()->resize(event->size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
#define EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../api_response/top_tags/edhrec_top_tags_api_response.h"
|
||||||
|
|
||||||
|
#include <QResizeEvent>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class EdhrecTopTagsApiResponseDisplayWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EdhrecTopTagsApiResponseDisplayWidget(QWidget *parent, EdhrecTopTagsApiResponse response);
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *layout;
|
||||||
|
QVBoxLayout *cardDisplayLayout;
|
||||||
|
QScrollArea *scrollArea;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
#include "edhrec_commander_api_response_card_details_display_widget.h"
|
|
||||||
|
|
||||||
#include "../../../../game/cards/card_database_manager.h"
|
|
||||||
|
|
||||||
EdhrecCommanderApiResponseCardDetailsDisplayWidget::EdhrecCommanderApiResponseCardDetailsDisplayWidget(
|
|
||||||
QWidget *parent,
|
|
||||||
const EdhrecCommanderApiResponseCardDetails &_toDisplay)
|
|
||||||
: QWidget(parent), toDisplay(_toDisplay)
|
|
||||||
{
|
|
||||||
layout = new QVBoxLayout(this);
|
|
||||||
setLayout(layout);
|
|
||||||
|
|
||||||
cardPictureWidget = new CardInfoPictureWidget(this);
|
|
||||||
cardPictureWidget->setCard(CardDatabaseManager::getInstance()->getCard(toDisplay.name));
|
|
||||||
|
|
||||||
label = new QLabel(this);
|
|
||||||
label->setText(toDisplay.name + "\n" + toDisplay.label);
|
|
||||||
label->setAlignment(Qt::AlignHCenter);
|
|
||||||
|
|
||||||
// Set label color based on inclusion rate
|
|
||||||
int inclusionRate = (toDisplay.numDecks * 100) / toDisplay.potentialDecks;
|
|
||||||
|
|
||||||
QColor labelColor;
|
|
||||||
if (inclusionRate <= 30) {
|
|
||||||
labelColor = QColor(255, 0, 0); // Red
|
|
||||||
} else if (inclusionRate <= 60) {
|
|
||||||
int red = 255 - ((inclusionRate - 30) * 2);
|
|
||||||
int green = (inclusionRate - 30) * 4; // Adjust green to make the transition smoother
|
|
||||||
labelColor = QColor(red, green, 0); // purple-ish
|
|
||||||
} else if (inclusionRate <= 90) {
|
|
||||||
int green = (inclusionRate - 60) * 5; // Increase green
|
|
||||||
labelColor = QColor(100, green, 100); // Green shades
|
|
||||||
} else {
|
|
||||||
labelColor = QColor(100, 200, 100); // Dark Green
|
|
||||||
}
|
|
||||||
|
|
||||||
label->setStyleSheet(QString("color: %1").arg(labelColor.name()));
|
|
||||||
|
|
||||||
layout->addWidget(cardPictureWidget);
|
|
||||||
layout->addWidget(label);
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
|
||||||
#define EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
|
||||||
|
|
||||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
|
||||||
#include "api_response/edhrec_commander_api_response_card_details.h"
|
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
class EdhrecCommanderApiResponseCardDetailsDisplayWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit EdhrecCommanderApiResponseCardDetailsDisplayWidget(
|
|
||||||
QWidget *parent,
|
|
||||||
const EdhrecCommanderApiResponseCardDetails &_toDisplay);
|
|
||||||
|
|
||||||
private:
|
|
||||||
EdhrecCommanderApiResponseCardDetails toDisplay;
|
|
||||||
QVBoxLayout *layout;
|
|
||||||
CardInfoPictureWidget *cardPictureWidget;
|
|
||||||
QLabel *label;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#include "edhrec_commander_api_response_card_list_display_widget.h"
|
|
||||||
|
|
||||||
#include "../../../ui/widgets/general/display/banner_widget.h"
|
|
||||||
#include "edhrec_commander_api_response_card_details_display_widget.h"
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
EdhrecCommanderApiResponseCardListDisplayWidget::EdhrecCommanderApiResponseCardListDisplayWidget(
|
|
||||||
QWidget *parent,
|
|
||||||
EdhrecCommanderApiResponseCardList toDisplay)
|
|
||||||
: QWidget(parent)
|
|
||||||
{
|
|
||||||
layout = new QVBoxLayout(this);
|
|
||||||
setLayout(layout);
|
|
||||||
|
|
||||||
header = new BannerWidget(this, toDisplay.header);
|
|
||||||
|
|
||||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
|
|
||||||
header->setBuddy(flowWidget);
|
|
||||||
|
|
||||||
foreach (EdhrecCommanderApiResponseCardDetails card_detail, toDisplay.cardViews) {
|
|
||||||
auto widget = new EdhrecCommanderApiResponseCardDetailsDisplayWidget(flowWidget, card_detail);
|
|
||||||
flowWidget->addWidget(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
layout->addWidget(header);
|
|
||||||
layout->addWidget(flowWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdhrecCommanderApiResponseCardListDisplayWidget::resizeEvent(QResizeEvent *event)
|
|
||||||
{
|
|
||||||
QWidget::resizeEvent(event);
|
|
||||||
qDebug() << event->size();
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "tab_edhrec.h"
|
#include "tab_edhrec.h"
|
||||||
|
|
||||||
#include "api_response/edhrec_commander_api_response.h"
|
#include "api_response/commander/edhrec_commander_api_response.h"
|
||||||
#include "edhrec_commander_api_response_display_widget.h"
|
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
@ -21,7 +21,7 @@ TabEdhRec::TabEdhRec(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||||
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(processApiJson(QNetworkReply *)));
|
connect(networkManager, &QNetworkAccessManager::finished, this, &TabEdhRec::processApiJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabEdhRec::retranslateUi()
|
void TabEdhRec::retranslateUi()
|
||||||
|
|
@ -76,7 +76,7 @@ void TabEdhRec::processApiJson(QNetworkReply *reply)
|
||||||
EdhrecCommanderApiResponse deckData;
|
EdhrecCommanderApiResponse deckData;
|
||||||
deckData.fromJson(jsonObj);
|
deckData.fromJson(jsonObj);
|
||||||
|
|
||||||
displayWidget = new EdhrecCommanderApiResponseDisplayWidget(this, deckData);
|
displayWidget = new EdhrecCommanderApiResponseDisplayWidget(this, deckData, reply->url().toString());
|
||||||
// flowWidget->addWidget(displayWidget);
|
// flowWidget->addWidget(displayWidget);
|
||||||
setCentralWidget(displayWidget);
|
setCentralWidget(displayWidget);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#ifndef TAB_EDHREC_H
|
#ifndef TAB_EDHREC_H
|
||||||
#define TAB_EDHREC_H
|
#define TAB_EDHREC_H
|
||||||
|
|
||||||
#include "../../../../game/cards/card_database.h"
|
#include "../../../../game/cards/card_info.h"
|
||||||
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||||
#include "../../tab.h"
|
#include "../../tab.h"
|
||||||
#include "edhrec_commander_api_response_display_widget.h"
|
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
class TabEdhRec : public Tab
|
class TabEdhRec : public Tab
|
||||||
|
|
|
||||||
380
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.cpp
Normal file
380
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.cpp
Normal file
|
|
@ -0,0 +1,380 @@
|
||||||
|
#include "tab_edhrec_main.h"
|
||||||
|
|
||||||
|
#include "../../../../game/cards/card_completer_proxy_model.h"
|
||||||
|
#include "../../../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../../../game/cards/card_search_model.h"
|
||||||
|
#include "../../tab_supervisor.h"
|
||||||
|
#include "api_response/average_deck/edhrec_average_deck_api_response.h"
|
||||||
|
#include "api_response/commander/edhrec_commander_api_response.h"
|
||||||
|
#include "api_response/top_cards/edhrec_top_cards_api_response.h"
|
||||||
|
#include "api_response/top_commanders/edhrec_top_commanders_api_response.h"
|
||||||
|
#include "api_response/top_tags/edhrec_top_tags_api_response.h"
|
||||||
|
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||||
|
#include "display/top_cards/edhrec_top_cards_api_response_display_widget.h"
|
||||||
|
#include "display/top_commander/edhrec_top_commanders_api_response_display_widget.h"
|
||||||
|
#include "display/top_tags/edhrec_top_tags_api_response_display_widget.h"
|
||||||
|
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QResizeEvent>
|
||||||
|
|
||||||
|
static bool canBeCommander(const CardInfoPtr &cardInfo)
|
||||||
|
{
|
||||||
|
return ((cardInfo->getCardType().contains("Legendary", Qt::CaseInsensitive) &&
|
||||||
|
cardInfo->getCardType().contains("Creature", Qt::CaseInsensitive))) ||
|
||||||
|
cardInfo->getText().contains("can be your commander", Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
TabEdhRecMain::TabEdhRecMain(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||||
|
{
|
||||||
|
networkManager = new QNetworkAccessManager(this);
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
|
networkManager->setTransferTimeout(); // Use Qt's default timeout
|
||||||
|
#endif
|
||||||
|
|
||||||
|
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||||
|
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(processApiJson(QNetworkReply *)));
|
||||||
|
|
||||||
|
container = new QWidget(this);
|
||||||
|
mainLayout = new QVBoxLayout(container);
|
||||||
|
container->setLayout(mainLayout);
|
||||||
|
|
||||||
|
navigationContainer = new QWidget(container);
|
||||||
|
navigationContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
navigationLayout = new QHBoxLayout(navigationContainer);
|
||||||
|
navigationLayout->setSpacing(5);
|
||||||
|
navigationContainer->setLayout(navigationLayout);
|
||||||
|
|
||||||
|
cardsPushButton = new QPushButton(navigationContainer);
|
||||||
|
connect(cardsPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopCards);
|
||||||
|
topCommandersPushButton = new QPushButton(navigationContainer);
|
||||||
|
connect(topCommandersPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopCommanders);
|
||||||
|
tagsPushButton = new QPushButton(navigationContainer);
|
||||||
|
connect(tagsPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopTags);
|
||||||
|
|
||||||
|
searchBar = new QLineEdit(this);
|
||||||
|
auto cardDatabaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), false, this);
|
||||||
|
auto displayModel = new CardDatabaseDisplayModel(this);
|
||||||
|
displayModel->setSourceModel(cardDatabaseModel);
|
||||||
|
CardSearchModel *searchModel = new CardSearchModel(displayModel, this);
|
||||||
|
|
||||||
|
CardCompleterProxyModel *proxyModel = new CardCompleterProxyModel(this);
|
||||||
|
proxyModel->setSourceModel(searchModel);
|
||||||
|
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
proxyModel->setFilterRole(Qt::DisplayRole);
|
||||||
|
|
||||||
|
QCompleter *completer = new QCompleter(proxyModel, this);
|
||||||
|
completer->setCompletionRole(Qt::DisplayRole);
|
||||||
|
completer->setCompletionMode(QCompleter::PopupCompletion);
|
||||||
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
completer->setFilterMode(Qt::MatchContains);
|
||||||
|
completer->setMaxVisibleItems(10);
|
||||||
|
searchBar->setCompleter(completer);
|
||||||
|
|
||||||
|
// Update suggestions dynamically
|
||||||
|
connect(searchBar, &QLineEdit::textChanged, searchModel, &CardSearchModel::updateSearchResults);
|
||||||
|
connect(searchBar, &QLineEdit::textChanged, this, [=](const QString &text) {
|
||||||
|
// Ensure substring matching
|
||||||
|
QString pattern = ".*" + QRegularExpression::escape(text) + ".*";
|
||||||
|
proxyModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
|
||||||
|
|
||||||
|
if (!text.isEmpty()) {
|
||||||
|
completer->complete(); // Force the dropdown to appear
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
searchPushButton = new QPushButton(navigationContainer);
|
||||||
|
connect(searchPushButton, &QPushButton::clicked, this, [=, this]() { doSearch(); });
|
||||||
|
|
||||||
|
navigationLayout->addWidget(cardsPushButton);
|
||||||
|
navigationLayout->addWidget(topCommandersPushButton);
|
||||||
|
navigationLayout->addWidget(tagsPushButton);
|
||||||
|
navigationLayout->addWidget(searchBar);
|
||||||
|
navigationLayout->addWidget(searchPushButton);
|
||||||
|
|
||||||
|
currentPageDisplay = new QWidget(container);
|
||||||
|
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||||
|
currentPageDisplay->setLayout(currentPageLayout);
|
||||||
|
|
||||||
|
mainLayout->addWidget(navigationContainer);
|
||||||
|
mainLayout->addWidget(currentPageDisplay);
|
||||||
|
|
||||||
|
// Ensure navigation stays at the top and currentPageDisplay takes remaining space
|
||||||
|
mainLayout->setStretch(0, 0); // navigationContainer gets minimum space
|
||||||
|
mainLayout->setStretch(1, 1); // currentPageDisplay expands as much as possible
|
||||||
|
|
||||||
|
setCentralWidget(container);
|
||||||
|
|
||||||
|
TabEdhRecMain::retranslateUi();
|
||||||
|
|
||||||
|
getTopCards();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::retranslateUi()
|
||||||
|
{
|
||||||
|
cardsPushButton->setText(tr("&Cards"));
|
||||||
|
topCommandersPushButton->setText(tr("Top Commanders"));
|
||||||
|
tagsPushButton->setText(tr("Tags"));
|
||||||
|
searchBar->setPlaceholderText(tr("Search for a card ..."));
|
||||||
|
searchPushButton->setText(tr("Search"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::doSearch()
|
||||||
|
{
|
||||||
|
CardInfoPtr searchedCard = CardDatabaseManager::getInstance()->getCard(searchBar->text());
|
||||||
|
if (!searchedCard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCard(searchedCard, canBeCommander(searchedCard));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::setCard(CardInfoPtr _cardToQuery, bool isCommander)
|
||||||
|
{
|
||||||
|
cardToQuery = _cardToQuery;
|
||||||
|
|
||||||
|
if (!cardToQuery) {
|
||||||
|
qDebug() << "Invalid card information provided.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString cardName = cardToQuery->getName();
|
||||||
|
QString formattedName = cardName.toLower().replace(" ", "-").remove(QRegularExpression("[^a-z0-9\\-]"));
|
||||||
|
|
||||||
|
QString url;
|
||||||
|
if (isCommander) {
|
||||||
|
url = QString("https://json.edhrec.com/pages/commanders/%1.json").arg(formattedName);
|
||||||
|
} else {
|
||||||
|
url = QString("https://json.edhrec.com/pages/cards/%1.json").arg(formattedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkRequest request{QUrl(url)};
|
||||||
|
|
||||||
|
networkManager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::actNavigatePage(QString url)
|
||||||
|
{
|
||||||
|
QNetworkRequest request{QUrl("https://json.edhrec.com/pages" + url + ".json")};
|
||||||
|
|
||||||
|
networkManager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::getTopCards()
|
||||||
|
{
|
||||||
|
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/top/year.json")};
|
||||||
|
|
||||||
|
networkManager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::getTopCommanders()
|
||||||
|
{
|
||||||
|
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/commanders/year.json")};
|
||||||
|
|
||||||
|
networkManager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::getTopTags()
|
||||||
|
{
|
||||||
|
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/tags.json")};
|
||||||
|
|
||||||
|
networkManager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::processApiJson(QNetworkReply *reply)
|
||||||
|
{
|
||||||
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
|
qDebug() << "Network error occurred:" << reply->errorString();
|
||||||
|
reply->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray responseData = reply->readAll();
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
|
||||||
|
|
||||||
|
if (!jsonDoc.isObject()) {
|
||||||
|
qDebug() << "Invalid JSON response received.";
|
||||||
|
reply->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject jsonObj = jsonDoc.object();
|
||||||
|
|
||||||
|
// Get the actual URL from the reply
|
||||||
|
QString responseUrl = reply->url().toString();
|
||||||
|
|
||||||
|
// Check if the response URL matches a commander request
|
||||||
|
if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/year.json")) {
|
||||||
|
processTopCommandersResponse(jsonObj);
|
||||||
|
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/")) {
|
||||||
|
qInfo() << "Received top kek";
|
||||||
|
processCommanderResponse(jsonObj, responseUrl);
|
||||||
|
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/cards/")) {
|
||||||
|
processCommanderResponse(jsonObj);
|
||||||
|
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags/")) {
|
||||||
|
processCommanderResponse(jsonObj);
|
||||||
|
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags.json")) {
|
||||||
|
processTopTagsResponse(jsonObj);
|
||||||
|
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/top/year.json")) {
|
||||||
|
processTopCardsResponse(jsonObj);
|
||||||
|
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/combos/")) {
|
||||||
|
qInfo() << "Received combos";
|
||||||
|
processCommanderResponse(jsonObj);
|
||||||
|
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/average-decks/")) {
|
||||||
|
processAverageDeckResponse(jsonObj);
|
||||||
|
} else {
|
||||||
|
prettyPrintJson(jsonObj, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::processTopCardsResponse(QJsonObject reply)
|
||||||
|
{
|
||||||
|
EdhrecTopCardsApiResponse deckData;
|
||||||
|
deckData.fromJson(reply);
|
||||||
|
|
||||||
|
// **Remove previous page display to prevent stacking**
|
||||||
|
if (currentPageDisplay) {
|
||||||
|
mainLayout->removeWidget(currentPageDisplay);
|
||||||
|
delete currentPageDisplay;
|
||||||
|
currentPageDisplay = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **Create new currentPageDisplay**
|
||||||
|
currentPageDisplay = new QWidget(container);
|
||||||
|
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||||
|
currentPageDisplay->setLayout(currentPageLayout);
|
||||||
|
|
||||||
|
auto display = new EdhrecTopCardsApiResponseDisplayWidget(currentPageDisplay, deckData);
|
||||||
|
currentPageLayout->addWidget(display);
|
||||||
|
|
||||||
|
mainLayout->addWidget(currentPageDisplay);
|
||||||
|
|
||||||
|
// **Ensure layout stays correct**
|
||||||
|
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||||
|
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::processTopTagsResponse(QJsonObject reply)
|
||||||
|
{
|
||||||
|
EdhrecTopTagsApiResponse deckData;
|
||||||
|
deckData.fromJson(reply);
|
||||||
|
|
||||||
|
// **Remove previous page display to prevent stacking**
|
||||||
|
if (currentPageDisplay) {
|
||||||
|
mainLayout->removeWidget(currentPageDisplay);
|
||||||
|
delete currentPageDisplay;
|
||||||
|
currentPageDisplay = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **Create new currentPageDisplay**
|
||||||
|
currentPageDisplay = new QWidget(container);
|
||||||
|
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||||
|
currentPageDisplay->setLayout(currentPageLayout);
|
||||||
|
|
||||||
|
auto display = new EdhrecTopTagsApiResponseDisplayWidget(currentPageDisplay, deckData);
|
||||||
|
currentPageLayout->addWidget(display);
|
||||||
|
|
||||||
|
mainLayout->addWidget(currentPageDisplay);
|
||||||
|
|
||||||
|
// **Ensure layout stays correct**
|
||||||
|
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||||
|
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::processTopCommandersResponse(QJsonObject reply)
|
||||||
|
{
|
||||||
|
EdhrecTopCommandersApiResponse deckData;
|
||||||
|
deckData.fromJson(reply);
|
||||||
|
|
||||||
|
// **Remove previous page display to prevent stacking**
|
||||||
|
if (currentPageDisplay) {
|
||||||
|
mainLayout->removeWidget(currentPageDisplay);
|
||||||
|
delete currentPageDisplay;
|
||||||
|
currentPageDisplay = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **Create new currentPageDisplay**
|
||||||
|
currentPageDisplay = new QWidget(container);
|
||||||
|
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||||
|
currentPageDisplay->setLayout(currentPageLayout);
|
||||||
|
|
||||||
|
auto display = new EdhrecTopCommandersApiResponseDisplayWidget(currentPageDisplay, deckData);
|
||||||
|
currentPageLayout->addWidget(display);
|
||||||
|
|
||||||
|
mainLayout->addWidget(currentPageDisplay);
|
||||||
|
|
||||||
|
// **Ensure layout stays correct**
|
||||||
|
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||||
|
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::processCommanderResponse(QJsonObject reply, QString responseUrl)
|
||||||
|
{
|
||||||
|
EdhrecCommanderApiResponse deckData;
|
||||||
|
deckData.fromJson(reply);
|
||||||
|
|
||||||
|
// **Remove previous page display to prevent stacking**
|
||||||
|
if (currentPageDisplay) {
|
||||||
|
mainLayout->removeWidget(currentPageDisplay);
|
||||||
|
delete currentPageDisplay;
|
||||||
|
currentPageDisplay = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **Create new currentPageDisplay**
|
||||||
|
currentPageDisplay = new QWidget(container);
|
||||||
|
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||||
|
currentPageDisplay->setLayout(currentPageLayout);
|
||||||
|
|
||||||
|
auto display = new EdhrecCommanderApiResponseDisplayWidget(currentPageDisplay, deckData, responseUrl);
|
||||||
|
currentPageLayout->addWidget(display);
|
||||||
|
|
||||||
|
mainLayout->addWidget(currentPageDisplay);
|
||||||
|
|
||||||
|
// **Ensure layout stays correct**
|
||||||
|
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||||
|
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::processAverageDeckResponse(QJsonObject reply)
|
||||||
|
{
|
||||||
|
EdhrecAverageDeckApiResponse deckData;
|
||||||
|
deckData.fromJson(reply);
|
||||||
|
tabSupervisor->addVisualDeckEditorTab(deckData.deck.deckLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabEdhRecMain::prettyPrintJson(const QJsonValue &value, int indentLevel)
|
||||||
|
{
|
||||||
|
const QString indent(indentLevel * 2, ' '); // Adjust spacing as needed for pretty printing
|
||||||
|
|
||||||
|
if (value.isObject()) {
|
||||||
|
QJsonObject obj = value.toObject();
|
||||||
|
for (auto it = obj.begin(); it != obj.end(); ++it) {
|
||||||
|
qDebug().noquote() << indent + it.key() + ":";
|
||||||
|
prettyPrintJson(it.value(), indentLevel + 1);
|
||||||
|
}
|
||||||
|
} else if (value.isArray()) {
|
||||||
|
QJsonArray array = value.toArray();
|
||||||
|
for (int i = 0; i < array.size(); ++i) {
|
||||||
|
qDebug().noquote() << indent + QString("[%1]:").arg(i);
|
||||||
|
prettyPrintJson(array[i], indentLevel + 1);
|
||||||
|
}
|
||||||
|
} else if (value.isString()) {
|
||||||
|
qDebug().noquote() << indent + "\"" + value.toString() + "\"";
|
||||||
|
} else if (value.isDouble()) {
|
||||||
|
qDebug().noquote() << indent + QString::number(value.toDouble());
|
||||||
|
} else if (value.isBool()) {
|
||||||
|
qDebug().noquote() << indent + (value.toBool() ? "true" : "false");
|
||||||
|
} else if (value.isNull()) {
|
||||||
|
qDebug().noquote() << indent + "null";
|
||||||
|
}
|
||||||
|
}
|
||||||
60
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.h
Normal file
60
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.h
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef TAB_EDHREC_MAIN_H
|
||||||
|
#define TAB_EDHREC_MAIN_H
|
||||||
|
|
||||||
|
#include "../../../../game/cards/card_database.h"
|
||||||
|
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||||
|
#include "../../tab.h"
|
||||||
|
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
class TabEdhRecMain : public Tab
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TabEdhRecMain(TabSupervisor *_tabSupervisor);
|
||||||
|
|
||||||
|
void retranslateUi() override;
|
||||||
|
void doSearch();
|
||||||
|
QString getTabText() const override
|
||||||
|
{
|
||||||
|
auto cardName = cardToQuery.isNull() ? QString() : cardToQuery->getName();
|
||||||
|
return tr("EDHREC: ") + cardName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkAccessManager *networkManager;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void processApiJson(QNetworkReply *reply);
|
||||||
|
void processCommanderResponse(QJsonObject reply, QString responseUrl = "");
|
||||||
|
void processTopCardsResponse(QJsonObject reply);
|
||||||
|
void processTopTagsResponse(QJsonObject reply);
|
||||||
|
void processTopCommandersResponse(QJsonObject reply);
|
||||||
|
void processAverageDeckResponse(QJsonObject reply);
|
||||||
|
void prettyPrintJson(const QJsonValue &value, int indentLevel);
|
||||||
|
void setCard(CardInfoPtr _cardToQuery, bool isCommander = false);
|
||||||
|
void actNavigatePage(QString url);
|
||||||
|
void getTopCards();
|
||||||
|
void getTopCommanders();
|
||||||
|
void getTopTags();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *container;
|
||||||
|
QWidget *navigationContainer;
|
||||||
|
QWidget *currentPageDisplay;
|
||||||
|
QVBoxLayout *mainLayout;
|
||||||
|
QHBoxLayout *navigationLayout;
|
||||||
|
QVBoxLayout *currentPageLayout;
|
||||||
|
QPushButton *cardsPushButton;
|
||||||
|
QPushButton *topCommandersPushButton;
|
||||||
|
QPushButton *tagsPushButton;
|
||||||
|
QLineEdit *searchBar;
|
||||||
|
QPushButton *searchPushButton;
|
||||||
|
CardInfoPtr cardToQuery;
|
||||||
|
EdhrecCommanderApiResponseDisplayWidget *displayWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TAB_EDHREC_MAIN_H
|
||||||
|
|
@ -55,7 +55,7 @@ TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor) : AbstractTabDeckEdi
|
||||||
|
|
||||||
void TabDeckEditor::createMenus()
|
void TabDeckEditor::createMenus()
|
||||||
{
|
{
|
||||||
deckMenu = new DeckEditorMenu(this, this);
|
deckMenu = new DeckEditorMenu(this);
|
||||||
addTabMenu(deckMenu);
|
addTabMenu(deckMenu);
|
||||||
|
|
||||||
viewMenu = new QMenu(this);
|
viewMenu = new QMenu(this);
|
||||||
|
|
@ -67,36 +67,36 @@ void TabDeckEditor::createMenus()
|
||||||
|
|
||||||
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||||
aCardInfoDockVisible->setCheckable(true);
|
aCardInfoDockVisible->setCheckable(true);
|
||||||
connect(aCardInfoDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aCardInfoDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||||
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||||
aCardInfoDockFloating->setCheckable(true);
|
aCardInfoDockFloating->setCheckable(true);
|
||||||
connect(aCardInfoDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aCardInfoDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||||
|
|
||||||
aDeckDockVisible = deckDockMenu->addAction(QString());
|
aDeckDockVisible = deckDockMenu->addAction(QString());
|
||||||
aDeckDockVisible->setCheckable(true);
|
aDeckDockVisible->setCheckable(true);
|
||||||
connect(aDeckDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aDeckDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||||
aDeckDockFloating = deckDockMenu->addAction(QString());
|
aDeckDockFloating = deckDockMenu->addAction(QString());
|
||||||
aDeckDockFloating->setCheckable(true);
|
aDeckDockFloating->setCheckable(true);
|
||||||
connect(aDeckDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aDeckDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||||
|
|
||||||
aFilterDockVisible = filterDockMenu->addAction(QString());
|
aFilterDockVisible = filterDockMenu->addAction(QString());
|
||||||
aFilterDockVisible->setCheckable(true);
|
aFilterDockVisible->setCheckable(true);
|
||||||
connect(aFilterDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aFilterDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||||
aFilterDockFloating = filterDockMenu->addAction(QString());
|
aFilterDockFloating = filterDockMenu->addAction(QString());
|
||||||
aFilterDockFloating->setCheckable(true);
|
aFilterDockFloating->setCheckable(true);
|
||||||
connect(aFilterDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aFilterDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||||
|
|
||||||
aPrintingSelectorDockVisible = printingSelectorDockMenu->addAction(QString());
|
aPrintingSelectorDockVisible = printingSelectorDockMenu->addAction(QString());
|
||||||
aPrintingSelectorDockVisible->setCheckable(true);
|
aPrintingSelectorDockVisible->setCheckable(true);
|
||||||
connect(aPrintingSelectorDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aPrintingSelectorDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||||
aPrintingSelectorDockFloating = printingSelectorDockMenu->addAction(QString());
|
aPrintingSelectorDockFloating = printingSelectorDockMenu->addAction(QString());
|
||||||
aPrintingSelectorDockFloating->setCheckable(true);
|
aPrintingSelectorDockFloating->setCheckable(true);
|
||||||
connect(aPrintingSelectorDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aPrintingSelectorDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||||
|
|
||||||
viewMenu->addSeparator();
|
viewMenu->addSeparator();
|
||||||
|
|
||||||
aResetLayout = viewMenu->addAction(QString());
|
aResetLayout = viewMenu->addAction(QString());
|
||||||
connect(aResetLayout, SIGNAL(triggered()), this, SLOT(restartLayout()));
|
connect(aResetLayout, &QAction::triggered, this, &TabDeckEditor::restartLayout);
|
||||||
viewMenu->addAction(aResetLayout);
|
viewMenu->addAction(aResetLayout);
|
||||||
|
|
||||||
deckMenu->setSaveStatus(false);
|
deckMenu->setSaveStatus(false);
|
||||||
|
|
@ -200,7 +200,7 @@ void TabDeckEditor::loadLayout()
|
||||||
databaseDisplayDockWidget->setMinimumSize(100, 100);
|
databaseDisplayDockWidget->setMinimumSize(100, 100);
|
||||||
databaseDisplayDockWidget->setMaximumSize(1400, 5000);
|
databaseDisplayDockWidget->setMaximumSize(1400, 5000);
|
||||||
|
|
||||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
QTimer::singleShot(100, this, &TabDeckEditor::freeDocksSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabDeckEditor::restartLayout()
|
void TabDeckEditor::restartLayout()
|
||||||
|
|
@ -236,7 +236,7 @@ void TabDeckEditor::restartLayout()
|
||||||
splitDockWidget(cardInfoDockWidget, printingSelectorDockWidget, Qt::Horizontal);
|
splitDockWidget(cardInfoDockWidget, printingSelectorDockWidget, Qt::Horizontal);
|
||||||
splitDockWidget(cardInfoDockWidget, filterDockWidget, Qt::Vertical);
|
splitDockWidget(cardInfoDockWidget, filterDockWidget, Qt::Vertical);
|
||||||
|
|
||||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
QTimer::singleShot(100, this, &TabDeckEditor::freeDocksSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabDeckEditor::freeDocksSize()
|
void TabDeckEditor::freeDocksSize()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef WINDOW_DECKEDITOR_H
|
#ifndef WINDOW_DECKEDITOR_H
|
||||||
#define WINDOW_DECKEDITOR_H
|
#define WINDOW_DECKEDITOR_H
|
||||||
|
|
||||||
#include "../../game/cards/card_database.h"
|
#include "../../game/cards/card_info.h"
|
||||||
#include "../game_logic/key_signals.h"
|
#include "../game_logic/key_signals.h"
|
||||||
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||||
#include "abstract_tab_deck_editor.h"
|
#include "abstract_tab_deck_editor.h"
|
||||||
|
|
|
||||||
|
|
@ -105,19 +105,19 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
||||||
// Left side actions
|
// Left side actions
|
||||||
aOpenLocalDeck = new QAction(this);
|
aOpenLocalDeck = new QAction(this);
|
||||||
aOpenLocalDeck->setIcon(QPixmap("theme:icons/pencil"));
|
aOpenLocalDeck->setIcon(QPixmap("theme:icons/pencil"));
|
||||||
connect(aOpenLocalDeck, SIGNAL(triggered()), this, SLOT(actOpenLocalDeck()));
|
connect(aOpenLocalDeck, &QAction::triggered, this, &TabDeckStorage::actOpenLocalDeck);
|
||||||
aRenameLocal = new QAction(this);
|
aRenameLocal = new QAction(this);
|
||||||
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
||||||
connect(aRenameLocal, &QAction::triggered, this, &TabDeckStorage::actRenameLocal);
|
connect(aRenameLocal, &QAction::triggered, this, &TabDeckStorage::actRenameLocal);
|
||||||
aUpload = new QAction(this);
|
aUpload = new QAction(this);
|
||||||
aUpload->setIcon(QPixmap("theme:icons/arrow_right_green"));
|
aUpload->setIcon(QPixmap("theme:icons/arrow_right_green"));
|
||||||
connect(aUpload, SIGNAL(triggered()), this, SLOT(actUpload()));
|
connect(aUpload, &QAction::triggered, this, &TabDeckStorage::actUpload);
|
||||||
aNewLocalFolder = new QAction(this);
|
aNewLocalFolder = new QAction(this);
|
||||||
aNewLocalFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_FileDialogNewFolder));
|
aNewLocalFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_FileDialogNewFolder));
|
||||||
connect(aNewLocalFolder, &QAction::triggered, this, &TabDeckStorage::actNewLocalFolder);
|
connect(aNewLocalFolder, &QAction::triggered, this, &TabDeckStorage::actNewLocalFolder);
|
||||||
aDeleteLocalDeck = new QAction(this);
|
aDeleteLocalDeck = new QAction(this);
|
||||||
aDeleteLocalDeck->setIcon(QPixmap("theme:icons/remove_row"));
|
aDeleteLocalDeck->setIcon(QPixmap("theme:icons/remove_row"));
|
||||||
connect(aDeleteLocalDeck, SIGNAL(triggered()), this, SLOT(actDeleteLocalDeck()));
|
connect(aDeleteLocalDeck, &QAction::triggered, this, &TabDeckStorage::actDeleteLocalDeck);
|
||||||
|
|
||||||
aOpenDecksFolder = new QAction(this);
|
aOpenDecksFolder = new QAction(this);
|
||||||
aOpenDecksFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_DirOpenIcon));
|
aOpenDecksFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_DirOpenIcon));
|
||||||
|
|
@ -126,16 +126,16 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
||||||
// Right side actions
|
// Right side actions
|
||||||
aOpenRemoteDeck = new QAction(this);
|
aOpenRemoteDeck = new QAction(this);
|
||||||
aOpenRemoteDeck->setIcon(QPixmap("theme:icons/pencil"));
|
aOpenRemoteDeck->setIcon(QPixmap("theme:icons/pencil"));
|
||||||
connect(aOpenRemoteDeck, SIGNAL(triggered()), this, SLOT(actOpenRemoteDeck()));
|
connect(aOpenRemoteDeck, &QAction::triggered, this, &TabDeckStorage::actOpenRemoteDeck);
|
||||||
aDownload = new QAction(this);
|
aDownload = new QAction(this);
|
||||||
aDownload->setIcon(QPixmap("theme:icons/arrow_left_green"));
|
aDownload->setIcon(QPixmap("theme:icons/arrow_left_green"));
|
||||||
connect(aDownload, SIGNAL(triggered()), this, SLOT(actDownload()));
|
connect(aDownload, &QAction::triggered, this, &TabDeckStorage::actDownload);
|
||||||
aNewFolder = new QAction(this);
|
aNewFolder = new QAction(this);
|
||||||
aNewFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_FileDialogNewFolder));
|
aNewFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_FileDialogNewFolder));
|
||||||
connect(aNewFolder, SIGNAL(triggered()), this, SLOT(actNewFolder()));
|
connect(aNewFolder, &QAction::triggered, this, &TabDeckStorage::actNewFolder);
|
||||||
aDeleteRemoteDeck = new QAction(this);
|
aDeleteRemoteDeck = new QAction(this);
|
||||||
aDeleteRemoteDeck->setIcon(QPixmap("theme:icons/remove_row"));
|
aDeleteRemoteDeck->setIcon(QPixmap("theme:icons/remove_row"));
|
||||||
connect(aDeleteRemoteDeck, SIGNAL(triggered()), this, SLOT(actDeleteRemoteDeck()));
|
connect(aDeleteRemoteDeck, &QAction::triggered, this, &TabDeckStorage::actDeleteRemoteDeck);
|
||||||
|
|
||||||
// Add actions to toolbars
|
// Add actions to toolbars
|
||||||
leftToolBar->addAction(aOpenLocalDeck);
|
leftToolBar->addAction(aOpenLocalDeck);
|
||||||
|
|
@ -339,8 +339,7 @@ void TabDeckStorage::uploadDeck(const QString &filePath, const QString &targetPa
|
||||||
cmd.set_deck_list(deckString.toStdString());
|
cmd.set_deck_list(deckString.toStdString());
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::uploadFinished);
|
||||||
SLOT(uploadFinished(Response, CommandContainer)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -421,8 +420,7 @@ void TabDeckStorage::actOpenRemoteDeck()
|
||||||
cmd.set_deck_id(node->getId());
|
cmd.set_deck_id(node->getId());
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::openRemoteDeckFinished);
|
||||||
SLOT(openRemoteDeckFinished(Response, CommandContainer)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -479,8 +477,7 @@ void TabDeckStorage::downloadNodeAtIndex(const QModelIndex &curLeft, const QMode
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
pend->setExtraData(filePath);
|
pend->setExtraData(filePath);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::downloadFinished);
|
||||||
SLOT(downloadFinished(Response, CommandContainer, QVariant)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
// node at index is invalid
|
// node at index is invalid
|
||||||
|
|
@ -522,8 +519,7 @@ void TabDeckStorage::actNewFolder()
|
||||||
cmd.set_dir_name(folder);
|
cmd.set_dir_name(folder);
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::newFolderFinished);
|
||||||
SLOT(newFolderFinished(Response, CommandContainer)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -573,15 +569,13 @@ void TabDeckStorage::deleteRemoteDeck(const RemoteDeckList_TreeModel::Node *curR
|
||||||
Command_DeckDelDir cmd;
|
Command_DeckDelDir cmd;
|
||||||
cmd.set_path(targetPath.toStdString());
|
cmd.set_path(targetPath.toStdString());
|
||||||
pend = client->prepareSessionCommand(cmd);
|
pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::deleteFolderFinished);
|
||||||
SLOT(deleteFolderFinished(Response, CommandContainer)));
|
|
||||||
} else {
|
} else {
|
||||||
const auto *deckNode = dynamic_cast<const RemoteDeckList_TreeModel::FileNode *>(curRight);
|
const auto *deckNode = dynamic_cast<const RemoteDeckList_TreeModel::FileNode *>(curRight);
|
||||||
Command_DeckDel cmd;
|
Command_DeckDel cmd;
|
||||||
cmd.set_deck_id(deckNode->getId());
|
cmd.set_deck_id(deckNode->getId());
|
||||||
pend = client->prepareSessionCommand(cmd);
|
pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::deleteDeckFinished);
|
||||||
SLOT(deleteDeckFinished(Response, CommandContainer)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
|
|
|
||||||
|
|
@ -115,11 +115,12 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
|
||||||
createReplayMenuItems();
|
createReplayMenuItems();
|
||||||
createViewMenuItems();
|
createViewMenuItems();
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||||
|
&TabGame::refreshShortcuts);
|
||||||
refreshShortcuts();
|
refreshShortcuts();
|
||||||
messageLog->logReplayStarted(gameInfo.game_id());
|
messageLog->logReplayStarted(gameInfo.game_id());
|
||||||
|
|
||||||
QTimer::singleShot(0, this, SLOT(loadLayout()));
|
QTimer::singleShot(0, this, &TabGame::loadLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
TabGame::TabGame(TabSupervisor *_tabSupervisor,
|
TabGame::TabGame(TabSupervisor *_tabSupervisor,
|
||||||
|
|
@ -156,14 +157,15 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor,
|
||||||
createMenuItems();
|
createMenuItems();
|
||||||
createViewMenuItems();
|
createViewMenuItems();
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||||
|
&TabGame::refreshShortcuts);
|
||||||
refreshShortcuts();
|
refreshShortcuts();
|
||||||
|
|
||||||
// append game to rooms game list for others to see
|
// append game to rooms game list for others to see
|
||||||
for (int i = gameInfo.game_types_size() - 1; i >= 0; i--)
|
for (int i = gameInfo.game_types_size() - 1; i >= 0; i--)
|
||||||
gameTypes.append(roomGameTypes.find(gameInfo.game_types(i)).value());
|
gameTypes.append(roomGameTypes.find(gameInfo.game_types(i)).value());
|
||||||
|
|
||||||
QTimer::singleShot(0, this, SLOT(loadLayout()));
|
QTimer::singleShot(0, this, &TabGame::loadLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::addMentionTag(const QString &value)
|
void TabGame::addMentionTag(const QString &value)
|
||||||
|
|
@ -628,7 +630,7 @@ Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info)
|
||||||
}
|
}
|
||||||
scene->addPlayer(newPlayer);
|
scene->addPlayer(newPlayer);
|
||||||
|
|
||||||
connect(newPlayer, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
|
connect(newPlayer, &Player::newCardAdded, this, &TabGame::newCardAdded);
|
||||||
messageLog->connectToPlayer(newPlayer);
|
messageLog->connectToPlayer(newPlayer);
|
||||||
|
|
||||||
if (local && !spectator) {
|
if (local && !spectator) {
|
||||||
|
|
@ -636,7 +638,7 @@ Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info)
|
||||||
newPlayer->setShortcutsActive();
|
newPlayer->setShortcutsActive();
|
||||||
|
|
||||||
auto *deckView = new DeckViewContainer(playerId, this);
|
auto *deckView = new DeckViewContainer(playerId, this);
|
||||||
connect(deckView, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
|
connect(deckView, &DeckViewContainer::newCardAdded, this, &TabGame::newCardAdded);
|
||||||
deckViewContainers.insert(playerId, deckView);
|
deckViewContainers.insert(playerId, deckView);
|
||||||
deckViewContainerLayout->addWidget(deckView);
|
deckViewContainerLayout->addWidget(deckView);
|
||||||
|
|
||||||
|
|
@ -784,8 +786,7 @@ void TabGame::sendGameCommand(PendingCommand *pend, int playerId)
|
||||||
if (!client)
|
if (!client)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabGame::commandFinished);
|
||||||
SLOT(commandFinished(const Response &)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -796,8 +797,7 @@ void TabGame::sendGameCommand(const google::protobuf::Message &command, int play
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PendingCommand *pend = prepareGameCommand(command);
|
PendingCommand *pend = prepareGameCommand(command);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabGame::commandFinished);
|
||||||
SLOT(commandFinished(const Response &)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1198,10 +1198,11 @@ void TabGame::eventSetActivePhase(const Event_SetActivePhase &event,
|
||||||
|
|
||||||
void TabGame::newCardAdded(AbstractCardItem *card)
|
void TabGame::newCardAdded(AbstractCardItem *card)
|
||||||
{
|
{
|
||||||
connect(card, SIGNAL(hovered(AbstractCardItem *)), cardInfoFrameWidget, SLOT(setCard(AbstractCardItem *)));
|
connect(card, &AbstractCardItem::hovered, cardInfoFrameWidget,
|
||||||
|
qOverload<AbstractCardItem *>(&CardInfoFrameWidget::setCard));
|
||||||
connect(card, &AbstractCardItem::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
connect(card, &AbstractCardItem::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
||||||
connect(card, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
connect(card, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||||
connect(card, SIGNAL(cardShiftClicked(QString)), this, SLOT(linkCardToChat(QString)));
|
connect(card, &AbstractCardItem::cardShiftClicked, this, &TabGame::linkCardToChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const
|
CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const
|
||||||
|
|
@ -1289,34 +1290,34 @@ void TabGame::updateCardMenu(AbstractCardItem *card)
|
||||||
void TabGame::createMenuItems()
|
void TabGame::createMenuItems()
|
||||||
{
|
{
|
||||||
aNextPhase = new QAction(this);
|
aNextPhase = new QAction(this);
|
||||||
connect(aNextPhase, SIGNAL(triggered()), this, SLOT(actNextPhase()));
|
connect(aNextPhase, &QAction::triggered, this, &TabGame::actNextPhase);
|
||||||
aNextPhaseAction = new QAction(this);
|
aNextPhaseAction = new QAction(this);
|
||||||
connect(aNextPhaseAction, SIGNAL(triggered()), this, SLOT(actNextPhaseAction()));
|
connect(aNextPhaseAction, &QAction::triggered, this, &TabGame::actNextPhaseAction);
|
||||||
aNextTurn = new QAction(this);
|
aNextTurn = new QAction(this);
|
||||||
connect(aNextTurn, SIGNAL(triggered()), this, SLOT(actNextTurn()));
|
connect(aNextTurn, &QAction::triggered, this, &TabGame::actNextTurn);
|
||||||
aReverseTurn = new QAction(this);
|
aReverseTurn = new QAction(this);
|
||||||
connect(aReverseTurn, SIGNAL(triggered()), this, SLOT(actReverseTurn()));
|
connect(aReverseTurn, &QAction::triggered, this, &TabGame::actReverseTurn);
|
||||||
aRemoveLocalArrows = new QAction(this);
|
aRemoveLocalArrows = new QAction(this);
|
||||||
connect(aRemoveLocalArrows, SIGNAL(triggered()), this, SLOT(actRemoveLocalArrows()));
|
connect(aRemoveLocalArrows, &QAction::triggered, this, &TabGame::actRemoveLocalArrows);
|
||||||
aRotateViewCW = new QAction(this);
|
aRotateViewCW = new QAction(this);
|
||||||
connect(aRotateViewCW, SIGNAL(triggered()), this, SLOT(actRotateViewCW()));
|
connect(aRotateViewCW, &QAction::triggered, this, &TabGame::actRotateViewCW);
|
||||||
aRotateViewCCW = new QAction(this);
|
aRotateViewCCW = new QAction(this);
|
||||||
connect(aRotateViewCCW, SIGNAL(triggered()), this, SLOT(actRotateViewCCW()));
|
connect(aRotateViewCCW, &QAction::triggered, this, &TabGame::actRotateViewCCW);
|
||||||
aGameInfo = new QAction(this);
|
aGameInfo = new QAction(this);
|
||||||
connect(aGameInfo, SIGNAL(triggered()), this, SLOT(actGameInfo()));
|
connect(aGameInfo, &QAction::triggered, this, &TabGame::actGameInfo);
|
||||||
aConcede = new QAction(this);
|
aConcede = new QAction(this);
|
||||||
connect(aConcede, SIGNAL(triggered()), this, SLOT(actConcede()));
|
connect(aConcede, &QAction::triggered, this, &TabGame::actConcede);
|
||||||
aLeaveGame = new QAction(this);
|
aLeaveGame = new QAction(this);
|
||||||
connect(aLeaveGame, &QAction::triggered, this, [this] { closeRequest(); });
|
connect(aLeaveGame, &QAction::triggered, this, [this] { closeRequest(); });
|
||||||
aFocusChat = new QAction(this);
|
aFocusChat = new QAction(this);
|
||||||
connect(aFocusChat, SIGNAL(triggered()), sayEdit, SLOT(setFocus()));
|
connect(aFocusChat, &QAction::triggered, sayEdit, qOverload<>(&LineEditCompleter::setFocus));
|
||||||
aCloseReplay = nullptr;
|
aCloseReplay = nullptr;
|
||||||
|
|
||||||
phasesMenu = new TearOffMenu(this);
|
phasesMenu = new TearOffMenu(this);
|
||||||
|
|
||||||
for (int i = 0; i < phasesToolbar->phaseCount(); ++i) {
|
for (int i = 0; i < phasesToolbar->phaseCount(); ++i) {
|
||||||
QAction *temp = new QAction(QString(), this);
|
QAction *temp = new QAction(QString(), this);
|
||||||
connect(temp, SIGNAL(triggered()), this, SLOT(actPhaseAction()));
|
connect(temp, &QAction::triggered, this, &TabGame::actPhaseAction);
|
||||||
phasesMenu->addAction(temp);
|
phasesMenu->addAction(temp);
|
||||||
phaseActions.append(temp);
|
phaseActions.append(temp);
|
||||||
}
|
}
|
||||||
|
|
@ -1375,40 +1376,40 @@ void TabGame::createViewMenuItems()
|
||||||
|
|
||||||
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||||
aCardInfoDockVisible->setCheckable(true);
|
aCardInfoDockVisible->setCheckable(true);
|
||||||
connect(aCardInfoDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aCardInfoDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||||
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||||
aCardInfoDockFloating->setCheckable(true);
|
aCardInfoDockFloating->setCheckable(true);
|
||||||
connect(aCardInfoDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aCardInfoDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||||
|
|
||||||
aMessageLayoutDockVisible = messageLayoutDockMenu->addAction(QString());
|
aMessageLayoutDockVisible = messageLayoutDockMenu->addAction(QString());
|
||||||
aMessageLayoutDockVisible->setCheckable(true);
|
aMessageLayoutDockVisible->setCheckable(true);
|
||||||
connect(aMessageLayoutDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aMessageLayoutDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||||
aMessageLayoutDockFloating = messageLayoutDockMenu->addAction(QString());
|
aMessageLayoutDockFloating = messageLayoutDockMenu->addAction(QString());
|
||||||
aMessageLayoutDockFloating->setCheckable(true);
|
aMessageLayoutDockFloating->setCheckable(true);
|
||||||
connect(aMessageLayoutDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aMessageLayoutDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||||
|
|
||||||
aPlayerListDockVisible = playerListDockMenu->addAction(QString());
|
aPlayerListDockVisible = playerListDockMenu->addAction(QString());
|
||||||
aPlayerListDockVisible->setCheckable(true);
|
aPlayerListDockVisible->setCheckable(true);
|
||||||
connect(aPlayerListDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aPlayerListDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||||
aPlayerListDockFloating = playerListDockMenu->addAction(QString());
|
aPlayerListDockFloating = playerListDockMenu->addAction(QString());
|
||||||
aPlayerListDockFloating->setCheckable(true);
|
aPlayerListDockFloating->setCheckable(true);
|
||||||
connect(aPlayerListDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aPlayerListDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||||
|
|
||||||
if (replayDock) {
|
if (replayDock) {
|
||||||
replayDockMenu = viewMenu->addMenu(QString());
|
replayDockMenu = viewMenu->addMenu(QString());
|
||||||
|
|
||||||
aReplayDockVisible = replayDockMenu->addAction(QString());
|
aReplayDockVisible = replayDockMenu->addAction(QString());
|
||||||
aReplayDockVisible->setCheckable(true);
|
aReplayDockVisible->setCheckable(true);
|
||||||
connect(aReplayDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
connect(aReplayDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||||
aReplayDockFloating = replayDockMenu->addAction(QString());
|
aReplayDockFloating = replayDockMenu->addAction(QString());
|
||||||
aReplayDockFloating->setCheckable(true);
|
aReplayDockFloating->setCheckable(true);
|
||||||
connect(aReplayDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
connect(aReplayDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewMenu->addSeparator();
|
viewMenu->addSeparator();
|
||||||
|
|
||||||
aResetLayout = viewMenu->addAction(QString());
|
aResetLayout = viewMenu->addAction(QString());
|
||||||
connect(aResetLayout, SIGNAL(triggered()), this, SLOT(actResetLayout()));
|
connect(aResetLayout, &QAction::triggered, this, &TabGame::actResetLayout);
|
||||||
viewMenu->addAction(aResetLayout);
|
viewMenu->addAction(aResetLayout);
|
||||||
|
|
||||||
addTabMenu(viewMenu);
|
addTabMenu(viewMenu);
|
||||||
|
|
@ -1459,7 +1460,7 @@ void TabGame::loadLayout()
|
||||||
aReplayDockFloating->setChecked(replayDock->isFloating());
|
aReplayDockFloating->setChecked(replayDock->isFloating());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
QTimer::singleShot(100, this, &TabGame::freeDocksSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::freeDocksSize()
|
void TabGame::freeDocksSize()
|
||||||
|
|
@ -1525,15 +1526,15 @@ void TabGame::actResetLayout()
|
||||||
playerListDock->setMaximumSize(250, 50);
|
playerListDock->setMaximumSize(250, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
QTimer::singleShot(100, this, &TabGame::freeDocksSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::createPlayAreaWidget(bool bReplay)
|
void TabGame::createPlayAreaWidget(bool bReplay)
|
||||||
{
|
{
|
||||||
phasesToolbar = new PhasesToolbar;
|
phasesToolbar = new PhasesToolbar;
|
||||||
if (!bReplay)
|
if (!bReplay)
|
||||||
connect(phasesToolbar, SIGNAL(sendGameCommand(const ::google::protobuf::Message &, int)), this,
|
connect(phasesToolbar, &PhasesToolbar::sendGameCommand, this,
|
||||||
SLOT(sendGameCommand(const ::google::protobuf::Message &, int)));
|
qOverload<const ::google::protobuf::Message &, int>(&TabGame::sendGameCommand));
|
||||||
scene = new GameScene(phasesToolbar, this);
|
scene = new GameScene(phasesToolbar, this);
|
||||||
gameView = new GameView(scene);
|
gameView = new GameView(scene);
|
||||||
|
|
||||||
|
|
@ -1551,9 +1552,8 @@ void TabGame::createReplayDock()
|
||||||
// timeline widget
|
// timeline widget
|
||||||
timelineWidget = new ReplayTimelineWidget;
|
timelineWidget = new ReplayTimelineWidget;
|
||||||
timelineWidget->setTimeline(replayTimeline);
|
timelineWidget->setTimeline(replayTimeline);
|
||||||
connect(timelineWidget, SIGNAL(processNextEvent(Player::EventProcessingOptions)), this,
|
connect(timelineWidget, &ReplayTimelineWidget::processNextEvent, this, &TabGame::replayNextEvent);
|
||||||
SLOT(replayNextEvent(Player::EventProcessingOptions)));
|
connect(timelineWidget, &ReplayTimelineWidget::replayFinished, this, &TabGame::replayFinished);
|
||||||
connect(timelineWidget, SIGNAL(replayFinished()), this, SLOT(replayFinished()));
|
|
||||||
connect(timelineWidget, &ReplayTimelineWidget::rewound, this, &TabGame::replayRewind);
|
connect(timelineWidget, &ReplayTimelineWidget::rewound, this, &TabGame::replayRewind);
|
||||||
|
|
||||||
// timeline skip shortcuts
|
// timeline skip shortcuts
|
||||||
|
|
@ -1585,13 +1585,13 @@ void TabGame::createReplayDock()
|
||||||
playButtonIcon.addPixmap(QPixmap("theme:replay/pause"), QIcon::Normal, QIcon::On);
|
playButtonIcon.addPixmap(QPixmap("theme:replay/pause"), QIcon::Normal, QIcon::On);
|
||||||
replayPlayButton->setIcon(playButtonIcon);
|
replayPlayButton->setIcon(playButtonIcon);
|
||||||
replayPlayButton->setCheckable(true);
|
replayPlayButton->setCheckable(true);
|
||||||
connect(replayPlayButton, SIGNAL(toggled(bool)), this, SLOT(replayPlayButtonToggled(bool)));
|
connect(replayPlayButton, &QToolButton::toggled, this, &TabGame::replayPlayButtonToggled);
|
||||||
|
|
||||||
replayFastForwardButton = new QToolButton;
|
replayFastForwardButton = new QToolButton;
|
||||||
replayFastForwardButton->setIconSize(QSize(32, 32));
|
replayFastForwardButton->setIconSize(QSize(32, 32));
|
||||||
replayFastForwardButton->setIcon(QPixmap("theme:replay/fastforward"));
|
replayFastForwardButton->setIcon(QPixmap("theme:replay/fastforward"));
|
||||||
replayFastForwardButton->setCheckable(true);
|
replayFastForwardButton->setCheckable(true);
|
||||||
connect(replayFastForwardButton, SIGNAL(toggled(bool)), this, SLOT(replayFastForwardButtonToggled(bool)));
|
connect(replayFastForwardButton, &QToolButton::toggled, this, &TabGame::replayFastForwardButtonToggled);
|
||||||
|
|
||||||
// putting everything together
|
// putting everything together
|
||||||
replayControlLayout = new QHBoxLayout;
|
replayControlLayout = new QHBoxLayout;
|
||||||
|
|
@ -1611,7 +1611,7 @@ void TabGame::createReplayDock()
|
||||||
replayDock->setFloating(false);
|
replayDock->setFloating(false);
|
||||||
|
|
||||||
replayDock->installEventFilter(this);
|
replayDock->installEventFilter(this);
|
||||||
connect(replayDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
connect(replayDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::createDeckViewContainerWidget(bool bReplay)
|
void TabGame::createDeckViewContainerWidget(bool bReplay)
|
||||||
|
|
@ -1652,7 +1652,7 @@ void TabGame::createCardInfoDock(bool bReplay)
|
||||||
cardInfoDock->setFloating(false);
|
cardInfoDock->setFloating(false);
|
||||||
|
|
||||||
cardInfoDock->installEventFilter(this);
|
cardInfoDock->installEventFilter(this);
|
||||||
connect(cardInfoDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
connect(cardInfoDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::createPlayerListDock(bool bReplay)
|
void TabGame::createPlayerListDock(bool bReplay)
|
||||||
|
|
@ -1674,26 +1674,28 @@ void TabGame::createPlayerListDock(bool bReplay)
|
||||||
playerListDock->setFloating(false);
|
playerListDock->setFloating(false);
|
||||||
|
|
||||||
playerListDock->installEventFilter(this);
|
playerListDock->installEventFilter(this);
|
||||||
connect(playerListDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
connect(playerListDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::createMessageDock(bool bReplay)
|
void TabGame::createMessageDock(bool bReplay)
|
||||||
{
|
{
|
||||||
messageLog = new MessageLogWidget(tabSupervisor, this);
|
messageLog = new MessageLogWidget(tabSupervisor, this);
|
||||||
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfoFrameWidget, SLOT(setCard(QString)));
|
connect(messageLog, &MessageLogWidget::cardNameHovered, cardInfoFrameWidget,
|
||||||
|
qOverload<const QString &>(&CardInfoFrameWidget::setCard));
|
||||||
connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
||||||
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
connect(messageLog, &MessageLogWidget::deleteCardInfoPopup, this, &TabGame::deleteCardInfoPopup);
|
||||||
|
|
||||||
if (!bReplay) {
|
if (!bReplay) {
|
||||||
connect(messageLog, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
connect(messageLog, &MessageLogWidget::openMessageDialog, this, &TabGame::openMessageDialog);
|
||||||
connect(messageLog, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
connect(messageLog, &MessageLogWidget::addMentionTag, this, &TabGame::addMentionTag);
|
||||||
connect(&SettingsCache::instance(), SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
connect(&SettingsCache::instance(), &SettingsCache::chatMentionCompleterChanged, this,
|
||||||
|
&TabGame::actCompleterChanged);
|
||||||
|
|
||||||
timeElapsedLabel = new QLabel;
|
timeElapsedLabel = new QLabel;
|
||||||
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
||||||
gameTimer = new QTimer(this);
|
gameTimer = new QTimer(this);
|
||||||
gameTimer->setInterval(1000);
|
gameTimer->setInterval(1000);
|
||||||
connect(gameTimer, SIGNAL(timeout()), this, SLOT(incrementGameTime()));
|
connect(gameTimer, &QTimer::timeout, this, &TabGame::incrementGameTime);
|
||||||
gameTimer->start();
|
gameTimer->start();
|
||||||
|
|
||||||
sayLabel = new QLabel;
|
sayLabel = new QLabel;
|
||||||
|
|
@ -1721,8 +1723,8 @@ void TabGame::createMessageDock(bool bReplay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(tabSupervisor, SIGNAL(adminLockChanged(bool)), this, SLOT(adminLockChanged(bool)));
|
connect(tabSupervisor, &TabSupervisor::adminLockChanged, this, &TabGame::adminLockChanged);
|
||||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay()));
|
connect(sayEdit, &LineEditCompleter::returnPressed, this, &TabGame::actSay);
|
||||||
|
|
||||||
sayHLayout = new QHBoxLayout;
|
sayHLayout = new QHBoxLayout;
|
||||||
sayHLayout->addWidget(sayLabel);
|
sayHLayout->addWidget(sayLabel);
|
||||||
|
|
@ -1748,7 +1750,7 @@ void TabGame::createMessageDock(bool bReplay)
|
||||||
messageLayoutDock->setFloating(false);
|
messageLayoutDock->setFloating(false);
|
||||||
|
|
||||||
messageLayoutDock->installEventFilter(this);
|
messageLayoutDock->installEventFilter(this);
|
||||||
connect(messageLayoutDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
connect(messageLayoutDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::hideEvent(QHideEvent *event)
|
void TabGame::hideEvent(QHideEvent *event)
|
||||||
|
|
|
||||||
|
|
@ -116,8 +116,7 @@ void TabLog::getClicked()
|
||||||
cmd.set_date_range(dateRange);
|
cmd.set_date_range(dateRange);
|
||||||
cmd.set_maximum_results(maximumResults->value());
|
cmd.set_maximum_results(maximumResults->value());
|
||||||
PendingCommand *pend = client->prepareModeratorCommand(cmd);
|
PendingCommand *pend = client->prepareModeratorCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabLog::viewLogHistory_processResponse);
|
||||||
SLOT(viewLogHistory_processResponse(Response)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,11 +185,11 @@ void TabLog::createDock()
|
||||||
|
|
||||||
getButton = new QPushButton(tr("Get User Logs"));
|
getButton = new QPushButton(tr("Get User Logs"));
|
||||||
getButton->setAutoDefault(true);
|
getButton->setAutoDefault(true);
|
||||||
connect(getButton, SIGNAL(clicked()), this, SLOT(getClicked()));
|
connect(getButton, &QPushButton::clicked, this, &TabLog::getClicked);
|
||||||
|
|
||||||
clearButton = new QPushButton(tr("Clear Filters"));
|
clearButton = new QPushButton(tr("Clear Filters"));
|
||||||
clearButton->setAutoDefault(true);
|
clearButton->setAutoDefault(true);
|
||||||
connect(clearButton, SIGNAL(clicked()), this, SLOT(clearClicked()));
|
connect(clearButton, &QPushButton::clicked, this, &TabLog::clearClicked);
|
||||||
|
|
||||||
criteriaGrid = new QGridLayout;
|
criteriaGrid = new QGridLayout;
|
||||||
criteriaGrid->addWidget(labelFindUserName, 0, 0);
|
criteriaGrid->addWidget(labelFindUserName, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor,
|
||||||
{
|
{
|
||||||
chatView = new ChatView(tabSupervisor, 0, true);
|
chatView = new ChatView(tabSupervisor, 0, true);
|
||||||
connect(chatView, &ChatView::showCardInfoPopup, this, &TabMessage::showCardInfoPopup);
|
connect(chatView, &ChatView::showCardInfoPopup, this, &TabMessage::showCardInfoPopup);
|
||||||
connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabMessage::deleteCardInfoPopup);
|
||||||
connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
connect(chatView, &ChatView::addMentionTag, this, &TabMessage::addMentionTag);
|
||||||
sayEdit = new LineEditUnfocusable;
|
sayEdit = new LineEditUnfocusable;
|
||||||
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
||||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
connect(sayEdit, &LineEditUnfocusable::returnPressed, this, &TabMessage::sendMessage);
|
||||||
|
|
||||||
QVBoxLayout *vbox = new QVBoxLayout;
|
QVBoxLayout *vbox = new QVBoxLayout;
|
||||||
vbox->addWidget(chatView);
|
vbox->addWidget(chatView);
|
||||||
|
|
@ -102,7 +102,7 @@ void TabMessage::sendMessage()
|
||||||
cmd.set_message(sayEdit->text().toStdString());
|
cmd.set_message(sayEdit->text().toStdString());
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(messageSent(const Response &)));
|
connect(pend, &PendingCommand::finished, this, &TabMessage::messageSent);
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
|
|
||||||
sayEdit->clear();
|
sayEdit->clear();
|
||||||
|
|
@ -140,10 +140,10 @@ bool TabMessage::shouldShowSystemPopup(const Event_UserMessage &event)
|
||||||
void TabMessage::showSystemPopup(const Event_UserMessage &event)
|
void TabMessage::showSystemPopup(const Event_UserMessage &event)
|
||||||
{
|
{
|
||||||
if (trayIcon) {
|
if (trayIcon) {
|
||||||
disconnect(trayIcon, SIGNAL(messageClicked()), 0, 0);
|
disconnect(trayIcon, &QSystemTrayIcon::messageClicked, 0, 0);
|
||||||
trayIcon->showMessage(tr("Private message from") + " " + otherUserInfo->name().c_str(),
|
trayIcon->showMessage(tr("Private message from") + " " + otherUserInfo->name().c_str(),
|
||||||
event.message().c_str());
|
event.message().c_str());
|
||||||
connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
|
connect(trayIcon, &QSystemTrayIcon::messageClicked, this, &TabMessage::messageClicked);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(TabMessageLog) << "Error: trayIcon is NULL. TabMessage::showSystemPopup failed";
|
qCWarning(TabMessageLog) << "Error: trayIcon is NULL. TabMessage::showSystemPopup failed";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
||||||
// Left side actions
|
// Left side actions
|
||||||
aOpenLocalReplay = new QAction(this);
|
aOpenLocalReplay = new QAction(this);
|
||||||
aOpenLocalReplay->setIcon(QPixmap("theme:icons/view"));
|
aOpenLocalReplay->setIcon(QPixmap("theme:icons/view"));
|
||||||
connect(aOpenLocalReplay, SIGNAL(triggered()), this, SLOT(actOpenLocalReplay()));
|
connect(aOpenLocalReplay, &QAction::triggered, this, &TabReplays::actOpenLocalReplay);
|
||||||
connect(localDirView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(actOpenLocalReplay()));
|
connect(localDirView, &QTreeView::doubleClicked, this, &TabReplays::actOpenLocalReplay);
|
||||||
aRenameLocal = new QAction(this);
|
aRenameLocal = new QAction(this);
|
||||||
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
||||||
connect(aRenameLocal, &QAction::triggered, this, &TabReplays::actRenameLocal);
|
connect(aRenameLocal, &QAction::triggered, this, &TabReplays::actRenameLocal);
|
||||||
|
|
@ -106,7 +106,7 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
||||||
connect(aNewLocalFolder, &QAction::triggered, this, &TabReplays::actNewLocalFolder);
|
connect(aNewLocalFolder, &QAction::triggered, this, &TabReplays::actNewLocalFolder);
|
||||||
aDeleteLocalReplay = new QAction(this);
|
aDeleteLocalReplay = new QAction(this);
|
||||||
aDeleteLocalReplay->setIcon(QPixmap("theme:icons/remove_row"));
|
aDeleteLocalReplay->setIcon(QPixmap("theme:icons/remove_row"));
|
||||||
connect(aDeleteLocalReplay, SIGNAL(triggered()), this, SLOT(actDeleteLocalReplay()));
|
connect(aDeleteLocalReplay, &QAction::triggered, this, &TabReplays::actDeleteLocalReplay);
|
||||||
|
|
||||||
aOpenReplaysFolder = new QAction(this);
|
aOpenReplaysFolder = new QAction(this);
|
||||||
aOpenReplaysFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_DirOpenIcon));
|
aOpenReplaysFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_DirOpenIcon));
|
||||||
|
|
@ -115,17 +115,17 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
||||||
// Right side actions
|
// Right side actions
|
||||||
aOpenRemoteReplay = new QAction(this);
|
aOpenRemoteReplay = new QAction(this);
|
||||||
aOpenRemoteReplay->setIcon(QPixmap("theme:icons/view"));
|
aOpenRemoteReplay->setIcon(QPixmap("theme:icons/view"));
|
||||||
connect(aOpenRemoteReplay, SIGNAL(triggered()), this, SLOT(actOpenRemoteReplay()));
|
connect(aOpenRemoteReplay, &QAction::triggered, this, &TabReplays::actOpenRemoteReplay);
|
||||||
connect(serverDirView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(actOpenRemoteReplay()));
|
connect(serverDirView, &QTreeView::doubleClicked, this, &TabReplays::actOpenRemoteReplay);
|
||||||
aDownload = new QAction(this);
|
aDownload = new QAction(this);
|
||||||
aDownload->setIcon(QPixmap("theme:icons/arrow_left_green"));
|
aDownload->setIcon(QPixmap("theme:icons/arrow_left_green"));
|
||||||
connect(aDownload, SIGNAL(triggered()), this, SLOT(actDownload()));
|
connect(aDownload, &QAction::triggered, this, &TabReplays::actDownload);
|
||||||
aKeep = new QAction(this);
|
aKeep = new QAction(this);
|
||||||
aKeep->setIcon(QPixmap("theme:icons/lock"));
|
aKeep->setIcon(QPixmap("theme:icons/lock"));
|
||||||
connect(aKeep, SIGNAL(triggered()), this, SLOT(actKeepRemoteReplay()));
|
connect(aKeep, &QAction::triggered, this, &TabReplays::actKeepRemoteReplay);
|
||||||
aDeleteRemoteReplay = new QAction(this);
|
aDeleteRemoteReplay = new QAction(this);
|
||||||
aDeleteRemoteReplay->setIcon(QPixmap("theme:icons/remove_row"));
|
aDeleteRemoteReplay->setIcon(QPixmap("theme:icons/remove_row"));
|
||||||
connect(aDeleteRemoteReplay, SIGNAL(triggered()), this, SLOT(actDeleteRemoteReplay()));
|
connect(aDeleteRemoteReplay, &QAction::triggered, this, &TabReplays::actDeleteRemoteReplay);
|
||||||
|
|
||||||
// Add actions to toolbars
|
// Add actions to toolbars
|
||||||
leftToolBar->addAction(aOpenLocalReplay);
|
leftToolBar->addAction(aOpenLocalReplay);
|
||||||
|
|
@ -146,8 +146,7 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
||||||
mainWidget->setLayout(hbox);
|
mainWidget->setLayout(hbox);
|
||||||
setCentralWidget(mainWidget);
|
setCentralWidget(mainWidget);
|
||||||
|
|
||||||
connect(client, SIGNAL(replayAddedEventReceived(const Event_ReplayAdded &)), this,
|
connect(client, &AbstractClient::replayAddedEventReceived, this, &TabReplays::replayAddedEventReceived);
|
||||||
SLOT(replayAddedEventReceived(const Event_ReplayAdded &)));
|
|
||||||
|
|
||||||
connect(client, &AbstractClient::userInfoChanged, this, &TabReplays::handleConnected);
|
connect(client, &AbstractClient::userInfoChanged, this, &TabReplays::handleConnected);
|
||||||
connect(client, &AbstractClient::statusChanged, this, &TabReplays::handleConnectionChanged);
|
connect(client, &AbstractClient::statusChanged, this, &TabReplays::handleConnectionChanged);
|
||||||
|
|
@ -323,8 +322,7 @@ void TabReplays::actOpenRemoteReplay()
|
||||||
cmd.set_replay_id(curRight->replay_id());
|
cmd.set_replay_id(curRight->replay_id());
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabReplays::openRemoteReplayFinished);
|
||||||
SLOT(openRemoteReplayFinished(const Response &)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -378,8 +376,7 @@ void TabReplays::downloadNodeAtIndex(const QModelIndex &curLeft, const QModelInd
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
pend->setExtraData(filePath);
|
pend->setExtraData(filePath);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabReplays::downloadFinished);
|
||||||
SLOT(downloadFinished(Response, CommandContainer, QVariant)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
// node at index was invalid
|
// node at index was invalid
|
||||||
|
|
@ -416,8 +413,7 @@ void TabReplays::actKeepRemoteReplay()
|
||||||
cmd.set_do_not_hide(!curRight->do_not_hide());
|
cmd.set_do_not_hide(!curRight->do_not_hide());
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabReplays::keepRemoteReplayFinished);
|
||||||
SLOT(keepRemoteReplayFinished(Response, CommandContainer)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -455,8 +451,7 @@ void TabReplays::actDeleteRemoteReplay()
|
||||||
cmd.set_game_id(curRight->game_id());
|
cmd.set_game_id(curRight->game_id());
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabReplays::deleteRemoteReplayFinished);
|
||||||
SLOT(deleteRemoteReplayFinished(Response, CommandContainer)));
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,28 +53,29 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor,
|
||||||
SIGNAL(openMessageDialog(const QString &, bool)));
|
SIGNAL(openMessageDialog(const QString &, bool)));
|
||||||
|
|
||||||
chatView = new ChatView(tabSupervisor, nullptr, true, this);
|
chatView = new ChatView(tabSupervisor, nullptr, true, this);
|
||||||
connect(chatView, SIGNAL(showMentionPopup(const QString &)), this, SLOT(actShowMentionPopup(const QString &)));
|
connect(chatView, &ChatView::showMentionPopup, this, &TabRoom::actShowMentionPopup);
|
||||||
connect(chatView, SIGNAL(messageClickedSignal()), this, SLOT(focusTab()));
|
connect(chatView, &ChatView::messageClickedSignal, this, &TabRoom::focusTab);
|
||||||
connect(chatView, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
connect(chatView, &ChatView::openMessageDialog, this, &TabRoom::openMessageDialog);
|
||||||
connect(chatView, &ChatView::showCardInfoPopup, this, &TabRoom::showCardInfoPopup);
|
connect(chatView, &ChatView::showCardInfoPopup, this, &TabRoom::showCardInfoPopup);
|
||||||
connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabRoom::deleteCardInfoPopup);
|
||||||
connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
connect(chatView, &ChatView::addMentionTag, this, &TabRoom::addMentionTag);
|
||||||
connect(&SettingsCache::instance(), SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
connect(&SettingsCache::instance(), &SettingsCache::chatMentionCompleterChanged, this,
|
||||||
|
&TabRoom::actCompleterChanged);
|
||||||
sayLabel = new QLabel;
|
sayLabel = new QLabel;
|
||||||
sayEdit = new LineEditCompleter;
|
sayEdit = new LineEditCompleter;
|
||||||
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
||||||
sayLabel->setBuddy(sayEdit);
|
sayLabel->setBuddy(sayEdit);
|
||||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
connect(sayEdit, &LineEditCompleter::returnPressed, this, &TabRoom::sendMessage);
|
||||||
|
|
||||||
QMenu *chatSettingsMenu = new QMenu(this);
|
QMenu *chatSettingsMenu = new QMenu(this);
|
||||||
|
|
||||||
aClearChat = chatSettingsMenu->addAction(QString());
|
aClearChat = chatSettingsMenu->addAction(QString());
|
||||||
connect(aClearChat, SIGNAL(triggered()), this, SLOT(actClearChat()));
|
connect(aClearChat, &QAction::triggered, this, &TabRoom::actClearChat);
|
||||||
|
|
||||||
chatSettingsMenu->addSeparator();
|
chatSettingsMenu->addSeparator();
|
||||||
|
|
||||||
aOpenChatSettings = chatSettingsMenu->addAction(QString());
|
aOpenChatSettings = chatSettingsMenu->addAction(QString());
|
||||||
connect(aOpenChatSettings, SIGNAL(triggered()), this, SLOT(actOpenChatSettings()));
|
connect(aOpenChatSettings, &QAction::triggered, this, &TabRoom::actOpenChatSettings);
|
||||||
|
|
||||||
QToolButton *chatSettingsButton = new QToolButton;
|
QToolButton *chatSettingsButton = new QToolButton;
|
||||||
chatSettingsButton->setIcon(QPixmap("theme:icons/settings"));
|
chatSettingsButton->setIcon(QPixmap("theme:icons/settings"));
|
||||||
|
|
@ -126,7 +127,8 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor,
|
||||||
|
|
||||||
sayEdit->setCompleter(completer);
|
sayEdit->setCompleter(completer);
|
||||||
actCompleterChanged();
|
actCompleterChanged();
|
||||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||||
|
&TabRoom::refreshShortcuts);
|
||||||
refreshShortcuts();
|
refreshShortcuts();
|
||||||
|
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
|
|
@ -165,9 +167,9 @@ void TabRoom::actShowPopup(const QString &message)
|
||||||
{
|
{
|
||||||
if (trayIcon && (tabSupervisor->currentIndex() != tabSupervisor->indexOf(this) ||
|
if (trayIcon && (tabSupervisor->currentIndex() != tabSupervisor->indexOf(this) ||
|
||||||
QApplication::activeWindow() == nullptr || QApplication::focusWidget() == nullptr)) {
|
QApplication::activeWindow() == nullptr || QApplication::focusWidget() == nullptr)) {
|
||||||
disconnect(trayIcon, SIGNAL(messageClicked()), nullptr, nullptr);
|
disconnect(trayIcon, &QSystemTrayIcon::messageClicked, nullptr, nullptr);
|
||||||
trayIcon->showMessage(message, tr("Click to view"));
|
trayIcon->showMessage(message, tr("Click to view"));
|
||||||
connect(trayIcon, SIGNAL(messageClicked()), chatView, SLOT(actMessageClicked()));
|
connect(trayIcon, &QSystemTrayIcon::messageClicked, chatView, &ChatView::messageClickedSignal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,8 +203,7 @@ void TabRoom::sendMessage()
|
||||||
cmd.set_message(sayEdit->text().toStdString());
|
cmd.set_message(sayEdit->text().toStdString());
|
||||||
|
|
||||||
PendingCommand *pend = prepareRoomCommand(cmd);
|
PendingCommand *pend = prepareRoomCommand(cmd);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabRoom::sayFinished);
|
||||||
SLOT(sayFinished(const Response &)));
|
|
||||||
sendRoomCommand(pend);
|
sendRoomCommand(pend);
|
||||||
sayEdit->clear();
|
sayEdit->clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) : QGroupBox
|
||||||
roomList->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
roomList->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||||
|
|
||||||
joinButton = new QPushButton;
|
joinButton = new QPushButton;
|
||||||
connect(joinButton, SIGNAL(clicked()), this, SLOT(joinClicked()));
|
connect(joinButton, &QPushButton::clicked, this, &RoomSelector::joinClicked);
|
||||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||||
buttonLayout->addStretch();
|
buttonLayout->addStretch();
|
||||||
buttonLayout->addWidget(joinButton);
|
buttonLayout->addWidget(joinButton);
|
||||||
|
|
@ -44,9 +44,8 @@ RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) : QGroupBox
|
||||||
retranslateUi();
|
retranslateUi();
|
||||||
setLayout(vbox);
|
setLayout(vbox);
|
||||||
|
|
||||||
connect(client, SIGNAL(listRoomsEventReceived(const Event_ListRooms &)), this,
|
connect(client, &AbstractClient::listRoomsEventReceived, this, &RoomSelector::processListRoomsEvent);
|
||||||
SLOT(processListRoomsEvent(const Event_ListRooms &)));
|
connect(roomList, &QTreeWidget::activated, this, &RoomSelector::joinClicked);
|
||||||
connect(roomList, SIGNAL(activated(const QModelIndex &)), this, SLOT(joinClicked()));
|
|
||||||
client->sendCommand(client->prepareSessionCommand(Command_ListRooms()));
|
client->sendCommand(client->prepareSessionCommand(Command_ListRooms()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,10 +143,9 @@ TabServer::TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client) : T
|
||||||
serverInfoBox = new QTextBrowser;
|
serverInfoBox = new QTextBrowser;
|
||||||
serverInfoBox->setOpenExternalLinks(true);
|
serverInfoBox->setOpenExternalLinks(true);
|
||||||
|
|
||||||
connect(roomSelector, SIGNAL(joinRoomRequest(int, bool)), this, SLOT(joinRoom(int, bool)));
|
connect(roomSelector, &RoomSelector::joinRoomRequest, this, &TabServer::joinRoom);
|
||||||
|
|
||||||
connect(client, SIGNAL(serverMessageEventReceived(const Event_ServerMessage &)), this,
|
connect(client, &AbstractClient::serverMessageEventReceived, this, &TabServer::processServerMessageEvent);
|
||||||
SLOT(processServerMessageEvent(const Event_ServerMessage &)));
|
|
||||||
|
|
||||||
QVBoxLayout *vbox = new QVBoxLayout;
|
QVBoxLayout *vbox = new QVBoxLayout;
|
||||||
vbox->addWidget(roomSelector);
|
vbox->addWidget(roomSelector);
|
||||||
|
|
@ -185,8 +183,7 @@ void TabServer::joinRoom(int id, bool setCurrent)
|
||||||
|
|
||||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||||
pend->setExtraData(setCurrent);
|
pend->setExtraData(setCurrent);
|
||||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
connect(pend, &PendingCommand::finished, this, &TabServer::joinRoomFinished);
|
||||||
SLOT(joinRoomFinished(Response, CommandContainer, QVariant)));
|
|
||||||
|
|
||||||
client->sendCommand(pend);
|
client->sendCommand(pend);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../../server/user/user_list_widget.h"
|
#include "../../server/user/user_list_widget.h"
|
||||||
#include "../../settings/cache_settings.h"
|
#include "../../settings/cache_settings.h"
|
||||||
#include "../ui/pixel_map_generator.h"
|
#include "../ui/pixel_map_generator.h"
|
||||||
|
#include "api/edhrec/tab_edhrec_main.h"
|
||||||
#include "pb/event_game_joined.pb.h"
|
#include "pb/event_game_joined.pb.h"
|
||||||
#include "pb/event_notify_user.pb.h"
|
#include "pb/event_notify_user.pb.h"
|
||||||
#include "pb/event_user_message.pb.h"
|
#include "pb/event_user_message.pb.h"
|
||||||
|
|
@ -25,6 +26,9 @@
|
||||||
#include "tab_replays.h"
|
#include "tab_replays.h"
|
||||||
#include "tab_room.h"
|
#include "tab_room.h"
|
||||||
#include "tab_server.h"
|
#include "tab_server.h"
|
||||||
|
#include "tab_visual_database_display.h"
|
||||||
|
#include "visual_deck_editor/tab_deck_editor_visual.h"
|
||||||
|
#include "visual_deck_editor/tab_deck_editor_visual_tab_widget.h"
|
||||||
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
@ -130,10 +134,19 @@ TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *
|
||||||
aTabDeckEditor = new QAction(this);
|
aTabDeckEditor = new QAction(this);
|
||||||
connect(aTabDeckEditor, &QAction::triggered, this, [this] { addDeckEditorTab(nullptr); });
|
connect(aTabDeckEditor, &QAction::triggered, this, [this] { addDeckEditorTab(nullptr); });
|
||||||
|
|
||||||
|
aTabVisualDeckEditor = new QAction(this);
|
||||||
|
connect(aTabVisualDeckEditor, &QAction::triggered, this, [this] { addVisualDeckEditorTab(nullptr); });
|
||||||
|
|
||||||
|
aTabEdhRec = new QAction(this);
|
||||||
|
connect(aTabEdhRec, &QAction::triggered, this, [this] { addEdhrecMainTab(); });
|
||||||
|
|
||||||
aTabVisualDeckStorage = new QAction(this);
|
aTabVisualDeckStorage = new QAction(this);
|
||||||
aTabVisualDeckStorage->setCheckable(true);
|
aTabVisualDeckStorage->setCheckable(true);
|
||||||
connect(aTabVisualDeckStorage, &QAction::triggered, this, &TabSupervisor::actTabVisualDeckStorage);
|
connect(aTabVisualDeckStorage, &QAction::triggered, this, &TabSupervisor::actTabVisualDeckStorage);
|
||||||
|
|
||||||
|
aTabVisualDatabaseDisplay = new QAction(this);
|
||||||
|
connect(aTabVisualDatabaseDisplay, &QAction::triggered, this, [this] { addVisualDatabaseDisplayTab(); });
|
||||||
|
|
||||||
aTabServer = new QAction(this);
|
aTabServer = new QAction(this);
|
||||||
aTabServer->setCheckable(true);
|
aTabServer->setCheckable(true);
|
||||||
connect(aTabServer, &QAction::triggered, this, &TabSupervisor::actTabServer);
|
connect(aTabServer, &QAction::triggered, this, &TabSupervisor::actTabServer);
|
||||||
|
|
@ -176,7 +189,10 @@ void TabSupervisor::retranslateUi()
|
||||||
{
|
{
|
||||||
// tab menu actions
|
// tab menu actions
|
||||||
aTabDeckEditor->setText(tr("Deck Editor"));
|
aTabDeckEditor->setText(tr("Deck Editor"));
|
||||||
|
aTabVisualDeckEditor->setText(tr("Visual Deck Editor"));
|
||||||
|
aTabEdhRec->setText(tr("EDHRec"));
|
||||||
aTabVisualDeckStorage->setText(tr("&Visual Deck Storage"));
|
aTabVisualDeckStorage->setText(tr("&Visual Deck Storage"));
|
||||||
|
aTabVisualDatabaseDisplay->setText(tr("Visual Database Display"));
|
||||||
aTabServer->setText(tr("Server"));
|
aTabServer->setText(tr("Server"));
|
||||||
aTabAccount->setText(tr("Account"));
|
aTabAccount->setText(tr("Account"));
|
||||||
aTabDeckStorage->setText(tr("Deck Storage"));
|
aTabDeckStorage->setText(tr("Deck Storage"));
|
||||||
|
|
@ -223,6 +239,7 @@ void TabSupervisor::refreshShortcuts()
|
||||||
{
|
{
|
||||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||||
aTabDeckEditor->setShortcuts(shortcuts.getShortcut("Tabs/aTabDeckEditor"));
|
aTabDeckEditor->setShortcuts(shortcuts.getShortcut("Tabs/aTabDeckEditor"));
|
||||||
|
aTabVisualDeckEditor->setShortcuts(shortcuts.getShortcut("Tabs/aTabVisualDeckEditor"));
|
||||||
aTabVisualDeckStorage->setShortcuts(shortcuts.getShortcut("Tabs/aTabVisualDeckStorage"));
|
aTabVisualDeckStorage->setShortcuts(shortcuts.getShortcut("Tabs/aTabVisualDeckStorage"));
|
||||||
aTabServer->setShortcuts(shortcuts.getShortcut("Tabs/aTabServer"));
|
aTabServer->setShortcuts(shortcuts.getShortcut("Tabs/aTabServer"));
|
||||||
aTabAccount->setShortcuts(shortcuts.getShortcut("Tabs/aTabAccount"));
|
aTabAccount->setShortcuts(shortcuts.getShortcut("Tabs/aTabAccount"));
|
||||||
|
|
@ -370,8 +387,11 @@ void TabSupervisor::resetTabsMenu()
|
||||||
{
|
{
|
||||||
tabsMenu->clear();
|
tabsMenu->clear();
|
||||||
tabsMenu->addAction(aTabDeckEditor);
|
tabsMenu->addAction(aTabDeckEditor);
|
||||||
|
tabsMenu->addAction(aTabVisualDeckEditor);
|
||||||
|
tabsMenu->addAction(aTabEdhRec);
|
||||||
tabsMenu->addSeparator();
|
tabsMenu->addSeparator();
|
||||||
tabsMenu->addAction(aTabVisualDeckStorage);
|
tabsMenu->addAction(aTabVisualDeckStorage);
|
||||||
|
tabsMenu->addAction(aTabVisualDatabaseDisplay);
|
||||||
tabsMenu->addAction(aTabDeckStorage);
|
tabsMenu->addAction(aTabDeckStorage);
|
||||||
tabsMenu->addAction(aTabReplays);
|
tabsMenu->addAction(aTabReplays);
|
||||||
}
|
}
|
||||||
|
|
@ -804,6 +824,36 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TabDeckEditorVisual *TabSupervisor::addVisualDeckEditorTab(const DeckLoader *deckToOpen)
|
||||||
|
{
|
||||||
|
auto *tab = new TabDeckEditorVisual(this);
|
||||||
|
if (deckToOpen)
|
||||||
|
tab->openDeck(new DeckLoader(*deckToOpen));
|
||||||
|
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
|
||||||
|
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addVisualDeckEditorTab);
|
||||||
|
myAddTab(tab);
|
||||||
|
deckEditorTabs.append(tab);
|
||||||
|
setCurrentWidget(tab);
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
TabEdhRecMain *TabSupervisor::addEdhrecMainTab()
|
||||||
|
{
|
||||||
|
auto *tab = new TabEdhRecMain(this);
|
||||||
|
|
||||||
|
myAddTab(tab);
|
||||||
|
setCurrentWidget(tab);
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
TabVisualDatabaseDisplay *TabSupervisor::addVisualDatabaseDisplayTab()
|
||||||
|
{
|
||||||
|
auto *tab = new TabVisualDatabaseDisplay(this);
|
||||||
|
myAddTab(tab);
|
||||||
|
setCurrentWidget(tab);
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
TabEdhRec *TabSupervisor::addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander)
|
TabEdhRec *TabSupervisor::addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander)
|
||||||
{
|
{
|
||||||
auto *tab = new TabEdhRec(this);
|
auto *tab = new TabEdhRec(this);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
#include "../../server/user/user_list_proxy.h"
|
#include "../../server/user/user_list_proxy.h"
|
||||||
#include "abstract_tab_deck_editor.h"
|
#include "abstract_tab_deck_editor.h"
|
||||||
#include "api/edhrec/tab_edhrec.h"
|
#include "api/edhrec/tab_edhrec.h"
|
||||||
|
#include "api/edhrec/tab_edhrec_main.h"
|
||||||
|
#include "tab_visual_database_display.h"
|
||||||
|
#include "visual_deck_editor/tab_deck_editor_visual.h"
|
||||||
|
#include "visual_deck_editor/tab_deck_editor_visual_tab_widget.h"
|
||||||
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
||||||
|
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
|
|
@ -91,8 +95,8 @@ private:
|
||||||
QList<AbstractTabDeckEditor *> deckEditorTabs;
|
QList<AbstractTabDeckEditor *> deckEditorTabs;
|
||||||
bool isLocalGame;
|
bool isLocalGame;
|
||||||
|
|
||||||
QAction *aTabDeckEditor, *aTabVisualDeckStorage, *aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays,
|
QAction *aTabDeckEditor, *aTabVisualDeckEditor, *aTabEdhRec, *aTabVisualDeckStorage, *aTabVisualDatabaseDisplay,
|
||||||
*aTabAdmin, *aTabLog;
|
*aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays, *aTabAdmin, *aTabLog;
|
||||||
|
|
||||||
int myAddTab(Tab *tab, QAction *manager = nullptr);
|
int myAddTab(Tab *tab, QAction *manager = nullptr);
|
||||||
void addCloseButtonToTab(Tab *tab, int tabIndex, QAction *manager);
|
void addCloseButtonToTab(Tab *tab, int tabIndex, QAction *manager);
|
||||||
|
|
@ -149,6 +153,9 @@ signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
TabDeckEditor *addDeckEditorTab(const DeckLoader *deckToOpen);
|
TabDeckEditor *addDeckEditorTab(const DeckLoader *deckToOpen);
|
||||||
|
TabDeckEditorVisual *addVisualDeckEditorTab(const DeckLoader *deckToOpen);
|
||||||
|
TabVisualDatabaseDisplay *addVisualDatabaseDisplayTab();
|
||||||
|
TabEdhRecMain *addEdhrecMainTab();
|
||||||
TabEdhRec *addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander = false);
|
TabEdhRec *addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander = false);
|
||||||
void openReplay(GameReplay *replay);
|
void openReplay(GameReplay *replay);
|
||||||
void maximizeMainWindow();
|
void maximizeMainWindow();
|
||||||
|
|
|
||||||
20
cockatrice/src/client/tabs/tab_visual_database_display.cpp
Normal file
20
cockatrice/src/client/tabs/tab_visual_database_display.cpp
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "tab_visual_database_display.h"
|
||||||
|
|
||||||
|
#include "tab_deck_editor.h"
|
||||||
|
|
||||||
|
TabVisualDatabaseDisplay::TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||||
|
{
|
||||||
|
deckEditor = new TabDeckEditor(_tabSupervisor);
|
||||||
|
deckEditor->setHidden(true);
|
||||||
|
visualDatabaseDisplayWidget =
|
||||||
|
new VisualDatabaseDisplayWidget(this, deckEditor, deckEditor->databaseDisplayDockWidget->databaseModel,
|
||||||
|
deckEditor->databaseDisplayDockWidget->databaseDisplayModel);
|
||||||
|
|
||||||
|
setCentralWidget(visualDatabaseDisplayWidget);
|
||||||
|
|
||||||
|
TabVisualDatabaseDisplay::retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabVisualDatabaseDisplay::retranslateUi()
|
||||||
|
{
|
||||||
|
}
|
||||||
26
cockatrice/src/client/tabs/tab_visual_database_display.h
Normal file
26
cockatrice/src/client/tabs/tab_visual_database_display.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef TAB_VISUAL_DATABASE_DISPLAY_H
|
||||||
|
#define TAB_VISUAL_DATABASE_DISPLAY_H
|
||||||
|
|
||||||
|
#include "../ui/widgets/visual_database_display/visual_database_display_widget.h"
|
||||||
|
#include "tab.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
class TabVisualDatabaseDisplay : public Tab
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
TabDeckEditor *deckEditor;
|
||||||
|
VisualDatabaseDisplayWidget *visualDatabaseDisplayWidget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor);
|
||||||
|
void retranslateUi() override;
|
||||||
|
QString getTabText() const override
|
||||||
|
{
|
||||||
|
return tr("Visual Database Display");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TAB_VISUAL_DATABASE_DISPLAY_H
|
||||||
|
|
@ -0,0 +1,470 @@
|
||||||
|
#include "tab_deck_editor_visual.h"
|
||||||
|
|
||||||
|
#include "../../../deck/deck_list_model.h"
|
||||||
|
#include "../../../deck/deck_stats_interface.h"
|
||||||
|
#include "../../../game/cards/card_database_model.h"
|
||||||
|
#include "../../../game/filters/filter_builder.h"
|
||||||
|
#include "../../../server/pending_command.h"
|
||||||
|
#include "../../../settings/cache_settings.h"
|
||||||
|
#include "../../ui/pixel_map_generator.h"
|
||||||
|
#include "../../ui/widgets/cards/card_info_frame_widget.h"
|
||||||
|
#include "../../ui/widgets/deck_analytics/deck_analytics_widget.h"
|
||||||
|
#include "../../ui/widgets/visual_deck_editor/visual_deck_editor_widget.h"
|
||||||
|
#include "../tab_deck_editor.h"
|
||||||
|
#include "../tab_supervisor.h"
|
||||||
|
#include "pb/command_deck_upload.pb.h"
|
||||||
|
#include "tab_deck_editor_visual_tab_widget.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCloseEvent>
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QPrintPreviewDialog>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
TabDeckEditorVisual::TabDeckEditorVisual(TabSupervisor *_tabSupervisor) : AbstractTabDeckEditor(_tabSupervisor)
|
||||||
|
{
|
||||||
|
setObjectName("TabDeckEditorVisual");
|
||||||
|
|
||||||
|
createCentralFrame();
|
||||||
|
|
||||||
|
TabDeckEditorVisual::createMenus();
|
||||||
|
|
||||||
|
installEventFilter(this);
|
||||||
|
|
||||||
|
TabDeckEditorVisual::retranslateUi();
|
||||||
|
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||||
|
TabDeckEditorVisual::refreshShortcuts();
|
||||||
|
|
||||||
|
TabDeckEditorVisual::loadLayout();
|
||||||
|
databaseDisplayDockWidget->setHidden(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::createCentralFrame()
|
||||||
|
{
|
||||||
|
centralWidget = new QWidget(this);
|
||||||
|
centralWidget->setObjectName("centralWidget");
|
||||||
|
|
||||||
|
centralFrame = new QVBoxLayout;
|
||||||
|
centralWidget->setLayout(centralFrame);
|
||||||
|
|
||||||
|
tabContainer = new TabDeckEditorVisualTabWidget(centralWidget, this, deckDockWidget->deckModel,
|
||||||
|
databaseDisplayDockWidget->databaseModel,
|
||||||
|
databaseDisplayDockWidget->databaseDisplayModel);
|
||||||
|
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardChanged, this,
|
||||||
|
&TabDeckEditorVisual::changeModelIndexAndCardInfo);
|
||||||
|
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardChangedDatabaseDisplay, this,
|
||||||
|
&AbstractTabDeckEditor::updateCard);
|
||||||
|
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardClicked, this,
|
||||||
|
&TabDeckEditorVisual::processMainboardCardClick);
|
||||||
|
|
||||||
|
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardClickedDatabaseDisplay, this,
|
||||||
|
&TabDeckEditorVisual::processCardClickDatabaseDisplay);
|
||||||
|
centralFrame->addWidget(tabContainer);
|
||||||
|
|
||||||
|
setCentralWidget(centralWidget);
|
||||||
|
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::onDeckChanged()
|
||||||
|
{
|
||||||
|
AbstractTabDeckEditor::onDeckChanged();
|
||||||
|
tabContainer->visualDeckView->decklistDataChanged(QModelIndex(), QModelIndex());
|
||||||
|
tabContainer->deckAnalytics->refreshDisplays(deckDockWidget->deckModel);
|
||||||
|
tabContainer->sampleHandWidget->setDeckModel(deckDockWidget->deckModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::createMenus()
|
||||||
|
{
|
||||||
|
deckMenu = new DeckEditorMenu(this);
|
||||||
|
addTabMenu(deckMenu);
|
||||||
|
|
||||||
|
viewMenu = new QMenu(this);
|
||||||
|
|
||||||
|
cardInfoDockMenu = viewMenu->addMenu(QString());
|
||||||
|
deckDockMenu = viewMenu->addMenu(QString());
|
||||||
|
deckAnalyticsMenu = viewMenu->addMenu(QString());
|
||||||
|
filterDockMenu = viewMenu->addMenu(QString());
|
||||||
|
printingSelectorDockMenu = viewMenu->addMenu(QString());
|
||||||
|
|
||||||
|
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||||
|
aCardInfoDockVisible->setCheckable(true);
|
||||||
|
connect(aCardInfoDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||||
|
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||||
|
aCardInfoDockFloating->setCheckable(true);
|
||||||
|
connect(aCardInfoDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||||
|
|
||||||
|
aDeckDockVisible = deckDockMenu->addAction(QString());
|
||||||
|
aDeckDockVisible->setCheckable(true);
|
||||||
|
connect(aDeckDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||||
|
aDeckDockFloating = deckDockMenu->addAction(QString());
|
||||||
|
aDeckDockFloating->setCheckable(true);
|
||||||
|
connect(aDeckDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||||
|
|
||||||
|
aDeckAnalyticsDockVisible = deckAnalyticsMenu->addAction(QString());
|
||||||
|
aDeckAnalyticsDockVisible->setCheckable(true);
|
||||||
|
connect(aDeckAnalyticsDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||||
|
aDeckAnalyticsDockFloating = deckAnalyticsMenu->addAction(QString());
|
||||||
|
aDeckAnalyticsDockFloating->setCheckable(true);
|
||||||
|
connect(aDeckAnalyticsDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||||
|
|
||||||
|
aFilterDockVisible = filterDockMenu->addAction(QString());
|
||||||
|
aFilterDockVisible->setCheckable(true);
|
||||||
|
connect(aFilterDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||||
|
aFilterDockFloating = filterDockMenu->addAction(QString());
|
||||||
|
aFilterDockFloating->setCheckable(true);
|
||||||
|
connect(aFilterDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||||
|
|
||||||
|
aPrintingSelectorDockVisible = printingSelectorDockMenu->addAction(QString());
|
||||||
|
aPrintingSelectorDockVisible->setCheckable(true);
|
||||||
|
connect(aPrintingSelectorDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||||
|
aPrintingSelectorDockFloating = printingSelectorDockMenu->addAction(QString());
|
||||||
|
aPrintingSelectorDockFloating->setCheckable(true);
|
||||||
|
connect(aPrintingSelectorDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||||
|
|
||||||
|
viewMenu->addSeparator();
|
||||||
|
|
||||||
|
aResetLayout = viewMenu->addAction(QString());
|
||||||
|
connect(aResetLayout, SIGNAL(triggered()), this, SLOT(restartLayout()));
|
||||||
|
viewMenu->addAction(aResetLayout);
|
||||||
|
|
||||||
|
deckMenu->setSaveStatus(false);
|
||||||
|
|
||||||
|
addTabMenu(viewMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TabDeckEditorVisual::getTabText() const
|
||||||
|
{
|
||||||
|
QString result = tr("Visual Deck: %1").arg(deckDockWidget->getSimpleDeckName());
|
||||||
|
if (modified)
|
||||||
|
result.prepend("* ");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::changeModelIndexAndCardInfo(const CardInfoPtr &activeCard)
|
||||||
|
{
|
||||||
|
updateCard(activeCard);
|
||||||
|
changeModelIndexToCard(activeCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::changeModelIndexToCard(const CardInfoPtr &activeCard)
|
||||||
|
{
|
||||||
|
QString cardName = activeCard->getName();
|
||||||
|
QModelIndex index = deckDockWidget->deckModel->findCard(cardName, DECK_ZONE_MAIN);
|
||||||
|
if (!index.isValid()) {
|
||||||
|
index = deckDockWidget->deckModel->findCard(cardName, DECK_ZONE_SIDE);
|
||||||
|
}
|
||||||
|
deckDockWidget->deckView->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event,
|
||||||
|
CardInfoPictureWithTextOverlayWidget *instance,
|
||||||
|
QString zoneName)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
actSwapCard(instance->getInfo(), zoneName);
|
||||||
|
} else if (event->button() == Qt::RightButton) {
|
||||||
|
actDecrementCard(instance->getInfo());
|
||||||
|
} else if (event->button() == Qt::MiddleButton) {
|
||||||
|
deckDockWidget->actRemoveCard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::processCardClickDatabaseDisplay(QMouseEvent *event,
|
||||||
|
CardInfoPictureWithTextOverlayWidget *instance)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
actAddCard(instance->getInfo());
|
||||||
|
} else if (event->button() == Qt::RightButton) {
|
||||||
|
actDecrementCard(instance->getInfo());
|
||||||
|
} else if (event->button() == Qt::MiddleButton) {
|
||||||
|
deckDockWidget->actRemoveCard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TabDeckEditorVisual::actSaveDeckAs()
|
||||||
|
{
|
||||||
|
// We have to disable the quick-add search bar or else it'll steal focus after dialog creation.
|
||||||
|
tabContainer->visualDeckView->searchBar->setEnabled(false);
|
||||||
|
auto result = AbstractTabDeckEditor::actSaveDeckAs();
|
||||||
|
tabContainer->visualDeckView->searchBar->setEnabled(true);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::showPrintingSelector()
|
||||||
|
{
|
||||||
|
printingSelectorDockWidget->printingSelector->setCard(cardInfoDockWidget->cardInfo->getInfo(), DECK_ZONE_MAIN);
|
||||||
|
printingSelectorDockWidget->printingSelector->updateDisplay();
|
||||||
|
aPrintingSelectorDockVisible->setChecked(true);
|
||||||
|
printingSelectorDockWidget->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::restartLayout()
|
||||||
|
{
|
||||||
|
deckDockWidget->setVisible(true);
|
||||||
|
cardInfoDockWidget->setVisible(true);
|
||||||
|
filterDockWidget->setVisible(true);
|
||||||
|
|
||||||
|
deckDockWidget->setFloating(false);
|
||||||
|
cardInfoDockWidget->setFloating(false);
|
||||||
|
filterDockWidget->setFloating(false);
|
||||||
|
|
||||||
|
aCardInfoDockVisible->setChecked(true);
|
||||||
|
aDeckDockVisible->setChecked(true);
|
||||||
|
aFilterDockVisible->setChecked(true);
|
||||||
|
|
||||||
|
aCardInfoDockFloating->setChecked(false);
|
||||||
|
aDeckDockFloating->setChecked(false);
|
||||||
|
aFilterDockFloating->setChecked(false);
|
||||||
|
|
||||||
|
addDockWidget(static_cast<Qt::DockWidgetArea>(2), deckDockWidget);
|
||||||
|
addDockWidget(static_cast<Qt::DockWidgetArea>(2), cardInfoDockWidget);
|
||||||
|
addDockWidget(static_cast<Qt::DockWidgetArea>(1), deckAnalyticsDock);
|
||||||
|
addDockWidget(static_cast<Qt::DockWidgetArea>(2), filterDockWidget);
|
||||||
|
|
||||||
|
splitDockWidget(cardInfoDockWidget, deckDockWidget, Qt::Horizontal);
|
||||||
|
splitDockWidget(cardInfoDockWidget, filterDockWidget, Qt::Vertical);
|
||||||
|
splitDockWidget(searchAndDatabaseDock, deckAnalyticsDock, Qt::Vertical);
|
||||||
|
|
||||||
|
deckDockWidget->setMinimumWidth(360);
|
||||||
|
deckDockWidget->setMaximumWidth(360);
|
||||||
|
|
||||||
|
cardInfoDockWidget->setMinimumSize(250, 360);
|
||||||
|
cardInfoDockWidget->setMaximumSize(250, 360);
|
||||||
|
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::freeDocksSize()
|
||||||
|
{
|
||||||
|
deckDockWidget->setMinimumSize(100, 100);
|
||||||
|
deckDockWidget->setMaximumSize(5000, 5000);
|
||||||
|
|
||||||
|
cardInfoDockWidget->setMinimumSize(100, 100);
|
||||||
|
cardInfoDockWidget->setMaximumSize(5000, 5000);
|
||||||
|
|
||||||
|
filterDockWidget->setMinimumSize(100, 100);
|
||||||
|
filterDockWidget->setMaximumSize(5000, 5000);
|
||||||
|
|
||||||
|
databaseDisplayDockWidget->setMinimumSize(100, 100);
|
||||||
|
databaseDisplayDockWidget->setMaximumSize(1400, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::refreshShortcuts()
|
||||||
|
{
|
||||||
|
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||||
|
aResetLayout->setShortcuts(shortcuts.getShortcut("TabDeckEditorVisual/aResetLayout"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::loadLayout()
|
||||||
|
{
|
||||||
|
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||||
|
auto &layoutState = layouts.getDeckEditorLayoutState();
|
||||||
|
if (layoutState.isNull()) {
|
||||||
|
restartLayout();
|
||||||
|
} else {
|
||||||
|
restoreState(layoutState);
|
||||||
|
restoreGeometry(layouts.getDeckEditorGeometry());
|
||||||
|
}
|
||||||
|
|
||||||
|
aCardInfoDockVisible->setChecked(!cardInfoDockWidget->isHidden());
|
||||||
|
aFilterDockVisible->setChecked(!filterDockWidget->isHidden());
|
||||||
|
aDeckDockVisible->setChecked(!deckDockWidget->isHidden());
|
||||||
|
aPrintingSelectorDockVisible->setChecked(!printingSelectorDockWidget->isHidden());
|
||||||
|
|
||||||
|
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||||
|
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||||
|
aFilterDockFloating->setEnabled(aFilterDockVisible->isChecked());
|
||||||
|
aPrintingSelectorDockFloating->setEnabled(aPrintingSelectorDockVisible->isChecked());
|
||||||
|
|
||||||
|
aCardInfoDockFloating->setChecked(cardInfoDockWidget->isFloating());
|
||||||
|
aFilterDockFloating->setChecked(filterDockWidget->isFloating());
|
||||||
|
aDeckDockFloating->setChecked(deckDockWidget->isFloating());
|
||||||
|
aPrintingSelectorDockFloating->setChecked(printingSelectorDockWidget->isFloating());
|
||||||
|
|
||||||
|
cardInfoDockWidget->setMinimumSize(layouts.getDeckEditorCardSize());
|
||||||
|
cardInfoDockWidget->setMaximumSize(layouts.getDeckEditorCardSize());
|
||||||
|
|
||||||
|
filterDockWidget->setMinimumSize(layouts.getDeckEditorFilterSize());
|
||||||
|
filterDockWidget->setMaximumSize(layouts.getDeckEditorFilterSize());
|
||||||
|
|
||||||
|
deckDockWidget->setMinimumSize(layouts.getDeckEditorDeckSize());
|
||||||
|
deckDockWidget->setMaximumSize(layouts.getDeckEditorDeckSize());
|
||||||
|
|
||||||
|
printingSelectorDockWidget->setMinimumSize(layouts.getDeckEditorPrintingSelectorSize());
|
||||||
|
printingSelectorDockWidget->setMaximumSize(layouts.getDeckEditorPrintingSelectorSize());
|
||||||
|
|
||||||
|
databaseDisplayDockWidget->setMinimumSize(100, 100);
|
||||||
|
databaseDisplayDockWidget->setMaximumSize(1400, 5000);
|
||||||
|
|
||||||
|
QTimer::singleShot(100, this, &TabDeckEditorVisual::freeDocksSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::retranslateUi()
|
||||||
|
{
|
||||||
|
deckMenu->setTitle(tr("&Visual Deck Editor"));
|
||||||
|
|
||||||
|
cardInfoDockWidget->setWindowTitle(tr("Card Info"));
|
||||||
|
deckDockWidget->setWindowTitle(tr("Deck"));
|
||||||
|
filterDockWidget->setWindowTitle(tr("Filters"));
|
||||||
|
|
||||||
|
viewMenu->setTitle(tr("&View"));
|
||||||
|
cardInfoDockMenu->setTitle(tr("Card Info"));
|
||||||
|
deckDockMenu->setTitle(tr("Deck"));
|
||||||
|
deckAnalyticsMenu->setTitle(tr("Deck Analytics"));
|
||||||
|
filterDockMenu->setTitle(tr("Filters"));
|
||||||
|
printingSelectorDockMenu->setTitle(tr("Printing"));
|
||||||
|
|
||||||
|
aCardInfoDockVisible->setText(tr("Visible"));
|
||||||
|
aCardInfoDockFloating->setText(tr("Floating"));
|
||||||
|
|
||||||
|
aDeckDockVisible->setText(tr("Visible"));
|
||||||
|
aDeckDockFloating->setText(tr("Floating"));
|
||||||
|
|
||||||
|
aDeckAnalyticsDockVisible->setText(tr("Visible"));
|
||||||
|
aDeckAnalyticsDockFloating->setText(tr("Floating"));
|
||||||
|
|
||||||
|
aFilterDockVisible->setText(tr("Visible"));
|
||||||
|
aFilterDockFloating->setText(tr("Floating"));
|
||||||
|
|
||||||
|
aPrintingSelectorDockVisible->setText(tr("Visible"));
|
||||||
|
aPrintingSelectorDockFloating->setText(tr("Floating"));
|
||||||
|
|
||||||
|
aResetLayout->setText(tr("Reset layout"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method uses to sync docks state with menu items state
|
||||||
|
bool TabDeckEditorVisual::eventFilter(QObject *o, QEvent *e)
|
||||||
|
{
|
||||||
|
if (e->type() == QEvent::Close) {
|
||||||
|
if (o == cardInfoDockWidget) {
|
||||||
|
aCardInfoDockVisible->setChecked(false);
|
||||||
|
aCardInfoDockFloating->setEnabled(false);
|
||||||
|
} else if (o == deckDockWidget) {
|
||||||
|
aDeckDockVisible->setChecked(false);
|
||||||
|
aDeckDockFloating->setEnabled(false);
|
||||||
|
} else if (o == deckAnalyticsDock) {
|
||||||
|
aDeckAnalyticsDockVisible->setChecked(false);
|
||||||
|
aDeckAnalyticsDockFloating->setEnabled(false);
|
||||||
|
} else if (o == filterDockWidget) {
|
||||||
|
aFilterDockVisible->setChecked(false);
|
||||||
|
aFilterDockFloating->setEnabled(false);
|
||||||
|
} else if (o == printingSelectorDockWidget) {
|
||||||
|
aPrintingSelectorDockVisible->setChecked(false);
|
||||||
|
aPrintingSelectorDockFloating->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o == this && e->type() == QEvent::Hide) {
|
||||||
|
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||||
|
layouts.setDeckEditorLayoutState(saveState());
|
||||||
|
layouts.setDeckEditorGeometry(saveGeometry());
|
||||||
|
layouts.setDeckEditorCardSize(cardInfoDockWidget->size());
|
||||||
|
layouts.setDeckEditorFilterSize(filterDockWidget->size());
|
||||||
|
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
||||||
|
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::dockVisibleTriggered()
|
||||||
|
{
|
||||||
|
QObject *o = sender();
|
||||||
|
if (o == aCardInfoDockVisible) {
|
||||||
|
cardInfoDockWidget->setHidden(!aCardInfoDockVisible->isChecked());
|
||||||
|
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aDeckDockVisible) {
|
||||||
|
deckDockWidget->setHidden(!aDeckDockVisible->isChecked());
|
||||||
|
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aDeckAnalyticsDockVisible) {
|
||||||
|
deckAnalyticsDock->setHidden(!aDeckAnalyticsDockVisible->isChecked());
|
||||||
|
aDeckAnalyticsDockFloating->setEnabled(aDeckAnalyticsDockVisible->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aFilterDockVisible) {
|
||||||
|
filterDockWidget->setHidden(!aFilterDockVisible->isChecked());
|
||||||
|
aFilterDockFloating->setEnabled(aFilterDockVisible->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aPrintingSelectorDockVisible) {
|
||||||
|
printingSelectorDockWidget->setHidden(!aPrintingSelectorDockVisible->isChecked());
|
||||||
|
aPrintingSelectorDockFloating->setEnabled(aPrintingSelectorDockVisible->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::dockFloatingTriggered()
|
||||||
|
{
|
||||||
|
QObject *o = sender();
|
||||||
|
if (o == aCardInfoDockFloating) {
|
||||||
|
cardInfoDockWidget->setFloating(aCardInfoDockFloating->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aDeckDockFloating) {
|
||||||
|
deckDockWidget->setFloating(aDeckDockFloating->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aDeckAnalyticsDockFloating) {
|
||||||
|
deckAnalyticsDock->setFloating(aDeckAnalyticsDockFloating->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aFilterDockFloating) {
|
||||||
|
filterDockWidget->setFloating(aFilterDockFloating->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == aPrintingSelectorDockFloating) {
|
||||||
|
printingSelectorDockWidget->setFloating(aPrintingSelectorDockFloating->isChecked());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisual::dockTopLevelChanged(bool topLevel)
|
||||||
|
{
|
||||||
|
QObject *o = sender();
|
||||||
|
if (o == cardInfoDockWidget) {
|
||||||
|
aCardInfoDockFloating->setChecked(topLevel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == deckDockWidget) {
|
||||||
|
aDeckDockFloating->setChecked(topLevel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == filterDockWidget) {
|
||||||
|
aFilterDockFloating->setChecked(topLevel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == deckAnalyticsDock) {
|
||||||
|
aDeckAnalyticsDockFloating->setChecked(topLevel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o == printingSelectorDockWidget) {
|
||||||
|
aPrintingSelectorDockFloating->setChecked(topLevel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef WINDOW_DECKEDITORVISUAL_H
|
||||||
|
#define WINDOW_DECKEDITORVISUAL_H
|
||||||
|
|
||||||
|
#include "../tab.h"
|
||||||
|
#include "tab_deck_editor_visual_tab_widget.h"
|
||||||
|
|
||||||
|
class TabDeckEditorVisual : public AbstractTabDeckEditor
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
protected slots:
|
||||||
|
void loadLayout() override;
|
||||||
|
void restartLayout() override;
|
||||||
|
void freeDocksSize() override;
|
||||||
|
void refreshShortcuts() override;
|
||||||
|
|
||||||
|
bool eventFilter(QObject *o, QEvent *e) override;
|
||||||
|
void dockVisibleTriggered() override;
|
||||||
|
void dockFloatingTriggered() override;
|
||||||
|
void dockTopLevelChanged(bool topLevel) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TabDeckEditorVisualTabWidget *tabContainer;
|
||||||
|
|
||||||
|
QVBoxLayout *centralFrame;
|
||||||
|
QVBoxLayout *searchAndDatabaseFrame;
|
||||||
|
QHBoxLayout *searchLayout;
|
||||||
|
QDockWidget *searchAndDatabaseDock;
|
||||||
|
QDockWidget *deckAnalyticsDock;
|
||||||
|
QWidget *centralWidget;
|
||||||
|
QMenu *deckAnalyticsMenu;
|
||||||
|
QAction *aDeckAnalyticsDockVisible, *aDeckAnalyticsDockFloating;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TabDeckEditorVisual(TabSupervisor *_tabSupervisor);
|
||||||
|
void retranslateUi() override;
|
||||||
|
QString getTabText() const override;
|
||||||
|
void changeModelIndexAndCardInfo(const CardInfoPtr &activeCard);
|
||||||
|
void changeModelIndexToCard(const CardInfoPtr &activeCard);
|
||||||
|
void createDeckAnalyticsDock();
|
||||||
|
void createMenus() override;
|
||||||
|
void createSearchAndDatabaseFrame();
|
||||||
|
void createCentralFrame();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onDeckChanged() override;
|
||||||
|
void showPrintingSelector() override;
|
||||||
|
void
|
||||||
|
processMainboardCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||||
|
void processCardClickDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||||
|
bool actSaveDeckAs() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include "tab_deck_editor_visual_tab_widget.h"
|
||||||
|
|
||||||
|
#include "../../ui/widgets/visual_database_display/visual_database_display_widget.h"
|
||||||
|
#include "../abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
|
TabDeckEditorVisualTabWidget::TabDeckEditorVisualTabWidget(QWidget *parent,
|
||||||
|
AbstractTabDeckEditor *_deckEditor,
|
||||||
|
DeckListModel *_deckModel,
|
||||||
|
CardDatabaseModel *_cardDatabaseModel,
|
||||||
|
CardDatabaseDisplayModel *_cardDatabaseDisplayModel)
|
||||||
|
: QTabWidget(parent), deckEditor(_deckEditor), deckModel(_deckModel), cardDatabaseModel(_cardDatabaseModel),
|
||||||
|
cardDatabaseDisplayModel(_cardDatabaseDisplayModel)
|
||||||
|
{
|
||||||
|
this->setTabsClosable(true); // Enable tab closing
|
||||||
|
connect(this, &QTabWidget::tabCloseRequested, this, &TabDeckEditorVisualTabWidget::handleTabClose);
|
||||||
|
|
||||||
|
// Set up the layout and add tab widget
|
||||||
|
layout = new QVBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
visualDeckView = new VisualDeckEditorWidget(this, deckModel);
|
||||||
|
visualDeckView->setObjectName("visualDeckView");
|
||||||
|
connect(visualDeckView, &VisualDeckEditorWidget::activeCardChanged, this,
|
||||||
|
&TabDeckEditorVisualTabWidget::onCardChanged);
|
||||||
|
connect(visualDeckView, &VisualDeckEditorWidget::cardClicked, this,
|
||||||
|
&TabDeckEditorVisualTabWidget::onCardClickedDeckEditor);
|
||||||
|
connect(visualDeckView, &VisualDeckEditorWidget::cardAdditionRequested, deckEditor,
|
||||||
|
&AbstractTabDeckEditor::actAddCard);
|
||||||
|
|
||||||
|
visualDatabaseDisplay =
|
||||||
|
new VisualDatabaseDisplayWidget(this, deckEditor, _cardDatabaseModel, _cardDatabaseDisplayModel);
|
||||||
|
visualDatabaseDisplay->setObjectName("visualDatabaseView");
|
||||||
|
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardHoveredDatabaseDisplay, this,
|
||||||
|
&TabDeckEditorVisualTabWidget::onCardChangedDatabaseDisplay);
|
||||||
|
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardClickedDatabaseDisplay, this,
|
||||||
|
&TabDeckEditorVisualTabWidget::onCardClickedDatabaseDisplay);
|
||||||
|
|
||||||
|
deckAnalytics = new DeckAnalyticsWidget(this, deckModel);
|
||||||
|
deckAnalytics->setObjectName("deckAnalytics");
|
||||||
|
|
||||||
|
sampleHandWidget = new VisualDeckEditorSampleHandWidget(this, deckModel);
|
||||||
|
|
||||||
|
this->addNewTab(visualDeckView, tr("Visual Deck View"));
|
||||||
|
this->addNewTab(visualDatabaseDisplay, tr("Visual Database Display"));
|
||||||
|
this->addNewTab(deckAnalytics, tr("Deck Analytics"));
|
||||||
|
this->addNewTab(sampleHandWidget, tr("Sample Hand"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::onCardChanged(CardInfoPtr activeCard)
|
||||||
|
{
|
||||||
|
emit cardChanged(activeCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::onCardChangedDatabaseDisplay(CardInfoPtr activeCard)
|
||||||
|
{
|
||||||
|
emit cardChangedDatabaseDisplay(activeCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::onCardClickedDeckEditor(QMouseEvent *event,
|
||||||
|
CardInfoPictureWithTextOverlayWidget *instance,
|
||||||
|
QString zoneName)
|
||||||
|
{
|
||||||
|
emit cardClicked(event, instance, zoneName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::onCardClickedDatabaseDisplay(QMouseEvent *event,
|
||||||
|
CardInfoPictureWithTextOverlayWidget *instance)
|
||||||
|
{
|
||||||
|
emit cardClickedDatabaseDisplay(event, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::addNewTab(QWidget *widget, const QString &title)
|
||||||
|
{
|
||||||
|
// Add new tab to the tab widget
|
||||||
|
this->addTab(widget, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::removeCurrentTab()
|
||||||
|
{
|
||||||
|
// Remove the currently selected tab
|
||||||
|
int currentIndex = this->currentIndex();
|
||||||
|
if (currentIndex != -1) {
|
||||||
|
this->removeTab(currentIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::setTabTitle(int index, const QString &title)
|
||||||
|
{
|
||||||
|
// Set the title of the tab at the given index
|
||||||
|
if (index >= 0 && index < this->count()) {
|
||||||
|
this->setTabText(index, title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *TabDeckEditorVisualTabWidget::getCurrentTab() const
|
||||||
|
{
|
||||||
|
// Return the currently selected tab widget
|
||||||
|
return this->currentWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
int TabDeckEditorVisualTabWidget::getTabCount() const
|
||||||
|
{
|
||||||
|
// Return the number of tabs
|
||||||
|
return this->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckEditorVisualTabWidget::handleTabClose(int index)
|
||||||
|
{
|
||||||
|
// Handle closing of the tab at the given index
|
||||||
|
QWidget *tab = this->widget(index);
|
||||||
|
this->removeTab(index);
|
||||||
|
delete tab; // Delete the tab's widget to free memory
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H
|
||||||
|
#define TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../ui/widgets/deck_analytics/deck_analytics_widget.h"
|
||||||
|
#include "../../ui/widgets/printing_selector/printing_selector.h"
|
||||||
|
#include "../../ui/widgets/visual_database_display/visual_database_display_widget.h"
|
||||||
|
#include "../../ui/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h"
|
||||||
|
#include "../../ui/widgets/visual_deck_editor/visual_deck_editor_widget.h"
|
||||||
|
#include "../abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
|
#include <QTabWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class TabDeckEditorVisualTabWidget : public QTabWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TabDeckEditorVisualTabWidget(QWidget *parent,
|
||||||
|
AbstractTabDeckEditor *_deckEditor,
|
||||||
|
DeckListModel *_deckModel,
|
||||||
|
CardDatabaseModel *_cardDatabaseModel,
|
||||||
|
CardDatabaseDisplayModel *_cardDatabaseDisplayModel);
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
void addNewTab(QWidget *widget, const QString &title);
|
||||||
|
void removeCurrentTab();
|
||||||
|
void setTabTitle(int index, const QString &title);
|
||||||
|
QWidget *getCurrentTab() const;
|
||||||
|
int getTabCount() const;
|
||||||
|
|
||||||
|
VisualDeckEditorWidget *visualDeckView;
|
||||||
|
DeckAnalyticsWidget *deckAnalytics;
|
||||||
|
VisualDatabaseDisplayWidget *visualDatabaseDisplay;
|
||||||
|
PrintingSelector *printingSelector;
|
||||||
|
VisualDeckEditorSampleHandWidget *sampleHandWidget;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onCardChanged(CardInfoPtr activeCard);
|
||||||
|
void onCardChangedDatabaseDisplay(CardInfoPtr activeCard);
|
||||||
|
void onCardClickedDeckEditor(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||||
|
void onCardClickedDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void cardChanged(CardInfoPtr activeCard);
|
||||||
|
void cardChangedDatabaseDisplay(CardInfoPtr activeCard);
|
||||||
|
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||||
|
void cardClickedDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVBoxLayout *layout; // Layout for the tab widget and other controls
|
||||||
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
DeckListModel *deckModel;
|
||||||
|
CardDatabaseModel *cardDatabaseModel;
|
||||||
|
CardDatabaseDisplayModel *cardDatabaseDisplayModel;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleTabClose(int index); // Slot for closing a tab
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
|
TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
|
||||||
: Tab(_tabSupervisor), visualDeckStorageWidget(new VisualDeckStorageWidget(this))
|
: Tab(_tabSupervisor), visualDeckStorageWidget(new VisualDeckStorageWidget(this))
|
||||||
{
|
{
|
||||||
connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::addDeckEditorTab);
|
connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::addVisualDeckEditorTab);
|
||||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckLoadRequested, this,
|
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckLoadRequested, this,
|
||||||
&TabDeckStorageVisual::actOpenLocalDeck);
|
&TabDeckStorageVisual::actOpenLocalDeck);
|
||||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::openDeckEditor, this,
|
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::openDeckEditor, this,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "overlap_layout.h"
|
#include "overlap_layout.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -32,9 +33,10 @@ OverlapLayout::OverlapLayout(QWidget *parent,
|
||||||
const int overlapPercentage,
|
const int overlapPercentage,
|
||||||
const int maxColumns,
|
const int maxColumns,
|
||||||
const int maxRows,
|
const int maxRows,
|
||||||
const Qt::Orientation direction)
|
const Qt::Orientation _overlapDirection,
|
||||||
|
const Qt::Orientation _flowDirection)
|
||||||
: QLayout(parent), overlapPercentage(overlapPercentage), maxColumns(maxColumns), maxRows(maxRows),
|
: QLayout(parent), overlapPercentage(overlapPercentage), maxColumns(maxColumns), maxRows(maxRows),
|
||||||
direction(direction)
|
overlapDirection(_overlapDirection), flowDirection(_flowDirection)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,17 +150,21 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the overlap offsets based on the layout direction and overlap percentage.
|
// Calculate the overlap offsets based on the layout direction and overlap percentage.
|
||||||
const int overlapOffsetWidth = (direction == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
const int overlapOffsetWidth = (overlapDirection == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
||||||
const int overlapOffsetHeight = (direction == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
const int overlapOffsetHeight = (overlapDirection == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
||||||
|
|
||||||
// Determine the number of columns based on layout constraints and available space.
|
// Determine the number of columns based on layout constraints and available space.
|
||||||
int columns;
|
int columns;
|
||||||
if (direction == Qt::Horizontal) {
|
if (flowDirection == Qt::Horizontal) {
|
||||||
if (maxColumns > 0) {
|
if (maxColumns > 0) {
|
||||||
// Calculate the maximum possible columns given the available width and overlap.
|
// Calculate the maximum possible columns given the available width and overlap.
|
||||||
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
||||||
// Use the smaller of maxColumns and availableColumns.
|
// Use the smaller of maxColumns and availableColumns.
|
||||||
|
qCDebug(OverlapLayoutLog) << " Max Columns " << maxColumns << " available columns " << availableColumns;
|
||||||
columns = qMin(maxColumns, availableColumns);
|
columns = qMin(maxColumns, availableColumns);
|
||||||
|
if (columns < 1) {
|
||||||
|
columns = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no maxColumns constraint, allow as many columns as possible.
|
// If no maxColumns constraint, allow as many columns as possible.
|
||||||
columns = INT_MAX;
|
columns = INT_MAX;
|
||||||
|
|
@ -170,12 +176,16 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
|
|
||||||
// Determine the number of rows based on layout constraints and available space.
|
// Determine the number of rows based on layout constraints and available space.
|
||||||
int rows;
|
int rows;
|
||||||
if (direction == Qt::Vertical) {
|
if (flowDirection == Qt::Vertical) {
|
||||||
if (maxRows > 0) {
|
if (maxRows > 0) {
|
||||||
// Calculate the maximum possible rows given the available height and overlap.
|
// Calculate the maximum possible rows given the available height and overlap.
|
||||||
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
||||||
// Use the smaller of maxRows and availableRows.
|
// Use the smaller of maxRows and availableRows.
|
||||||
|
qCDebug(OverlapLayoutLog) << " Max Rows " << maxRows << " available rows " << availableRows;
|
||||||
rows = qMin(maxRows, availableRows);
|
rows = qMin(maxRows, availableRows);
|
||||||
|
if (rows < 1) {
|
||||||
|
rows = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no maxRows constraint, allow as many rows as possible.
|
// If no maxRows constraint, allow as many rows as possible.
|
||||||
rows = INT_MAX;
|
rows = INT_MAX;
|
||||||
|
|
@ -200,16 +210,17 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
const int yPos = rect.top() + currentRow * (maxItemHeight - overlapOffsetHeight);
|
const int yPos = rect.top() + currentRow * (maxItemHeight - overlapOffsetHeight);
|
||||||
item->setGeometry(QRect(xPos, yPos, maxItemWidth, maxItemHeight));
|
item->setGeometry(QRect(xPos, yPos, maxItemWidth, maxItemHeight));
|
||||||
|
|
||||||
|
// TODO: Figure this out properly or maybe adjust size hint to account for this?
|
||||||
// Update row and column indices based on the layout direction.
|
// Update row and column indices based on the layout direction.
|
||||||
if (direction == Qt::Horizontal) {
|
if (overlapDirection == Qt::Horizontal) {
|
||||||
currentColumn++;
|
currentColumn++;
|
||||||
if (currentColumn >= columns) {
|
if (currentColumn > qCeil(itemList.size() / rows)) {
|
||||||
currentColumn = 0;
|
currentColumn = 0;
|
||||||
currentRow++;
|
currentRow++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
currentRow++;
|
currentRow++;
|
||||||
if (currentRow >= rows) {
|
if (currentRow > qCeil(itemList.size() / columns)) {
|
||||||
currentRow = 0;
|
currentRow = 0;
|
||||||
currentColumn++;
|
currentColumn++;
|
||||||
}
|
}
|
||||||
|
|
@ -223,88 +234,86 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
||||||
*/
|
*/
|
||||||
QSize OverlapLayout::calculatePreferredSize() const
|
QSize OverlapLayout::calculatePreferredSize() const
|
||||||
{
|
{
|
||||||
|
// Get the parent widget for size and margin calculations.
|
||||||
|
const QWidget *parentWidget = this->parentWidget();
|
||||||
|
if (!parentWidget) {
|
||||||
|
return QSize(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the maximum item dimensions.
|
if (itemList.isEmpty()) {
|
||||||
|
return QSize(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int availableWidth = parentWidget->width();
|
||||||
|
int availableHeight = parentWidget->height();
|
||||||
|
const QMargins margins = parentWidget->contentsMargins();
|
||||||
|
availableWidth -= margins.left() + margins.right();
|
||||||
|
availableHeight -= margins.top() + margins.bottom();
|
||||||
|
|
||||||
|
// Determine the maximum item width and height among all layout items.
|
||||||
int maxItemWidth = 0;
|
int maxItemWidth = 0;
|
||||||
int maxItemHeight = 0;
|
int maxItemHeight = 0;
|
||||||
for (QLayoutItem *item : itemList) {
|
for (QLayoutItem *item : itemList) {
|
||||||
if (item == nullptr) {
|
if (item != nullptr && item->widget()) {
|
||||||
continue;
|
QSize itemSize = item->widget()->sizeHint();
|
||||||
|
maxItemWidth = qMax(maxItemWidth, itemSize.width());
|
||||||
|
maxItemHeight = qMax(maxItemHeight, itemSize.height());
|
||||||
}
|
}
|
||||||
if (!item->widget()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize itemSize = item->widget()->sizeHint();
|
|
||||||
maxItemWidth = qMax(maxItemWidth, itemSize.width());
|
|
||||||
maxItemHeight = qMax(maxItemHeight, itemSize.height());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the overlap offsets.
|
// Calculate the overlap offsets based on the layout direction and overlap percentage.
|
||||||
const int extra_for_overlap = (100 - overlapPercentage);
|
const int overlapOffsetWidth = (overlapDirection == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
||||||
const int overlapOffsetWidth =
|
const int overlapOffsetHeight = (overlapDirection == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
||||||
(direction == Qt::Horizontal) ? qRound((maxItemWidth / 100.0) * extra_for_overlap) : 0;
|
|
||||||
const int overlapOffsetHeight =
|
|
||||||
(direction == Qt::Vertical) ? qRound((maxItemHeight / 100.0) * extra_for_overlap) : 0;
|
|
||||||
|
|
||||||
// Variables to hold the total dimensions based on layout orientation.
|
// Determine the number of columns based on layout constraints and available space.
|
||||||
int totalWidth = 0;
|
int columns;
|
||||||
int totalHeight = 0;
|
if (flowDirection == Qt::Horizontal) {
|
||||||
|
if (maxColumns > 0) {
|
||||||
// Calculate the total size based on the layout direction and constraints.
|
// Calculate the maximum possible columns given the available width and overlap.
|
||||||
if (direction == Qt::Horizontal) {
|
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
||||||
// Determine the number of columns:
|
// Use the smaller of maxColumns and availableColumns.
|
||||||
// - Use maxColumns if it is greater than 0 (constraint set by the user).
|
qCDebug(OverlapLayoutLog) << " Max Columns " << maxColumns << " available columns " << availableColumns;
|
||||||
// - Otherwise, set the number of columns to the total number of items in the layout.
|
columns = qMin(maxColumns, availableColumns);
|
||||||
const int numColumns = (maxColumns > 0) ? static_cast<int>(maxColumns) : static_cast<int>(itemList.size());
|
if (columns < 1) {
|
||||||
|
columns = 1;
|
||||||
// Calculate the extra space required for overlaps between columns:
|
}
|
||||||
// - Each overlap reduces the effective width of subsequent items.
|
} else {
|
||||||
const int extra_space_for_overlaps = overlapOffsetWidth * (numColumns - 1);
|
// If no maxColumns constraint, allow as many columns as possible.
|
||||||
|
columns = INT_MAX;
|
||||||
// Total width:
|
}
|
||||||
// - The first item's width is fully included (maxItemWidth).
|
} else {
|
||||||
// - Add the space for all overlaps between adjacent items.
|
// If not a horizontal layout, column count is irrelevant.
|
||||||
totalWidth = maxItemWidth + extra_space_for_overlaps;
|
columns = INT_MAX;
|
||||||
|
|
||||||
// Determine the number of rows:
|
|
||||||
// - Use maxRows if maxColumns is set (to constrain the number of rows).
|
|
||||||
// - Otherwise, assume a single row.
|
|
||||||
const int numRows =
|
|
||||||
(maxColumns > 0) ? qCeil(static_cast<double>(itemList.size()) / static_cast<double>(numColumns)) : 1;
|
|
||||||
|
|
||||||
// Total height:
|
|
||||||
// - Multiply the number of rows by the item height (maxItemHeight).
|
|
||||||
// - Subtract the height overlap between rows to avoid double-counting.
|
|
||||||
totalHeight = maxItemHeight * numRows - (numRows - 1) * overlapOffsetHeight;
|
|
||||||
} else if (direction == Qt::Vertical) {
|
|
||||||
// Determine the number of columns:
|
|
||||||
// - Use maxRows to calculate how many columns are needed if a row constraint exists.
|
|
||||||
// - Otherwise, assume a single column.
|
|
||||||
const int numColumns =
|
|
||||||
(maxRows != 0) ? qCeil(static_cast<double>(itemList.size()) / static_cast<double>(maxRows)) : 1;
|
|
||||||
|
|
||||||
// Total width:
|
|
||||||
// - Multiply the number of columns by the item width (maxItemWidth).
|
|
||||||
// - Subtract the width overlap between columns to avoid double-counting.
|
|
||||||
totalWidth = maxItemWidth * numColumns - (numColumns - 1) * overlapOffsetWidth;
|
|
||||||
|
|
||||||
// Determine the number of rows:
|
|
||||||
// - Use maxRows if it is greater than 0 (constraint set by the user).
|
|
||||||
// - Otherwise, set the number of rows to the total number of items in the layout.
|
|
||||||
const int numRows = (maxRows > 0) ? static_cast<int>(maxRows) : static_cast<int>(itemList.size());
|
|
||||||
|
|
||||||
// Calculate the extra space required for overlaps between rows:
|
|
||||||
// - Each overlap reduces the effective height of subsequent items.
|
|
||||||
const int extraSpaceForOverlaps = overlapOffsetHeight * (numRows - 1);
|
|
||||||
|
|
||||||
// Total height:
|
|
||||||
// - The first item's height is fully included (maxItemHeight).
|
|
||||||
// - Add the space for all overlaps between adjacent items.
|
|
||||||
totalHeight = maxItemHeight + extraSpaceForOverlaps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {totalWidth, totalHeight};
|
// Determine the number of rows based on layout constraints and available space.
|
||||||
|
int rows;
|
||||||
|
if (flowDirection == Qt::Vertical) {
|
||||||
|
if (maxRows > 0) {
|
||||||
|
// Calculate the maximum possible rows given the available height and overlap.
|
||||||
|
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
||||||
|
// Use the smaller of maxRows and availableRows.
|
||||||
|
qCDebug(OverlapLayoutLog) << " Max Rows " << maxRows << " available rows " << availableRows;
|
||||||
|
rows = qMin(maxRows, availableRows);
|
||||||
|
if (rows < 1) {
|
||||||
|
rows = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If no maxRows constraint, allow as many rows as possible.
|
||||||
|
rows = INT_MAX;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If not a vertical layout, row count is irrelevant.
|
||||||
|
rows = INT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlapDirection == Qt::Horizontal) {
|
||||||
|
return QSize(maxItemWidth + ((qCeil(itemList.size() / rows)) * (maxItemWidth - overlapOffsetWidth)),
|
||||||
|
rows * maxItemHeight);
|
||||||
|
} else {
|
||||||
|
return QSize(columns * maxItemWidth,
|
||||||
|
maxItemHeight + ((qCeil(itemList.size() / columns)) * (maxItemHeight - overlapOffsetHeight)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -341,7 +350,7 @@ QSize OverlapLayout::minimumSize() const
|
||||||
*/
|
*/
|
||||||
void OverlapLayout::setDirection(const Qt::Orientation _direction)
|
void OverlapLayout::setDirection(const Qt::Orientation _direction)
|
||||||
{
|
{
|
||||||
direction = _direction;
|
overlapDirection = _direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -378,7 +387,7 @@ void OverlapLayout::setMaxRows(const int _maxRows)
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateMaxColumns() const
|
int OverlapLayout::calculateMaxColumns() const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Vertical || itemList.isEmpty()) {
|
if (overlapDirection != Qt::Vertical || itemList.isEmpty()) {
|
||||||
return 1; // Only relevant if the layout direction is vertical
|
return 1; // Only relevant if the layout direction is vertical
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -410,7 +419,7 @@ int OverlapLayout::calculateMaxColumns() const
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateRowsForColumns(const int columns) const
|
int OverlapLayout::calculateRowsForColumns(const int columns) const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Vertical || itemList.isEmpty() || columns <= 0) {
|
if (overlapDirection != Qt::Vertical || itemList.isEmpty() || columns <= 0) {
|
||||||
return 1; // Only relevant if the layout direction is vertical and there are items
|
return 1; // Only relevant if the layout direction is vertical and there are items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,7 +438,7 @@ int OverlapLayout::calculateRowsForColumns(const int columns) const
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateMaxRows() const
|
int OverlapLayout::calculateMaxRows() const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Horizontal || itemList.isEmpty()) {
|
if (overlapDirection != Qt::Horizontal || itemList.isEmpty()) {
|
||||||
return 1; // Only relevant if the layout direction is horizontal
|
return 1; // Only relevant if the layout direction is horizontal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,7 +473,7 @@ int OverlapLayout::calculateMaxRows() const
|
||||||
*/
|
*/
|
||||||
int OverlapLayout::calculateColumnsForRows(const int rows) const
|
int OverlapLayout::calculateColumnsForRows(const int rows) const
|
||||||
{
|
{
|
||||||
if (direction != Qt::Horizontal || itemList.isEmpty() || rows <= 0) {
|
if (overlapDirection != Qt::Horizontal || itemList.isEmpty() || rows <= 0) {
|
||||||
return 1; // Only relevant if the layout direction is horizontal and there are items
|
return 1; // Only relevant if the layout direction is horizontal and there are items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,11 @@
|
||||||
|
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QLoggingCategory>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
inline Q_LOGGING_CATEGORY(OverlapLayoutLog, "overlap_layout");
|
||||||
|
|
||||||
class OverlapLayout : public QLayout
|
class OverlapLayout : public QLayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -12,7 +15,8 @@ public:
|
||||||
int overlapPercentage = 10,
|
int overlapPercentage = 10,
|
||||||
int maxColumns = 2,
|
int maxColumns = 2,
|
||||||
int maxRows = 2,
|
int maxRows = 2,
|
||||||
Qt::Orientation direction = Qt::Horizontal);
|
Qt::Orientation overlapDirection = Qt::Vertical,
|
||||||
|
Qt::Orientation flowDirection = Qt::Horizontal);
|
||||||
~OverlapLayout();
|
~OverlapLayout();
|
||||||
|
|
||||||
void addItem(QLayoutItem *item) override;
|
void addItem(QLayoutItem *item) override;
|
||||||
|
|
@ -35,7 +39,8 @@ private:
|
||||||
int overlapPercentage;
|
int overlapPercentage;
|
||||||
int maxColumns;
|
int maxColumns;
|
||||||
int maxRows;
|
int maxRows;
|
||||||
Qt::Orientation direction;
|
Qt::Orientation overlapDirection;
|
||||||
|
Qt::Orientation flowDirection;
|
||||||
|
|
||||||
// Calculate the preferred size of the layout
|
// Calculate the preferred size of the layout
|
||||||
QSize calculatePreferredSize() const;
|
QSize calculatePreferredSize() const;
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ void LineEditCompleter::setCompleter(QCompleter *completer)
|
||||||
{
|
{
|
||||||
c = completer;
|
c = completer;
|
||||||
c->setWidget(this);
|
c->setWidget(this);
|
||||||
connect(c, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString)));
|
connect(c, qOverload<const QString &>(&QCompleter::activated), this, &LineEditCompleter::insertCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineEditCompleter::setCompletionList(QStringList completionList)
|
void LineEditCompleter::setCompletionList(QStringList completionList)
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ PhaseButton::PhaseButton(const QString &_name, QGraphicsItem *parent, QAction *_
|
||||||
{
|
{
|
||||||
if (highlightable) {
|
if (highlightable) {
|
||||||
activeAnimationTimer = new QTimer(this);
|
activeAnimationTimer = new QTimer(this);
|
||||||
connect(activeAnimationTimer, SIGNAL(timeout()), this, SLOT(updateAnimation()));
|
connect(activeAnimationTimer, &QTimer::timeout, this, &PhaseButton::updateAnimation);
|
||||||
activeAnimationTimer->setSingleShot(false);
|
activeAnimationTimer->setSingleShot(false);
|
||||||
} else
|
} else
|
||||||
activeAnimationCounter = 9;
|
activeAnimationCounter = 9;
|
||||||
|
|
@ -106,9 +106,9 @@ PhasesToolbar::PhasesToolbar(QGraphicsItem *parent)
|
||||||
: QGraphicsItem(parent), width(100), height(100), ySpacing(1), symbolSize(8)
|
: QGraphicsItem(parent), width(100), height(100), ySpacing(1), symbolSize(8)
|
||||||
{
|
{
|
||||||
auto *aUntapAll = new QAction(this);
|
auto *aUntapAll = new QAction(this);
|
||||||
connect(aUntapAll, SIGNAL(triggered()), this, SLOT(actUntapAll()));
|
connect(aUntapAll, &QAction::triggered, this, &PhasesToolbar::actUntapAll);
|
||||||
auto *aDrawCard = new QAction(this);
|
auto *aDrawCard = new QAction(this);
|
||||||
connect(aDrawCard, SIGNAL(triggered()), this, SLOT(actDrawCard()));
|
connect(aDrawCard, &QAction::triggered, this, &PhasesToolbar::actDrawCard);
|
||||||
|
|
||||||
PhaseButton *untapButton = new PhaseButton("untap", this, aUntapAll);
|
PhaseButton *untapButton = new PhaseButton("untap", this, aUntapAll);
|
||||||
PhaseButton *upkeepButton = new PhaseButton("upkeep", this);
|
PhaseButton *upkeepButton = new PhaseButton("upkeep", this);
|
||||||
|
|
@ -126,10 +126,10 @@ PhasesToolbar::PhasesToolbar(QGraphicsItem *parent)
|
||||||
<< combatBlockersButton << combatDamageButton << combatEndButton << main2Button << cleanupButton;
|
<< combatBlockersButton << combatDamageButton << combatEndButton << main2Button << cleanupButton;
|
||||||
|
|
||||||
for (auto &i : buttonList)
|
for (auto &i : buttonList)
|
||||||
connect(i, SIGNAL(clicked()), this, SLOT(phaseButtonClicked()));
|
connect(i, &PhaseButton::clicked, this, &PhasesToolbar::phaseButtonClicked);
|
||||||
|
|
||||||
nextTurnButton = new PhaseButton("nextturn", this, nullptr, false);
|
nextTurnButton = new PhaseButton("nextturn", this, nullptr, false);
|
||||||
connect(nextTurnButton, SIGNAL(clicked()), this, SLOT(actNextTurn()));
|
connect(nextTurnButton, &PhaseButton::clicked, this, &PhasesToolbar::actNextTurn);
|
||||||
|
|
||||||
rearrangeButtons();
|
rearrangeButtons();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,10 @@
|
||||||
PictureLoader::PictureLoader() : QObject(nullptr)
|
PictureLoader::PictureLoader() : QObject(nullptr)
|
||||||
{
|
{
|
||||||
worker = new PictureLoaderWorker;
|
worker = new PictureLoaderWorker;
|
||||||
connect(&SettingsCache::instance(), SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged()));
|
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this, &PictureLoader::picsPathChanged);
|
||||||
connect(&SettingsCache::instance(), SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged()));
|
connect(&SettingsCache::instance(), &SettingsCache::picDownloadChanged, this, &PictureLoader::picDownloadChanged);
|
||||||
|
|
||||||
connect(worker, SIGNAL(imageLoaded(CardInfoPtr, const QImage &)), this,
|
connect(worker, &PictureLoaderWorker::imageLoaded, this, &PictureLoader::imageLoaded);
|
||||||
SLOT(imageLoaded(CardInfoPtr, const QImage &)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PictureLoader::~PictureLoader()
|
PictureLoader::~PictureLoader()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef PICTURELOADER_H
|
#ifndef PICTURELOADER_H
|
||||||
#define PICTURELOADER_H
|
#define PICTURELOADER_H
|
||||||
|
|
||||||
#include "../../../game/cards/card_database.h"
|
#include "../../../game/cards/card_info.h"
|
||||||
#include "picture_loader_worker.h"
|
#include "picture_loader_worker.h"
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,11 @@ PictureLoaderWorker::PictureLoaderWorker()
|
||||||
picDownload(SettingsCache::instance().getPicDownload()), downloadRunning(false), loadQueueRunning(false),
|
picDownload(SettingsCache::instance().getPicDownload()), downloadRunning(false), loadQueueRunning(false),
|
||||||
overrideAllCardArtWithPersonalPreference(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference())
|
overrideAllCardArtWithPersonalPreference(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference())
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(startLoadQueue()), this, SLOT(processLoadQueue()), Qt::QueuedConnection);
|
connect(this, &PictureLoaderWorker::startLoadQueue, this, &PictureLoaderWorker::processLoadQueue,
|
||||||
connect(&SettingsCache::instance(), SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged()));
|
Qt::QueuedConnection);
|
||||||
connect(&SettingsCache::instance(), SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged()));
|
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this, &PictureLoaderWorker::picsPathChanged);
|
||||||
|
connect(&SettingsCache::instance(), &SettingsCache::picDownloadChanged, this,
|
||||||
|
&PictureLoaderWorker::picDownloadChanged);
|
||||||
connect(&SettingsCache::instance(), &SettingsCache::overrideAllCardArtWithPersonalPreferenceChanged, this,
|
connect(&SettingsCache::instance(), &SettingsCache::overrideAllCardArtWithPersonalPreferenceChanged, this,
|
||||||
&PictureLoaderWorker::setOverrideAllCardArtWithPersonalPreference);
|
&PictureLoaderWorker::setOverrideAllCardArtWithPersonalPreference);
|
||||||
|
|
||||||
|
|
@ -43,7 +45,7 @@ PictureLoaderWorker::PictureLoaderWorker()
|
||||||
// Use a ManualRedirectPolicy since we keep track of redirects in picDownloadFinished
|
// Use a ManualRedirectPolicy since we keep track of redirects in picDownloadFinished
|
||||||
// We can't use NoLessSafeRedirectPolicy because it is not applied with AlwaysCache
|
// We can't use NoLessSafeRedirectPolicy because it is not applied with AlwaysCache
|
||||||
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||||
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(picDownloadFinished(QNetworkReply *)));
|
connect(networkManager, &QNetworkAccessManager::finished, this, &PictureLoaderWorker::picDownloadFinished);
|
||||||
|
|
||||||
cacheFilePath = SettingsCache::instance().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
|
cacheFilePath = SettingsCache::instance().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
|
||||||
loadRedirectCache();
|
loadRedirectCache();
|
||||||
|
|
@ -244,6 +246,23 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url)
|
||||||
|
|
||||||
QNetworkRequest req(url);
|
QNetworkRequest req(url);
|
||||||
|
|
||||||
|
// QNetworkDiskCache leaks file descriptors when downloading compressed
|
||||||
|
// files, see https://bugreports.qt.io/browse/QTBUG-135641
|
||||||
|
//
|
||||||
|
// We can set the Accept-Encoding header manually to disable Qt's automatic
|
||||||
|
// response decompression, but then we would have to deal with decompression
|
||||||
|
// ourselves.
|
||||||
|
//
|
||||||
|
// Since we are dowloading images that are usually stored in a
|
||||||
|
// compressed format (e.g. jpeg or webp), it's not clear compression at the
|
||||||
|
// HTTP level helps; in fact, images are typically returned without
|
||||||
|
// compression. Redirects, on the other hand, are compressed and cause file
|
||||||
|
// descriptor leaks -- but since redirects have no payload, we don't really
|
||||||
|
// care either.
|
||||||
|
//
|
||||||
|
// In the end, just do the simple thing and disable HTTP compression.
|
||||||
|
req.setRawHeader("accept-encoding", "identity");
|
||||||
|
|
||||||
if (!picDownload) {
|
if (!picDownload) {
|
||||||
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
|
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef PICTURE_LOADER_WORKER_H
|
#ifndef PICTURE_LOADER_WORKER_H
|
||||||
#define PICTURE_LOADER_WORKER_H
|
#define PICTURE_LOADER_WORKER_H
|
||||||
|
|
||||||
#include "../../../game/cards/card_database.h"
|
#include "../../../game/cards/card_info.h"
|
||||||
#include "picture_to_load.h"
|
#include "picture_to_load.h"
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef PICTURE_TO_LOAD_H
|
#ifndef PICTURE_TO_LOAD_H
|
||||||
#define PICTURE_TO_LOAD_H
|
#define PICTURE_TO_LOAD_H
|
||||||
|
|
||||||
#include "../../../game/cards/card_database.h"
|
#include "../../../game/cards/card_info.h"
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ static const QStringList DEFAULT_RESOURCE_PATHS = {":/resources"};
|
||||||
ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
|
ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
ensureThemeDirectoryExists();
|
ensureThemeDirectoryExists();
|
||||||
connect(&SettingsCache::instance(), SIGNAL(themeChanged()), this, SLOT(themeChangedSlot()));
|
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this, &ThemeManager::themeChangedSlot);
|
||||||
themeChangedSlot();
|
themeChangedSlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef COLOR_IDENTITY_WIDGET_H
|
#ifndef COLOR_IDENTITY_WIDGET_H
|
||||||
#define COLOR_IDENTITY_WIDGET_H
|
#define COLOR_IDENTITY_WIDGET_H
|
||||||
|
|
||||||
#include "../../../../../game/cards/card_database.h"
|
#include "../../../../../game/cards/card_info.h"
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef MANA_COST_WIDGET_H
|
#ifndef MANA_COST_WIDGET_H
|
||||||
#define MANA_COST_WIDGET_H
|
#define MANA_COST_WIDGET_H
|
||||||
|
|
||||||
#include "../../../../../game/cards/card_database.h"
|
#include "../../../../../game/cards/card_info.h"
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include "card_group_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../../deck/deck_list_model.h"
|
||||||
|
#include "../../../../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../../../../utility/card_info_comparator.h"
|
||||||
|
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||||
|
|
||||||
|
#include <QResizeEvent>
|
||||||
|
|
||||||
|
CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent,
|
||||||
|
DeckListModel *_deckListModel,
|
||||||
|
QString _zoneName,
|
||||||
|
QString _cardGroupCategory,
|
||||||
|
QString _activeGroupCriteria,
|
||||||
|
QStringList _activeSortCriteria,
|
||||||
|
int bannerOpacity,
|
||||||
|
CardSizeWidget *_cardSizeWidget)
|
||||||
|
: QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory),
|
||||||
|
activeGroupCriteria(_activeGroupCriteria), activeSortCriteria(_activeSortCriteria),
|
||||||
|
cardSizeWidget(_cardSizeWidget)
|
||||||
|
{
|
||||||
|
layout = new QVBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
setMinimumSize(QSize(0, 0));
|
||||||
|
|
||||||
|
banner = new BannerWidget(this, cardGroupCategory, Qt::Orientation::Vertical, bannerOpacity);
|
||||||
|
|
||||||
|
layout->addWidget(banner);
|
||||||
|
updateCardDisplays();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardGroupDisplayWidget::updateCardDisplays()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<CardInfoPtr> CardGroupDisplayWidget::getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort)
|
||||||
|
{
|
||||||
|
cardsToSort = sortCardList(cardsToSort, activeSortCriteria, Qt::SortOrder::AscendingOrder);
|
||||||
|
|
||||||
|
QList<CardInfoPtr> activeList;
|
||||||
|
for (const CardInfoPtr &info : cardsToSort) {
|
||||||
|
if (info && info->getProperty(activeGroupCriteria) == cardGroupCategory) {
|
||||||
|
activeList.append(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return activeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<CardInfoPtr> CardGroupDisplayWidget::sortCardList(QList<CardInfoPtr> cardsToSort,
|
||||||
|
const QStringList properties,
|
||||||
|
Qt::SortOrder order = Qt::AscendingOrder)
|
||||||
|
{
|
||||||
|
CardInfoComparator comparator(properties, order);
|
||||||
|
std::sort(cardsToSort.begin(), cardsToSort.end(), comparator);
|
||||||
|
|
||||||
|
return cardsToSort;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardGroupDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria)
|
||||||
|
{
|
||||||
|
if (activeSortCriteria != _activeSortCriteria) {
|
||||||
|
activeSortCriteria = _activeSortCriteria;
|
||||||
|
updateCardDisplays(); // Refresh display with new sorting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardGroupDisplayWidget::onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card)
|
||||||
|
{
|
||||||
|
emit cardClicked(event, card);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardGroupDisplayWidget::onHover(CardInfoPtr card)
|
||||||
|
{
|
||||||
|
emit cardHovered(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardGroupDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
#define CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../../../../deck/deck_list_model.h"
|
||||||
|
#include "../../../../../game/cards/card_info.h"
|
||||||
|
#include "../../general/display/banner_widget.h"
|
||||||
|
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||||
|
#include "../card_size_widget.h"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class CardGroupDisplayWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CardGroupDisplayWidget(QWidget *parent,
|
||||||
|
DeckListModel *deckListModel,
|
||||||
|
QString zoneName,
|
||||||
|
QString cardGroupCategory,
|
||||||
|
QString activeGroupCriteria,
|
||||||
|
QStringList activeSortCriteria,
|
||||||
|
int bannerOpacity,
|
||||||
|
CardSizeWidget *cardSizeWidget);
|
||||||
|
|
||||||
|
QList<CardInfoPtr> getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort);
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
DeckListModel *deckListModel;
|
||||||
|
QString zoneName;
|
||||||
|
QString cardGroupCategory;
|
||||||
|
QString activeGroupCriteria;
|
||||||
|
QStringList activeSortCriteria;
|
||||||
|
CardSizeWidget *cardSizeWidget;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
QList<CardInfoPtr> sortCardList(QList<CardInfoPtr> cardsToSort, QStringList properties, Qt::SortOrder order);
|
||||||
|
void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||||
|
void onHover(CardInfoPtr card);
|
||||||
|
virtual void updateCardDisplays();
|
||||||
|
void onActiveSortCriteriaChanged(QStringList activeSortCriteria);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||||
|
void cardHovered(CardInfoPtr card);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVBoxLayout *layout;
|
||||||
|
BannerWidget *banner;
|
||||||
|
};
|
||||||
|
#endif // CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
#include "flat_card_group_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../../deck/deck_list_model.h"
|
||||||
|
#include "../../../../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../../../../utility/card_info_comparator.h"
|
||||||
|
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||||
|
|
||||||
|
#include <QResizeEvent>
|
||||||
|
|
||||||
|
FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent,
|
||||||
|
DeckListModel *_deckListModel,
|
||||||
|
QString _zoneName,
|
||||||
|
QString _cardGroupCategory,
|
||||||
|
QString _activeGroupCriteria,
|
||||||
|
QStringList _activeSortCriteria,
|
||||||
|
int bannerOpacity,
|
||||||
|
CardSizeWidget *_cardSizeWidget)
|
||||||
|
: CardGroupDisplayWidget(parent,
|
||||||
|
_deckListModel,
|
||||||
|
_zoneName,
|
||||||
|
_cardGroupCategory,
|
||||||
|
_activeGroupCriteria,
|
||||||
|
_activeSortCriteria,
|
||||||
|
bannerOpacity,
|
||||||
|
_cardSizeWidget)
|
||||||
|
{
|
||||||
|
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
|
||||||
|
banner->setBuddy(flowWidget);
|
||||||
|
|
||||||
|
layout->addWidget(flowWidget);
|
||||||
|
FlatCardGroupDisplayWidget::updateCardDisplays();
|
||||||
|
connect(deckListModel, &DeckListModel::dataChanged, this, &FlatCardGroupDisplayWidget::updateCardDisplays);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlatCardGroupDisplayWidget::updateCardDisplays()
|
||||||
|
{
|
||||||
|
// Retrieve and sort cards
|
||||||
|
QList<CardInfoPtr> cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName));
|
||||||
|
|
||||||
|
// Show or hide widget
|
||||||
|
bool shouldBeVisible = !cardsInZone.isEmpty();
|
||||||
|
if (shouldBeVisible != isVisible()) {
|
||||||
|
setVisible(shouldBeVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve existing widgets
|
||||||
|
QList<CardInfoPictureWithTextOverlayWidget *> existingWidgets =
|
||||||
|
flowWidget->findChildren<CardInfoPictureWithTextOverlayWidget *>();
|
||||||
|
|
||||||
|
QHash<QString, QList<CardInfoPictureWithTextOverlayWidget *>> widgetMap;
|
||||||
|
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||||
|
widgetMap[widget->getInfo()->getName()].append(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<CardInfoPictureWithTextOverlayWidget *> sortedWidgets;
|
||||||
|
QSet<CardInfoPictureWithTextOverlayWidget *> usedWidgets;
|
||||||
|
|
||||||
|
// Ensure widgets are ordered to match the sorted cards
|
||||||
|
for (const CardInfoPtr &card : cardsInZone) {
|
||||||
|
QString name = card->getName();
|
||||||
|
CardInfoPictureWithTextOverlayWidget *widget = nullptr;
|
||||||
|
|
||||||
|
if (!widgetMap[name].isEmpty()) {
|
||||||
|
// Reuse an existing widget
|
||||||
|
widget = widgetMap[name].takeFirst();
|
||||||
|
} else {
|
||||||
|
// Create a new widget if needed
|
||||||
|
widget = new CardInfoPictureWithTextOverlayWidget(flowWidget, true);
|
||||||
|
widget->setScaleFactor(cardSizeWidget->getSlider()->value());
|
||||||
|
widget->setCard(card);
|
||||||
|
|
||||||
|
connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this,
|
||||||
|
&FlatCardGroupDisplayWidget::onClick);
|
||||||
|
connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this,
|
||||||
|
&FlatCardGroupDisplayWidget::onHover);
|
||||||
|
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget,
|
||||||
|
&CardInfoPictureWidget::setScaleFactor);
|
||||||
|
|
||||||
|
flowWidget->addWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store in sorted order
|
||||||
|
sortedWidgets.append(widget);
|
||||||
|
usedWidgets.insert(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove extra widgets
|
||||||
|
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||||
|
if (!usedWidgets.contains(widget)) {
|
||||||
|
flowWidget->layout()->removeWidget(widget);
|
||||||
|
widget->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// **Reorder widgets in place**
|
||||||
|
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||||
|
sortedWidgets[i]->setParent(nullptr); // Temporarily detach
|
||||||
|
}
|
||||||
|
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||||
|
flowWidget->addWidget(sortedWidgets[i]); // Reattach in correct order
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlatCardGroupDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef FLAT_CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
#define FLAT_CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../general/layout_containers/flow_widget.h"
|
||||||
|
#include "card_group_display_widget.h"
|
||||||
|
|
||||||
|
class FlatCardGroupDisplayWidget : public CardGroupDisplayWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlatCardGroupDisplayWidget(QWidget *parent,
|
||||||
|
DeckListModel *deckListModel,
|
||||||
|
QString zoneName,
|
||||||
|
QString cardGroupCategory,
|
||||||
|
QString activeGroupCriteria,
|
||||||
|
QStringList activeSortCriteria,
|
||||||
|
int bannerOpacity,
|
||||||
|
CardSizeWidget *cardSizeWidget);
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateCardDisplays() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FlowWidget *flowWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FLAT_CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include "overlapped_card_group_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../../deck/deck_list_model.h"
|
||||||
|
#include "../../../../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../../../../utility/card_info_comparator.h"
|
||||||
|
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||||
|
|
||||||
|
#include <QResizeEvent>
|
||||||
|
|
||||||
|
OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *parent,
|
||||||
|
DeckListModel *_deckListModel,
|
||||||
|
QString _zoneName,
|
||||||
|
QString _cardGroupCategory,
|
||||||
|
QString _activeGroupCriteria,
|
||||||
|
QStringList _activeSortCriteria,
|
||||||
|
int bannerOpacity,
|
||||||
|
CardSizeWidget *_cardSizeWidget)
|
||||||
|
: CardGroupDisplayWidget(parent,
|
||||||
|
_deckListModel,
|
||||||
|
_zoneName,
|
||||||
|
_cardGroupCategory,
|
||||||
|
_activeGroupCriteria,
|
||||||
|
_activeSortCriteria,
|
||||||
|
bannerOpacity,
|
||||||
|
_cardSizeWidget)
|
||||||
|
{
|
||||||
|
overlapWidget = new OverlapWidget(this, 80, 1, 1, Qt::Vertical, true);
|
||||||
|
banner->setBuddy(overlapWidget);
|
||||||
|
|
||||||
|
layout->addWidget(overlapWidget);
|
||||||
|
OverlappedCardGroupDisplayWidget::updateCardDisplays();
|
||||||
|
connect(deckListModel, &DeckListModel::dataChanged, this, &OverlappedCardGroupDisplayWidget::updateCardDisplays);
|
||||||
|
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, this,
|
||||||
|
[this]() { overlapWidget->adjustMaxColumnsAndRows(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlappedCardGroupDisplayWidget::updateCardDisplays()
|
||||||
|
{
|
||||||
|
overlapWidget->setUpdatesEnabled(false);
|
||||||
|
// Retrieve and sort cards
|
||||||
|
QList<CardInfoPtr> cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName));
|
||||||
|
|
||||||
|
// Show or hide widget
|
||||||
|
bool shouldBeVisible = !cardsInZone.isEmpty();
|
||||||
|
if (shouldBeVisible != isVisible()) {
|
||||||
|
setVisible(shouldBeVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve existing widgets
|
||||||
|
QList<CardInfoPictureWithTextOverlayWidget *> existingWidgets =
|
||||||
|
overlapWidget->findChildren<CardInfoPictureWithTextOverlayWidget *>();
|
||||||
|
|
||||||
|
QHash<QString, QList<CardInfoPictureWithTextOverlayWidget *>> widgetMap;
|
||||||
|
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||||
|
widgetMap[widget->getInfo()->getName()].append(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<CardInfoPictureWithTextOverlayWidget *> sortedWidgets;
|
||||||
|
QSet<CardInfoPictureWithTextOverlayWidget *> usedWidgets;
|
||||||
|
|
||||||
|
// Ensure widgets are ordered to match the sorted cards
|
||||||
|
for (const CardInfoPtr &card : cardsInZone) {
|
||||||
|
QString name = card->getName();
|
||||||
|
CardInfoPictureWithTextOverlayWidget *widget = nullptr;
|
||||||
|
|
||||||
|
if (!widgetMap[name].isEmpty()) {
|
||||||
|
// Reuse an existing widget
|
||||||
|
widget = widgetMap[name].takeFirst();
|
||||||
|
} else {
|
||||||
|
// Create a new widget if needed
|
||||||
|
widget = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true);
|
||||||
|
widget->setScaleFactor(cardSizeWidget->getSlider()->value());
|
||||||
|
widget->setCard(card);
|
||||||
|
|
||||||
|
connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this,
|
||||||
|
&OverlappedCardGroupDisplayWidget::onClick);
|
||||||
|
connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this,
|
||||||
|
&OverlappedCardGroupDisplayWidget::onHover);
|
||||||
|
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget,
|
||||||
|
&CardInfoPictureWidget::setScaleFactor);
|
||||||
|
|
||||||
|
overlapWidget->addWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store in sorted order
|
||||||
|
sortedWidgets.append(widget);
|
||||||
|
usedWidgets.insert(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove extra widgets
|
||||||
|
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||||
|
if (!usedWidgets.contains(widget)) {
|
||||||
|
overlapWidget->layout()->removeWidget(widget);
|
||||||
|
widget->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// **Reorder widgets in place**
|
||||||
|
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||||
|
sortedWidgets[i]->setParent(nullptr); // Temporarily detach
|
||||||
|
}
|
||||||
|
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||||
|
overlapWidget->addWidget(sortedWidgets[i]); // Reattach in correct order
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure proper layering
|
||||||
|
for (CardInfoPictureWithTextOverlayWidget *widget : sortedWidgets) {
|
||||||
|
widget->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
overlapWidget->adjustMaxColumnsAndRows();
|
||||||
|
overlapWidget->setUpdatesEnabled(true);
|
||||||
|
overlapWidget->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlappedCardGroupDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(event);
|
||||||
|
|
||||||
|
overlapWidget->resize(event->size());
|
||||||
|
overlapWidget->adjustMaxColumnsAndRows();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
#define OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../general/layout_containers/overlap_widget.h"
|
||||||
|
#include "card_group_display_widget.h"
|
||||||
|
|
||||||
|
class OverlappedCardGroupDisplayWidget : public CardGroupDisplayWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
OverlappedCardGroupDisplayWidget(QWidget *parent,
|
||||||
|
DeckListModel *deckListModel,
|
||||||
|
QString zoneName,
|
||||||
|
QString cardGroupCategory,
|
||||||
|
QString activeGroupCriteria,
|
||||||
|
QStringList activeSortCriteria,
|
||||||
|
int bannerOpacity,
|
||||||
|
CardSizeWidget *cardSizeWidget);
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateCardDisplays() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OverlapWidget *overlapWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||||
|
|
@ -22,7 +22,7 @@ CardInfoDisplayWidget::CardInfoDisplayWidget(const QString &cardName,
|
||||||
pic->setObjectName("pic");
|
pic->setObjectName("pic");
|
||||||
text = new CardInfoTextWidget();
|
text = new CardInfoTextWidget();
|
||||||
text->setObjectName("text");
|
text->setObjectName("text");
|
||||||
connect(text, SIGNAL(linkActivated(const QString &)), this, SLOT(setCard(const QString &)));
|
connect(text, &CardInfoTextWidget::linkActivated, this, [this](const QString &card) { setCard(card); });
|
||||||
|
|
||||||
auto *layout = new QVBoxLayout();
|
auto *layout = new QVBoxLayout();
|
||||||
layout->setObjectName("layout");
|
layout->setObjectName("layout");
|
||||||
|
|
@ -52,7 +52,7 @@ void CardInfoDisplayWidget::setCard(CardInfoPtr card)
|
||||||
disconnect(info.data(), nullptr, this, nullptr);
|
disconnect(info.data(), nullptr, this, nullptr);
|
||||||
info = std::move(card);
|
info = std::move(card);
|
||||||
if (info)
|
if (info)
|
||||||
connect(info.data(), SIGNAL(destroyed()), this, SLOT(clear()));
|
connect(info.data(), &QObject::destroyed, this, &CardInfoDisplayWidget::clear);
|
||||||
|
|
||||||
text->setCard(info);
|
text->setCard(info);
|
||||||
pic->setCard(info);
|
pic->setCard(info);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef CARDINFOWIDGET_H
|
#ifndef CARDINFOWIDGET_H
|
||||||
#define CARDINFOWIDGET_H
|
#define CARDINFOWIDGET_H
|
||||||
|
|
||||||
#include "../../../../game/cards/card_database.h"
|
#include "../../../../game/cards/card_info.h"
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ CardInfoFrameWidget::CardInfoFrameWidget(const QString &cardName, QWidget *paren
|
||||||
|
|
||||||
text = new CardInfoTextWidget();
|
text = new CardInfoTextWidget();
|
||||||
text->setObjectName("text");
|
text->setObjectName("text");
|
||||||
connect(text, SIGNAL(linkActivated(const QString &)), this, SLOT(setCard(const QString &)));
|
connect(text, &CardInfoTextWidget::linkActivated, this, qOverload<const QString &>(&CardInfoFrameWidget::setCard));
|
||||||
|
|
||||||
tab1 = new QWidget(this);
|
tab1 = new QWidget(this);
|
||||||
tab2 = new QWidget(this);
|
tab2 = new QWidget(this);
|
||||||
|
|
@ -34,7 +34,7 @@ CardInfoFrameWidget::CardInfoFrameWidget(const QString &cardName, QWidget *paren
|
||||||
insertTab(ImageOnlyView, tab1, QString());
|
insertTab(ImageOnlyView, tab1, QString());
|
||||||
insertTab(TextOnlyView, tab2, QString());
|
insertTab(TextOnlyView, tab2, QString());
|
||||||
insertTab(ImageAndTextView, tab3, QString());
|
insertTab(ImageAndTextView, tab3, QString());
|
||||||
connect(this, SIGNAL(currentChanged(int)), this, SLOT(setViewMode(int)));
|
connect(this, &CardInfoFrameWidget::currentChanged, this, &CardInfoFrameWidget::setViewMode);
|
||||||
|
|
||||||
tab1Layout = new QVBoxLayout();
|
tab1Layout = new QVBoxLayout();
|
||||||
tab1Layout->setObjectName("tab1Layout");
|
tab1Layout->setObjectName("tab1Layout");
|
||||||
|
|
@ -61,6 +61,7 @@ CardInfoFrameWidget::CardInfoFrameWidget(const QString &cardName, QWidget *paren
|
||||||
|
|
||||||
setViewMode(SettingsCache::instance().getCardInfoViewMode());
|
setViewMode(SettingsCache::instance().getCardInfoViewMode());
|
||||||
|
|
||||||
|
// TODO: Change this to be by UUID
|
||||||
setCard(CardDatabaseManager::getInstance()->getCard(cardName));
|
setCard(CardDatabaseManager::getInstance()->getCard(cardName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,7 +155,7 @@ void CardInfoFrameWidget::setCard(CardInfoPtr card)
|
||||||
info = std::move(card);
|
info = std::move(card);
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
connect(info.data(), SIGNAL(destroyed()), this, SLOT(clearCard()));
|
connect(info.data(), &QObject::destroyed, this, &CardInfoFrameWidget::clearCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
setViewTransformationButtonVisibility(hasTransformation(info));
|
setViewTransformationButtonVisibility(hasTransformation(info));
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue