From c5cd7d87001ed5738c428dadb38f73999c033a87 Mon Sep 17 00:00:00 2001
From: RickyRister <42636155+RickyRister@users.noreply.github.com>
Date: Wed, 18 Mar 2026 02:13:36 -0700
Subject: [PATCH 01/60] [ShortcutsSettings] Fix duplicate aPlay shortcut;
change play shortcut's group (#6716)
* [ShortcutsSettings] Fix duplicate aPlay shortcut; change play shortcut's group
* update description
---
cockatrice/src/client/settings/shortcuts_settings.h | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/cockatrice/src/client/settings/shortcuts_settings.h b/cockatrice/src/client/settings/shortcuts_settings.h
index 47332b8c4..51615745b 100644
--- a/cockatrice/src/client/settings/shortcuts_settings.h
+++ b/cockatrice/src/client/settings/shortcuts_settings.h
@@ -513,6 +513,9 @@ private:
{"Player/aPlay", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Play Card"),
parseSequenceString(""),
ShortcutGroup::Playing_Area)},
+ {"Player/aPlayFacedown", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Play Card, Face Down"),
+ parseSequenceString(""),
+ ShortcutGroup::Playing_Area)},
{"Player/aAttach", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Attach Card..."),
parseSequenceString("Ctrl+Alt+A"),
ShortcutGroup::Playing_Area)},
@@ -560,12 +563,6 @@ private:
{"Player/aMoveToTopLibrary", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Top of Library"),
parseSequenceString(""),
ShortcutGroup::Move_selected)},
- {"Player/aPlayFacedown", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Battlefield, Face Down"),
- parseSequenceString(""),
- ShortcutGroup::Move_selected)},
- {"Player/aPlay", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Battlefield"),
- parseSequenceString(""),
- ShortcutGroup::Move_selected)},
{"Player/aViewHand",
ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Hand"), parseSequenceString(""), ShortcutGroup::View)},
{"Player/aViewGraveyard",
From 38c85e6db16dbc692dbc908c1a9693a11761788c Mon Sep 17 00:00:00 2001
From: RickyRister <42636155+RickyRister@users.noreply.github.com>
Date: Wed, 18 Mar 2026 10:24:34 -0700
Subject: [PATCH 02/60] [Dialog] Reduce spacing in create local game dialog
(#6719)
---
.../src/interface/widgets/dialogs/dlg_local_game_options.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp
index 52466ff10..a9adfd907 100644
--- a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp
+++ b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp
@@ -20,6 +20,7 @@ DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent)
numberPlayersLabel->setBuddy(numberPlayersEdit);
auto *generalGrid = new QGridLayout;
+ generalGrid->setContentsMargins(5, 5, 5, 5);
generalGrid->addWidget(numberPlayersLabel, 0, 0);
generalGrid->addWidget(numberPlayersEdit, 0, 1);
generalGroupBox = new QGroupBox(tr("General"), this);
@@ -33,6 +34,7 @@ DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent)
startingLifeTotalLabel->setBuddy(startingLifeTotalEdit);
auto *gameSetupGrid = new QGridLayout;
+ gameSetupGrid->setContentsMargins(5, 5, 5, 5);
gameSetupGrid->addWidget(startingLifeTotalLabel, 0, 0);
gameSetupGrid->addWidget(startingLifeTotalEdit, 0, 1);
gameSetupOptionsGroupBox = new QGroupBox(tr("Game setup options"), this);
From 067fe9b5349a673f2d61f0cf5e2e92e0873013b4 Mon Sep 17 00:00:00 2001
From: "transifex-integration[bot]"
<43880903+transifex-integration[bot]@users.noreply.github.com>
Date: Sat, 21 Mar 2026 10:13:43 +0100
Subject: [PATCH 03/60] Translate cockatrice/cockatrice_en@source.ts in it
(#6724)
100% translated source file: 'cockatrice/cockatrice_en@source.ts'
on 'it'.
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
---
cockatrice/translations/cockatrice_it.ts | 348 ++++++++++++-----------
1 file changed, 180 insertions(+), 168 deletions(-)
diff --git a/cockatrice/translations/cockatrice_it.ts b/cockatrice/translations/cockatrice_it.ts
index a0765fbfb..5893d4121 100644
--- a/cockatrice/translations/cockatrice_it.ts
+++ b/cockatrice/translations/cockatrice_it.ts
@@ -101,7 +101,7 @@ Controlla se la cartella è valida e prova ancora.
Add Analytics Panel
-
+ Aggiungi pannello di analisi
@@ -156,7 +156,13 @@ You will not be able to manage printing preferences on a per-deck basis, or see
You will have to use the Set Manager, available through Card Database -> Manage Sets.
Are you sure you would like to enable this feature?
-
+ Abilitare questa funzione disattiverà il Selettore di stampa.
+
+Non potrai gestire le preferenze delle stampe per i singoli mazzi, o vedere le stampe scelte dagli altri giocatori per i loro mazzi.
+
+Dovrai usare il Gestore dei set, raggiungibile tramite Database carte -> Organizza set.
+
+Sicuro di voler abilitare questa funzione?
@@ -167,12 +173,18 @@ You can now choose printings on a per-deck basis in the Deck Editor and configur
You can also use the Set Manager to adjust custom sort order for printings in the Printing Selector (other sort orders like alphabetical or release date are available).
Are you sure you would like to disable this feature?
-
+ Disabilitare questa funzione attiverà il Selettore di stampa.
+
+Potrai gestire le preferenze delle stampe per i singoli mazzi nell'Editor, e configurare quale stampa viene aggiunta di default a un mazzo fissandola nel selettore.
+
+Potrai anche usare il Gestore dei set per personalizzare l'ordine delle stampe nel Selettore (sono disponibili anche ordinamenti predefiniti come alfabetico o per data di uscita).
+
+Sicuro di voler disabilitare questa funzione?
Confirm Change
-
+ Conferma modifica
@@ -217,7 +229,7 @@ Are you sure you would like to disable this feature?
Show game filter toolbar above list in room tab
-
+ Mostra barra di filtro sopra la lista delle partite
@@ -237,7 +249,7 @@ Are you sure you would like to disable this feature?
Override all card art with personal set preference (Pre-ProviderID change behavior)
-
+ Determina l'illustrazione della carta attraverso la priorità dei set (come prima dell'implementazione del ProviderID)
@@ -326,7 +338,7 @@ Are you sure you would like to disable this feature?
Open Deck in Deck Editor
-
+ Apri mazzo nell'editor dei mazzi
@@ -550,7 +562,7 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Name (Exact)
-
+ Nome (esatto)
@@ -674,12 +686,12 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Set:
-
+ Set:
Collector Number:
-
+ Numero di collezione:
@@ -822,7 +834,7 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Card Size
- Dimensioni della carta
+ Dimensioni carte
@@ -995,22 +1007,22 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Add Panel
-
+ Aggiungi pannello
Remove Panel
-
+ Rimuovi pannello
Save Layout
-
+ Salva disposizione
Load Layout
-
+ Carica disposizione
@@ -1018,7 +1030,7 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Card Database
-
+ Database carte
@@ -1082,7 +1094,7 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Loading Database...
-
+ Caricamento database...
@@ -1147,7 +1159,7 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Format:
-
+ Formato:
@@ -1488,32 +1500,32 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Undo
-
+ Annulla
Redo
-
+ Ripeti
Undo/Redo history
-
+ Annulla/Ripeti Storico
Click on an entry to revert to that point in the history.
-
+ Clicca su una riga per ritornare a quel punto nello storico delle modifiche.
[redo]
-
+ [ripeti]
[undo]
-
+ [annulla]
@@ -1746,57 +1758,57 @@ Questa è visibile solo ai moderatori e non alla persona bannata.
Rename deck to "%1" from "%2"
-
+ Rinominato mazzo in "%1" da "%2"
Updated comments (was %1 chars, now %2 chars)
-
+ Commenti aggiornati (prima %1 caratteri, ora %2 caratteri)
Set banner card to %1 (%2)
-
+ Impostata carta copertina a %1 (%2)
Tags changed
-
+ Etichette modificate
Set format to %1
-
+ Formato impostato a %1
Added (%1): %2 (%3) %4
-
+ Aggiunto (%1): %2 (%3) %4
Moved to %1 1 × "%2" (%3)
-
+ Spostato in %1 1 × "%2" (%3)
Removed "%1" (all copies)
-
+ Rimosso "%1" (tutte le copie)
%1 1 × "%2" (%3)
-
+ %1 1 × "%2" (%3)
Added
-
+ Aggiunto
Removed
-
+ Rimosso
@@ -2150,7 +2162,7 @@ Vuoi convertire il mazzo al formato .cod?
Create game as judge
-
+ Crea partita come arbitro
@@ -2526,7 +2538,7 @@ Per rimuovere il tuo avatar attuale, conferma senza scegliere una nuova immagine
The chosen name conflicts with an existing card or token.
Make sure to enable the 'Token' set in the "Manage sets" dialog to display them correctly.
Il nome scelto è in conflitto con una carta o pedina esistente.
-Assicurati di abilitare il set "Pedine" nella finestra "Organizza set" per visualizzarle correttamente.
+Assicurati di abilitare il set "Pedine" nella finestra "Gestisci Espansioni" per visualizzarle correttamente.
@@ -2618,7 +2630,7 @@ Assicurati di abilitare il set "Pedine" nella finestra "Organizza
Hide games not created by buddies
Hide games not created by buddy
-
+ Nascondi partite non create dagli amici
@@ -3150,17 +3162,17 @@ La tua email verrà utilizzata per verificare il tuo account.
Bulk modified printings.
-
+ Stampe modificate massivamente.
Cleared all printing information.
-
+ Informazioni sulle stampe eliminate.
Set all printings to preferred.
-
+ Imposta tutte le stampe come preferite.
@@ -3556,63 +3568,63 @@ Dovrai scaricare la nuova versione manualmente.
Draw Probability Settings
-
+ Impostazioni probabilità di pescare
Criteria:
-
+ Criterio:
Card Name
-
+ Nome carta
Type
-
+ Tipo
Subtype
-
+ Sottotipo
Mana Value
-
+ Valore di mana
Exactness:
-
+ Precisione:
At least
-
+ Almeno
Exactly
-
+ Esattamente
Quantity (N):
-
+ Quantità (N):
Cards drawn (M):
-
+ Carte pescate (M):
cards
-
+ carte
@@ -3620,67 +3632,67 @@ Dovrai scaricare la nuova versione manualmente.
Draw Probability
-
+ Probabilità di pescare
Probability of drawing
-
+ Probabilità di pescare
Card Name
-
+ Nome carta
Type
-
+ Tipo
Subtype
-
+ Sottotipo
Mana Value
-
+ Valore di mana
At least
-
+ Almeno
Exactly
-
+ Esattamente
card(s) having drawn at least
-
+ carta/e avendo pescato almeno
cards
-
+ carte
Category
-
+ Categoria
Qty
-
+ Quantità
Odds (%)
-
+ Probabilità (%)
@@ -3757,7 +3769,7 @@ Dovrai scaricare la nuova versione manualmente.
Game Changers
-
+ Carte decisive
@@ -3765,7 +3777,7 @@ Dovrai scaricare la nuova versione manualmente.
Budget
-
+ Budget
@@ -3916,12 +3928,12 @@ Dovrai scaricare la nuova versione manualmente.
Join Game as Judge
-
+ Unisciti a una partita come arbitro
Spectate Game as Judge
-
+ Osserva partita come arbitro
@@ -3961,7 +3973,7 @@ Dovrai scaricare la nuova versione manualmente.
Join as judge
-
+ Unisciti come arbitro
@@ -3971,7 +3983,7 @@ Dovrai scaricare la nuova versione manualmente.
Join as judge spectator
-
+ Unisciti come arbitro spettatore
@@ -3989,32 +4001,32 @@ Dovrai scaricare la nuova versione manualmente.
All types
-
+ Tutti i tipi
Filter by game name...
-
+ Filtra per nome della partita...
Filter by game type/format
-
+ Filtra per tipo / formato di partita
Hide games not created by buddies
-
+ Nascondi le partite non create da amici
Hide full games
-
+ Nascondi partite al completo
Hide started games
-
+ Nascondi partite iniziate
@@ -4297,7 +4309,7 @@ Dovrai scaricare la nuova versione manualmente.
&All players
-
+ &Tutti i giocatori
@@ -4330,37 +4342,37 @@ Dovrai scaricare la nuova versione manualmente.
Sort hand by...
-
+ Ordina mano per...
Name
-
+ Nome
Type
-
+ Tipo
Mana Value
-
+ Valore di mana
Take &mulligan (Choose hand size)
-
+ Effettua un &mulligan (Scegli numero di carte)
Take mulligan (Same hand size)
-
+ Effettua un mulligan (Stessa dimensione della mano)
Take mulligan (Hand size - 1)
-
+ Effettua un mulligan (Dimensione della mano - 1)
@@ -4396,7 +4408,7 @@ Dovrai scaricare la nuova versione manualmente.
All players
-
+ Tutti i giocatori
@@ -4429,7 +4441,7 @@ Dovrai scaricare la nuova versione manualmente.
Browse Archidekt
-
+ Esplora Archidekt
@@ -4638,17 +4650,17 @@ Dovrai scaricare la nuova versione manualmente.
&All players
-
+ &Tutti i giocatori
Reveal top cards of library
-
+ Rivela le carte in cima al grimorio
Number of cards: (max. %1)
-
+ Numero di carte: (max. %1)
@@ -5186,7 +5198,7 @@ La tua versione è la %1, la versione online è la %2.
&Manage sets...
- &Organizza set...
+ &Gestisci Espansioni...
@@ -5358,7 +5370,7 @@ All the sets in the card database have been enabled.
Read more about changing the set order or disabling specific sets and consequent effects in the "Manage Sets" dialog.
Ciao! Sembra che tu stia usando questa versione di Cockatrice per la prima volta
Tutti i set nell'archivio delle carte sono stati abilitati.
-Scopri metodi alternativi per visualizzare i set o disabilitare set ed effetti nella finestra "Organizza set".
+Scopri metodi alternativi per visualizzare i set o disabilitare set ed effetti nella finestra "Gestisci Espansioni".
@@ -5488,42 +5500,42 @@ Il database delle carte verrà ricaricato.
Mana Base Configuration
-
+ Configurazione Base di mana
Display type:
-
+ Modalità di visualizzazione:
pie
-
+ a torta
bar
-
+ a barre
combinedBar
-
+ a barre combinate
Filter Colors (optional):
-
+ Filtra per colori (opzionale):
OK
-
+ OK
Cancel
-
+ Annulla
@@ -5539,47 +5551,47 @@ Il database delle carte verrà ricaricato.
Group By:
-
+ Raggruppa per:
type
-
+ tipo
color
-
+ colore
subtype
-
+ sottotipo
power
-
+ forza
toughness
-
+ costituzione
Filters (optional):
-
+ Filtri (opzionali):
Show main bar row
-
+ Mostra il grafico principale
Show per-category rows
-
+ Mostra i grafici per categorie
@@ -5595,27 +5607,27 @@ Il database delle carte verrà ricaricato.
Display type:
-
+ Modalità di visualizzazione:
pie
-
+ A torta
bar
-
+ A barre
combinedBar
-
+ A barra combinata
Filter Colors (optional):
-
+ Filtri per colore (opzionali):
@@ -5631,27 +5643,27 @@ Il database delle carte verrà ricaricato.
Top display type:
-
+ Modalità di visualizzazione principale:
pie
-
+ A torta
bar
-
+ A barre
Colors:
-
+ Colori:
Show per-color rows
-
+ Mostra grafici per colore
@@ -5659,12 +5671,12 @@ Il database delle carte verrà ricaricato.
%1 pips (%2 cards)
-
+ %1 simboli (%2 carte)
%1 mana (%2 cards)
-
+ %1 mana (%2 carte)
@@ -5672,12 +5684,12 @@ Il database delle carte verrà ricaricato.
Mana Production + Devotion
-
+ Produzione + Devozione di mana
Mana Distribution Settings
-
+ Impostazioni distribuzione di mana
@@ -7637,58 +7649,58 @@ Controlla le impostazioni!
Desc.
-
+ Decrescente
Asc.
-
+ Crescente
Any Bracket
-
+ Qualsiasi fascia
Deck name contains...
-
+ Nome del mazzo contiene...
Owner name contains...
-
+ Nome del proprietario contiene...
Disabled
-
+ Disabilitato
Search
-
+ Cerca
Formats
-
+ Formati
Min. # of Cards:
-
+ Num. minimo di carte:
Page:
-
+ Pagina:
Archidekt:
-
+ Archidekt:
@@ -7716,7 +7728,7 @@ Controlla le impostazioni!
Card Database
-
+ Database carte
@@ -7819,12 +7831,12 @@ Controlla le impostazioni!
Visual Deck View
- Galleria mazzo
+ Mazzo visuale
Visual Database Display
- Galleria database
+ Database visuale
@@ -8729,7 +8741,7 @@ Più informazioni inserisci, più specifici saranno i risultati.
Archidekt
-
+ Archidekt
@@ -8857,7 +8869,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Database Display
-
+ Visualizzazione Database
@@ -9353,7 +9365,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Do not delete &arrows inside of subphases
-
+ Non eliminare le &freccie al cambio di sottofase
@@ -9555,7 +9567,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Search filter...
-
+ Filtro di ricerca...
@@ -9578,22 +9590,22 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Do not display formats with less than this amount of cards in the database
-
+ Non mostrare i formati con meno di questo ammontare di carte nel database
Filter mode (AND/OR/NOT conjunctions of filters)
-
+ Modalità di filtraggio (utilizzabile con connettivi logici AND/OR/NOT)
Mode: Exact Match
-
+ Modalità: Corrispondenza esatta
Mode: Includes
-
+ Modalità: Include
@@ -9624,7 +9636,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Filter by name... (Exact match)
-
+ Filtra per nome... (Corrispondenza esatta)
@@ -9714,7 +9726,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Visual
-
+ Visuale
@@ -9729,12 +9741,12 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Sort by:
-
+ Ordina per:
Filter by:
-
+ Filtra per:
@@ -9759,7 +9771,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Table
-
+ Tabella
@@ -9767,43 +9779,43 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Group by:
-
+ Raggruppa per:
Change how cards are divided into categories/groups.
-
+ Modifica come le carte sono divise in categorie / gruppi.
Sort by:
-
+ Ordina per:
Click and drag to change the sort order within the groups
-
+ Clicca e trascina per modificare l'ordinamento interno ai gruppi
Configure how cards are sorted within their groups
-
+ Configura come le carte sono ordinate all'interno dei loro gruppi
Toggle Layout: Overlap
-
+ Disposizione: Sovrapposta
Change how cards are displayed within zones (i.e. overlapped or fully visible.)
-
+ Modifica come le carte vengono mostrate nelle zone (es. sovrapposte o completamente visibili.)
Toggle Layout: Flat
-
+ Disposizione: Piatta
@@ -9824,7 +9836,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Type a card name here for suggestions from the database...
-
+ Scrivi un nome di carta qui per avere suggerimenti dal database...
@@ -10948,7 +10960,7 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Reveal Selected Cards to All Players
-
+ Rivela Carta Selezionata a Tutti i Giocatori
@@ -11103,12 +11115,12 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Mulligan (Same hand size)
-
+ Mulligan (Come la mano attuale)
Mulligan (Hand size - 1)
-
+ Mulligan (Dimensione della mano - 1)
@@ -11138,27 +11150,27 @@ Se pregato di evitare di continuare questa attività o potrebbero venire presi u
Sort Hand by Name
-
+ Ordina mano per Nome
Sort Hand by Type
-
+ Ordina mano per Tipo
Sort Hand by Mana Value
-
+ Ordina mano per Valore di Mana
Reveal Hand to All Players
-
+ Rivela Mano a Tutti i Giocatori
Reveal Random Card to All Players
-
+ Rivela Carta Casuale a Tutti i Giocatori
From 652c8464a7c391884b1295fca96a82c08881cbb8 Mon Sep 17 00:00:00 2001
From: tooomm
Date: Sun, 22 Mar 2026 10:28:24 +0100
Subject: [PATCH 04/60] Docker compose: Link to our GHCR hosted `servatrice`
image (#6728)
* Point to our own image
* Point to our own image
* Readd build
* Readd build
---
docker-compose.yml | 2 +-
docker-compose.yml.windows | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docker-compose.yml b/docker-compose.yml
index 3d9f9f38f..6cbac61f0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -16,7 +16,7 @@ services:
build:
context: .
dockerfile: Dockerfile
- image: servatrice
+ image: ghcr.io/cockatrice/servatrice:latest
depends_on:
- mysql
ports:
diff --git a/docker-compose.yml.windows b/docker-compose.yml.windows
index 6663c90fd..3d29b1e5f 100644
--- a/docker-compose.yml.windows
+++ b/docker-compose.yml.windows
@@ -16,7 +16,7 @@ services:
build:
context: .
dockerfile: Dockerfile
- image: servatrice
+ image: ghcr.io/cockatrice/servatrice:latest
depends_on:
- mysql
ports:
From bc219191dbdcf5e870c36470b9c633558f483de9 Mon Sep 17 00:00:00 2001
From: RickyRister <42636155+RickyRister@users.noreply.github.com>
Date: Sun, 22 Mar 2026 04:32:42 -0700
Subject: [PATCH 05/60] [Game] Refactor options in DlgMoveTopCardsUntil into
struct (#6718)
---
.../game/dialogs/dlg_move_top_cards_until.cpp | 28 ++++++++-----------
.../game/dialogs/dlg_move_top_cards_until.h | 20 +++++++------
cockatrice/src/game/player/player_actions.cpp | 11 +++-----
cockatrice/src/game/player/player_actions.h | 5 ++--
4 files changed, 30 insertions(+), 34 deletions(-)
diff --git a/cockatrice/src/game/dialogs/dlg_move_top_cards_until.cpp b/cockatrice/src/game/dialogs/dlg_move_top_cards_until.cpp
index a9db4cef6..2b54452ac 100644
--- a/cockatrice/src/game/dialogs/dlg_move_top_cards_until.cpp
+++ b/cockatrice/src/game/dialogs/dlg_move_top_cards_until.cpp
@@ -12,8 +12,7 @@
#include
#include
-DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QStringList exprs, uint _numberOfHits, bool autoPlay)
- : QDialog(parent)
+DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, const MoveTopCardsUntilOptions &options) : QDialog(parent)
{
exprLabel = new QLabel(tr("Card name (or search expressions):"));
@@ -21,13 +20,13 @@ DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QStringList exprs, u
exprComboBox->setFocus();
exprComboBox->setEditable(true);
exprComboBox->setInsertPolicy(QComboBox::InsertAtTop);
- exprComboBox->insertItems(0, exprs);
+ exprComboBox->insertItems(0, options.exprs);
exprLabel->setBuddy(exprComboBox);
numberOfHitsLabel = new QLabel(tr("Number of hits:"));
numberOfHitsEdit = new QSpinBox(this);
numberOfHitsEdit->setRange(1, 99);
- numberOfHitsEdit->setValue(_numberOfHits);
+ numberOfHitsEdit->setValue(options.numberOfHits);
numberOfHitsLabel->setBuddy(numberOfHitsEdit);
auto *grid = new QGridLayout;
@@ -35,7 +34,7 @@ DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QStringList exprs, u
grid->addWidget(numberOfHitsEdit, 0, 1);
autoPlayCheckBox = new QCheckBox(tr("Auto play hits"));
- autoPlayCheckBox->setChecked(autoPlay);
+ autoPlayCheckBox->setChecked(options.autoPlay);
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgMoveTopCardsUntil::validateAndAccept);
@@ -118,6 +117,13 @@ QString DlgMoveTopCardsUntil::getExpr() const
return exprComboBox->currentText();
}
+MoveTopCardsUntilOptions DlgMoveTopCardsUntil::getOptions() const
+{
+ return {.exprs = getExprs(),
+ .numberOfHits = numberOfHitsEdit->text().toInt(),
+ .autoPlay = autoPlayCheckBox->isChecked()};
+}
+
QStringList DlgMoveTopCardsUntil::getExprs() const
{
QStringList exprs;
@@ -125,14 +131,4 @@ QStringList DlgMoveTopCardsUntil::getExprs() const
exprs.append(exprComboBox->itemText(i));
}
return exprs;
-}
-
-uint DlgMoveTopCardsUntil::getNumberOfHits() const
-{
- return numberOfHitsEdit->text().toUInt();
-}
-
-bool DlgMoveTopCardsUntil::isAutoPlay() const
-{
- return autoPlayCheckBox->isChecked();
-}
+}
\ No newline at end of file
diff --git a/cockatrice/src/game/dialogs/dlg_move_top_cards_until.h b/cockatrice/src/game/dialogs/dlg_move_top_cards_until.h
index 9a9dc91e7..20ba11c5c 100644
--- a/cockatrice/src/game/dialogs/dlg_move_top_cards_until.h
+++ b/cockatrice/src/game/dialogs/dlg_move_top_cards_until.h
@@ -16,6 +16,13 @@
class FilterString;
+struct MoveTopCardsUntilOptions
+{
+ QStringList exprs = {};
+ int numberOfHits = 1;
+ bool autoPlay = false;
+};
+
class DlgMoveTopCardsUntil : public QDialog
{
Q_OBJECT
@@ -29,15 +36,12 @@ class DlgMoveTopCardsUntil : public QDialog
void validateAndAccept();
bool validateMatchExists(const FilterString &filterString);
-public:
- explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr,
- QStringList exprs = QStringList(),
- uint numberOfHits = 1,
- bool autoPlay = false);
- [[nodiscard]] QString getExpr() const;
[[nodiscard]] QStringList getExprs() const;
- [[nodiscard]] uint getNumberOfHits() const;
- [[nodiscard]] bool isAutoPlay() const;
+
+public:
+ explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr, const MoveTopCardsUntilOptions &options = {});
+ [[nodiscard]] QString getExpr() const;
+ [[nodiscard]] MoveTopCardsUntilOptions getOptions() const;
};
#endif // DLG_MOVE_TOP_CARDS_UNTIL_H
diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp
index 20e526727..287231402 100644
--- a/cockatrice/src/game/player/player_actions.cpp
+++ b/cockatrice/src/game/player/player_actions.cpp
@@ -485,22 +485,19 @@ void PlayerActions::actMoveTopCardsUntil()
{
stopMoveTopCardsUntil();
- DlgMoveTopCardsUntil dlg(player->getGame()->getTab(), movingCardsUntilExprs, movingCardsUntilNumberOfHits,
- movingCardsUntilAutoPlay);
+ DlgMoveTopCardsUntil dlg(player->getGame()->getTab(), movingCardsUntilOptions);
if (!dlg.exec()) {
return;
}
auto expr = dlg.getExpr();
- movingCardsUntilExprs = dlg.getExprs();
- movingCardsUntilNumberOfHits = dlg.getNumberOfHits();
- movingCardsUntilAutoPlay = dlg.isAutoPlay();
+ movingCardsUntilOptions = dlg.getOptions();
if (player->getDeckZone()->getCards().empty()) {
stopMoveTopCardsUntil();
} else {
movingCardsUntilFilter = FilterString(expr);
- movingCardsUntilCounter = movingCardsUntilNumberOfHits;
+ movingCardsUntilCounter = movingCardsUntilOptions.numberOfHits;
movingCardsUntil = true;
actMoveTopCardToPlay();
}
@@ -512,7 +509,7 @@ void PlayerActions::moveOneCardUntil(CardItem *card)
const bool isMatch = card && movingCardsUntilFilter.check(card->getCard().getCardPtr());
- if (isMatch && movingCardsUntilAutoPlay) {
+ if (isMatch && movingCardsUntilOptions.autoPlay) {
// Directly calling playCard will deadlock, since we are already in the middle of processing an event.
// Use QTimer::singleShot to queue up the playCard on the event loop.
QTimer::singleShot(0, this, [card, this] { playCard(card, false); });
diff --git a/cockatrice/src/game/player/player_actions.h b/cockatrice/src/game/player/player_actions.h
index 1d695578d..d4c6daacf 100644
--- a/cockatrice/src/game/player/player_actions.h
+++ b/cockatrice/src/game/player/player_actions.h
@@ -8,6 +8,7 @@
#ifndef COCKATRICE_PLAYER_ACTIONS_H
#define COCKATRICE_PLAYER_ACTIONS_H
#include "../dialogs/dlg_create_token.h"
+#include "../dialogs/dlg_move_top_cards_until.h"
#include "event_processing_options.h"
#include "player.h"
@@ -178,11 +179,9 @@ private:
bool movingCardsUntil;
QTimer *moveTopCardTimer;
- QStringList movingCardsUntilExprs = {};
- int movingCardsUntilNumberOfHits = 1;
- bool movingCardsUntilAutoPlay = false;
FilterString movingCardsUntilFilter;
int movingCardsUntilCounter = 0;
+ MoveTopCardsUntilOptions movingCardsUntilOptions;
void moveTopCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown);
void moveBottomCardsTo(const QString &targetZone, const QString &zoneDisplayName, bool faceDown);
From 414567f8b671c3f7487aa69d9bec96ce5d79d05c Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 23 Mar 2026 21:43:42 +0100
Subject: [PATCH 06/60] Bump docker/login-action from 3 to 4 (#6736)
---
.github/workflows/docker-release.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml
index 2a4aab1ea..cdcf77e97 100644
--- a/.github/workflows/docker-release.yml
+++ b/.github/workflows/docker-release.yml
@@ -48,7 +48,7 @@ jobs:
- name: Login to GitHub Container Registry
if: github.ref_type == 'tag'
- uses: docker/login-action@v3
+ uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
From fa2934373c556e4c485a8748cb5de412ccdae5c1 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 23 Mar 2026 21:44:31 +0100
Subject: [PATCH 07/60] Bump microsoft/setup-msbuild from 2 to 3 (#6735)
---
.github/workflows/desktop-build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml
index 02c3f7aec..820044059 100644
--- a/.github/workflows/desktop-build.yml
+++ b/.github/workflows/desktop-build.yml
@@ -341,7 +341,7 @@ jobs:
- name: Add msbuild to PATH
if: matrix.os == 'Windows'
id: add-msbuild
- uses: microsoft/setup-msbuild@v2
+ uses: microsoft/setup-msbuild@v3
with:
msbuild-architecture: x64
From 51c684251fa96dbeca4725e4687ae69097e7223d Mon Sep 17 00:00:00 2001
From: tooomm
Date: Tue, 24 Mar 2026 00:16:26 +0100
Subject: [PATCH 08/60] Add Docker to release template (#6732)
---
.ci/release_template.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.ci/release_template.md b/.ci/release_template.md
index 0e6c05165..b0924b92a 100644
--- a/.ci/release_template.md
+++ b/.ci/release_template.md
@@ -27,6 +27,8 @@ Available pre-compiled binaries for installation:
We are also packaged in Arch Linux's official extra repository, courtesy of @FFY00.
General Linux support is available via a flatpak package at Flathub!
+
+We provide a Docker image for "Servatrice" in GHCR. You can docker pull it or use our Docker Compose files!
From aa85a39d6add9b19983e2f5a1426a6f6114100d7 Mon Sep 17 00:00:00 2001
From: ebbit1q
Date: Tue, 24 Mar 2026 00:16:48 +0100
Subject: [PATCH 09/60] expand local game life total limits (#6730)
---
.../src/interface/widgets/dialogs/dlg_local_game_options.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp
index a9adfd907..d2d291556 100644
--- a/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp
+++ b/cockatrice/src/interface/widgets/dialogs/dlg_local_game_options.cpp
@@ -28,8 +28,8 @@ DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent)
startingLifeTotalLabel = new QLabel(tr("Starting life total:"), this);
startingLifeTotalEdit = new QSpinBox(this);
- startingLifeTotalEdit->setMinimum(1);
- startingLifeTotalEdit->setMaximum(99999);
+ startingLifeTotalEdit->setMinimum(-999999999);
+ startingLifeTotalEdit->setMaximum(999999999);
startingLifeTotalEdit->setValue(20);
startingLifeTotalLabel->setBuddy(startingLifeTotalEdit);
From 70b41c20958c3a1e87195540756635ea4cdb4891 Mon Sep 17 00:00:00 2001
From: DawnFire42
Date: Tue, 24 Mar 2026 15:31:34 -0400
Subject: [PATCH 10/60] refactor: extract AbstractPlayerComponent interface for
polymorphic player component management. (#6696)
Non-QObject polymorphic interface with setShortcutsActive(), setShortcutsInactive(), and retranslateUi(). Uses regular multiple inheritance to avoid diamond inheritance with Qt's MOC.
All zone menus, SayMenu, and AbstractCounter implement this interface. PlayerMenu manages them via a managedComponents list with two template helpers (addManagedMenu/registerManagedComponent), replacing individual if-guarded lifecycle calls with a single polymorphic loop.
SayMenu now owns its shortcut and translation lifecycle instead of having PlayerMenu manage its title and shortcuts externally.
Counters are iterated via Player::getCounters() rather than managedComponents to avoid duplicating the authoritative owner's map.
---
cockatrice/src/game/board/abstract_counter.h | 9 +-
.../player/menu/abstract_player_component.h | 32 +++++++
.../src/game/player/menu/custom_zone_menu.h | 12 ++-
cockatrice/src/game/player/menu/grave_menu.h | 9 +-
cockatrice/src/game/player/menu/hand_menu.h | 9 +-
.../src/game/player/menu/library_menu.h | 9 +-
.../src/game/player/menu/player_menu.cpp | 89 ++++---------------
cockatrice/src/game/player/menu/player_menu.h | 27 +++++-
cockatrice/src/game/player/menu/rfg_menu.h | 11 ++-
cockatrice/src/game/player/menu/say_menu.cpp | 34 ++++++-
cockatrice/src/game/player/menu/say_menu.h | 11 ++-
.../src/game/player/menu/sideboard_menu.h | 10 ++-
.../src/game/player/menu/utility_menu.h | 10 ++-
13 files changed, 164 insertions(+), 108 deletions(-)
create mode 100644 cockatrice/src/game/player/menu/abstract_player_component.h
diff --git a/cockatrice/src/game/board/abstract_counter.h b/cockatrice/src/game/board/abstract_counter.h
index ea13cb00f..074650d54 100644
--- a/cockatrice/src/game/board/abstract_counter.h
+++ b/cockatrice/src/game/board/abstract_counter.h
@@ -8,6 +8,7 @@
#define COUNTER_H
#include "../../interface/widgets/menus/tearoff_menu.h"
+#include "../player/menu/abstract_player_component.h"
#include
#include
@@ -18,7 +19,7 @@ class QKeyEvent;
class QMenu;
class QString;
-class AbstractCounter : public QObject, public QGraphicsItem
+class AbstractCounter : public QObject, public QGraphicsItem, public AbstractPlayerComponent
{
Q_OBJECT
Q_INTERFACES(QGraphicsItem)
@@ -56,10 +57,10 @@ public:
QGraphicsItem *parent = nullptr);
~AbstractCounter() override;
- void retranslateUi();
+ void retranslateUi() override;
void setValue(int _value);
- void setShortcutsActive();
- void setShortcutsInactive();
+ void setShortcutsActive() override;
+ void setShortcutsInactive() override;
void delCounter();
QMenu *getMenu() const
diff --git a/cockatrice/src/game/player/menu/abstract_player_component.h b/cockatrice/src/game/player/menu/abstract_player_component.h
new file mode 100644
index 000000000..989300d41
--- /dev/null
+++ b/cockatrice/src/game/player/menu/abstract_player_component.h
@@ -0,0 +1,32 @@
+/**
+ * @file abstract_player_component.h
+ * @ingroup GameMenusPlayers
+ * @brief Polymorphic interface for player-bound UI components managed by PlayerMenu.
+ */
+
+#ifndef COCKATRICE_ABSTRACT_PLAYER_COMPONENT_H
+#define COCKATRICE_ABSTRACT_PLAYER_COMPONENT_H
+
+/**
+ * @brief Interface for player-bound UI components that need shortcut and translation lifecycle management.
+ *
+ * Not a QObject — avoids diamond inheritance with Qt's MOC. Each concrete component
+ * inherits QObject through its Qt base class (QMenu, TearOffMenu, QGraphicsItem, etc.)
+ * and this interface through regular multiple inheritance.
+ */
+class AbstractPlayerComponent
+{
+public:
+ virtual ~AbstractPlayerComponent() = default;
+
+ /// Bind keyboard shortcuts. Called when this player gains focus.
+ virtual void setShortcutsActive() = 0;
+
+ /// Unbind keyboard shortcuts. Called when this player loses focus.
+ virtual void setShortcutsInactive() = 0;
+
+ /// Retranslate all user-visible strings. Called on language change.
+ virtual void retranslateUi() = 0;
+};
+
+#endif // COCKATRICE_ABSTRACT_PLAYER_COMPONENT_H
diff --git a/cockatrice/src/game/player/menu/custom_zone_menu.h b/cockatrice/src/game/player/menu/custom_zone_menu.h
index 0944029f4..c4e66754e 100644
--- a/cockatrice/src/game/player/menu/custom_zone_menu.h
+++ b/cockatrice/src/game/player/menu/custom_zone_menu.h
@@ -7,15 +7,23 @@
#ifndef COCKATRICE_CUSTOM_ZONE_MENU_H
#define COCKATRICE_CUSTOM_ZONE_MENU_H
+#include "abstract_player_component.h"
+
#include
class Player;
-class CustomZoneMenu : public QMenu
+class CustomZoneMenu : public QMenu, public AbstractPlayerComponent
{
Q_OBJECT
public:
explicit CustomZoneMenu(Player *player);
- void retranslateUi();
+ void retranslateUi() override;
+ void setShortcutsActive() override
+ {
+ }
+ void setShortcutsInactive() override
+ {
+ }
private:
Player *player;
diff --git a/cockatrice/src/game/player/menu/grave_menu.h b/cockatrice/src/game/player/menu/grave_menu.h
index faaf497b6..429173afa 100644
--- a/cockatrice/src/game/player/menu/grave_menu.h
+++ b/cockatrice/src/game/player/menu/grave_menu.h
@@ -8,12 +8,13 @@
#define COCKATRICE_GRAVE_MENU_H
#include "../../../interface/widgets/menus/tearoff_menu.h"
+#include "abstract_player_component.h"
#include
#include
class Player;
-class GraveyardMenu : public TearOffMenu
+class GraveyardMenu : public TearOffMenu, public AbstractPlayerComponent
{
Q_OBJECT
signals:
@@ -25,9 +26,9 @@ public:
void createViewActions();
void populateRevealRandomMenuWithActivePlayers();
void onRevealRandomTriggered();
- void retranslateUi();
- void setShortcutsActive();
- void setShortcutsInactive();
+ void retranslateUi() override;
+ void setShortcutsActive() override;
+ void setShortcutsInactive() override;
QMenu *mRevealRandomGraveyardCard = nullptr;
QMenu *moveGraveMenu = nullptr;
diff --git a/cockatrice/src/game/player/menu/hand_menu.h b/cockatrice/src/game/player/menu/hand_menu.h
index 51e071a62..76434cc98 100644
--- a/cockatrice/src/game/player/menu/hand_menu.h
+++ b/cockatrice/src/game/player/menu/hand_menu.h
@@ -8,6 +8,7 @@
#define COCKATRICE_HAND_MENU_H
#include "../../../interface/widgets/menus/tearoff_menu.h"
+#include "abstract_player_component.h"
#include
#include
@@ -15,7 +16,7 @@
class Player;
class PlayerActions;
-class HandMenu : public TearOffMenu
+class HandMenu : public TearOffMenu, public AbstractPlayerComponent
{
Q_OBJECT
@@ -31,9 +32,9 @@ public:
return mRevealRandomHandCard;
}
- void retranslateUi();
- void setShortcutsActive();
- void setShortcutsInactive();
+ void retranslateUi() override;
+ void setShortcutsActive() override;
+ void setShortcutsInactive() override;
private slots:
void populateRevealHandMenuWithActivePlayers();
diff --git a/cockatrice/src/game/player/menu/library_menu.h b/cockatrice/src/game/player/menu/library_menu.h
index c0883107c..444e8f516 100644
--- a/cockatrice/src/game/player/menu/library_menu.h
+++ b/cockatrice/src/game/player/menu/library_menu.h
@@ -8,6 +8,7 @@
#define COCKATRICE_LIBRARY_MENU_H
#include "../../../interface/widgets/menus/tearoff_menu.h"
+#include "abstract_player_component.h"
#include
#include
@@ -15,7 +16,7 @@
class Player;
class PlayerActions;
-class LibraryMenu : public TearOffMenu
+class LibraryMenu : public TearOffMenu, public AbstractPlayerComponent
{
Q_OBJECT
public slots:
@@ -28,15 +29,15 @@ public:
void createShuffleActions();
void createMoveActions();
void createViewActions();
- void retranslateUi();
+ void retranslateUi() override;
void populateRevealLibraryMenuWithActivePlayers();
void populateLendLibraryMenuWithActivePlayers();
void populateRevealTopCardMenuWithActivePlayers();
void onRevealLibraryTriggered();
void onLendLibraryTriggered();
void onRevealTopCardTriggered();
- void setShortcutsActive();
- void setShortcutsInactive();
+ void setShortcutsActive() override;
+ void setShortcutsInactive() override;
[[nodiscard]] bool isAlwaysRevealTopCardChecked() const
{
diff --git a/cockatrice/src/game/player/menu/player_menu.cpp b/cockatrice/src/game/player/menu/player_menu.cpp
index 3016a727f..7786ec3fc 100644
--- a/cockatrice/src/game/player/menu/player_menu.cpp
+++ b/cockatrice/src/game/player/menu/player_menu.cpp
@@ -15,33 +15,24 @@ PlayerMenu::PlayerMenu(Player *_player) : player(_player)
playerMenu = new TearOffMenu();
if (player->getPlayerInfo()->getLocalOrJudge()) {
- handMenu = new HandMenu(player, player->getPlayerActions(), playerMenu);
- playerMenu->addMenu(handMenu);
-
- libraryMenu = new LibraryMenu(player, playerMenu);
- playerMenu->addMenu(libraryMenu);
+ handMenu = addManagedMenu(player, player->getPlayerActions(), playerMenu);
+ libraryMenu = addManagedMenu(player, playerMenu);
} else {
handMenu = nullptr;
libraryMenu = nullptr;
}
- graveMenu = new GraveyardMenu(player, playerMenu);
- playerMenu->addMenu(graveMenu);
-
- rfgMenu = new RfgMenu(player, playerMenu);
- playerMenu->addMenu(rfgMenu);
+ graveMenu = addManagedMenu(player, playerMenu);
+ rfgMenu = addManagedMenu(player, playerMenu);
if (player->getPlayerInfo()->getLocalOrJudge()) {
- sideboardMenu = new SideboardMenu(player, playerMenu);
- playerMenu->addMenu(sideboardMenu);
-
- customZonesMenu = new CustomZoneMenu(player);
- playerMenu->addMenu(customZonesMenu);
+ sideboardMenu = addManagedMenu(player, playerMenu);
+ customZonesMenu = addManagedMenu(player);
playerMenu->addSeparator();
countersMenu = playerMenu->addMenu(QString());
- utilityMenu = new UtilityMenu(player, playerMenu);
+ utilityMenu = createManagedComponent(player, playerMenu);
} else {
sideboardMenu = nullptr;
customZonesMenu = nullptr;
@@ -50,8 +41,7 @@ PlayerMenu::PlayerMenu(Player *_player) : player(_player)
}
if (player->getPlayerInfo()->getLocal()) {
- sayMenu = new SayMenu(player);
- playerMenu->addMenu(sayMenu);
+ sayMenu = addManagedMenu(player);
} else {
sayMenu = nullptr;
}
@@ -99,40 +89,18 @@ void PlayerMenu::retranslateUi()
{
playerMenu->setTitle(tr("Player \"%1\"").arg(player->getPlayerInfo()->getName()));
- if (handMenu) {
- handMenu->retranslateUi();
- }
- if (libraryMenu) {
- libraryMenu->retranslateUi();
- }
-
- graveMenu->retranslateUi();
- rfgMenu->retranslateUi();
-
- if (sideboardMenu) {
- sideboardMenu->retranslateUi();
+ for (auto *component : managedComponents) {
+ component->retranslateUi();
}
if (countersMenu) {
countersMenu->setTitle(tr("&Counters"));
}
- if (customZonesMenu) {
- customZonesMenu->retranslateUi();
- }
-
QMapIterator counterIterator(player->getCounters());
while (counterIterator.hasNext()) {
counterIterator.next().value()->retranslateUi();
}
-
- if (utilityMenu) {
- utilityMenu->retranslateUi();
- }
-
- if (sayMenu) {
- sayMenu->setTitle(tr("S&ay"));
- }
}
void PlayerMenu::refreshShortcuts()
@@ -153,52 +121,29 @@ void PlayerMenu::setShortcutsActive()
{
shortcutsActive = true;
- if (handMenu) {
- handMenu->setShortcutsActive();
- }
- if (libraryMenu) {
- libraryMenu->setShortcutsActive();
- }
- graveMenu->setShortcutsActive();
- // No shortcuts for RfgMenu yet
-
- if (sideboardMenu) {
- sideboardMenu->setShortcutsActive();
+ for (auto *component : managedComponents) {
+ component->setShortcutsActive();
}
+ // Counters implement AbstractPlayerComponent but are iterated via Player::counters
+ // (the authoritative source) rather than managedComponents to avoid a redundant
+ // list that must stay in sync with the map.
QMapIterator counterIterator(player->getCounters());
while (counterIterator.hasNext()) {
counterIterator.next().value()->setShortcutsActive();
}
-
- if (utilityMenu) {
- utilityMenu->setShortcutsActive();
- }
}
void PlayerMenu::setShortcutsInactive()
{
shortcutsActive = false;
- if (handMenu) {
- handMenu->setShortcutsInactive();
- }
- if (libraryMenu) {
- libraryMenu->setShortcutsInactive();
- }
- graveMenu->setShortcutsInactive();
- // No shortcuts for RfgMenu yet
-
- if (sideboardMenu) {
- sideboardMenu->setShortcutsInactive();
+ for (auto *component : managedComponents) {
+ component->setShortcutsInactive();
}
QMapIterator counterIterator(player->getCounters());
while (counterIterator.hasNext()) {
counterIterator.next().value()->setShortcutsInactive();
}
-
- if (utilityMenu) {
- utilityMenu->setShortcutsInactive();
- }
}
\ No newline at end of file
diff --git a/cockatrice/src/game/player/menu/player_menu.h b/cockatrice/src/game/player/menu/player_menu.h
index 882bfedc5..5fce27158 100644
--- a/cockatrice/src/game/player/menu/player_menu.h
+++ b/cockatrice/src/game/player/menu/player_menu.h
@@ -1,7 +1,7 @@
/**
* @file player_menu.h
* @ingroup GameMenusPlayers
- * @brief TODO: Document this.
+ * @brief Orchestrates lifecycle management for all player-bound UI components.
*/
#ifndef COCKATRICE_PLAYER_MENU_H
@@ -18,6 +18,7 @@
#include "sideboard_menu.h"
#include "utility_menu.h"
+#include
#include
#include
@@ -37,6 +38,7 @@ private slots:
public:
PlayerMenu(Player *player);
+ /// Lifecycle methods: delegate to all managedComponents, plus counters separately via player->getCounters().
void retranslateUi();
QMenu *updateCardMenu(const CardItem *card);
@@ -66,7 +68,9 @@ public:
return shortcutsActive;
}
+ /// Delegates to all managedComponents, plus counters separately.
void setShortcutsActive();
+ /// Delegates to all managedComponents, plus counters separately.
void setShortcutsInactive();
private:
@@ -82,9 +86,26 @@ private:
SayMenu *sayMenu;
CustomZoneMenu *customZonesMenu;
- bool shortcutsActive;
+ /// Drives AbstractPlayerComponent lifecycle delegation. Counters are iterated separately via player->getCounters().
+ QList managedComponents;
+ bool shortcutsActive = false;
- void initSayMenu();
+ /// Creates component, adds it as a submenu of playerMenu, and registers in managedComponents.
+ template MenuT *addManagedMenu(Args &&...args)
+ {
+ auto *menu = new MenuT(std::forward(args)...);
+ playerMenu->addMenu(menu);
+ managedComponents.append(menu);
+ return menu;
+ }
+
+ /// Creates component and registers in managedComponents, but does NOT add it as a submenu.
+ template ComponentT *createManagedComponent(Args &&...args)
+ {
+ auto *component = new ComponentT(std::forward(args)...);
+ managedComponents.append(component);
+ return component;
+ }
};
#endif // COCKATRICE_PLAYER_MENU_H
diff --git a/cockatrice/src/game/player/menu/rfg_menu.h b/cockatrice/src/game/player/menu/rfg_menu.h
index 0b4623d2a..8f79b2f4a 100644
--- a/cockatrice/src/game/player/menu/rfg_menu.h
+++ b/cockatrice/src/game/player/menu/rfg_menu.h
@@ -8,19 +8,26 @@
#define COCKATRICE_RFG_MENU_H
#include "../../../interface/widgets/menus/tearoff_menu.h"
+#include "abstract_player_component.h"
#include
#include
class Player;
-class RfgMenu : public TearOffMenu
+class RfgMenu : public TearOffMenu, public AbstractPlayerComponent
{
Q_OBJECT
public:
explicit RfgMenu(Player *player, QWidget *parent = nullptr);
void createMoveActions();
void createViewActions();
- void retranslateUi();
+ void retranslateUi() override;
+ void setShortcutsActive() override
+ {
+ }
+ void setShortcutsInactive() override
+ {
+ }
QMenu *moveRfgMenu = nullptr;
diff --git a/cockatrice/src/game/player/menu/say_menu.cpp b/cockatrice/src/game/player/menu/say_menu.cpp
index 3c4802aa5..116fba49a 100644
--- a/cockatrice/src/game/player/menu/say_menu.cpp
+++ b/cockatrice/src/game/player/menu/say_menu.cpp
@@ -8,6 +8,31 @@ SayMenu::SayMenu(Player *_player) : player(_player)
{
connect(&SettingsCache::instance().messages(), &MessageSettings::messageMacrosChanged, this, &SayMenu::initSayMenu);
initSayMenu();
+ retranslateUi();
+}
+
+void SayMenu::retranslateUi()
+{
+ setTitle(tr("S&ay"));
+}
+
+void SayMenu::setShortcutsActive()
+{
+ shortcutsActive = true;
+
+ const auto menuActions = actions();
+ for (int i = 0; i < menuActions.size() && i < 10; ++i) {
+ menuActions[i]->setShortcut(QKeySequence("Ctrl+" + QString::number((i + 1) % 10)));
+ }
+}
+
+void SayMenu::setShortcutsInactive()
+{
+ shortcutsActive = false;
+
+ for (auto *action : actions()) {
+ action->setShortcut(QKeySequence());
+ }
}
void SayMenu::initSayMenu()
@@ -19,10 +44,11 @@ void SayMenu::initSayMenu()
for (int i = 0; i < count; ++i) {
auto *newAction = new QAction(SettingsCache::instance().messages().getMessageAt(i), this);
- if (i < 10) {
- newAction->setShortcut(QKeySequence("Ctrl+" + QString::number((i + 1) % 10)));
- }
connect(newAction, &QAction::triggered, player->getPlayerActions(), &PlayerActions::actSayMessage);
addAction(newAction);
}
-}
\ No newline at end of file
+
+ if (shortcutsActive) {
+ setShortcutsActive();
+ }
+}
diff --git a/cockatrice/src/game/player/menu/say_menu.h b/cockatrice/src/game/player/menu/say_menu.h
index 5dbde2277..fadf5f368 100644
--- a/cockatrice/src/game/player/menu/say_menu.h
+++ b/cockatrice/src/game/player/menu/say_menu.h
@@ -7,18 +7,27 @@
#ifndef COCKATRICE_SAY_MENU_H
#define COCKATRICE_SAY_MENU_H
+#include "abstract_player_component.h"
+
#include
class Player;
-class SayMenu : public QMenu
+class SayMenu : public QMenu, public AbstractPlayerComponent
{
Q_OBJECT
public:
explicit SayMenu(Player *player);
+
+ void retranslateUi() override;
+ void setShortcutsActive() override;
+ void setShortcutsInactive() override;
+
+private slots:
void initSayMenu();
private:
Player *player;
+ bool shortcutsActive = false;
};
#endif // COCKATRICE_SAY_MENU_H
diff --git a/cockatrice/src/game/player/menu/sideboard_menu.h b/cockatrice/src/game/player/menu/sideboard_menu.h
index 22d5a2d69..4a77d1b52 100644
--- a/cockatrice/src/game/player/menu/sideboard_menu.h
+++ b/cockatrice/src/game/player/menu/sideboard_menu.h
@@ -7,18 +7,20 @@
#ifndef COCKATRICE_SIDEBOARD_MENU_H
#define COCKATRICE_SIDEBOARD_MENU_H
+#include "abstract_player_component.h"
+
#include
class Player;
-class SideboardMenu : public QMenu
+class SideboardMenu : public QMenu, public AbstractPlayerComponent
{
Q_OBJECT
public:
explicit SideboardMenu(Player *player, QMenu *playerMenu);
- void retranslateUi();
- void setShortcutsActive();
- void setShortcutsInactive();
+ void retranslateUi() override;
+ void setShortcutsActive() override;
+ void setShortcutsInactive() override;
private:
Player *player;
diff --git a/cockatrice/src/game/player/menu/utility_menu.h b/cockatrice/src/game/player/menu/utility_menu.h
index ff57e7252..f6577d7d1 100644
--- a/cockatrice/src/game/player/menu/utility_menu.h
+++ b/cockatrice/src/game/player/menu/utility_menu.h
@@ -7,17 +7,19 @@
#ifndef COCKATRICE_UTILITY_MENU_H
#define COCKATRICE_UTILITY_MENU_H
+#include "abstract_player_component.h"
+
#include
class Player;
-class UtilityMenu : public QMenu
+class UtilityMenu : public QMenu, public AbstractPlayerComponent
{
Q_OBJECT
public slots:
void populatePredefinedTokensMenu();
- void retranslateUi();
- void setShortcutsActive();
- void setShortcutsInactive();
+ void retranslateUi() override;
+ void setShortcutsActive() override;
+ void setShortcutsInactive() override;
public:
explicit UtilityMenu(Player *player, QMenu *playerMenu);
From 94ea574c76ea214d7d74910b71795f225b28b75e Mon Sep 17 00:00:00 2001
From: DawnFire42
Date: Tue, 24 Mar 2026 16:45:52 -0400
Subject: [PATCH 11/60] Add moveToTable context menu action and extract
tableRowToGridY helper (#6738)
Adds a Table option to the Move menu, allowing cards to be moved directly to the battlefield from any zone. Extracts the repeated tableRow-to-grid-Y conversion logic into TableZone::tableRowToGridY(), consolidating five call sites and fixing a latent bug where cards with tableRow > 2 could land on the wrong row.
---
.../src/client/settings/shortcuts_settings.h | 3 ++
.../src/game/player/card_menu_action_type.h | 5 ++-
cockatrice/src/game/player/menu/move_menu.cpp | 9 +++-
cockatrice/src/game/player/menu/move_menu.h | 1 +
cockatrice/src/game/player/player_actions.cpp | 45 ++++++++++++++-----
cockatrice/src/game/zones/table_zone.cpp | 8 ++++
cockatrice/src/game/zones/table_zone.h | 7 +++
7 files changed, 64 insertions(+), 14 deletions(-)
diff --git a/cockatrice/src/client/settings/shortcuts_settings.h b/cockatrice/src/client/settings/shortcuts_settings.h
index 51615745b..d0849042b 100644
--- a/cockatrice/src/client/settings/shortcuts_settings.h
+++ b/cockatrice/src/client/settings/shortcuts_settings.h
@@ -563,6 +563,9 @@ private:
{"Player/aMoveToTopLibrary", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Top of Library"),
parseSequenceString(""),
ShortcutGroup::Move_selected)},
+ {"Player/aMoveToTable", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Battlefield"),
+ parseSequenceString(""),
+ ShortcutGroup::Move_selected)},
{"Player/aViewHand",
ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Hand"), parseSequenceString(""), ShortcutGroup::View)},
{"Player/aViewGraveyard",
diff --git a/cockatrice/src/game/player/card_menu_action_type.h b/cockatrice/src/game/player/card_menu_action_type.h
index aec6d6397..1b63674fa 100644
--- a/cockatrice/src/game/player/card_menu_action_type.h
+++ b/cockatrice/src/game/player/card_menu_action_type.h
@@ -9,17 +9,20 @@
enum CardMenuActionType
{
+ // Per-card attribute actions (must be <= cmClone for cardMenuAction() dispatch)
cmTap,
cmUntap,
cmDoesntUntap,
cmFlip,
cmPeek,
cmClone,
+ // Move actions (must be > cmClone for cardMenuAction() dispatch)
cmMoveToTopLibrary,
cmMoveToBottomLibrary,
cmMoveToHand,
cmMoveToGraveyard,
- cmMoveToExile
+ cmMoveToExile,
+ cmMoveToTable
};
#endif // COCKATRICE_CARD_MENU_ACTION_TYPE_H
diff --git a/cockatrice/src/game/player/menu/move_menu.cpp b/cockatrice/src/game/player/menu/move_menu.cpp
index d27e16009..91e2d8d10 100644
--- a/cockatrice/src/game/player/menu/move_menu.cpp
+++ b/cockatrice/src/game/player/menu/move_menu.cpp
@@ -11,6 +11,8 @@ MoveMenu::MoveMenu(Player *player) : QMenu(tr("Move to"))
aMoveToBottomLibrary = new QAction(this);
aMoveToBottomLibrary->setData(cmMoveToBottomLibrary);
aMoveToXfromTopOfLibrary = new QAction(this);
+ aMoveToTable = new QAction(this);
+ aMoveToTable->setData(cmMoveToTable);
aMoveToGraveyard = new QAction(this);
aMoveToHand = new QAction(this);
aMoveToHand->setData(cmMoveToHand);
@@ -22,6 +24,7 @@ MoveMenu::MoveMenu(Player *player) : QMenu(tr("Move to"))
connect(aMoveToBottomLibrary, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction);
connect(aMoveToXfromTopOfLibrary, &QAction::triggered, player->getPlayerActions(),
&PlayerActions::actMoveCardXCardsFromTop);
+ connect(aMoveToTable, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction);
connect(aMoveToHand, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction);
connect(aMoveToGraveyard, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction);
connect(aMoveToExile, &QAction::triggered, player->getPlayerActions(), &PlayerActions::cardMenuAction);
@@ -30,6 +33,8 @@ MoveMenu::MoveMenu(Player *player) : QMenu(tr("Move to"))
addAction(aMoveToXfromTopOfLibrary);
addAction(aMoveToBottomLibrary);
addSeparator();
+ addAction(aMoveToTable);
+ addSeparator();
addAction(aMoveToHand);
addSeparator();
addAction(aMoveToGraveyard);
@@ -47,6 +52,7 @@ void MoveMenu::setShortcutsActive()
aMoveToTopLibrary->setShortcuts(shortcuts.getShortcut("Player/aMoveToTopLibrary"));
aMoveToBottomLibrary->setShortcuts(shortcuts.getShortcut("Player/aMoveToBottomLibrary"));
+ aMoveToTable->setShortcuts(shortcuts.getShortcut("Player/aMoveToTable"));
aMoveToHand->setShortcuts(shortcuts.getShortcut("Player/aMoveToHand"));
aMoveToGraveyard->setShortcuts(shortcuts.getShortcut("Player/aMoveToGraveyard"));
aMoveToExile->setShortcuts(shortcuts.getShortcut("Player/aMoveToExile"));
@@ -57,7 +63,8 @@ void MoveMenu::retranslateUi()
aMoveToTopLibrary->setText(tr("&Top of library in random order"));
aMoveToXfromTopOfLibrary->setText(tr("X cards from the top of library..."));
aMoveToBottomLibrary->setText(tr("&Bottom of library in random order"));
+ aMoveToTable->setText(tr("T&able"));
aMoveToHand->setText(tr("&Hand"));
aMoveToGraveyard->setText(tr("&Graveyard"));
aMoveToExile->setText(tr("&Exile"));
-}
\ No newline at end of file
+}
diff --git a/cockatrice/src/game/player/menu/move_menu.h b/cockatrice/src/game/player/menu/move_menu.h
index 5bf657fa4..dc39cb6a5 100644
--- a/cockatrice/src/game/player/menu/move_menu.h
+++ b/cockatrice/src/game/player/menu/move_menu.h
@@ -23,6 +23,7 @@ public:
QAction *aMoveToBottomLibrary = nullptr;
QAction *aMoveToHand = nullptr;
+ QAction *aMoveToTable = nullptr;
QAction *aMoveToGraveyard = nullptr;
QAction *aMoveToExile = nullptr;
};
diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp
index 287231402..cee04ac6b 100644
--- a/cockatrice/src/game/player/player_actions.cpp
+++ b/cockatrice/src/game/player/player_actions.cpp
@@ -75,7 +75,7 @@ void PlayerActions::playCard(CardItem *card, bool faceDown)
cmd.set_y(0);
} else {
tableRow = faceDown ? 2 : info.getUiAttributes().tableRow;
- QPoint gridPoint = QPoint(-1, TableZone::clampValidTableRow(2 - tableRow));
+ QPoint gridPoint = QPoint(-1, TableZone::tableRowToGridY(tableRow));
cardToMove->set_face_down(faceDown);
if (!faceDown) {
cardToMove->set_pt(info.getPowTough().toStdString());
@@ -114,12 +114,7 @@ void PlayerActions::playCardToTable(const CardItem *card, bool faceDown)
const CardInfo &info = exactCard.getInfo();
int tableRow = faceDown ? 2 : info.getUiAttributes().tableRow;
- // default instant/sorcery cards to the noncreatures row
- if (tableRow > 2) {
- tableRow = 1;
- }
-
- QPoint gridPoint = QPoint(-1, TableZone::clampValidTableRow(2 - tableRow));
+ QPoint gridPoint = QPoint(-1, TableZone::tableRowToGridY(tableRow));
cardToMove->set_face_down(faceDown);
if (!faceDown) {
cardToMove->set_pt(info.getPowTough().toStdString());
@@ -866,7 +861,7 @@ void PlayerActions::actCreateToken()
ExactCard correctedCard = CardDatabaseManager::query()->guessCard({lastTokenInfo.name, lastTokenInfo.providerId});
if (correctedCard) {
lastTokenInfo.name = correctedCard.getName();
- lastTokenTableRow = TableZone::clampValidTableRow(2 - correctedCard.getInfo().getUiAttributes().tableRow);
+ lastTokenTableRow = TableZone::tableRowToGridY(correctedCard.getInfo().getUiAttributes().tableRow);
if (lastTokenInfo.pt.isEmpty()) {
lastTokenInfo.pt = correctedCard.getInfo().getPowTough();
}
@@ -917,7 +912,7 @@ void PlayerActions::setLastToken(CardInfoPtr cardInfo)
.providerId =
SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardInfo->getName())};
- lastTokenTableRow = TableZone::clampValidTableRow(2 - cardInfo->getUiAttributes().tableRow);
+ lastTokenTableRow = TableZone::tableRowToGridY(cardInfo->getUiAttributes().tableRow);
utilityMenu->setAndEnableCreateAnotherTokenAction(tr("C&reate another %1 token").arg(lastTokenInfo.name));
}
@@ -1085,9 +1080,7 @@ void PlayerActions::createCard(const CardItem *sourceCard,
return;
}
- // get the target token's location
- // TODO: Define this QPoint into its own function along with the one below
- QPoint gridPoint = QPoint(-1, TableZone::clampValidTableRow(2 - cardInfo->getUiAttributes().tableRow));
+ QPoint gridPoint = QPoint(-1, TableZone::tableRowToGridY(cardInfo->getUiAttributes().tableRow));
// create the token for the related card
Command_CreateToken cmd;
@@ -1930,6 +1923,34 @@ void PlayerActions::cardMenuAction()
commandList.append(cmd);
break;
}
+ case cmMoveToTable: {
+ // Each card needs its own command because table row, pt, and cipt vary per card
+ for (const auto &card : cardList) {
+ auto *cmd = new Command_MoveCard;
+ cmd->set_start_player_id(startPlayerId);
+ cmd->set_start_zone(startZone.toStdString());
+ cmd->set_target_player_id(player->getPlayerInfo()->getId());
+ cmd->set_target_zone(ZoneNames::TABLE);
+ cmd->set_x(-1);
+
+ CardToMove *ctm = cmd->mutable_cards_to_move()->add_card();
+ ctm->set_card_id(card->getId());
+ ctm->set_face_down(false);
+
+ int tableRow = 0;
+ ExactCard exactCard = card->getCard();
+ if (exactCard) {
+ const CardInfo &info = exactCard.getInfo();
+ tableRow = info.getUiAttributes().tableRow;
+ ctm->set_pt(info.getPowTough().toStdString());
+ ctm->set_tapped(info.getUiAttributes().cipt);
+ }
+
+ cmd->set_y(TableZone::tableRowToGridY(tableRow));
+ commandList.append(cmd);
+ }
+ break;
+ }
default:
break;
}
diff --git a/cockatrice/src/game/zones/table_zone.cpp b/cockatrice/src/game/zones/table_zone.cpp
index b6ac2150b..2a382fafe 100644
--- a/cockatrice/src/game/zones/table_zone.cpp
+++ b/cockatrice/src/game/zones/table_zone.cpp
@@ -382,3 +382,11 @@ int TableZone::clampValidTableRow(const int row)
return TABLEROWS - 1;
return row;
}
+
+int TableZone::tableRowToGridY(int tableRow)
+{
+ if (tableRow > 2) {
+ tableRow = 1;
+ }
+ return clampValidTableRow(2 - tableRow);
+}
diff --git a/cockatrice/src/game/zones/table_zone.h b/cockatrice/src/game/zones/table_zone.h
index 61eb48d7b..7a53a9eb4 100644
--- a/cockatrice/src/game/zones/table_zone.h
+++ b/cockatrice/src/game/zones/table_zone.h
@@ -151,6 +151,13 @@ public:
static int clampValidTableRow(const int row);
+ /**
+ * Converts a card's logical table row (0=creatures, 1=noncreatures, 2=lands)
+ * to the corresponding grid Y coordinate. Cards with tableRow > 2 (e.g.,
+ * instants/sorceries) default to the noncreatures row.
+ */
+ static int tableRowToGridY(int tableRow);
+
/**
Resizes the TableZone in case CardItems are within or
outside of the TableZone constraints.
From 5ef428b9d0fec65b1b264023ce2b2196945ea7c5 Mon Sep 17 00:00:00 2001
From: scotland0208
Date: Wed, 25 Mar 2026 16:15:08 -0500
Subject: [PATCH 12/60] Add visual indicator to toggle untap button (#6737)
* Add visual indicator to toggle untap button
* Rename button to match tooltip
* Change name of string in shortcut settings
---
cockatrice/src/client/settings/shortcuts_settings.h | 2 +-
cockatrice/src/game/player/menu/card_menu.cpp | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/cockatrice/src/client/settings/shortcuts_settings.h b/cockatrice/src/client/settings/shortcuts_settings.h
index d0849042b..1de73c165 100644
--- a/cockatrice/src/client/settings/shortcuts_settings.h
+++ b/cockatrice/src/client/settings/shortcuts_settings.h
@@ -501,7 +501,7 @@ private:
{"Player/aUntapAll", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Untap All"),
parseSequenceString("Ctrl+U"),
ShortcutGroup::Playing_Area)},
- {"Player/aDoesntUntap", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Toggle Untap"),
+ {"Player/aDoesntUntap", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Toggle Skip Untapping"),
parseSequenceString("Alt+U"),
ShortcutGroup::Playing_Area)},
{"Player/aFlip", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Turn Card Over"),
diff --git a/cockatrice/src/game/player/menu/card_menu.cpp b/cockatrice/src/game/player/menu/card_menu.cpp
index cd77c2968..f2479e1da 100644
--- a/cockatrice/src/game/player/menu/card_menu.cpp
+++ b/cockatrice/src/game/player/menu/card_menu.cpp
@@ -35,6 +35,8 @@ CardMenu::CardMenu(Player *_player, const CardItem *_card, bool _shortcutsActive
connect(aTap, &QAction::triggered, playerActions, &PlayerActions::cardMenuAction);
aDoesntUntap = new QAction(this);
aDoesntUntap->setData(cmDoesntUntap);
+ aDoesntUntap->setCheckable(true);
+ aDoesntUntap->setChecked(card != nullptr && card->getDoesntUntap());
connect(aDoesntUntap, &QAction::triggered, playerActions, &PlayerActions::cardMenuAction);
aAttach = new QAction(this);
connect(aAttach, &QAction::triggered, playerActions, &PlayerActions::actAttach);
@@ -449,7 +451,7 @@ void CardMenu::retranslateUi()
aRevealToAll->setText(tr("&All players"));
//: Turn sideways or back again
aTap->setText(tr("&Tap / Untap"));
- aDoesntUntap->setText(tr("Toggle &normal untapping"));
+ aDoesntUntap->setText(tr("Skip &untapping"));
//: Turn face up/face down
aFlip->setText(tr("T&urn Over")); // Only the user facing names in client got renamed to "turn over"
// All code and proto bits are still unchanged (flip) for compatibility reasons
From dd053c76dfc357896b7a49a5ab636161b32a7aa7 Mon Sep 17 00:00:00 2001
From: DawnFire42
Date: Wed, 25 Mar 2026 18:03:59 -0400
Subject: [PATCH 13/60] [Game] Improve context menus and fix face-down play
from stack (#6739)
Reorganize card context menus across table, stack, and graveyard/exile zones for better consistency: promote Draw Arrow and Clone actions, move related card entries to the bottom, add Play/Play Face Down to the stack menu, and flatten if/else blocks with early returns. Also fix playCard() ignoring the faceDown flag when routing instants/sorceries from the stack, which sent them to the graveyard instead of the table.
---
cockatrice/src/game/player/menu/card_menu.cpp | 79 ++++++++++---------
cockatrice/src/game/player/player_actions.cpp | 2 +-
2 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/cockatrice/src/game/player/menu/card_menu.cpp b/cockatrice/src/game/player/menu/card_menu.cpp
index f2479e1da..66ca5e46b 100644
--- a/cockatrice/src/game/player/menu/card_menu.cpp
+++ b/cockatrice/src/game/player/menu/card_menu.cpp
@@ -110,6 +110,7 @@ CardMenu::CardMenu(Player *_player, const CardItem *_card, bool _shortcutsActive
if (revealedCard) {
addAction(aHide);
+ addSeparator();
addAction(aClone);
addSeparator();
addAction(aSelectAll);
@@ -148,16 +149,14 @@ void CardMenu::createTableMenu(bool canModifyCard)
{
// Card is on the battlefield
if (!canModifyCard) {
- addRelatedCardView();
- addRelatedCardActions();
-
- addSeparator();
addAction(aDrawArrow);
addSeparator();
addAction(aClone);
addSeparator();
addAction(aSelectAll);
addAction(aSelectRow);
+ addRelatedCardView();
+ addRelatedCardActions();
return;
}
@@ -167,10 +166,9 @@ void CardMenu::createTableMenu(bool canModifyCard)
if (card->getFaceDown()) {
addAction(aPeek);
}
-
- addRelatedCardView();
- addRelatedCardActions();
-
+ addSeparator();
+ addAction(aClone);
+ addMenu(new MoveMenu(player));
addSeparator();
addAction(aAttach);
if (card->getAttachedTo()) {
@@ -181,9 +179,6 @@ void CardMenu::createTableMenu(bool canModifyCard)
addMenu(new PtMenu(player));
addAction(aSetAnnotation);
addSeparator();
- addAction(aClone);
- addMenu(new MoveMenu(player));
- addSeparator();
addAction(aSelectAll);
addAction(aSelectRow);
@@ -199,27 +194,34 @@ void CardMenu::createTableMenu(bool canModifyCard)
}
addSeparator();
addMenu(mCardCounters);
+ addRelatedCardView();
+ addRelatedCardActions();
}
void CardMenu::createStackMenu(bool canModifyCard)
{
// Card is on the stack
- if (canModifyCard) {
- addAction(aAttach);
- addAction(aDrawArrow);
- addSeparator();
- addAction(aClone);
- addMenu(new MoveMenu(player));
- addSeparator();
- addAction(aSelectAll);
- } else {
+ if (!canModifyCard) {
addAction(aDrawArrow);
addSeparator();
addAction(aClone);
addSeparator();
addAction(aSelectAll);
+ addRelatedCardView();
+ addRelatedCardActions();
+ return;
}
+ addAction(aPlay);
+ addAction(aPlayFacedown);
+ addSeparator();
+ addAction(aClone);
+ addMenu(new MoveMenu(player));
+ addSeparator();
+ addAction(aAttach);
+ addAction(aDrawArrow);
+ addSeparator();
+ addAction(aSelectAll);
addRelatedCardView();
addRelatedCardActions();
}
@@ -227,29 +229,29 @@ void CardMenu::createStackMenu(bool canModifyCard)
void CardMenu::createGraveyardOrExileMenu(bool canModifyCard)
{
// Card is in the graveyard or exile
- if (canModifyCard) {
- addAction(aPlay);
- addAction(aPlayFacedown);
-
- addSeparator();
- addAction(aClone);
- addMenu(new MoveMenu(player));
- addSeparator();
- addAction(aSelectAll);
- addAction(aSelectColumn);
-
- addSeparator();
- addAction(aAttach);
+ if (!canModifyCard) {
addAction(aDrawArrow);
- } else {
+ addSeparator();
addAction(aClone);
addSeparator();
addAction(aSelectAll);
addAction(aSelectColumn);
- addSeparator();
- addAction(aDrawArrow);
+ addRelatedCardView();
+ addRelatedCardActions();
+ return;
}
+ addAction(aPlay);
+ addAction(aPlayFacedown);
+ addSeparator();
+ addAction(aClone);
+ addMenu(new MoveMenu(player));
+ addSeparator();
+ addAction(aAttach);
+ addAction(aDrawArrow);
+ addSeparator();
+ addAction(aSelectAll);
+ addAction(aSelectColumn);
addRelatedCardView();
addRelatedCardActions();
}
@@ -259,12 +261,11 @@ void CardMenu::createHandOrCustomZoneMenu(bool canModifyCard)
if (!canModifyCard) {
addAction(aDrawArrow);
addSeparator();
- addRelatedCardView();
- addRelatedCardActions();
- addSeparator();
addAction(aClone);
addSeparator();
addAction(aSelectAll);
+ addRelatedCardView();
+ addRelatedCardActions();
return;
}
diff --git a/cockatrice/src/game/player/player_actions.cpp b/cockatrice/src/game/player/player_actions.cpp
index cee04ac6b..ca0967636 100644
--- a/cockatrice/src/game/player/player_actions.cpp
+++ b/cockatrice/src/game/player/player_actions.cpp
@@ -64,7 +64,7 @@ void PlayerActions::playCard(CardItem *card, bool faceDown)
int tableRow = info.getUiAttributes().tableRow;
bool playToStack = SettingsCache::instance().getPlayToStack();
QString currentZone = card->getZone()->getName();
- if (currentZone == ZoneNames::STACK && tableRow == 3) {
+ if (!faceDown && currentZone == ZoneNames::STACK && tableRow == 3) {
cmd.set_target_zone(ZoneNames::GRAVE);
cmd.set_x(0);
cmd.set_y(0);
From 74cce5ccb2fbae2c4a6a424600b6ca4b155f2402 Mon Sep 17 00:00:00 2001
From: RickyRister <42636155+RickyRister@users.noreply.github.com>
Date: Fri, 27 Mar 2026 09:12:49 -0700
Subject: [PATCH 14/60] [SettingsManager] Properly handle multithreaded access
(#6747)
---
.../client/settings/card_counter_settings.cpp | 4 +++-
.../settings/settings_manager.cpp | 24 ++++++++++++++++---
.../libcockatrice/settings/settings_manager.h | 5 +++-
3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/cockatrice/src/client/settings/card_counter_settings.cpp b/cockatrice/src/client/settings/card_counter_settings.cpp
index 71ce4cfc6..399365c99 100644
--- a/cockatrice/src/client/settings/card_counter_settings.cpp
+++ b/cockatrice/src/client/settings/card_counter_settings.cpp
@@ -11,6 +11,8 @@ CardCounterSettings::CardCounterSettings(const QString &settingsPath, QObject *p
void CardCounterSettings::setColor(int counterId, const QColor &color)
{
+ QSettings settings = getSettings();
+
QString key = QString("cards/counters/%1/color").arg(counterId);
if (settings.value(key).value() == color)
@@ -36,7 +38,7 @@ QColor CardCounterSettings::color(int counterId) const
defaultColor = QColor::fromHsv(h, s, v);
}
- return settings.value(QString("cards/counters/%1/color").arg(counterId), defaultColor).value();
+ return getSettings().value(QString("cards/counters/%1/color").arg(counterId), defaultColor).value();
}
QString CardCounterSettings::displayName(int counterId) const
diff --git a/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp b/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp
index ede5a2027..3f3deb638 100644
--- a/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp
@@ -1,16 +1,22 @@
#include "settings_manager.h"
-SettingsManager::SettingsManager(const QString &settingPath,
+SettingsManager::SettingsManager(const QString &_settingPath,
const QString &_defaultGroup,
const QString &_defaultSubGroup,
QObject *parent)
- : QObject(parent), settings(settingPath, QSettings::IniFormat), defaultGroup(_defaultGroup),
- defaultSubGroup(_defaultSubGroup)
+ : QObject(parent), settingPath(_settingPath), defaultGroup(_defaultGroup), defaultSubGroup(_defaultSubGroup)
{
}
+QSettings SettingsManager::getSettings() const
+{
+ return QSettings(settingPath, QSettings::IniFormat);
+}
+
void SettingsManager::setValue(const QVariant &value, const QString &name)
{
+ auto settings = getSettings();
+
if (!defaultGroup.isEmpty()) {
settings.beginGroup(defaultGroup);
}
@@ -35,6 +41,8 @@ void SettingsManager::setValue(const QVariant &value,
const QString &group,
const QString &subGroup)
{
+ auto settings = getSettings();
+
if (!group.isEmpty()) {
settings.beginGroup(group);
}
@@ -56,6 +64,8 @@ void SettingsManager::setValue(const QVariant &value,
void SettingsManager::deleteValue(const QString &name)
{
+ auto settings = getSettings();
+
if (!defaultGroup.isEmpty()) {
settings.beginGroup(defaultGroup);
}
@@ -77,6 +87,8 @@ void SettingsManager::deleteValue(const QString &name)
void SettingsManager::deleteValue(const QString &name, const QString &group, const QString &subGroup)
{
+ auto settings = getSettings();
+
if (!group.isEmpty()) {
settings.beginGroup(group);
}
@@ -98,6 +110,8 @@ void SettingsManager::deleteValue(const QString &name, const QString &group, con
QVariant SettingsManager::getValue(const QString &name)
{
+ auto settings = getSettings();
+
if (!defaultGroup.isEmpty()) {
settings.beginGroup(defaultGroup);
}
@@ -121,6 +135,8 @@ QVariant SettingsManager::getValue(const QString &name)
QVariant SettingsManager::getValue(const QString &name, const QString &group, const QString &subGroup)
{
+ auto settings = getSettings();
+
if (!group.isEmpty()) {
settings.beginGroup(group);
}
@@ -147,5 +163,7 @@ QVariant SettingsManager::getValue(const QString &name, const QString &group, co
*/
void SettingsManager::sync()
{
+ auto settings = getSettings();
+
settings.sync();
}
\ No newline at end of file
diff --git a/libcockatrice_settings/libcockatrice/settings/settings_manager.h b/libcockatrice_settings/libcockatrice/settings/settings_manager.h
index 3592d8f8c..18abb8dbf 100644
--- a/libcockatrice_settings/libcockatrice/settings/settings_manager.h
+++ b/libcockatrice_settings/libcockatrice/settings/settings_manager.h
@@ -24,9 +24,12 @@ public:
void sync();
protected:
- QSettings settings;
+ QString settingPath;
QString defaultGroup;
QString defaultSubGroup;
+
+ QSettings getSettings() const;
+
void setValue(const QVariant &value, const QString &name);
void
setValue(const QVariant &value, const QString &name, const QString &group, const QString &subGroup = QString());
From abf6e72ad1b341feda04676554a751cdec97169c Mon Sep 17 00:00:00 2001
From: ebbit1q
Date: Fri, 27 Mar 2026 18:08:51 +0100
Subject: [PATCH 15/60] add a nulcheck in the card item animation timer (#6740)
---
cockatrice/src/game/board/card_item.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/cockatrice/src/game/board/card_item.cpp b/cockatrice/src/game/board/card_item.cpp
index 62de4a02e..cf3c7db20 100644
--- a/cockatrice/src/game/board/card_item.cpp
+++ b/cockatrice/src/game/board/card_item.cpp
@@ -460,6 +460,9 @@ void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
bool CardItem::animationEvent()
{
+ if (owner == nullptr) {
+ return false;
+ }
int rotation = ROTATION_DEGREES_PER_FRAME;
bool animationIncomplete = true;
if (!tapped)
From 42bd8164a0b9170a3ecfe68b43ca399e1e08e4a7 Mon Sep 17 00:00:00 2001
From: ebbit1q
Date: Fri, 27 Mar 2026 18:10:29 +0100
Subject: [PATCH 16/60] remove hardcoded white in vde banner widget (#6684)
* remove hardcoded white in vde banner widget
* set text color to white on higher opacities
---
.../widgets/general/display/banner_widget.cpp | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/cockatrice/src/interface/widgets/general/display/banner_widget.cpp b/cockatrice/src/interface/widgets/general/display/banner_widget.cpp
index f03869a4d..5de5457ea 100644
--- a/cockatrice/src/interface/widgets/general/display/banner_widget.cpp
+++ b/cockatrice/src/interface/widgets/general/display/banner_widget.cpp
@@ -7,8 +7,8 @@
#include
#include
-BannerWidget::BannerWidget(QWidget *parent, const QString &text, Qt::Orientation orientation, int transparency)
- : QWidget(parent), gradientOrientation(orientation), transparency(qBound(0, transparency, 100))
+BannerWidget::BannerWidget(QWidget *parent, const QString &text, Qt::Orientation orientation, int transparency_)
+ : QWidget(parent), gradientOrientation(orientation), transparency(qBound(0, transparency_, 100))
{
auto layout = new QHBoxLayout(this);
@@ -18,7 +18,12 @@ BannerWidget::BannerWidget(QWidget *parent, const QString &text, Qt::Orientation
// Create the banner label and set properties
bannerLabel = new QLabel(text, this);
bannerLabel->setAlignment(Qt::AlignCenter);
- bannerLabel->setStyleSheet("font-size: 24px; font-weight: bold; color: white;");
+
+ QString textColor;
+ if (transparency > 50) {
+ textColor = " color: white;";
+ }
+ bannerLabel->setStyleSheet("font-size: 24px; font-weight: bold;" + textColor);
layout->addWidget(iconLabel);
layout->addWidget(bannerLabel);
From d8e3807ec50be2b384b2c07a552f9efd315b2bb1 Mon Sep 17 00:00:00 2001
From: tooomm
Date: Fri, 27 Mar 2026 18:11:56 +0100
Subject: [PATCH 17/60] Dependabot: Enable git submodules tracking (#6727)
* Enable gitsubmodules
* update comment
---
.github/dependabot.yml | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 1e278a418..fc25af67f 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -2,19 +2,18 @@
version: 2
updates:
- # # Enable version updates for git submodules
- # Not yet possible to bump only on tags or releases, see:
+ # Enable version updates for git submodules
+ # If SemVer is used, updates will happen to new releases only (not HEAD)
# https://github.com/dependabot/dependabot-core/issues/1639
# https://github.com/dependabot/dependabot-core/issues/2192
- # Alternative: Action that updates submodule and can be manually run on demand (workflow_dispatch)
- # - package-ecosystem: "gitsubmodule"
- # # Look for `.gitmodules` in the `root` directory
- # directory: "/"
- # # Check for updates once a month
- # schedule:
- # interval: "monthly"
- # # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
- # open-pull-requests-limit: 1
+ - package-ecosystem: "gitsubmodule"
+ # Look for `.gitmodules` in the `root` directory
+ directory: "/"
+ # Check for updates once a month
+ schedule:
+ interval: "monthly"
+ # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
+ open-pull-requests-limit: 2
# # Enable version updates for Docker
# Not yet possible to bump from one LTS version to the next and skip others, see:
From 34a5b8b9ce95fce726301819638f52d1781b8088 Mon Sep 17 00:00:00 2001
From: RickyRister <42636155+RickyRister@users.noreply.github.com>
Date: Fri, 27 Mar 2026 10:13:25 -0700
Subject: [PATCH 18/60] [SettingsManager] Make setting getters const (#6748)
* [SettingsManager] Make setting getters const
* remove hashGameType from header
---
.../interface_card_set_priority_controller.h | 6 +--
.../noop_card_set_priority_controller.h | 6 +--
.../settings/card_database_settings.cpp | 6 +--
.../settings/card_database_settings.h | 6 +--
.../settings/card_override_settings.cpp | 2 +-
.../settings/card_override_settings.h | 2 +-
.../libcockatrice/settings/debug_settings.cpp | 8 ++--
.../libcockatrice/settings/debug_settings.h | 8 ++--
.../settings/download_settings.cpp | 2 +-
.../settings/download_settings.h | 2 +-
.../settings/game_filters_settings.cpp | 38 +++++++++----------
.../settings/game_filters_settings.h | 36 +++++++++---------
.../settings/layouts_settings.cpp | 26 ++++++-------
.../libcockatrice/settings/layouts_settings.h | 26 ++++++-------
.../settings/message_settings.cpp | 4 +-
.../libcockatrice/settings/message_settings.h | 4 +-
.../settings/recents_settings.cpp | 4 +-
.../libcockatrice/settings/recents_settings.h | 4 +-
.../settings/servers_settings.cpp | 26 ++++++-------
.../libcockatrice/settings/servers_settings.h | 26 ++++++-------
.../settings/settings_manager.cpp | 4 +-
.../libcockatrice/settings/settings_manager.h | 4 +-
22 files changed, 124 insertions(+), 126 deletions(-)
diff --git a/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h b/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h
index 46a5897f7..b8fbbc74a 100644
--- a/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h
+++ b/libcockatrice_interfaces/libcockatrice/interfaces/interface_card_set_priority_controller.h
@@ -12,9 +12,9 @@ public:
virtual void setEnabled(QString shortName, bool enabled) = 0;
virtual void setIsKnown(QString shortName, bool isknown) = 0;
- virtual unsigned int getSortKey(QString shortName) = 0;
- virtual bool isEnabled(QString shortName) = 0;
- virtual bool isKnown(QString shortName) = 0;
+ virtual unsigned int getSortKey(QString shortName) const = 0;
+ virtual bool isEnabled(QString shortName) const = 0;
+ virtual bool isKnown(QString shortName) const = 0;
};
#endif // COCKATRICE_INTERFACE_CARD_SET_PRIORITY_CONTROLLER_H
diff --git a/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h b/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h
index 949ab5a91..e5027648c 100644
--- a/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h
+++ b/libcockatrice_interfaces/libcockatrice/interfaces/noop_card_set_priority_controller.h
@@ -16,15 +16,15 @@ public:
{
}
- unsigned int getSortKey(QString /* shortName */) override
+ unsigned int getSortKey(QString /* shortName */) const override
{
return 0;
}
- bool isEnabled(QString /* shortName */) override
+ bool isEnabled(QString /* shortName */) const override
{
return true;
}
- bool isKnown(QString /* shortName */) override
+ bool isKnown(QString /* shortName */) const override
{
return true;
}
diff --git a/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp b/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp
index 79738f1cd..26a91a4dd 100644
--- a/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/card_database_settings.cpp
@@ -20,17 +20,17 @@ void CardDatabaseSettings::setIsKnown(QString shortName, bool isknown)
setValue(isknown, "isknown", "sets", std::move(shortName));
}
-unsigned int CardDatabaseSettings::getSortKey(QString shortName)
+unsigned int CardDatabaseSettings::getSortKey(QString shortName) const
{
return getValue("sortkey", "sets", std::move(shortName)).toUInt();
}
-bool CardDatabaseSettings::isEnabled(QString shortName)
+bool CardDatabaseSettings::isEnabled(QString shortName) const
{
return getValue("enabled", "sets", std::move(shortName)).toBool();
}
-bool CardDatabaseSettings::isKnown(QString shortName)
+bool CardDatabaseSettings::isKnown(QString shortName) const
{
return getValue("isknown", "sets", std::move(shortName)).toBool();
}
diff --git a/libcockatrice_settings/libcockatrice/settings/card_database_settings.h b/libcockatrice_settings/libcockatrice/settings/card_database_settings.h
index 9a176a99b..bb946ea80 100644
--- a/libcockatrice_settings/libcockatrice/settings/card_database_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/card_database_settings.h
@@ -22,9 +22,9 @@ public:
void setEnabled(QString shortName, bool enabled) override;
void setIsKnown(QString shortName, bool isknown) override;
- unsigned int getSortKey(QString shortName) override;
- bool isEnabled(QString shortName) override;
- bool isKnown(QString shortName) override;
+ unsigned int getSortKey(QString shortName) const override;
+ bool isEnabled(QString shortName) const override;
+ bool isKnown(QString shortName) const override;
private:
explicit CardDatabaseSettings(const QString &settingPath, QObject *parent = nullptr);
diff --git a/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp b/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp
index 894358be6..a61a4693b 100644
--- a/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/card_override_settings.cpp
@@ -15,7 +15,7 @@ void CardOverrideSettings::deleteCardPreferenceOverride(const QString &cardName)
deleteValue(cardName);
}
-QString CardOverrideSettings::getCardPreferenceOverride(const QString &cardName)
+QString CardOverrideSettings::getCardPreferenceOverride(const QString &cardName) const
{
return getValue(cardName).toString();
}
\ No newline at end of file
diff --git a/libcockatrice_settings/libcockatrice/settings/card_override_settings.h b/libcockatrice_settings/libcockatrice/settings/card_override_settings.h
index d5ee0287b..3d9db4e65 100644
--- a/libcockatrice_settings/libcockatrice/settings/card_override_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/card_override_settings.h
@@ -22,7 +22,7 @@ public:
void deleteCardPreferenceOverride(const QString &cardName);
- QString getCardPreferenceOverride(const QString &cardName);
+ QString getCardPreferenceOverride(const QString &cardName) const;
private:
explicit CardOverrideSettings(const QString &settingPath, QObject *parent = nullptr);
diff --git a/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp b/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp
index 084696dc1..5bf6eca30 100644
--- a/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/debug_settings.cpp
@@ -11,22 +11,22 @@ DebugSettings::DebugSettings(const QString &settingPath, QObject *parent)
}
}
-bool DebugSettings::getShowCardId()
+bool DebugSettings::getShowCardId() const
{
return getValue("showCardId").toBool();
}
-bool DebugSettings::getLocalGameOnStartup()
+bool DebugSettings::getLocalGameOnStartup() const
{
return getValue("onStartup", "localgame").toBool();
}
-int DebugSettings::getLocalGamePlayerCount()
+int DebugSettings::getLocalGamePlayerCount() const
{
return getValue("playerCount", "localgame").toInt();
}
-QString DebugSettings::getDeckPathForPlayer(const QString &playerName)
+QString DebugSettings::getDeckPathForPlayer(const QString &playerName) const
{
return getValue(playerName, "localgame", "deck").toString();
}
\ No newline at end of file
diff --git a/libcockatrice_settings/libcockatrice/settings/debug_settings.h b/libcockatrice_settings/libcockatrice/settings/debug_settings.h
index 2087b16b3..30cdd5fa5 100644
--- a/libcockatrice_settings/libcockatrice/settings/debug_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/debug_settings.h
@@ -17,12 +17,12 @@ class DebugSettings : public SettingsManager
DebugSettings(const DebugSettings & /*other*/);
public:
- bool getShowCardId();
+ bool getShowCardId() const;
- bool getLocalGameOnStartup();
- int getLocalGamePlayerCount();
+ bool getLocalGameOnStartup() const;
+ int getLocalGamePlayerCount() const;
- QString getDeckPathForPlayer(const QString &playerName);
+ QString getDeckPathForPlayer(const QString &playerName) const;
};
#endif // DEBUG_SETTINGS_H
diff --git a/libcockatrice_settings/libcockatrice/settings/download_settings.cpp b/libcockatrice_settings/libcockatrice/settings/download_settings.cpp
index ad4b81ec5..66525a598 100644
--- a/libcockatrice_settings/libcockatrice/settings/download_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/download_settings.cpp
@@ -18,7 +18,7 @@ void DownloadSettings::setDownloadUrls(const QStringList &downloadURLs)
setValue(QVariant::fromValue(downloadURLs), "urls");
}
-QStringList DownloadSettings::getAllURLs()
+QStringList DownloadSettings::getAllURLs() const
{
return getValue("urls").toStringList();
}
diff --git a/libcockatrice_settings/libcockatrice/settings/download_settings.h b/libcockatrice_settings/libcockatrice/settings/download_settings.h
index ed3634ea1..b7442301e 100644
--- a/libcockatrice_settings/libcockatrice/settings/download_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/download_settings.h
@@ -19,7 +19,7 @@ class DownloadSettings : public SettingsManager
public:
explicit DownloadSettings(const QString &, QObject *);
- QStringList getAllURLs();
+ QStringList getAllURLs() const;
void setDownloadUrls(const QStringList &downloadURLs);
void resetToDefaultURLs();
};
diff --git a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp
index e5db3010d..4f5bf52ee 100644
--- a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.cpp
@@ -8,11 +8,11 @@ GameFiltersSettings::GameFiltersSettings(const QString &settingPath, QObject *pa
{
}
-/*
+/**
* The game type might contain special characters, so to use it in
* QSettings we just hash it.
*/
-QString GameFiltersSettings::hashGameType(const QString &gameType) const
+static QString hashGameType(const QString &gameType)
{
return QCryptographicHash::hash(gameType.toUtf8(), QCryptographicHash::Md5).toHex();
}
@@ -22,7 +22,7 @@ void GameFiltersSettings::setHideBuddiesOnlyGames(bool hide)
setValue(hide, "hide_buddies_only_games");
}
-bool GameFiltersSettings::isHideBuddiesOnlyGames()
+bool GameFiltersSettings::isHideBuddiesOnlyGames() const
{
QVariant previous = getValue("hide_buddies_only_games");
return previous == QVariant() ? false : previous.toBool();
@@ -33,7 +33,7 @@ void GameFiltersSettings::setHideFullGames(bool hide)
setValue(hide, "hide_full_games");
}
-bool GameFiltersSettings::isHideFullGames()
+bool GameFiltersSettings::isHideFullGames() const
{
QVariant previous = getValue("hide_full_games");
return previous == QVariant() ? false : previous.toBool();
@@ -44,7 +44,7 @@ void GameFiltersSettings::setHideGamesThatStarted(bool hide)
setValue(hide, "hide_games_that_started");
}
-bool GameFiltersSettings::isHideGamesThatStarted()
+bool GameFiltersSettings::isHideGamesThatStarted() const
{
QVariant previous = getValue("hide_games_that_started");
return previous == QVariant() ? false : previous.toBool();
@@ -55,7 +55,7 @@ void GameFiltersSettings::setHidePasswordProtectedGames(bool hide)
setValue(hide, "hide_password_protected_games");
}
-bool GameFiltersSettings::isHidePasswordProtectedGames()
+bool GameFiltersSettings::isHidePasswordProtectedGames() const
{
QVariant previous = getValue("hide_password_protected_games");
return previous == QVariant() ? false : previous.toBool();
@@ -66,7 +66,7 @@ void GameFiltersSettings::setHideIgnoredUserGames(bool hide)
setValue(hide, "hide_ignored_user_games");
}
-bool GameFiltersSettings::isHideIgnoredUserGames()
+bool GameFiltersSettings::isHideIgnoredUserGames() const
{
QVariant previous = getValue("hide_ignored_user_games");
return previous == QVariant() ? true : previous.toBool();
@@ -77,7 +77,7 @@ void GameFiltersSettings::setHideNotBuddyCreatedGames(bool hide)
setValue(hide, "hide_not_buddy_created_games");
}
-bool GameFiltersSettings::isHideNotBuddyCreatedGames()
+bool GameFiltersSettings::isHideNotBuddyCreatedGames() const
{
QVariant previous = getValue("hide_not_buddy_created_games");
return previous == QVariant() ? false : previous.toBool();
@@ -88,7 +88,7 @@ void GameFiltersSettings::setHideOpenDecklistGames(bool hide)
setValue(hide, "hide_open_decklist_games");
}
-bool GameFiltersSettings::isHideOpenDecklistGames()
+bool GameFiltersSettings::isHideOpenDecklistGames() const
{
QVariant previous = getValue("hide_open_decklist_games");
return previous == QVariant() ? false : previous.toBool();
@@ -99,7 +99,7 @@ void GameFiltersSettings::setGameNameFilter(QString gameName)
setValue(gameName, "game_name_filter");
}
-QString GameFiltersSettings::getGameNameFilter()
+QString GameFiltersSettings::getGameNameFilter() const
{
return getValue("game_name_filter").toString();
}
@@ -109,7 +109,7 @@ void GameFiltersSettings::setCreatorNameFilters(QStringList creatorName)
setValue(creatorName, "creator_name_filter");
}
-QStringList GameFiltersSettings::getCreatorNameFilters()
+QStringList GameFiltersSettings::getCreatorNameFilters() const
{
return getValue("creator_name_filter").toStringList();
}
@@ -119,7 +119,7 @@ void GameFiltersSettings::setMinPlayers(int min)
setValue(min, "min_players");
}
-int GameFiltersSettings::getMinPlayers()
+int GameFiltersSettings::getMinPlayers() const
{
QVariant previous = getValue("min_players");
return previous == QVariant() ? 1 : previous.toInt();
@@ -130,7 +130,7 @@ void GameFiltersSettings::setMaxPlayers(int max)
setValue(max, "max_players");
}
-int GameFiltersSettings::getMaxPlayers()
+int GameFiltersSettings::getMaxPlayers() const
{
QVariant previous = getValue("max_players");
return previous == QVariant() ? 99 : previous.toInt();
@@ -141,7 +141,7 @@ void GameFiltersSettings::setMaxGameAge(const QTime &maxGameAge)
setValue(maxGameAge, "max_game_age_time");
}
-QTime GameFiltersSettings::getMaxGameAge()
+QTime GameFiltersSettings::getMaxGameAge() const
{
QVariant previous = getValue("max_game_age_time");
return previous.toTime();
@@ -157,7 +157,7 @@ void GameFiltersSettings::setGameHashedTypeEnabled(QString gametypeHASHED, bool
setValue(enabled, gametypeHASHED);
}
-bool GameFiltersSettings::isGameTypeEnabled(QString gametype)
+bool GameFiltersSettings::isGameTypeEnabled(QString gametype) const
{
QVariant previous = getValue("game_type/" + hashGameType(gametype));
return previous == QVariant() ? false : previous.toBool();
@@ -168,7 +168,7 @@ void GameFiltersSettings::setShowOnlyIfSpectatorsCanWatch(bool show)
setValue(show, "show_only_if_spectators_can_watch");
}
-bool GameFiltersSettings::isShowOnlyIfSpectatorsCanWatch()
+bool GameFiltersSettings::isShowOnlyIfSpectatorsCanWatch() const
{
QVariant previous = getValue("show_only_if_spectators_can_watch");
return previous == QVariant() ? false : previous.toBool();
@@ -179,7 +179,7 @@ void GameFiltersSettings::setShowSpectatorPasswordProtected(bool show)
setValue(show, "show_spectator_password_protected");
}
-bool GameFiltersSettings::isShowSpectatorPasswordProtected()
+bool GameFiltersSettings::isShowSpectatorPasswordProtected() const
{
QVariant previous = getValue("show_spectator_password_protected");
return previous == QVariant() ? false : previous.toBool();
@@ -190,7 +190,7 @@ void GameFiltersSettings::setShowOnlyIfSpectatorsCanChat(bool show)
setValue(show, "show_only_if_spectators_can_chat");
}
-bool GameFiltersSettings::isShowOnlyIfSpectatorsCanChat()
+bool GameFiltersSettings::isShowOnlyIfSpectatorsCanChat() const
{
QVariant previous = getValue("show_only_if_spectators_can_chat");
return previous == QVariant() ? false : previous.toBool();
@@ -201,7 +201,7 @@ void GameFiltersSettings::setShowOnlyIfSpectatorsCanSeeHands(bool show)
setValue(show, "show_only_if_spectators_can_see_hands");
}
-bool GameFiltersSettings::isShowOnlyIfSpectatorsCanSeeHands()
+bool GameFiltersSettings::isShowOnlyIfSpectatorsCanSeeHands() const
{
QVariant previous = getValue("show_only_if_spectators_can_see_hands");
return previous == QVariant() ? false : previous.toBool();
diff --git a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h
index 45e9b7441..c0e60551a 100644
--- a/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/game_filters_settings.h
@@ -16,23 +16,23 @@ class GameFiltersSettings : public SettingsManager
friend class SettingsCache;
public:
- bool isHideBuddiesOnlyGames();
- bool isHideFullGames();
- bool isHideGamesThatStarted();
- bool isHidePasswordProtectedGames();
- bool isHideIgnoredUserGames();
- bool isHideNotBuddyCreatedGames();
- bool isHideOpenDecklistGames();
- QString getGameNameFilter();
- QStringList getCreatorNameFilters();
- int getMinPlayers();
- int getMaxPlayers();
- QTime getMaxGameAge();
- bool isGameTypeEnabled(QString gametype);
- bool isShowOnlyIfSpectatorsCanWatch();
- bool isShowSpectatorPasswordProtected();
- bool isShowOnlyIfSpectatorsCanChat();
- bool isShowOnlyIfSpectatorsCanSeeHands();
+ bool isHideBuddiesOnlyGames() const;
+ bool isHideFullGames() const;
+ bool isHideGamesThatStarted() const;
+ bool isHidePasswordProtectedGames() const;
+ bool isHideIgnoredUserGames() const;
+ bool isHideNotBuddyCreatedGames() const;
+ bool isHideOpenDecklistGames() const;
+ QString getGameNameFilter() const;
+ QStringList getCreatorNameFilters() const;
+ int getMinPlayers() const;
+ int getMaxPlayers() const;
+ QTime getMaxGameAge() const;
+ bool isGameTypeEnabled(QString gametype) const;
+ bool isShowOnlyIfSpectatorsCanWatch() const;
+ bool isShowSpectatorPasswordProtected() const;
+ bool isShowOnlyIfSpectatorsCanChat() const;
+ bool isShowOnlyIfSpectatorsCanSeeHands() const;
void setHideBuddiesOnlyGames(bool hide);
void setHideIgnoredUserGames(bool hide);
@@ -56,8 +56,6 @@ public:
private:
explicit GameFiltersSettings(const QString &settingPath, QObject *parent = nullptr);
GameFiltersSettings(const GameFiltersSettings & /*other*/);
-
- [[nodiscard]] QString hashGameType(const QString &gameType) const;
};
#endif // GAMEFILTERSSETTINGS_H
diff --git a/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp b/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp
index f7704cbc7..e914dc2d8 100644
--- a/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/layouts_settings.cpp
@@ -23,12 +23,12 @@ void LayoutsSettings::setMainWindowGeometry(const QByteArray &value)
setValue(value, GEOMETRY_PROP, GROUP_MAIN_WINDOW);
}
-QByteArray LayoutsSettings::getMainWindowGeometry()
+QByteArray LayoutsSettings::getMainWindowGeometry() const
{
return getValue(GEOMETRY_PROP, GROUP_MAIN_WINDOW).toByteArray();
}
-QByteArray LayoutsSettings::getDeckEditorLayoutState()
+QByteArray LayoutsSettings::getDeckEditorLayoutState() const
{
return getValue(STATE_PROP, GROUP_DECK_EDITOR).toByteArray();
}
@@ -38,7 +38,7 @@ void LayoutsSettings::setDeckEditorLayoutState(const QByteArray &value)
setValue(value, STATE_PROP, GROUP_DECK_EDITOR);
}
-QByteArray LayoutsSettings::getDeckEditorGeometry()
+QByteArray LayoutsSettings::getDeckEditorGeometry() const
{
return getValue(GEOMETRY_PROP, GROUP_DECK_EDITOR).toByteArray();
}
@@ -48,7 +48,7 @@ void LayoutsSettings::setDeckEditorGeometry(const QByteArray &value)
setValue(value, GEOMETRY_PROP, GROUP_DECK_EDITOR);
}
-QByteArray LayoutsSettings::getVisualDeckEditorLayoutState()
+QByteArray LayoutsSettings::getVisualDeckEditorLayoutState() const
{
return getValue(STATE_PROP, GROUP_VISUAL_DECK_EDITOR).toByteArray();
}
@@ -58,7 +58,7 @@ void LayoutsSettings::setVisualDeckEditorLayoutState(const QByteArray &value)
setValue(value, STATE_PROP, GROUP_VISUAL_DECK_EDITOR);
}
-QByteArray LayoutsSettings::getVisualDeckEditorGeometry()
+QByteArray LayoutsSettings::getVisualDeckEditorGeometry() const
{
return getValue(GEOMETRY_PROP, GROUP_VISUAL_DECK_EDITOR).toByteArray();
}
@@ -68,7 +68,7 @@ void LayoutsSettings::setVisualDeckEditorGeometry(const QByteArray &value)
setValue(value, GEOMETRY_PROP, GROUP_VISUAL_DECK_EDITOR);
}
-QByteArray LayoutsSettings::getDeckEditorDbHeaderState()
+QByteArray LayoutsSettings::getDeckEditorDbHeaderState() const
{
return getValue(STATE_PROP, GROUP_DECK_EDITOR_DB, "header").toByteArray();
}
@@ -78,7 +78,7 @@ void LayoutsSettings::setDeckEditorDbHeaderState(const QByteArray &value)
setValue(value, STATE_PROP, GROUP_DECK_EDITOR_DB, "header");
}
-QByteArray LayoutsSettings::getSetsDialogHeaderState()
+QByteArray LayoutsSettings::getSetsDialogHeaderState() const
{
return getValue(STATE_PROP, GROUP_SETS_DIALOG, "header").toByteArray();
}
@@ -93,7 +93,7 @@ void LayoutsSettings::setSetsDialogGeometry(const QByteArray &value)
setValue(value, GEOMETRY_PROP, GROUP_SETS_DIALOG);
}
-QByteArray LayoutsSettings::getSetsDialogGeometry()
+QByteArray LayoutsSettings::getSetsDialogGeometry() const
{
return getValue(GEOMETRY_PROP, GROUP_SETS_DIALOG).toByteArray();
}
@@ -103,7 +103,7 @@ void LayoutsSettings::setTokenDialogGeometry(const QByteArray &value)
setValue(value, GEOMETRY_PROP, GROUP_TOKEN_DIALOG);
}
-QByteArray LayoutsSettings::getTokenDialogGeometry()
+QByteArray LayoutsSettings::getTokenDialogGeometry() const
{
return getValue(GEOMETRY_PROP, GROUP_TOKEN_DIALOG).toByteArray();
}
@@ -118,12 +118,12 @@ void LayoutsSettings::setGamePlayAreaState(const QByteArray &value)
setValue(value, STATE_PROP, GROUP_GAME_PLAY_AREA);
}
-QByteArray LayoutsSettings::getGamePlayAreaLayoutState()
+QByteArray LayoutsSettings::getGamePlayAreaLayoutState() const
{
return getValue(STATE_PROP, GROUP_GAME_PLAY_AREA).toByteArray();
}
-QByteArray LayoutsSettings::getGamePlayAreaGeometry()
+QByteArray LayoutsSettings::getGamePlayAreaGeometry() const
{
return getValue(GEOMETRY_PROP, GROUP_GAME_PLAY_AREA).toByteArray();
}
@@ -138,12 +138,12 @@ void LayoutsSettings::setReplayPlayAreaState(const QByteArray &value)
setValue(value, STATE_PROP, GROUP_REPLAY_PLAY_AREA);
}
-QByteArray LayoutsSettings::getReplayPlayAreaLayoutState()
+QByteArray LayoutsSettings::getReplayPlayAreaLayoutState() const
{
return getValue(STATE_PROP, GROUP_REPLAY_PLAY_AREA).toByteArray();
}
-QByteArray LayoutsSettings::getReplayPlayAreaGeometry()
+QByteArray LayoutsSettings::getReplayPlayAreaGeometry() const
{
return getValue(GEOMETRY_PROP, GROUP_REPLAY_PLAY_AREA).toByteArray();
}
diff --git a/libcockatrice_settings/libcockatrice/settings/layouts_settings.h b/libcockatrice_settings/libcockatrice/settings/layouts_settings.h
index cab9a456e..5353ce15a 100644
--- a/libcockatrice_settings/libcockatrice/settings/layouts_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/layouts_settings.h
@@ -36,24 +36,24 @@ public:
void setReplayPlayAreaGeometry(const QByteArray &value);
void setReplayPlayAreaState(const QByteArray &value);
- QByteArray getMainWindowGeometry();
+ QByteArray getMainWindowGeometry() const;
- QByteArray getDeckEditorLayoutState();
- QByteArray getDeckEditorGeometry();
+ QByteArray getDeckEditorLayoutState() const;
+ QByteArray getDeckEditorGeometry() const;
- QByteArray getVisualDeckEditorLayoutState();
- QByteArray getVisualDeckEditorGeometry();
+ QByteArray getVisualDeckEditorLayoutState() const;
+ QByteArray getVisualDeckEditorGeometry() const;
- QByteArray getDeckEditorDbHeaderState();
- QByteArray getSetsDialogHeaderState();
- QByteArray getSetsDialogGeometry();
- QByteArray getTokenDialogGeometry();
+ QByteArray getDeckEditorDbHeaderState() const;
+ QByteArray getSetsDialogHeaderState() const;
+ QByteArray getSetsDialogGeometry() const;
+ QByteArray getTokenDialogGeometry() const;
- QByteArray getGamePlayAreaLayoutState();
- QByteArray getGamePlayAreaGeometry();
+ QByteArray getGamePlayAreaLayoutState() const;
+ QByteArray getGamePlayAreaGeometry() const;
- QByteArray getReplayPlayAreaLayoutState();
- QByteArray getReplayPlayAreaGeometry();
+ QByteArray getReplayPlayAreaLayoutState() const;
+ QByteArray getReplayPlayAreaGeometry() const;
signals:
public slots:
diff --git a/libcockatrice_settings/libcockatrice/settings/message_settings.cpp b/libcockatrice_settings/libcockatrice/settings/message_settings.cpp
index 761c94484..50da39df6 100644
--- a/libcockatrice_settings/libcockatrice/settings/message_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/message_settings.cpp
@@ -5,12 +5,12 @@ MessageSettings::MessageSettings(const QString &settingPath, QObject *parent)
{
}
-QString MessageSettings::getMessageAt(int index)
+QString MessageSettings::getMessageAt(int index) const
{
return getValue(QString("msg%1").arg(index)).toString();
}
-int MessageSettings::getCount()
+int MessageSettings::getCount() const
{
return getValue("count").toInt();
}
diff --git a/libcockatrice_settings/libcockatrice/settings/message_settings.h b/libcockatrice_settings/libcockatrice/settings/message_settings.h
index 265c455e1..ec70027af 100644
--- a/libcockatrice_settings/libcockatrice/settings/message_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/message_settings.h
@@ -15,8 +15,8 @@ class MessageSettings : public SettingsManager
friend class SettingsCache;
public:
- int getCount();
- QString getMessageAt(int index);
+ int getCount() const;
+ QString getMessageAt(int index) const;
void setCount(int count);
void setMessageAt(int index, QString message);
diff --git a/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp b/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp
index e64dd7494..76bc4069e 100644
--- a/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/recents_settings.cpp
@@ -7,7 +7,7 @@ RecentsSettings::RecentsSettings(const QString &settingPath, QObject *parent)
{
}
-QStringList RecentsSettings::getRecentlyOpenedDeckPaths()
+QStringList RecentsSettings::getRecentlyOpenedDeckPaths() const
{
return getValue("deckpaths").toStringList();
}
@@ -31,7 +31,7 @@ void RecentsSettings::updateRecentlyOpenedDeckPaths(const QString &deckPath)
emit recentlyOpenedDeckPathsChanged();
}
-QString RecentsSettings::getLatestDeckDirPath()
+QString RecentsSettings::getLatestDeckDirPath() const
{
return getValue("latestDeckDir", "dirs").toString();
}
diff --git a/libcockatrice_settings/libcockatrice/settings/recents_settings.h b/libcockatrice_settings/libcockatrice/settings/recents_settings.h
index 23c8f1a9f..3aebff334 100644
--- a/libcockatrice_settings/libcockatrice/settings/recents_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/recents_settings.h
@@ -18,11 +18,11 @@ class RecentsSettings : public SettingsManager
RecentsSettings(const RecentsSettings & /*other*/);
public:
- QStringList getRecentlyOpenedDeckPaths();
+ QStringList getRecentlyOpenedDeckPaths() const;
void clearRecentlyOpenedDeckPaths();
void updateRecentlyOpenedDeckPaths(const QString &deckPath);
- QString getLatestDeckDirPath();
+ QString getLatestDeckDirPath() const;
void setLatestDeckDirPath(const QString &dirPath);
signals:
diff --git a/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp b/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp
index 5f69f47c9..0140182be 100644
--- a/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/servers_settings.cpp
@@ -13,7 +13,7 @@ void ServersSettings::setPreviousHostLogin(int previous)
setValue(previous, "previoushostlogin");
}
-int ServersSettings::getPreviousHostLogin()
+int ServersSettings::getPreviousHostLogin() const
{
QVariant previous = getValue("previoushostlogin");
return previous == QVariant() ? 1 : previous.toInt();
@@ -24,7 +24,7 @@ void ServersSettings::setPreviousHostList(QStringList list)
setValue(list, "previoushosts");
}
-QStringList ServersSettings::getPreviousHostList()
+QStringList ServersSettings::getPreviousHostList() const
{
return getValue("previoushosts").toStringList();
}
@@ -48,13 +48,13 @@ QString ServersSettings::getSite(QString defaultSite)
return site == QVariant() ? std::move(defaultSite) : site.toString();
}
-QString ServersSettings::getPrevioushostName()
+QString ServersSettings::getPrevioushostName() const
{
QVariant value = getValue("previoushostName");
return value == QVariant() ? "Rooster Ranges" : value.toString();
}
-int ServersSettings::getPrevioushostindex(const QString &saveName)
+int ServersSettings::getPrevioushostindex(const QString &saveName) const
{
int size = getValue("totalServers", "server", "server_details").toInt();
@@ -65,14 +65,14 @@ int ServersSettings::getPrevioushostindex(const QString &saveName)
return -1;
}
-QString ServersSettings::getHostname(QString defaultHost)
+QString ServersSettings::getHostname(QString defaultHost) const
{
int index = getPrevioushostindex(getPrevioushostName());
QVariant hostname = getValue(QString("server%1").arg(index), "server", "server_details");
return hostname == QVariant() ? std::move(defaultHost) : hostname.toString();
}
-QString ServersSettings::getPort(QString defaultPort)
+QString ServersSettings::getPort(QString defaultPort) const
{
int index = getPrevioushostindex(getPrevioushostName());
QVariant port = getValue(QString("port%1").arg(index), "server", "server_details");
@@ -80,7 +80,7 @@ QString ServersSettings::getPort(QString defaultPort)
return port == QVariant() ? std::move(defaultPort) : port.toString();
}
-QString ServersSettings::getPlayerName(QString defaultName)
+QString ServersSettings::getPlayerName(QString defaultName) const
{
int index = getPrevioushostindex(getPrevioushostName());
QVariant name = getValue(QString("username%1").arg(index), "server", "server_details");
@@ -98,7 +98,7 @@ QString ServersSettings::getPassword()
return QString();
}
-bool ServersSettings::getSavePassword()
+bool ServersSettings::getSavePassword() const
{
int index = getPrevioushostindex(getPrevioushostName());
bool save = getValue(QString("savePassword%1").arg(index), "server", "server_details").toBool();
@@ -110,7 +110,7 @@ void ServersSettings::setAutoConnect(int autoconnect)
setValue(autoconnect, "auto_connect");
}
-int ServersSettings::getAutoConnect()
+int ServersSettings::getAutoConnect() const
{
QVariant autoconnect = getValue("auto_connect");
return autoconnect == QVariant() ? 0 : autoconnect.toInt();
@@ -121,7 +121,7 @@ void ServersSettings::setFPHostName(QString hostname)
setValue(hostname, "fphostname");
}
-QString ServersSettings::getFPHostname(QString defaultHost)
+QString ServersSettings::getFPHostname(QString defaultHost) const
{
QVariant hostname = getValue("fphostname");
return hostname == QVariant() ? std::move(defaultHost) : hostname.toString();
@@ -132,7 +132,7 @@ void ServersSettings::setFPPort(QString port)
setValue(port, "fpport");
}
-QString ServersSettings::getFPPort(QString defaultPort)
+QString ServersSettings::getFPPort(QString defaultPort) const
{
QVariant port = getValue("fpport");
return port == QVariant() ? std::move(defaultPort) : port.toString();
@@ -143,7 +143,7 @@ void ServersSettings::setFPPlayerName(QString playerName)
setValue(playerName, "fpplayername");
}
-QString ServersSettings::getFPPlayerName(QString defaultName)
+QString ServersSettings::getFPPlayerName(QString defaultName) const
{
QVariant name = getValue("fpplayername");
return name == QVariant() ? std::move(defaultName) : name.toString();
@@ -154,7 +154,7 @@ void ServersSettings::setClearDebugLogStatus(bool abIsChecked)
setValue(abIsChecked, "save_debug_log");
}
-bool ServersSettings::getClearDebugLogStatus(bool abDefaultValue)
+bool ServersSettings::getClearDebugLogStatus(bool abDefaultValue) const
{
QVariant cbFlushLog = getValue("save_debug_log");
return cbFlushLog == QVariant() ? abDefaultValue : cbFlushLog.toBool();
diff --git a/libcockatrice_settings/libcockatrice/settings/servers_settings.h b/libcockatrice_settings/libcockatrice/settings/servers_settings.h
index 4d92c4647..22603a356 100644
--- a/libcockatrice_settings/libcockatrice/settings/servers_settings.h
+++ b/libcockatrice_settings/libcockatrice/settings/servers_settings.h
@@ -22,21 +22,21 @@ class ServersSettings : public SettingsManager
friend class SettingsCache;
public:
- int getPreviousHostLogin();
- int getPrevioushostindex(const QString &);
- QStringList getPreviousHostList();
- QString getPrevioushostName();
- QString getHostname(QString defaultHost = SERVERSETTINGS_DEFAULT_HOST);
- QString getPort(QString defaultPort = SERVERSETTINGS_DEFAULT_PORT);
- QString getPlayerName(QString defaultName = "");
- QString getFPHostname(QString defaultHost = SERVERSETTINGS_DEFAULT_HOST);
- QString getFPPort(QString defaultPort = SERVERSETTINGS_DEFAULT_PORT);
- QString getFPPlayerName(QString defaultName = "");
+ int getPreviousHostLogin() const;
+ int getPrevioushostindex(const QString &) const;
+ QStringList getPreviousHostList() const;
+ QString getPrevioushostName() const;
+ QString getHostname(QString defaultHost = SERVERSETTINGS_DEFAULT_HOST) const;
+ QString getPort(QString defaultPort = SERVERSETTINGS_DEFAULT_PORT) const;
+ QString getPlayerName(QString defaultName = "") const;
+ QString getFPHostname(QString defaultHost = SERVERSETTINGS_DEFAULT_HOST) const;
+ QString getFPPort(QString defaultPort = SERVERSETTINGS_DEFAULT_PORT) const;
+ QString getFPPlayerName(QString defaultName = "") const;
QString getPassword();
QString getSaveName(QString defaultname = "");
QString getSite(QString defaultName = "");
- bool getSavePassword();
- int getAutoConnect();
+ bool getSavePassword() const;
+ int getAutoConnect() const;
void setPreviousHostLogin(int previous);
void setPrevioushostName(const QString &);
@@ -67,7 +67,7 @@ public:
QString port = QString(),
QString site = QString());
void setClearDebugLogStatus(bool abIsChecked);
- bool getClearDebugLogStatus(bool abDefaultValue);
+ bool getClearDebugLogStatus(bool abDefaultValue) const;
private:
explicit ServersSettings(const QString &settingPath, QObject *parent = nullptr);
diff --git a/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp b/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp
index 3f3deb638..2d4f1c441 100644
--- a/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp
+++ b/libcockatrice_settings/libcockatrice/settings/settings_manager.cpp
@@ -108,7 +108,7 @@ void SettingsManager::deleteValue(const QString &name, const QString &group, con
}
}
-QVariant SettingsManager::getValue(const QString &name)
+QVariant SettingsManager::getValue(const QString &name) const
{
auto settings = getSettings();
@@ -133,7 +133,7 @@ QVariant SettingsManager::getValue(const QString &name)
return value;
}
-QVariant SettingsManager::getValue(const QString &name, const QString &group, const QString &subGroup)
+QVariant SettingsManager::getValue(const QString &name, const QString &group, const QString &subGroup) const
{
auto settings = getSettings();
diff --git a/libcockatrice_settings/libcockatrice/settings/settings_manager.h b/libcockatrice_settings/libcockatrice/settings/settings_manager.h
index 18abb8dbf..ad828f089 100644
--- a/libcockatrice_settings/libcockatrice/settings/settings_manager.h
+++ b/libcockatrice_settings/libcockatrice/settings/settings_manager.h
@@ -19,8 +19,8 @@ public:
const QString &defaultGroup = QString(),
const QString &defaultSubGroup = QString(),
QObject *parent = nullptr);
- QVariant getValue(const QString &name);
- QVariant getValue(const QString &name, const QString &group, const QString &subGroup = QString());
+ QVariant getValue(const QString &name) const;
+ QVariant getValue(const QString &name, const QString &group, const QString &subGroup = QString()) const;
void sync();
protected:
From 7caa88bc58b649b2536d83fed35fdcf2743dbdb6 Mon Sep 17 00:00:00 2001
From: Bruno Alexandre Rosa <1791393+brunoalr@users.noreply.github.com>
Date: Fri, 27 Mar 2026 14:37:30 -0300
Subject: [PATCH 19/60] fix: solve deprecated literal operator error by
updating peglib (#6745)
* fix: solve deprecated literal operator error
* update peglib
https://github.com/yhirose/cpp-peglib/commit/dcabc63cf4b966eb6f33abd571ae4cda6bf707f0
---
.../libcockatrice/utility/peglib.h | 8083 +++++++++--------
1 file changed, 4452 insertions(+), 3631 deletions(-)
diff --git a/libcockatrice_utility/libcockatrice/utility/peglib.h b/libcockatrice_utility/libcockatrice/utility/peglib.h
index 6a5b87b2d..3ae6040c4 100644
--- a/libcockatrice_utility/libcockatrice/utility/peglib.h
+++ b/libcockatrice_utility/libcockatrice/utility/peglib.h
@@ -1,4 +1,4 @@
-//
+//
// peglib.h
//
// Copyright (c) 2022 Yuji Hirose. All rights reserved.
@@ -17,6 +17,7 @@
#include
#include
+#include
#include
#include
#if __has_include()
@@ -30,6 +31,7 @@
#include