From b8b81170bf8676806aa1e1212cdbf78c69ade011 Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Sat, 3 Oct 2026 13:47:07 +0200 Subject: [PATCH] [Client] Show card names in the game log and [card] tags in the chosen card language (#7387) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../game_graphics/log/message_log_widget.cpp | 14 ++++++++----- cockatrice/src/interface/card_localization.h | 20 +++++++++++++++++++ .../widgets/server/chat_view/chat_view.cpp | 8 ++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/cockatrice/src/game_graphics/log/message_log_widget.cpp b/cockatrice/src/game_graphics/log/message_log_widget.cpp index 06b0301bd..b998a3650 100644 --- a/cockatrice/src/game_graphics/log/message_log_widget.cpp +++ b/cockatrice/src/game_graphics/log/message_log_widget.cpp @@ -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("%2").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("%2") + .arg(sanitizeHtml(cardName)) + .arg(sanitizeHtml(CardLocalization::displayNameFor(cardName))); } QPair @@ -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("%2").arg(sanitizeHtml(cardName)).arg(sanitizeHtml(cardName)))); + appendHtmlServerMessage(tr("%1 undoes their last draw (%2).") + .arg(sanitizeHtml(player->getPlayerInfo()->getName())) + .arg(cardLink(std::move(cardName)))); } } diff --git a/cockatrice/src/interface/card_localization.h b/cockatrice/src/interface/card_localization.h index 0bfe4a764..1a1e7be5d 100644 --- a/cockatrice/src/interface/card_localization.h +++ b/cockatrice/src/interface/card_localization.h @@ -5,6 +5,7 @@ #include #include +#include #include 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 \ No newline at end of file diff --git a/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp b/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp index ae9b2deb4..91a7cb965 100644 --- a/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp +++ b/cockatrice/src/interface/widgets/server/chat_view/chat_view.cpp @@ -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); }