Browse Source

Merge pull request #263 from djeada/copilot/prepare-internationalization-support

Add internationalization support with qsTr() for all user-facing strings
Adam Djellouli 1 month ago
parent
commit
fff0f8f69e

+ 691 - 0
translations/app_en.ts

@@ -0,0 +1,691 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="en_US">
+<context>
+    <name>BattleSummary</name>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="134"/>
+        <source>VICTORY!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="134"/>
+        <source>FAILURE!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="278"/>
+        <source>VICTORIOUS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="278"/>
+        <source>DEFEATED</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="303"/>
+        <source>Kills: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="314"/>
+        <source>Losses: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="325"/>
+        <source>Units Trained: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="336"/>
+        <source>Villages: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="347"/>
+        <source>Play Time: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="371"/>
+        <source>SCORE</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="483"/>
+        <source>YOU</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/BattleSummary.qml" line="500"/>
+        <source>Return to Menu</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>HUDBottom</name>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="43"/>
+        <source>SELECTED UNITS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="157"/>
+        <source>◉ Select Troops for Commands</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="157"/>
+        <source>◉ Normal Mode</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="157"/>
+        <source>⚔️ ATTACK MODE - Click Enemy</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="157"/>
+        <source>🛡️ GUARD MODE - Click Position</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="157"/>
+        <source>🚶 PATROL MODE - Set Waypoints</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="157"/>
+        <source>⏹️ STOP COMMAND</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="205"/>
+        <source>Attack</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="214"/>
+        <source>Attack enemy units or buildings.
+Units will chase targets.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="214"/>
+        <location filename="../ui/qml/HUDBottom.qml" line="247"/>
+        <location filename="../ui/qml/HUDBottom.qml" line="280"/>
+        <location filename="../ui/qml/HUDBottom.qml" line="313"/>
+        <location filename="../ui/qml/HUDBottom.qml" line="353"/>
+        <source>Select troops first</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="238"/>
+        <source>Guard</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="247"/>
+        <source>Guard a position.
+Units will defend from all sides.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="271"/>
+        <source>Patrol</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="280"/>
+        <source>Patrol between waypoints.
+Click start and end points.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="304"/>
+        <source>Stop</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="313"/>
+        <source>Stop all actions immediately</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="344"/>
+        <source>Hold</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="353"/>
+        <source>Exit hold mode (toggle)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDBottom.qml" line="353"/>
+        <source>Hold position and defend</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>HUDTop</name>
+    <message>
+        <location filename="../ui/qml/HUDTop.qml" line="145"/>
+        <source>Speed:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDTop.qml" line="250"/>
+        <source>Camera:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDTop.qml" line="264"/>
+        <source>Follow</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDTop.qml" line="295"/>
+        <source>Reset</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDTop.qml" line="458"/>
+        <source>MINIMAP</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>HUDVictory</name>
+    <message>
+        <location filename="../ui/qml/HUDVictory.qml" line="58"/>
+        <source>VICTORY!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDVictory.qml" line="58"/>
+        <source>DEFEAT</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDVictory.qml" line="66"/>
+        <source>Enemy barracks destroyed!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDVictory.qml" line="66"/>
+        <source>Your barracks was destroyed!</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/HUDVictory.qml" line="73"/>
+        <source>Continue</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>LoadGamePanel</name>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="117"/>
+        <source>Load Game</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="125"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="164"/>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="188"/>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="405"/>
+        <source>No saves found</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="243"/>
+        <source>No Preview</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="265"/>
+        <source>Slot: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="285"/>
+        <source>Last saved: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="293"/>
+        <source>Play time: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="313"/>
+        <source>Load</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="322"/>
+        <source>Delete</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="366"/>
+        <source>Selected: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="366"/>
+        <source>Select a save to load</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="372"/>
+        <source>Load Selected</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="396"/>
+        <source>Confirm Delete</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/LoadGamePanel.qml" line="433"/>
+        <source>Are you sure you want to delete the save:
+&quot;%1&quot;?
+
+This action cannot be undone.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>Main</name>
+    <message>
+        <location filename="../ui/qml/Main.qml" line="18"/>
+        <source>Standard of Iron - RTS Game</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/Main.qml" line="92"/>
+        <source>PAUSED</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/Main.qml" line="100"/>
+        <source>Press Space to resume</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>MainMenu</name>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="84"/>
+        <source>STANDARD OF IRON</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="94"/>
+        <source>A tiny but ambitious RTS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="109"/>
+        <source>Play — Skirmish</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="110"/>
+        <source>Select a map and start</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="115"/>
+        <source>Save Game</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="116"/>
+        <source>Save your current progress</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="121"/>
+        <source>Load Game</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="122"/>
+        <source>Resume a previous game</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="127"/>
+        <source>Settings</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="128"/>
+        <source>Adjust graphics &amp; controls</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="133"/>
+        <source>Exit</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="134"/>
+        <source>Quit the game</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="249"/>
+        <source>v0.9 — prototype</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="295"/>
+        <source>Featured</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="303"/>
+        <source>Skirmish Mode</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="312"/>
+        <source>Pick a map, adjust your forces and jump into battle. Modern controls and responsive UI.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="338"/>
+        <source>Tips</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MainMenu.qml" line="346"/>
+        <source>Hover menu items or use Up/Down and Enter to navigate. Play opens map selection.</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>MapSelect</name>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="271"/>
+        <source>Maps</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="486"/>
+        <source>No maps available</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="519"/>
+        <location filename="../ui/qml/MapSelect.qml" line="596"/>
+        <source>Loading maps...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="548"/>
+        <source>► %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="548"/>
+        <source>Select a map to continue</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="703"/>
+        <source>Loading map details...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="720"/>
+        <source>No Map Selected</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="786"/>
+        <source>Players</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="810"/>
+        <source>• Click color/team to cycle</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="888"/>
+        <source>Player color: %1 - Click to change</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="888"/>
+        <source>Color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="950"/>
+        <source>Team %1 - Click to change</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="966"/>
+        <source>Team %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="1016"/>
+        <source>Remove player</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="1087"/>
+        <source>+ Add CPU</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="1094"/>
+        <source>Add AI opponent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="1324"/>
+        <source>Back</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="1330"/>
+        <source>Return to main menu (Esc)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="1404"/>
+        <source>Play</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/MapSelect.qml" line="1411"/>
+        <source>Start game (Enter)</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>ProductionPanel</name>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="56"/>
+        <source>PRODUCTION QUEUE</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="210"/>
+        <source>Units Produced: %1 / %2</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="243"/>
+        <source>RECRUIT UNITS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="280"/>
+        <source>Archer</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="316"/>
+        <source>Recruit Archer
+Cost: %1 villagers
+Build time: %2s</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="316"/>
+        <location filename="../ui/qml/ProductionPanel.qml" line="390"/>
+        <location filename="../ui/qml/ProductionPanel.qml" line="464"/>
+        <source>Queue is full (5/5)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="316"/>
+        <location filename="../ui/qml/ProductionPanel.qml" line="390"/>
+        <location filename="../ui/qml/ProductionPanel.qml" line="464"/>
+        <source>Unit cap reached</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="316"/>
+        <location filename="../ui/qml/ProductionPanel.qml" line="390"/>
+        <location filename="../ui/qml/ProductionPanel.qml" line="464"/>
+        <source>Cannot recruit</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="354"/>
+        <source>Knight</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="390"/>
+        <source>Recruit Knight
+Cost: %1 villagers
+Build time: %2s</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="428"/>
+        <source>Spearman</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="464"/>
+        <source>Recruit Spearman
+Cost: %1 villagers
+Build time: %2s</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="518"/>
+        <source>📍 Click Map to Set Rally</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="518"/>
+        <source>📍 Set Rally Point</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="523"/>
+        <source>Set where newly recruited units will gather.
+Right-click to cancel.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="546"/>
+        <source>Right-click to cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="583"/>
+        <source>No Barracks Selected</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/ProductionPanel.qml" line="591"/>
+        <source>Select a barracks to recruit units</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
+    <name>SaveGamePanel</name>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="72"/>
+        <source>Save Game</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="80"/>
+        <source>Cancel</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="97"/>
+        <source>Save Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="106"/>
+        <source>Enter save name...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="121"/>
+        <source>Save</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="137"/>
+        <source>Existing Saves</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="231"/>
+        <source>No Preview</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="252"/>
+        <source>Slot: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="268"/>
+        <source>Last saved: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="278"/>
+        <source>Overwrite</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="316"/>
+        <source>Confirm Overwrite</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../ui/qml/SaveGamePanel.qml" line="335"/>
+        <source>Are you sure you want to overwrite the save:
+&quot;%1&quot;?</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+</TS>

