From dec5e217a2288c5aa35851708cc82645c43d0606 Mon Sep 17 00:00:00 2001 From: tooomm Date: Fri, 6 Nov 2026 21:43:14 +0100 Subject: [PATCH] Remove leading spaces from message log zone strings (#4945) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "from …" fragments built by getFromStr() carried a leading space so the sentence templates could concatenate them directly (%2%3). That blank is invisible on Transifex and most translations dropped it, merging the card name and the zone phrase in the log (#4943). Drop the blank from the tr() strings and add the separator in code where the fragment is built. The space is only prepended when the fragment is non-empty, so messages that put the zone in the card name instead — "the top card of their library." — keep their punctuation tight. The templates stay at %2%3, since %3 is empty on those paths. --- .../game_graphics/log/message_log_widget.cpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/cockatrice/src/game_graphics/log/message_log_widget.cpp b/cockatrice/src/game_graphics/log/message_log_widget.cpp index d526766af..9fe89c04b 100644 --- a/cockatrice/src/game_graphics/log/message_log_widget.cpp +++ b/cockatrice/src/game_graphics/log/message_log_widget.cpp @@ -64,13 +64,13 @@ MessageLogWidget::getFromStr(CardZoneLogic *zone, QString cardName, int position QString zoneName = zone->getName(); if (zoneName == ZoneNames::TABLE) { - fromStr = tr(" from play"); + fromStr = tr("from play"); } else if (zoneName == ZoneNames::GRAVE) { - fromStr = tr(" from their graveyard"); + fromStr = tr("from their graveyard"); } else if (zoneName == ZoneNames::EXILE) { - fromStr = tr(" from exile"); + fromStr = tr("from exile"); } else if (zoneName == ZoneNames::HAND) { - fromStr = tr(" from their hand"); + fromStr = tr("from their hand"); } else if (zoneName == ZoneNames::DECK) { if (position == 0) { if (cardName.isEmpty()) { @@ -82,9 +82,9 @@ MessageLogWidget::getFromStr(CardZoneLogic *zone, QString cardName, int position cardNameContainsStartZone = true; } else { if (ownerChange) { - fromStr = tr(" from the top of %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName()); + fromStr = tr("from the top of %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName()); } else { - fromStr = tr(" from the top of their library"); + fromStr = tr("from the top of their library"); } } } else if (position == zone->getCards().size()) { @@ -97,29 +97,34 @@ MessageLogWidget::getFromStr(CardZoneLogic *zone, QString cardName, int position cardNameContainsStartZone = true; } else { if (ownerChange) { - fromStr = tr(" from the bottom of %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName()); + fromStr = tr("from the bottom of %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName()); } else { - fromStr = tr(" from the bottom of their library"); + fromStr = tr("from the bottom of their library"); } } } else { if (ownerChange) { - fromStr = tr(" from %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName()); + fromStr = tr("from %1's library").arg(zone->getPlayer()->getPlayerInfo()->getName()); } else { - fromStr = tr(" from their library"); + fromStr = tr("from their library"); } } } else if (zoneName == ZoneNames::SIDEBOARD) { - fromStr = tr(" from sideboard"); + fromStr = tr("from sideboard"); } else if (zoneName == ZoneNames::STACK) { - fromStr = tr(" from the stack"); + fromStr = tr("from the stack"); } else { - fromStr = tr(" from custom zone '%1'").arg(zoneName); + fromStr = tr("from custom zone '%1'").arg(zoneName); } if (!cardNameContainsStartZone) { cardName.clear(); } + // The separator space is added here rather than stored in the tr() string so + // translators never have to preserve an invisible leading blank. + if (!fromStr.isEmpty()) { + fromStr.prepend(' '); + } return {cardName, fromStr}; }