[Client] Show card names in the game log and [card] tags in the chosen card language (#7387)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions

The game log translates its sentences, zone names and counter names, but every
card name was rendered as the raw canonical name straight from the server.
The card board and the card info text already went through
CardLocalization::displayName(), so the log was the odd one out.

cardLink() used one string for both the card:// href and the visible label,
which left no room for a localized label. Split the two: the href keeps the
canonical name because ChatView::mousePressEvent feeds it straight to
showCardInfoPopup for lookup, while the label goes through the display
language. Same split for [card] chat tags in ChatView::appendCardTag.

Sanitize the name while building the link. logUndoDraw already did this by
hand and had drifted into its own non-italic copy of cardLink(); route it back
through the helper.

Add CardLocalization::displayNameFor() for callers that only hold a canonical
name and need no CardInfoPtr of their own.

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-10-03 13:47:07 +02:00 • committed by GitHub
parent 014983b5bc
commit b8b81170bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 7 deletions

View file

@ -6,6 +6,7 @@
#include "../../game/game_state.h"
#include "../../game/phase.h"
#include "../../game/player/player_logic.h"
#include "../../interface/card_localization.h"
#include "../../interface/widgets/tabs/tab_game.h"
#include "../board/card_item.h"
#include "../board/translate_counter_name.h"
@ -23,7 +24,11 @@ static QString sanitizeHtml(QString dirty)
static QString cardLink(const QString &cardName)
{
return QString("<i><a href=\"card://%1\">%2</a></i>").arg(cardName).arg(cardName);
// The href keeps the canonical name so the card popup can resolve it, while the label shows the name
// in the configured card language.
return QString("<i><a href=\"card://%1\">%2</a></i>")
.arg(sanitizeHtml(cardName))
.arg(sanitizeHtml(CardLocalization::displayNameFor(cardName)));
}
QPair<QString, QString>
@ -803,10 +808,9 @@ void MessageLogWidget::logUndoDraw(PlayerLogic *player, QString cardName)
if (cardName.isEmpty()) {
appendHtmlServerMessage(tr("%1 undoes their last draw.").arg(sanitizeHtml(player->getPlayerInfo()->getName())));
} else {
appendHtmlServerMessage(
tr("%1 undoes their last draw (%2).")
.arg(sanitizeHtml(player->getPlayerInfo()->getName()))
.arg(QString("<a href=\"card://%1\">%2</a>").arg(sanitizeHtml(cardName)).arg(sanitizeHtml(cardName))));
appendHtmlServerMessage(tr("%1 undoes their last draw (%2).")
.arg(sanitizeHtml(player->getPlayerInfo()->getName()))
.arg(cardLink(std::move(cardName))));
}
}

View file

@ -5,6 +5,7 @@
#include <QString>
#include <libcockatrice/card/card_info.h>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/settings/cards_display_settings.h>
namespace CardLocalization
@ -54,6 +55,25 @@ inline QString displayText(const CardInfo &card)
{
return card.getLocalizedText(displayLang());
}
/**
* @brief Looks a card up by its canonical name and returns its name in the configured display language.
*
* Use this where only the canonical name is known, such as the game log or [card] chat tags. Callers that
* already hold a resolved card and need to keep the canonical name around (as a link target, say) should
* use displayName() directly instead.
*
* @param cardName The canonical card name.
* @return The localized name, or cardName unchanged when the card is unknown to the database.
*/
inline QString displayNameFor(const QString &cardName)
{
if (cardName.isEmpty()) {
return cardName;
}
const QString localizedName = displayName(CardDatabaseManager::query()->getCardInfo(cardName));
return localizedName.isEmpty() ? cardName : localizedName;
}
} // namespace CardLocalization
#endif // COCKATRICE_CARD_LOCALIZATION_H

View file

@ -2,6 +2,7 @@
#include "../../../../client/settings/cache_settings.h"
#include "../../client/sound_engine.h"
#include "../../interface/card_localization.h"
#include "../../interface/pixel_map_generator.h"
#include "../../interface/widgets/tabs/tab_account.h"
#include "../user/user_context_menu.h"
@ -190,7 +191,8 @@ void ChatView::appendCardTag(QTextCursor &cursor, const QString &cardName)
QTextCharFormat cardFormat = oldFormat;
cardFormat.setFontItalic(true);
if (!CardDatabaseManager::query()->lookupCardByName(cardName)) {
const CardInfoPtr card = CardDatabaseManager::query()->lookupCardByName(cardName);
if (card.isNull()) {
cardFormat.setForeground(unresolvedCardTagColor);
cursor.setCharFormat(cardFormat);
cursor.insertText(cardName);
@ -200,10 +202,12 @@ void ChatView::appendCardTag(QTextCursor &cursor, const QString &cardName)
cardFormat.setForeground(linkColor);
cardFormat.setAnchor(true);
// The href keeps the canonical name so the card popup can resolve it, while the text shows the name
// in the configured card language.
cardFormat.setAnchorHref("card://" + cardName);
cursor.setCharFormat(cardFormat);
cursor.insertText(cardName);
cursor.insertText(CardLocalization::displayName(card));
cursor.setCharFormat(oldFormat);
}