+ 10 - 10
ui/qml/BattleSummary.qml

@@ -131,7 +131,7 @@ Rectangle {
             id: mainTitle
             id: mainTitle
 
 
             anchors.horizontalCenter: parent.horizontalCenter
             anchors.horizontalCenter: parent.horizontalCenter
-            text: isVictory ? "VICTORY!" : "FAILURE!"
+            text: isVictory ? qsTr("VICTORY!") : qsTr("FAILURE!")
             color: "#FFD700"
             color: "#FFD700"
             font.family: "serif"
             font.family: "serif"
             font.pointSize: 64
             font.pointSize: 64
@@ -275,7 +275,7 @@ Rectangle {
 
 
                                     Text {
                                     Text {
                                         anchors.centerIn: parent
                                         anchors.centerIn: parent
-                                        text: model.isWinner ? "VICTORIOUS" : "DEFEATED"
+                                        text: model.isWinner ? qsTr("VICTORIOUS") : qsTr("DEFEATED")
                                         color: "white"
                                         color: "white"
                                         font.family: "serif"
                                         font.family: "serif"
                                         font.pointSize: 11
                                         font.pointSize: 11
@@ -300,7 +300,7 @@ Rectangle {
 
 
                                     Text {
                                     Text {
                                         anchors.horizontalCenter: parent.horizontalCenter
                                         anchors.horizontalCenter: parent.horizontalCenter
-                                        text: "Kills: " + model.kills
+                                        text: qsTr("Kills: %1").arg(model.kills)
                                         color: "#F5F5DC"
                                         color: "#F5F5DC"
                                         font.family: "serif"
                                         font.family: "serif"
                                         font.pointSize: 13
                                         font.pointSize: 13
@@ -311,7 +311,7 @@ Rectangle {
 
 
                                     Text {
                                     Text {
                                         anchors.horizontalCenter: parent.horizontalCenter
                                         anchors.horizontalCenter: parent.horizontalCenter
-                                        text: "Losses: " + model.losses
+                                        text: qsTr("Losses: %1").arg(model.losses)
                                         color: "#F5F5DC"
                                         color: "#F5F5DC"
                                         font.family: "serif"
                                         font.family: "serif"
                                         font.pointSize: 13
                                         font.pointSize: 13
@@ -322,7 +322,7 @@ Rectangle {
 
 
                                     Text {
                                     Text {
                                         anchors.horizontalCenter: parent.horizontalCenter
                                         anchors.horizontalCenter: parent.horizontalCenter
-                                        text: "Units Trained: " + model.unitsTrained
+                                        text: qsTr("Units Trained: %1").arg(model.unitsTrained)
                                         color: "#F5F5DC"
                                         color: "#F5F5DC"
                                         font.family: "serif"
                                         font.family: "serif"
                                         font.pointSize: 13
                                         font.pointSize: 13
@@ -333,7 +333,7 @@ Rectangle {
 
 
                                     Text {
                                     Text {
                                         anchors.horizontalCenter: parent.horizontalCenter
                                         anchors.horizontalCenter: parent.horizontalCenter
-                                        text: "Villages: " + model.villages
+                                        text: qsTr("Villages: %1").arg(model.villages)
                                         color: "#F5F5DC"
                                         color: "#F5F5DC"
                                         font.family: "serif"
                                         font.family: "serif"
                                         font.pointSize: 13
                                         font.pointSize: 13
@@ -344,7 +344,7 @@ Rectangle {
 
 
                                     Text {
                                     Text {
                                         anchors.horizontalCenter: parent.horizontalCenter
                                         anchors.horizontalCenter: parent.horizontalCenter
-                                        text: "Play Time: " + model.playTime
+                                        text: qsTr("Play Time: %1").arg(model.playTime)
                                         color: "#F5F5DC"
                                         color: "#F5F5DC"
                                         font.family: "serif"
                                         font.family: "serif"
                                         font.pointSize: 13
                                         font.pointSize: 13
@@ -368,7 +368,7 @@ Rectangle {
 
 
                                 Text {
                                 Text {
                                     anchors.horizontalCenter: parent.horizontalCenter
                                     anchors.horizontalCenter: parent.horizontalCenter
-                                    text: "SCORE"
+                                    text: qsTr("SCORE")
                                     color: "#FFD700"
                                     color: "#FFD700"
                                     font.family: "serif"
                                     font.family: "serif"
                                     font.pointSize: 15
                                     font.pointSize: 15
@@ -480,7 +480,7 @@ Rectangle {
 
 
                         Text {
                         Text {
                             anchors.centerIn: parent
                             anchors.centerIn: parent
-                            text: "YOU"
+                            text: qsTr("YOU")
                             color: "#FFD700"
                             color: "#FFD700"
                             font.family: "serif"
                             font.family: "serif"
                             font.pointSize: 12
                             font.pointSize: 12
@@ -497,7 +497,7 @@ Rectangle {
 
 
         Button {
         Button {
             anchors.horizontalCenter: parent.horizontalCenter
             anchors.horizontalCenter: parent.horizontalCenter
-            text: "Return to Menu"
+            text: qsTr("Return to Menu")
             font.pointSize: 16
             font.pointSize: 16
             font.bold: true
             font.bold: true
             padding: 12
             padding: 12

+ 12 - 12
ui/qml/HUDBottom.qml

@@ -40,7 +40,7 @@ RowLayout {
 
 
                 Text {
                 Text {
                     anchors.centerIn: parent
                     anchors.centerIn: parent
-                    text: "SELECTED UNITS"
+                    text: qsTr("SELECTED UNITS")
                     color: "#3498db"
                     color: "#3498db"
                     font.pointSize: 10
                     font.pointSize: 10
                     font.bold: true
                     font.bold: true
@@ -154,7 +154,7 @@ RowLayout {
 
 
             Text {
             Text {
                 anchors.centerIn: parent
                 anchors.centerIn: parent
-                text: !bottomRoot.hasMovableUnits ? "◉ Select Troops for Commands" : (bottomRoot.currentCommandMode === "normal" ? "◉ Normal Mode" : bottomRoot.currentCommandMode === "attack" ? "⚔️ ATTACK MODE - Click Enemy" : bottomRoot.currentCommandMode === "guard" ? "🛡️ GUARD MODE - Click Position" : bottomRoot.currentCommandMode === "patrol" ? "🚶 PATROL MODE - Set Waypoints" : "⏹️ STOP COMMAND")
+                text: !bottomRoot.hasMovableUnits ? qsTr("◉ Select Troops for Commands") : (bottomRoot.currentCommandMode === "normal" ? qsTr("◉ Normal Mode") : bottomRoot.currentCommandMode === "attack" ? qsTr("⚔️ ATTACK MODE - Click Enemy") : bottomRoot.currentCommandMode === "guard" ? qsTr("🛡️ GUARD MODE - Click Position") : bottomRoot.currentCommandMode === "patrol" ? qsTr("🚶 PATROL MODE - Set Waypoints") : qsTr("⏹️ STOP COMMAND"))
                 color: !bottomRoot.hasMovableUnits ? "#5a6c7d" : (bottomRoot.currentCommandMode === "normal" ? "#7f8c8d" : (bottomRoot.currentCommandMode === "attack" ? "#ff6b6b" : "#3498db"))
                 color: !bottomRoot.hasMovableUnits ? "#5a6c7d" : (bottomRoot.currentCommandMode === "normal" ? "#7f8c8d" : (bottomRoot.currentCommandMode === "attack" ? "#ff6b6b" : "#3498db"))
                 font.pointSize: bottomRoot.currentCommandMode === "normal" ? 10 : 11
                 font.pointSize: bottomRoot.currentCommandMode === "normal" ? 10 : 11
                 font.bold: bottomRoot.currentCommandMode !== "normal" && bottomRoot.hasMovableUnits
                 font.bold: bottomRoot.currentCommandMode !== "normal" && bottomRoot.hasMovableUnits
@@ -202,7 +202,7 @@ RowLayout {
             Button {
             Button {
                 Layout.fillWidth: true
                 Layout.fillWidth: true
                 Layout.preferredHeight: 38
                 Layout.preferredHeight: 38
-                text: "Attack"
+                text: qsTr("Attack")
                 focusPolicy: Qt.NoFocus
                 focusPolicy: Qt.NoFocus
                 enabled: bottomRoot.hasMovableUnits
                 enabled: bottomRoot.hasMovableUnits
                 checkable: true
                 checkable: true
@@ -211,7 +211,7 @@ RowLayout {
                     bottomRoot.commandModeChanged(checked ? "attack" : "normal");
                     bottomRoot.commandModeChanged(checked ? "attack" : "normal");
                 }
                 }
                 ToolTip.visible: hovered
                 ToolTip.visible: hovered
-                ToolTip.text: bottomRoot.hasMovableUnits ? "Attack enemy units or buildings.\nUnits will chase targets." : "Select troops first"
+                ToolTip.text: bottomRoot.hasMovableUnits ? qsTr("Attack enemy units or buildings.\nUnits will chase targets.") : qsTr("Select troops first")
                 ToolTip.delay: 500
                 ToolTip.delay: 500
 
 
                 background: Rectangle {
                 background: Rectangle {
@@ -235,7 +235,7 @@ RowLayout {
             Button {
             Button {
                 Layout.fillWidth: true
                 Layout.fillWidth: true
                 Layout.preferredHeight: 38
                 Layout.preferredHeight: 38
-                text: "Guard"
+                text: qsTr("Guard")
                 focusPolicy: Qt.NoFocus
                 focusPolicy: Qt.NoFocus
                 enabled: bottomRoot.hasMovableUnits
                 enabled: bottomRoot.hasMovableUnits
                 checkable: true
                 checkable: true
@@ -244,7 +244,7 @@ RowLayout {
                     bottomRoot.commandModeChanged(checked ? "guard" : "normal");
                     bottomRoot.commandModeChanged(checked ? "guard" : "normal");
                 }
                 }
                 ToolTip.visible: hovered
                 ToolTip.visible: hovered
-                ToolTip.text: bottomRoot.hasMovableUnits ? "Guard a position.\nUnits will defend from all sides." : "Select troops first"
+                ToolTip.text: bottomRoot.hasMovableUnits ? qsTr("Guard a position.\nUnits will defend from all sides.") : qsTr("Select troops first")
                 ToolTip.delay: 500
                 ToolTip.delay: 500
 
 
                 background: Rectangle {
                 background: Rectangle {
@@ -268,7 +268,7 @@ RowLayout {
             Button {
             Button {
                 Layout.fillWidth: true
                 Layout.fillWidth: true
                 Layout.preferredHeight: 38
                 Layout.preferredHeight: 38
-                text: "Patrol"
+                text: qsTr("Patrol")
                 focusPolicy: Qt.NoFocus
                 focusPolicy: Qt.NoFocus
                 enabled: bottomRoot.hasMovableUnits
                 enabled: bottomRoot.hasMovableUnits
                 checkable: true
                 checkable: true
@@ -277,7 +277,7 @@ RowLayout {
                     bottomRoot.commandModeChanged(checked ? "patrol" : "normal");
                     bottomRoot.commandModeChanged(checked ? "patrol" : "normal");
                 }
                 }
                 ToolTip.visible: hovered
                 ToolTip.visible: hovered
-                ToolTip.text: bottomRoot.hasMovableUnits ? "Patrol between waypoints.\nClick start and end points." : "Select troops first"
+                ToolTip.text: bottomRoot.hasMovableUnits ? qsTr("Patrol between waypoints.\nClick start and end points.") : qsTr("Select troops first")
                 ToolTip.delay: 500
                 ToolTip.delay: 500
 
 
                 background: Rectangle {
                 background: Rectangle {
@@ -301,7 +301,7 @@ RowLayout {
             Button {
             Button {
                 Layout.fillWidth: true
                 Layout.fillWidth: true
                 Layout.preferredHeight: 38
                 Layout.preferredHeight: 38
-                text: "Stop"
+                text: qsTr("Stop")
                 focusPolicy: Qt.NoFocus
                 focusPolicy: Qt.NoFocus
                 enabled: bottomRoot.hasMovableUnits
                 enabled: bottomRoot.hasMovableUnits
                 onClicked: {
                 onClicked: {
@@ -310,7 +310,7 @@ RowLayout {
 
 
                 }
                 }
                 ToolTip.visible: hovered
                 ToolTip.visible: hovered
-                ToolTip.text: bottomRoot.hasMovableUnits ? "Stop all actions immediately" : "Select troops first"
+                ToolTip.text: bottomRoot.hasMovableUnits ? qsTr("Stop all actions immediately") : qsTr("Select troops first")
                 ToolTip.delay: 500
                 ToolTip.delay: 500
 
 
                 background: Rectangle {
                 background: Rectangle {
@@ -341,7 +341,7 @@ RowLayout {
 
 
                 Layout.fillWidth: true
                 Layout.fillWidth: true
                 Layout.preferredHeight: 38
                 Layout.preferredHeight: 38
-                text: "Hold"
+                text: qsTr("Hold")
                 focusPolicy: Qt.NoFocus
                 focusPolicy: Qt.NoFocus
                 enabled: bottomRoot.hasMovableUnits
                 enabled: bottomRoot.hasMovableUnits
                 onClicked: {
                 onClicked: {
@@ -350,7 +350,7 @@ RowLayout {
 
 
                 }
                 }
                 ToolTip.visible: hovered
                 ToolTip.visible: hovered
-                ToolTip.text: bottomRoot.hasMovableUnits ? (isHoldActive ? "Exit hold mode (toggle)" : "Hold position and defend") : "Select troops first"
+                ToolTip.text: bottomRoot.hasMovableUnits ? (isHoldActive ? qsTr("Exit hold mode (toggle)") : qsTr("Hold position and defend")) : qsTr("Select troops first")
                 ToolTip.delay: 500
                 ToolTip.delay: 500
 
 
                 Connections {
                 Connections {

+ 5 - 5
ui/qml/HUDTop.qml

@@ -142,7 +142,7 @@ Item {
                     Layout.alignment: Qt.AlignVCenter
                     Layout.alignment: Qt.AlignVCenter
 
 
                     Label {
                     Label {
-                        text: "Speed:"
+                        text: qsTr("Speed:")
                         visible: !topRoot.compact
                         visible: !topRoot.compact
                         color: "#ecf0f1"
                         color: "#ecf0f1"
                         font.pixelSize: 14
                         font.pixelSize: 14
@@ -247,7 +247,7 @@ Item {
                     Layout.alignment: Qt.AlignVCenter
                     Layout.alignment: Qt.AlignVCenter
 
 
                     Label {
                     Label {
-                        text: "Camera:"
+                        text: qsTr("Camera:")
                         visible: !topRoot.compact
                         visible: !topRoot.compact
                         color: "#ecf0f1"
                         color: "#ecf0f1"
                         font.pixelSize: 14
                         font.pixelSize: 14
@@ -261,7 +261,7 @@ Item {
                         Layout.preferredWidth: topRoot.compact ? 44 : 80
                         Layout.preferredWidth: topRoot.compact ? 44 : 80
                         Layout.preferredHeight: Math.min(34, topPanel.height - 16)
                         Layout.preferredHeight: Math.min(34, topPanel.height - 16)
                         checkable: true
                         checkable: true
-                        text: topRoot.compact ? "\u2609" : "Follow"
+                        text: topRoot.compact ? "\u2609" : qsTr("Follow")
                         font.pixelSize: 13
                         font.pixelSize: 13
                         focusPolicy: Qt.NoFocus
                         focusPolicy: Qt.NoFocus
                         onToggled: {
                         onToggled: {
@@ -292,7 +292,7 @@ Item {
 
 
                         Layout.preferredWidth: topRoot.compact ? 44 : 80
                         Layout.preferredWidth: topRoot.compact ? 44 : 80
                         Layout.preferredHeight: Math.min(34, topPanel.height - 16)
                         Layout.preferredHeight: Math.min(34, topPanel.height - 16)
-                        text: topRoot.compact ? "\u21BA" : "Reset"
+                        text: topRoot.compact ? "\u21BA" : qsTr("Reset")
                         font.pixelSize: 13
                         font.pixelSize: 13
                         focusPolicy: Qt.NoFocus
                         focusPolicy: Qt.NoFocus
                         onClicked: {
                         onClicked: {
@@ -455,7 +455,7 @@ Item {
 
 
                             Label {
                             Label {
                                 anchors.centerIn: parent
                                 anchors.centerIn: parent
-                                text: "MINIMAP"
+                                text: qsTr("MINIMAP")
                                 color: "#3f5362"
                                 color: "#3f5362"
                                 font.pixelSize: 12
                                 font.pixelSize: 12
                                 font.bold: true
                                 font.bold: true

+ 3 - 3
ui/qml/HUDVictory.qml

@@ -55,7 +55,7 @@ Rectangle {
                 id: victoryText
                 id: victoryText
 
 
                 anchors.horizontalCenter: parent.horizontalCenter
                 anchors.horizontalCenter: parent.horizontalCenter
-                text: (typeof game !== 'undefined' && game.victoryState === "victory") ? "VICTORY!" : "DEFEAT"
+                text: (typeof game !== 'undefined' && game.victoryState === "victory") ? qsTr("VICTORY!") : qsTr("DEFEAT")
                 color: (typeof game !== 'undefined' && game.victoryState === "victory") ? "#27ae60" : "#e74c3c"
                 color: (typeof game !== 'undefined' && game.victoryState === "victory") ? "#27ae60" : "#e74c3c"
                 font.pointSize: 48
                 font.pointSize: 48
                 font.bold: true
                 font.bold: true
@@ -63,14 +63,14 @@ Rectangle {
 
 
             Text {
             Text {
                 anchors.horizontalCenter: parent.horizontalCenter
                 anchors.horizontalCenter: parent.horizontalCenter
-                text: (typeof game !== 'undefined' && game.victoryState === "victory") ? "Enemy barracks destroyed!" : "Your barracks was destroyed!"
+                text: (typeof game !== 'undefined' && game.victoryState === "victory") ? qsTr("Enemy barracks destroyed!") : qsTr("Your barracks was destroyed!")
                 color: "white"
                 color: "white"
                 font.pointSize: 18
                 font.pointSize: 18
             }
             }
 
 
             Button {
             Button {
                 anchors.horizontalCenter: parent.horizontalCenter
                 anchors.horizontalCenter: parent.horizontalCenter
-                text: "Continue"
+                text: qsTr("Continue")
                 font.pointSize: 14
                 font.pointSize: 14
                 focusPolicy: Qt.NoFocus
                 focusPolicy: Qt.NoFocus
                 onClicked: {
                 onClicked: {

+ 15 - 15
ui/qml/LoadGamePanel.qml

@@ -114,7 +114,7 @@ Item {
                 spacing: Theme.spacingMedium
                 spacing: Theme.spacingMedium
 
 
                 Label {
                 Label {
-                    text: "Load Game"
+                    text: qsTr("Load Game")
                     color: Theme.textMain
                     color: Theme.textMain
                     font.pointSize: Theme.fontSizeHero
                     font.pointSize: Theme.fontSizeHero
                     font.bold: true
                     font.bold: true
@@ -122,7 +122,7 @@ Item {
                 }
                 }
 
 
                 Button {
                 Button {
-                    text: "Cancel"
+                    text: qsTr("Cancel")
                     onClicked: root.cancelled()
                     onClicked: root.cancelled()
                 }
                 }
 
 
@@ -161,7 +161,7 @@ Item {
                                 clear();
                                 clear();
                                 if (typeof game === 'undefined' || !game.getSaveSlots) {
                                 if (typeof game === 'undefined' || !game.getSaveSlots) {
                                     append({
                                     append({
-                                        "slotName": "No saves found",
+                                        "slotName": qsTr("No saves found"),
                                         "title": "",
                                         "title": "",
                                         "timestamp": 0,
                                         "timestamp": 0,
                                         "mapName": "",
                                         "mapName": "",
@@ -185,7 +185,7 @@ Item {
                                 }
                                 }
                                 if (count === 0)
                                 if (count === 0)
                                     append({
                                     append({
-                                    "slotName": "No saves found",
+                                    "slotName": qsTr("No saves found"),
                                     "title": "",
                                     "title": "",
                                     "timestamp": 0,
                                     "timestamp": 0,
                                     "mapName": "",
                                     "mapName": "",
@@ -240,7 +240,7 @@ Item {
                                     Label {
                                     Label {
                                         anchors.centerIn: parent
                                         anchors.centerIn: parent
                                         visible: !loadThumbnailImage.visible
                                         visible: !loadThumbnailImage.visible
-                                        text: "No Preview"
+                                        text: qsTr("No Preview")
                                         color: Theme.textHint
                                         color: Theme.textHint
                                         font.pointSize: Theme.fontSizeTiny
                                         font.pointSize: Theme.fontSizeTiny
                                     }
                                     }
@@ -262,7 +262,7 @@ Item {
                                     }
                                     }
 
 
                                     Label {
                                     Label {
-                                        text: "Slot: " + model.slotName
+                                        text: qsTr("Slot: %1").arg(model.slotName)
                                         color: Theme.textSub
                                         color: Theme.textSub
                                         font.pointSize: Theme.fontSizeSmall
                                         font.pointSize: Theme.fontSizeSmall
                                         Layout.fillWidth: true
                                         Layout.fillWidth: true
@@ -282,7 +282,7 @@ Item {
                                         spacing: Theme.spacingLarge
                                         spacing: Theme.spacingLarge
 
 
                                         Label {
                                         Label {
-                                            text: "Last saved: " + Qt.formatDateTime(new Date(model.timestamp), "yyyy-MM-dd hh:mm:ss")
+                                            text: qsTr("Last saved: %1").arg(Qt.formatDateTime(new Date(model.timestamp), "yyyy-MM-dd hh:mm:ss"))
                                             color: Theme.textHint
                                             color: Theme.textHint
                                             font.pointSize: Theme.fontSizeSmall
                                             font.pointSize: Theme.fontSizeSmall
                                             Layout.fillWidth: true
                                             Layout.fillWidth: true
@@ -290,7 +290,7 @@ Item {
                                         }
                                         }
 
 
                                         Label {
                                         Label {
-                                            text: model.playTime !== "" ? "Play time: " + model.playTime : ""
+                                            text: model.playTime !== "" ? qsTr("Play time: %1").arg(model.playTime) : ""
                                             color: Theme.textHint
                                             color: Theme.textHint
                                             font.pointSize: Theme.fontSizeSmall
                                             font.pointSize: Theme.fontSizeSmall
                                             visible: model.playTime !== ""
                                             visible: model.playTime !== ""
@@ -310,7 +310,7 @@ Item {
                                 }
                                 }
 
 
                                 Button {
                                 Button {
-                                    text: "Load"
+                                    text: qsTr("Load")
                                     highlighted: true
                                     highlighted: true
                                     visible: !model.isEmpty
                                     visible: !model.isEmpty
                                     onClicked: {
                                     onClicked: {
@@ -319,7 +319,7 @@ Item {
                                 }
                                 }
 
 
                                 Button {
                                 Button {
-                                    text: "Delete"
+                                    text: qsTr("Delete")
                                     visible: !model.isEmpty
                                     visible: !model.isEmpty
                                     onClicked: {
                                     onClicked: {
                                         confirmDeleteDialog.slotName = model.slotName;
                                         confirmDeleteDialog.slotName = model.slotName;
@@ -363,13 +363,13 @@ Item {
                 }
                 }
 
 
                 Label {
                 Label {
-                    text: loadListView.selectedIndex >= 0 && !loadListModel.get(loadListView.selectedIndex).isEmpty ? "Selected: " + loadListModel.get(loadListView.selectedIndex).title : "Select a save to load"
+                    text: loadListView.selectedIndex >= 0 && !loadListModel.get(loadListView.selectedIndex).isEmpty ? qsTr("Selected: %1").arg(loadListModel.get(loadListView.selectedIndex).title) : qsTr("Select a save to load")
                     color: Theme.textSub
                     color: Theme.textSub
                     font.pointSize: Theme.fontSizeMedium
                     font.pointSize: Theme.fontSizeMedium
                 }
                 }
 
 
                 Button {
                 Button {
-                    text: "Load Selected"
+                    text: qsTr("Load Selected")
                     enabled: loadListView.selectedIndex >= 0 && !loadListModel.get(loadListView.selectedIndex).isEmpty
                     enabled: loadListView.selectedIndex >= 0 && !loadListModel.get(loadListView.selectedIndex).isEmpty
                     highlighted: true
                     highlighted: true
                     onClicked: {
                     onClicked: {
@@ -393,7 +393,7 @@ Item {
 
 
         anchors.centerIn: parent
         anchors.centerIn: parent
         width: Math.min(parent.width * 0.5, 400)
         width: Math.min(parent.width * 0.5, 400)
-        title: "Confirm Delete"
+        title: qsTr("Confirm Delete")
         modal: true
         modal: true
         standardButtons: Dialog.Yes | Dialog.No
         standardButtons: Dialog.Yes | Dialog.No
         onAccepted: {
         onAccepted: {
@@ -402,7 +402,7 @@ Item {
                     loadListModel.remove(slotIndex);
                     loadListModel.remove(slotIndex);
                     if (loadListModel.count === 0)
                     if (loadListModel.count === 0)
                         loadListModel.append({
                         loadListModel.append({
-                        "slotName": "No saves found",
+                        "slotName": qsTr("No saves found"),
                         "title": "",
                         "title": "",
                         "timestamp": 0,
                         "timestamp": 0,
                         "mapName": "",
                         "mapName": "",
@@ -430,7 +430,7 @@ Item {
                 Label {
                 Label {
                     id: warningText
                     id: warningText
 
 
-                    text: "Are you sure you want to delete the save:\n\"" + confirmDeleteDialog.slotName + "\"?\n\nThis action cannot be undone."
+                    text: qsTr("Are you sure you want to delete the save:\n\"%1\"?\n\nThis action cannot be undone.").arg(confirmDeleteDialog.slotName)
                     color: Theme.textMain
                     color: Theme.textMain
                     wrapMode: Text.WordWrap
                     wrapMode: Text.WordWrap
                     Layout.fillWidth: true
                     Layout.fillWidth: true

+ 3 - 3
ui/qml/Main.qml

@@ -15,7 +15,7 @@ ApplicationWindow {
     height: 720
     height: 720
     visibility: Window.FullScreen
     visibility: Window.FullScreen
     visible: true
     visible: true
-    title: "Standard of Iron - RTS Game"
+    title: qsTr("Standard of Iron - RTS Game")
 
 
     GameView {
     GameView {
         id: gameViewItem
         id: gameViewItem
@@ -89,7 +89,7 @@ ApplicationWindow {
                 spacing: 20
                 spacing: 20
 
 
                 Text {
                 Text {
-                    text: "PAUSED"
+                    text: qsTr("PAUSED")
                     color: "#ecf0f1"
                     color: "#ecf0f1"
                     font.pixelSize: 36
                     font.pixelSize: 36
                     font.bold: true
                     font.bold: true
@@ -97,7 +97,7 @@ ApplicationWindow {
                 }
                 }
 
 
                 Text {
                 Text {
-                    text: "Press Space to resume"
+                    text: qsTr("Press Space to resume")
                     color: "#bdc3c7"
                     color: "#bdc3c7"
                     font.pixelSize: 14
                     font.pixelSize: 14
                     anchors.horizontalCenter: parent.horizontalCenter
                     anchors.horizontalCenter: parent.horizontalCenter

+ 20 - 20
ui/qml/MainMenu.qml

@@ -81,7 +81,7 @@ Item {
                     spacing: Theme.spacingSmall
                     spacing: Theme.spacingSmall
 
 
                     Label {
                     Label {
-                        text: "STANDARD OF IRON"
+                        text: qsTr("STANDARD OF IRON")
                         color: Theme.textMain
                         color: Theme.textMain
                         font.pointSize: Theme.fontSizeHero
                         font.pointSize: Theme.fontSizeHero
                         font.bold: true
                         font.bold: true
@@ -91,7 +91,7 @@ Item {
                     }
                     }
 
 
                     Label {
                     Label {
-                        text: "A tiny but ambitious RTS"
+                        text: qsTr("A tiny but ambitious RTS")
                         color: Theme.textSub
                         color: Theme.textSub
                         font.pointSize: Theme.fontSizeMedium
                         font.pointSize: Theme.fontSizeMedium
                         horizontalAlignment: Text.AlignLeft
                         horizontalAlignment: Text.AlignLeft
@@ -106,32 +106,32 @@ Item {
 
 
                     ListElement {
                     ListElement {
                         idStr: "skirmish"
                         idStr: "skirmish"
-                        title: "Play — Skirmish"
-                        subtitle: "Select a map and start"
+                        title: QT_TR_NOOP("Play — Skirmish")
+                        subtitle: QT_TR_NOOP("Select a map and start")
                     }
                     }
 
 
                     ListElement {
                     ListElement {
                         idStr: "save"
                         idStr: "save"
-                        title: "Save Game"
-                        subtitle: "Save your current progress"
+                        title: QT_TR_NOOP("Save Game")
+                        subtitle: QT_TR_NOOP("Save your current progress")
                     }
                     }
 
 
                     ListElement {
                     ListElement {
                         idStr: "load"
                         idStr: "load"
-                        title: "Load Game"
-                        subtitle: "Resume a previous game"
+                        title: QT_TR_NOOP("Load Game")
+                        subtitle: QT_TR_NOOP("Resume a previous game")
                     }
                     }
 
 
                     ListElement {
                     ListElement {
                         idStr: "settings"
                         idStr: "settings"
-                        title: "Settings"
-                        subtitle: "Adjust graphics & controls"
+                        title: QT_TR_NOOP("Settings")
+                        subtitle: QT_TR_NOOP("Adjust graphics & controls")
                     }
                     }
 
 
                     ListElement {
                     ListElement {
                         idStr: "exit"
                         idStr: "exit"
-                        title: "Exit"
-                        subtitle: "Quit the game"
+                        title: QT_TR_NOOP("Exit")
+                        subtitle: QT_TR_NOOP("Quit the game")
                     }
                     }
 
 
                 }
                 }
@@ -170,7 +170,7 @@ Item {
                                     spacing: Theme.spacingTiny
                                     spacing: Theme.spacingTiny
 
 
                                     Text {
                                     Text {
-                                        text: model.title
+                                        text: qsTr(model.title)
                                         Layout.fillWidth: true
                                         Layout.fillWidth: true
                                         elide: Text.ElideRight
                                         elide: Text.ElideRight
                                         color: container.selectedIndex === idx ? Theme.textMain : Theme.textBright
                                         color: container.selectedIndex === idx ? Theme.textMain : Theme.textBright
@@ -179,7 +179,7 @@ Item {
                                     }
                                     }
 
 
                                     Text {
                                     Text {
-                                        text: model.subtitle
+                                        text: qsTr(model.subtitle)
                                         Layout.fillWidth: true
                                         Layout.fillWidth: true
                                         elide: Text.ElideRight
                                         elide: Text.ElideRight
                                         color: container.selectedIndex === idx ? Theme.accentBright : Theme.textSubLite
                                         color: container.selectedIndex === idx ? Theme.accentBright : Theme.textSubLite
@@ -246,7 +246,7 @@ Item {
                     spacing: Theme.spacingSmall
                     spacing: Theme.spacingSmall
 
 
                     Label {
                     Label {
-                        text: "v0.9 — prototype"
+                        text: qsTr("v0.9 — prototype")
                         color: Theme.textDim
                         color: Theme.textDim
                         font.pointSize: Theme.fontSizeSmall
                         font.pointSize: Theme.fontSizeSmall
                     }
                     }
@@ -292,7 +292,7 @@ Item {
                             spacing: Theme.spacingSmall
                             spacing: Theme.spacingSmall
 
 
                             Label {
                             Label {
-                                text: "Featured"
+                                text: qsTr("Featured")
                                 color: Theme.accent
                                 color: Theme.accent
                                 font.pointSize: Theme.fontSizeMedium
                                 font.pointSize: Theme.fontSizeMedium
                                 Layout.fillWidth: true
                                 Layout.fillWidth: true
@@ -300,7 +300,7 @@ Item {
                             }
                             }
 
 
                             Label {
                             Label {
-                                text: "Skirmish Mode"
+                                text: qsTr("Skirmish Mode")
                                 color: Theme.textMain
                                 color: Theme.textMain
                                 font.pointSize: Theme.fontSizeTitle
                                 font.pointSize: Theme.fontSizeTitle
                                 font.bold: true
                                 font.bold: true
@@ -309,7 +309,7 @@ Item {
                             }
                             }
 
 
                             Text {
                             Text {
-                                text: "Pick a map, adjust your forces and jump into battle. Modern controls and responsive UI."
+                                text: qsTr("Pick a map, adjust your forces and jump into battle. Modern controls and responsive UI.")
                                 color: Theme.textSubLite
                                 color: Theme.textSubLite
                                 wrapMode: Text.WordWrap
                                 wrapMode: Text.WordWrap
                                 maximumLineCount: 3
                                 maximumLineCount: 3
@@ -335,7 +335,7 @@ Item {
                             spacing: Theme.spacingSmall
                             spacing: Theme.spacingSmall
 
 
                             Label {
                             Label {
-                                text: "Tips"
+                                text: qsTr("Tips")
                                 color: Theme.accent
                                 color: Theme.accent
                                 font.pointSize: Theme.fontSizeMedium
                                 font.pointSize: Theme.fontSizeMedium
                                 Layout.fillWidth: true
                                 Layout.fillWidth: true
@@ -343,7 +343,7 @@ Item {
                             }
                             }
 
 
                             Text {
                             Text {
-                                text: "Hover menu items or use Up/Down and Enter to navigate. Play opens map selection."
+                                text: qsTr("Hover menu items or use Up/Down and Enter to navigate. Play opens map selection.")
                                 color: Theme.textSubLite
                                 color: Theme.textSubLite
                                 wrapMode: Text.WordWrap
                                 wrapMode: Text.WordWrap
                                 maximumLineCount: 3
                                 maximumLineCount: 3

+ 19 - 19
ui/qml/MapSelect.qml

@@ -268,7 +268,7 @@ Item {
             Text {
             Text {
                 id: leftTitle
                 id: leftTitle
 
 
-                text: "Maps"
+                text: qsTr("Maps")
                 color: Theme.textMain
                 color: Theme.textMain
                 font.pixelSize: 20
                 font.pixelSize: 20
                 font.bold: true
                 font.bold: true
@@ -483,7 +483,7 @@ Item {
                 visible: list.count === 0 && !mapsLoading
                 visible: list.count === 0 && !mapsLoading
 
 
                 Text {
                 Text {
-                    text: "No maps available"
+                    text: qsTr("No maps available")
                     color: Theme.textSub
                     color: Theme.textSub
                     font.pixelSize: 14
                     font.pixelSize: 14
                     anchors.centerIn: parent
                     anchors.centerIn: parent
@@ -516,7 +516,7 @@ Item {
                     }
                     }
 
 
                     Text {
                     Text {
-                        text: "Loading maps..."
+                        text: qsTr("Loading maps...")
                         color: Theme.textSub
                         color: Theme.textSub
                         font.pixelSize: 12
                         font.pixelSize: 12
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
@@ -545,7 +545,7 @@ Item {
             Text {
             Text {
                 id: breadcrumb
                 id: breadcrumb
 
 
-                text: selectedMapData ? "► " + field(selectedMapData, "name") : "Select a map to continue"
+                text: selectedMapData ? qsTr("► %1").arg(field(selectedMapData, "name")) : qsTr("Select a map to continue")
                 color: selectedMapData ? Theme.accent : Theme.textHint
                 color: selectedMapData ? Theme.accent : Theme.textHint
                 font.pixelSize: 13
                 font.pixelSize: 13
                 font.italic: !selectedMapData
                 font.italic: !selectedMapData
@@ -593,7 +593,7 @@ Item {
                     }
                     }
 
 
                     Text {
                     Text {
-                        text: "Loading maps..."
+                        text: qsTr("Loading maps...")
                         color: Theme.textSub
                         color: Theme.textSub
                         font.pixelSize: 14
                         font.pixelSize: 14
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
@@ -700,7 +700,7 @@ Item {
                     }
                     }
 
 
                     Text {
                     Text {
-                        text: "Loading map details..."
+                        text: qsTr("Loading map details...")
                         color: Theme.textHint
                         color: Theme.textHint
                         font.pixelSize: 12
                         font.pixelSize: 12
                         font.italic: true
                         font.italic: true
@@ -717,7 +717,7 @@ Item {
                 text: {
                 text: {
                     var it = selectedMapData;
                     var it = selectedMapData;
                     var t = field(it, "name");
                     var t = field(it, "name");
-                    return t || field(it, "path") || "No Map Selected";
+                    return t || field(it, "path") || qsTr("No Map Selected");
                 }
                 }
                 visible: selectedMapData !== null
                 visible: selectedMapData !== null
                 color: Theme.textMain
                 color: Theme.textMain
@@ -783,7 +783,7 @@ Item {
                         spacing: Theme.spacingSmall + 2
                         spacing: Theme.spacingSmall + 2
 
 
                         Text {
                         Text {
-                            text: "Players"
+                            text: qsTr("Players")
                             color: Theme.textMain
                             color: Theme.textMain
                             font.pixelSize: 17
                             font.pixelSize: 17
                             font.bold: true
                             font.bold: true
@@ -807,7 +807,7 @@ Item {
                         }
                         }
 
 
                         Text {
                         Text {
-                            text: "• Click color/team to cycle"
+                            text: qsTr("• Click color/team to cycle")
                             color: Theme.textSubLite
                             color: Theme.textSubLite
                             font.pixelSize: 11
                             font.pixelSize: 11
                             font.italic: true
                             font.italic: true
@@ -885,7 +885,7 @@ Item {
                                         border.color: model.colorHex || Theme.textDim
                                         border.color: model.colorHex || Theme.textDim
                                         border.width: colorMA.containsMouse ? 3 : 2
                                         border.width: colorMA.containsMouse ? 3 : 2
                                         ToolTip.visible: colorMA.containsMouse
                                         ToolTip.visible: colorMA.containsMouse
-                                        ToolTip.text: "Player color: " + (model.colorName || "Color") + " - Click to change"
+                                        ToolTip.text: qsTr("Player color: %1 - Click to change").arg(model.colorName || qsTr("Color"))
 
 
                                         Rectangle {
                                         Rectangle {
                                             anchors.fill: parent
                                             anchors.fill: parent
@@ -947,7 +947,7 @@ Item {
                                         border.color: teamMA.containsMouse ? Theme.selectedBr : Theme.thumbBr
                                         border.color: teamMA.containsMouse ? Theme.selectedBr : Theme.thumbBr
                                         border.width: teamMA.containsMouse ? 2 : 1
                                         border.width: teamMA.containsMouse ? 2 : 1
                                         ToolTip.visible: teamMA.containsMouse
                                         ToolTip.visible: teamMA.containsMouse
-                                        ToolTip.text: "Team " + (model.teamId || 0) + " - Click to change"
+                                        ToolTip.text: qsTr("Team %1 - Click to change").arg(model.teamId || 0)
 
 
                                         Column {
                                         Column {
                                             anchors.centerIn: parent
                                             anchors.centerIn: parent
@@ -963,7 +963,7 @@ Item {
 
 
                                             Text {
                                             Text {
                                                 anchors.horizontalCenter: parent.horizontalCenter
                                                 anchors.horizontalCenter: parent.horizontalCenter
-                                                text: "Team " + (model.teamId || 0)
+                                                text: qsTr("Team %1").arg(model.teamId || 0)
                                                 color: Theme.textBright
                                                 color: Theme.textBright
                                                 font.pixelSize: 10
                                                 font.pixelSize: 10
                                                 font.bold: true
                                                 font.bold: true
@@ -1013,7 +1013,7 @@ Item {
                                         border.width: removeMA.containsMouse ? 2 : 1
                                         border.width: removeMA.containsMouse ? 2 : 1
                                         visible: !model.isHuman
                                         visible: !model.isHuman
                                         ToolTip.visible: removeMA.containsMouse
                                         ToolTip.visible: removeMA.containsMouse
-                                        ToolTip.text: "Remove player"
+                                        ToolTip.text: qsTr("Remove player")
 
 
                                         Text {
                                         Text {
                                             anchors.centerIn: parent
                                             anchors.centerIn: parent
@@ -1084,14 +1084,14 @@ Item {
                     }
                     }
 
 
                     Button {
                     Button {
-                        text: "+ Add CPU"
+                        text: qsTr("+ Add CPU")
                         enabled: playersModel.count < (selectedMapData && selectedMapData.playerIds ? selectedMapData.playerIds.length : 0)
                         enabled: playersModel.count < (selectedMapData && selectedMapData.playerIds ? selectedMapData.playerIds.length : 0)
                         onClicked: addCPU()
                         onClicked: addCPU()
                         hoverEnabled: true
                         hoverEnabled: true
                         implicitHeight: 38
                         implicitHeight: 38
                         implicitWidth: 120
                         implicitWidth: 120
                         ToolTip.visible: addCpuHover.containsMouse && parent.enabled
                         ToolTip.visible: addCpuHover.containsMouse && parent.enabled
-                        ToolTip.text: "Add AI opponent"
+                        ToolTip.text: qsTr("Add AI opponent")
 
 
                         MouseArea {
                         MouseArea {
                             id: addCpuHover
                             id: addCpuHover
@@ -1321,13 +1321,13 @@ Item {
             }
             }
 
 
             Button {
             Button {
-                text: "Back"
+                text: qsTr("Back")
                 onClicked: root.cancelled()
                 onClicked: root.cancelled()
                 hoverEnabled: true
                 hoverEnabled: true
                 implicitHeight: 42
                 implicitHeight: 42
                 implicitWidth: 120
                 implicitWidth: 120
                 ToolTip.visible: backHover.containsMouse
                 ToolTip.visible: backHover.containsMouse
-                ToolTip.text: "Return to main menu (Esc)"
+                ToolTip.text: qsTr("Return to main menu (Esc)")
 
 
                 anchors {
                 anchors {
                     left: parent.left
                     left: parent.left
@@ -1401,14 +1401,14 @@ Item {
             }
             }
 
 
             Button {
             Button {
-                text: "Play"
+                text: qsTr("Play")
                 enabled: list.currentIndex >= 0 && list.count > 0 && playersModel.count >= 2
                 enabled: list.currentIndex >= 0 && list.count > 0 && playersModel.count >= 2
                 onClicked: acceptSelection()
                 onClicked: acceptSelection()
                 hoverEnabled: true
                 hoverEnabled: true
                 implicitHeight: 42
                 implicitHeight: 42
                 implicitWidth: 130
                 implicitWidth: 130
                 ToolTip.visible: playHover.containsMouse && parent.enabled
                 ToolTip.visible: playHover.containsMouse && parent.enabled
-                ToolTip.text: "Start game (Enter)"
+                ToolTip.text: qsTr("Start game (Enter)")
 
 
                 anchors {
                 anchors {
                     right: parent.right
                     right: parent.right

+ 14 - 14
ui/qml/ProductionPanel.qml

@@ -53,7 +53,7 @@ Rectangle {
 
 
                     Text {
                     Text {
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
-                        text: "PRODUCTION QUEUE"
+                        text: qsTr("PRODUCTION QUEUE")
                         color: "#3498db"
                         color: "#3498db"
                         font.pointSize: 8
                         font.pointSize: 8
                         font.bold: true
                         font.bold: true
@@ -207,7 +207,7 @@ Rectangle {
 
 
                     Text {
                     Text {
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
-                        text: "Units Produced: " + (productionContent.prod.producedCount || 0) + " / " + (productionContent.prod.maxUnits || 0)
+                        text: qsTr("Units Produced: %1 / %2").arg(productionContent.prod.producedCount || 0).arg(productionContent.prod.maxUnits || 0)
                         color: (productionContent.prod.producedCount >= productionContent.prod.maxUnits) ? "#e74c3c" : "#bdc3c7"
                         color: (productionContent.prod.producedCount >= productionContent.prod.maxUnits) ? "#e74c3c" : "#bdc3c7"
                         font.pointSize: 8
                         font.pointSize: 8
                     }
                     }
@@ -240,7 +240,7 @@ Rectangle {
 
 
                     Text {
                     Text {
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
-                        text: "RECRUIT UNITS"
+                        text: qsTr("RECRUIT UNITS")
                         color: "#3498db"
                         color: "#3498db"
                         font.pointSize: 8
                         font.pointSize: 8
                         font.bold: true
                         font.bold: true
@@ -277,7 +277,7 @@ Rectangle {
 
 
                                 Text {
                                 Text {
                                     anchors.horizontalCenter: parent.horizontalCenter
                                     anchors.horizontalCenter: parent.horizontalCenter
-                                    text: "Archer"
+                                    text: qsTr("Archer")
                                     color: parent.parent.parent.isEnabled ? "#ecf0f1" : "#5a5a5a"
                                     color: parent.parent.parent.isEnabled ? "#ecf0f1" : "#5a5a5a"
                                     font.pointSize: 10
                                     font.pointSize: 10
                                     font.bold: true
                                     font.bold: true
@@ -313,7 +313,7 @@ Rectangle {
                                 onClicked: productionPanel.recruitUnit("archer")
                                 onClicked: productionPanel.recruitUnit("archer")
                                 cursorShape: parent.isEnabled ? Qt.PointingHandCursor : Qt.ForbiddenCursor
                                 cursorShape: parent.isEnabled ? Qt.PointingHandCursor : Qt.ForbiddenCursor
                                 ToolTip.visible: containsMouse
                                 ToolTip.visible: containsMouse
-                                ToolTip.text: parent.isEnabled ? "Recruit Archer\nCost: " + (unitGridContent.prod.villagerCost || 1) + " villagers\nBuild time: " + (unitGridContent.prod.buildTime || 0).toFixed(0) + "s" : (parent.queueTotal >= 5 ? "Queue is full (5/5)" : (unitGridContent.prod.producedCount >= unitGridContent.prod.maxUnits ? "Unit cap reached" : "Cannot recruit"))
+                                ToolTip.text: parent.isEnabled ? qsTr("Recruit Archer\nCost: %1 villagers\nBuild time: %2s").arg(unitGridContent.prod.villagerCost || 1).arg((unitGridContent.prod.buildTime || 0).toFixed(0)) : (parent.queueTotal >= 5 ? qsTr("Queue is full (5/5)") : (unitGridContent.prod.producedCount >= unitGridContent.prod.maxUnits ? qsTr("Unit cap reached") : qsTr("Cannot recruit")))
                                 ToolTip.delay: 300
                                 ToolTip.delay: 300
                             }
                             }
 
 
@@ -351,7 +351,7 @@ Rectangle {
 
 
                                 Text {
                                 Text {
                                     anchors.horizontalCenter: parent.horizontalCenter
                                     anchors.horizontalCenter: parent.horizontalCenter
-                                    text: "Knight"
+                                    text: qsTr("Knight")
                                     color: parent.parent.parent.isEnabled ? "#ecf0f1" : "#5a5a5a"
                                     color: parent.parent.parent.isEnabled ? "#ecf0f1" : "#5a5a5a"
                                     font.pointSize: 10
                                     font.pointSize: 10
                                     font.bold: true
                                     font.bold: true
@@ -387,7 +387,7 @@ Rectangle {
                                 onClicked: productionPanel.recruitUnit("knight")
                                 onClicked: productionPanel.recruitUnit("knight")
                                 cursorShape: parent.isEnabled ? Qt.PointingHandCursor : Qt.ForbiddenCursor
                                 cursorShape: parent.isEnabled ? Qt.PointingHandCursor : Qt.ForbiddenCursor
                                 ToolTip.visible: containsMouse
                                 ToolTip.visible: containsMouse
-                                ToolTip.text: parent.isEnabled ? "Recruit Knight\nCost: " + (unitGridContent.prod.villagerCost || 1) + " villagers\nBuild time: " + (unitGridContent.prod.buildTime || 0).toFixed(0) + "s" : (parent.queueTotal >= 5 ? "Queue is full (5/5)" : (unitGridContent.prod.producedCount >= unitGridContent.prod.maxUnits ? "Unit cap reached" : "Cannot recruit"))
+                                ToolTip.text: parent.isEnabled ? qsTr("Recruit Knight\nCost: %1 villagers\nBuild time: %2s").arg(unitGridContent.prod.villagerCost || 1).arg((unitGridContent.prod.buildTime || 0).toFixed(0)) : (parent.queueTotal >= 5 ? qsTr("Queue is full (5/5)") : (unitGridContent.prod.producedCount >= unitGridContent.prod.maxUnits ? qsTr("Unit cap reached") : qsTr("Cannot recruit")))
                                 ToolTip.delay: 300
                                 ToolTip.delay: 300
                             }
                             }
 
 
@@ -425,7 +425,7 @@ Rectangle {
 
 
                                 Text {
                                 Text {
                                     anchors.horizontalCenter: parent.horizontalCenter
                                     anchors.horizontalCenter: parent.horizontalCenter
-                                    text: "Spearman"
+                                    text: qsTr("Spearman")
                                     color: parent.parent.parent.isEnabled ? "#ecf0f1" : "#5a5a5a"
                                     color: parent.parent.parent.isEnabled ? "#ecf0f1" : "#5a5a5a"
                                     font.pointSize: 10
                                     font.pointSize: 10
                                     font.bold: true
                                     font.bold: true
@@ -461,7 +461,7 @@ Rectangle {
                                 onClicked: productionPanel.recruitUnit("spearman")
                                 onClicked: productionPanel.recruitUnit("spearman")
                                 cursorShape: parent.isEnabled ? Qt.PointingHandCursor : Qt.ForbiddenCursor
                                 cursorShape: parent.isEnabled ? Qt.PointingHandCursor : Qt.ForbiddenCursor
                                 ToolTip.visible: containsMouse
                                 ToolTip.visible: containsMouse
-                                ToolTip.text: parent.isEnabled ? "Recruit Spearman\nCost: " + (unitGridContent.prod.villagerCost || 1) + " villagers\nBuild time: " + (unitGridContent.prod.buildTime || 0).toFixed(0) + "s" : (parent.queueTotal >= 5 ? "Queue is full (5/5)" : (unitGridContent.prod.producedCount >= unitGridContent.prod.maxUnits ? "Unit cap reached" : "Cannot recruit"))
+                                ToolTip.text: parent.isEnabled ? qsTr("Recruit Spearman\nCost: %1 villagers\nBuild time: %2s").arg(unitGridContent.prod.villagerCost || 1).arg((unitGridContent.prod.buildTime || 0).toFixed(0)) : (parent.queueTotal >= 5 ? qsTr("Queue is full (5/5)") : (unitGridContent.prod.producedCount >= unitGridContent.prod.maxUnits ? qsTr("Unit cap reached") : qsTr("Cannot recruit")))
                                 ToolTip.delay: 300
                                 ToolTip.delay: 300
                             }
                             }
 
 
@@ -515,12 +515,12 @@ Rectangle {
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
                         width: parent.parent.width - 20
                         width: parent.parent.width - 20
                         height: 32
                         height: 32
-                        text: (typeof gameView !== 'undefined' && gameView.setRallyMode) ? "📍 Click Map to Set Rally" : "📍 Set Rally Point"
+                        text: (typeof gameView !== 'undefined' && gameView.setRallyMode) ? qsTr("📍 Click Map to Set Rally") : qsTr("📍 Set Rally Point")
                         focusPolicy: Qt.NoFocus
                         focusPolicy: Qt.NoFocus
                         enabled: rallyContent.prod.hasBarracks
                         enabled: rallyContent.prod.hasBarracks
                         onClicked: productionPanel.rallyModeToggled()
                         onClicked: productionPanel.rallyModeToggled()
                         ToolTip.visible: hovered
                         ToolTip.visible: hovered
-                        ToolTip.text: "Set where newly recruited units will gather.\nRight-click to cancel."
+                        ToolTip.text: qsTr("Set where newly recruited units will gather.\nRight-click to cancel.")
                         ToolTip.delay: 500
                         ToolTip.delay: 500
 
 
                         background: Rectangle {
                         background: Rectangle {
@@ -543,7 +543,7 @@ Rectangle {
 
 
                     Text {
                     Text {
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
-                        text: (typeof gameView !== 'undefined' && gameView.setRallyMode) ? "Right-click to cancel" : ""
+                        text: (typeof gameView !== 'undefined' && gameView.setRallyMode) ? qsTr("Right-click to cancel") : ""
                         color: "#7f8c8d"
                         color: "#7f8c8d"
                         font.pointSize: 8
                         font.pointSize: 8
                         font.italic: true
                         font.italic: true
@@ -580,7 +580,7 @@ Rectangle {
 
 
                     Text {
                     Text {
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
-                        text: "No Barracks Selected"
+                        text: qsTr("No Barracks Selected")
                         color: "#7f8c8d"
                         color: "#7f8c8d"
                         font.pointSize: 11
                         font.pointSize: 11
                         font.bold: true
                         font.bold: true
@@ -588,7 +588,7 @@ Rectangle {
 
 
                     Text {
                     Text {
                         anchors.horizontalCenter: parent.horizontalCenter
                         anchors.horizontalCenter: parent.horizontalCenter
-                        text: "Select a barracks to recruit units"
+                        text: qsTr("Select a barracks to recruit units")
                         color: "#5a6c7d"
                         color: "#5a6c7d"
                         font.pointSize: 9
                         font.pointSize: 9
                     }
                     }

+ 12 - 12
ui/qml/SaveGamePanel.qml

@@ -69,7 +69,7 @@ Item {
                 spacing: Theme.spacingMedium
                 spacing: Theme.spacingMedium
 
 
                 Label {
                 Label {
-                    text: "Save Game"
+                    text: qsTr("Save Game")
                     color: Theme.textMain
                     color: Theme.textMain
                     font.pointSize: Theme.fontSizeHero
                     font.pointSize: Theme.fontSizeHero
                     font.bold: true
                     font.bold: true
@@ -77,7 +77,7 @@ Item {
                 }
                 }
 
 
                 Button {
                 Button {
-                    text: "Cancel"
+                    text: qsTr("Cancel")
                     onClicked: root.cancelled()
                     onClicked: root.cancelled()
                 }
                 }
 
 
@@ -94,7 +94,7 @@ Item {
                 spacing: Theme.spacingMedium
                 spacing: Theme.spacingMedium
 
 
                 Label {
                 Label {
-                    text: "Save Name:"
+                    text: qsTr("Save Name:")
                     color: Theme.textSub
                     color: Theme.textSub
                     font.pointSize: Theme.fontSizeMedium
                     font.pointSize: Theme.fontSizeMedium
                 }
                 }
@@ -103,7 +103,7 @@ Item {
                     id: saveNameField
                     id: saveNameField
 
 
                     Layout.fillWidth: true
                     Layout.fillWidth: true
-                    placeholderText: "Enter save name..."
+                    placeholderText: qsTr("Enter save name...")
                     text: "Save_" + Qt.formatDateTime(new Date(), "yyyy-MM-dd_HH-mm")
                     text: "Save_" + Qt.formatDateTime(new Date(), "yyyy-MM-dd_HH-mm")
                     font.pointSize: Theme.fontSizeMedium
                     font.pointSize: Theme.fontSizeMedium
                     color: Theme.textMain
                     color: Theme.textMain
@@ -118,7 +118,7 @@ Item {
                 }
                 }
 
 
                 Button {
                 Button {
-                    text: "Save"
+                    text: qsTr("Save")
                     enabled: saveNameField.text.length > 0
                     enabled: saveNameField.text.length > 0
                     highlighted: true
                     highlighted: true
                     onClicked: {
                     onClicked: {
@@ -134,7 +134,7 @@ Item {
             }
             }
 
 
             Label {
             Label {
-                text: "Existing Saves"
+                text: qsTr("Existing Saves")
                 color: Theme.textSub
                 color: Theme.textSub
                 font.pointSize: Theme.fontSizeMedium
                 font.pointSize: Theme.fontSizeMedium
             }
             }
@@ -228,7 +228,7 @@ Item {
                                     Label {
                                     Label {
                                         anchors.centerIn: parent
                                         anchors.centerIn: parent
                                         visible: !thumbnailImage.visible
                                         visible: !thumbnailImage.visible
-                                        text: "No Preview"
+                                        text: qsTr("No Preview")
                                         color: Theme.textHint
                                         color: Theme.textHint
                                         font.pointSize: Theme.fontSizeTiny
                                         font.pointSize: Theme.fontSizeTiny
                                     }
                                     }
@@ -249,7 +249,7 @@ Item {
                                     }
                                     }
 
 
                                     Label {
                                     Label {
-                                        text: "Slot: " + model.slotName
+                                        text: qsTr("Slot: %1").arg(model.slotName)
                                         color: Theme.textSub
                                         color: Theme.textSub
                                         font.pointSize: Theme.fontSizeSmall
                                         font.pointSize: Theme.fontSizeSmall
                                         Layout.fillWidth: true
                                         Layout.fillWidth: true
@@ -265,7 +265,7 @@ Item {
                                     }
                                     }
 
 
                                     Label {
                                     Label {
-                                        text: "Last saved: " + Qt.formatDateTime(new Date(model.timestamp), "yyyy-MM-dd hh:mm:ss")
+                                        text: qsTr("Last saved: %1").arg(Qt.formatDateTime(new Date(model.timestamp), "yyyy-MM-dd hh:mm:ss"))
                                         color: Theme.textHint
                                         color: Theme.textHint
                                         font.pointSize: Theme.fontSizeSmall
                                         font.pointSize: Theme.fontSizeSmall
                                         Layout.fillWidth: true
                                         Layout.fillWidth: true
@@ -275,7 +275,7 @@ Item {
                                 }
                                 }
 
 
                                 Button {
                                 Button {
-                                    text: "Overwrite"
+                                    text: qsTr("Overwrite")
                                     onClicked: {
                                     onClicked: {
                                         confirmOverwriteDialog.slotName = model.slotName;
                                         confirmOverwriteDialog.slotName = model.slotName;
                                         confirmOverwriteDialog.open();
                                         confirmOverwriteDialog.open();
@@ -313,7 +313,7 @@ Item {
 
 
         anchors.centerIn: parent
         anchors.centerIn: parent
         width: Math.min(parent.width * 0.5, 400)
         width: Math.min(parent.width * 0.5, 400)
-        title: "Confirm Overwrite"
+        title: qsTr("Confirm Overwrite")
         modal: true
         modal: true
         standardButtons: Dialog.Yes | Dialog.No
         standardButtons: Dialog.Yes | Dialog.No
         onAccepted: {
         onAccepted: {
@@ -332,7 +332,7 @@ Item {
                 Label {
                 Label {
                     id: warningText
                     id: warningText
 
 
-                    text: "Are you sure you want to overwrite the save:\n\"" + confirmOverwriteDialog.slotName + "\"?"
+                    text: qsTr("Are you sure you want to overwrite the save:\n\"%1\"?").arg(confirmOverwriteDialog.slotName)
                     color: Theme.textMain
                     color: Theme.textMain
                     wrapMode: Text.WordWrap
                     wrapMode: Text.WordWrap
                     Layout.fillWidth: true
                     Layout.fillWidth: true