Rename Fluent-related code to be more precise.

This commit is contained in:
Paul Chote
2024-10-01 19:34:12 +01:00
committed by Gustas
parent 771b9ddfda
commit b29b685058
176 changed files with 1349 additions and 1369 deletions

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Commands
public class ChatCommands : INotifyChat
{
[TranslationReference("name")]
[FluentReference("name")]
const string InvalidCommand = "notification-invalid-command";
public Dictionary<string, IChatCommand> Commands { get; }
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Commands
if (Commands.TryGetValue(name, out var command))
command.InvokeCommand(name, message[(1 + name.Length)..].Trim());
else
TextNotificationsManager.Debug(TranslationProvider.GetString(InvalidCommand, Translation.Arguments("name", name)));
TextNotificationsManager.Debug(FluentProvider.GetString(InvalidCommand, FluentBundle.Arguments("name", name)));
return false;
}

View File

@@ -23,19 +23,19 @@ namespace OpenRA.Mods.Common.Commands
public class DebugVisualizationCommands : IChatCommand, IWorldLoaded
{
[TranslationReference]
[FluentReference]
const string CombatGeometryDescription = "description-combat-geometry";
[TranslationReference]
[FluentReference]
const string RenderGeometryDescription = "description-render-geometry";
[TranslationReference]
[FluentReference]
const string ScreenMapOverlayDescription = "description-screen-map-overlay";
[TranslationReference]
[FluentReference]
const string DepthBufferDescription = "description-depth-buffer";
[TranslationReference]
[FluentReference]
const string ActorTagsOverlayDescripition = "description-actor-tags-overlay";
readonly IDictionary<string, (string Description, Action<DebugVisualizations, DeveloperMode> Handler)> commandHandlers =

View File

@@ -24,55 +24,55 @@ namespace OpenRA.Mods.Common.Commands
public class DevCommands : IChatCommand, IWorldLoaded
{
[TranslationReference]
[FluentReference]
const string CheatsDisabled = "notification-cheats-disabled";
[TranslationReference]
[FluentReference]
const string InvalidCashAmount = "notification-invalid-cash-amount";
[TranslationReference]
[FluentReference]
const string ToggleVisiblityDescription = "description-toggle-visibility";
[TranslationReference]
[FluentReference]
const string GiveCashDescription = "description-give-cash";
[TranslationReference]
[FluentReference]
const string GiveCashAllDescription = "description-give-cash-all";
[TranslationReference]
[FluentReference]
const string InstantBuildingDescription = "description-instant-building";
[TranslationReference]
[FluentReference]
const string BuildAnywhereDescription = "description-build-anywhere";
[TranslationReference]
[FluentReference]
const string UnlimitedPowerDescription = "description-unlimited-power";
[TranslationReference]
[FluentReference]
const string EnableTechDescription = "description-enable-tech";
[TranslationReference]
[FluentReference]
const string FastChargeDescription = "description-fast-charge";
[TranslationReference]
[FluentReference]
const string DevCheatAllDescription = "description-dev-cheat-all";
[TranslationReference]
[FluentReference]
const string DevCrashDescription = "description-dev-crash";
[TranslationReference]
[FluentReference]
const string LevelUpActorDescription = "description-levelup-actor";
[TranslationReference]
[FluentReference]
const string PlayerExperienceDescription = "description-player-experience";
[TranslationReference]
[FluentReference]
const string PowerOutageDescription = "description-power-outage";
[TranslationReference]
[FluentReference]
const string KillSelectedActorsDescription = "description-kill-selected-actors";
[TranslationReference]
[FluentReference]
const string DisposeSelectedActorsDescription = "description-dispose-selected-actors";
readonly IDictionary<string, (string Description, Action<string, World> Handler)> commandHandlers = new Dictionary<string, (string, Action<string, World>)>
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Commands
if (!developerMode.Enabled)
{
TextNotificationsManager.Debug(TranslationProvider.GetString(CheatsDisabled));
TextNotificationsManager.Debug(FluentProvider.GetString(CheatsDisabled));
return;
}
@@ -149,7 +149,7 @@ namespace OpenRA.Mods.Common.Commands
giveCashOrder.ExtraData = (uint)cash;
else
{
TextNotificationsManager.Debug(TranslationProvider.GetString(InvalidCashAmount));
TextNotificationsManager.Debug(FluentProvider.GetString(InvalidCashAmount));
return;
}

View File

@@ -22,13 +22,13 @@ namespace OpenRA.Mods.Common.Commands
public class HelpCommand : IChatCommand, IWorldLoaded
{
[TranslationReference]
[FluentReference]
const string AvailableCommands = "notification-available-commands";
[TranslationReference]
[FluentReference]
const string NoDescription = "description-no-description";
[TranslationReference]
[FluentReference]
const string HelpDescription = "description-help-description";
readonly Dictionary<string, string> helpDescriptions;
@@ -52,12 +52,12 @@ namespace OpenRA.Mods.Common.Commands
public void InvokeCommand(string name, string arg)
{
TextNotificationsManager.Debug(TranslationProvider.GetString(AvailableCommands));
TextNotificationsManager.Debug(FluentProvider.GetString(AvailableCommands));
foreach (var key in console.Commands.Keys.OrderBy(k => k))
{
if (!helpDescriptions.TryGetValue(key, out var description))
description = TranslationProvider.GetString(NoDescription);
description = FluentProvider.GetString(NoDescription);
TextNotificationsManager.Debug($"{key}: {description}");
}
@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Commands
public void RegisterHelp(string name, string description)
{
helpDescriptions[name] = TranslationProvider.GetString(description);
helpDescriptions[name] = FluentProvider.GetString(description);
}
}
}

View File

@@ -20,10 +20,10 @@ namespace OpenRA.Mods.Common.Commands
public class PlayerCommands : IChatCommand, IWorldLoaded
{
[TranslationReference]
[FluentReference]
const string PauseDescription = "description-pause-description";
[TranslationReference]
[FluentReference]
const string SurrenderDescription = "description-surrender-description";
World world;

View File

@@ -143,7 +143,7 @@ namespace OpenRA.Mods.Common.Widgets
{
public string Text { get; private set; }
[TranslationReference("name", "id")]
[FluentReference("name", "id")]
const string AddedActor = "notification-added-actor";
readonly EditorActorLayer editorLayer;
@@ -167,8 +167,8 @@ namespace OpenRA.Mods.Common.Widgets
public void Do()
{
editorActorPreview = editorLayer.Add(actor);
Text = TranslationProvider.GetString(AddedActor,
Translation.Arguments("name", editorActorPreview.Info.Name, "id", editorActorPreview.ID));
Text = FluentProvider.GetString(AddedActor,
FluentBundle.Arguments("name", editorActorPreview.Info.Name, "id", editorActorPreview.ID));
}
public void Undo()

View File

@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Widgets
sealed class CopyPasteEditorAction : IEditorAction
{
[TranslationReference("amount")]
[FluentReference("amount")]
const string CopiedTiles = "notification-copied-tiles";
public string Text { get; }
@@ -146,7 +146,7 @@ namespace OpenRA.Mods.Common.Widgets
undoClipboard = CopySelectionContents();
Text = TranslationProvider.GetString(CopiedTiles, Translation.Arguments("amount", clipboard.Tiles.Count));
Text = FluentProvider.GetString(CopiedTiles, FluentBundle.Arguments("amount", clipboard.Tiles.Count));
}
/// <summary>

View File

@@ -279,13 +279,13 @@ namespace OpenRA.Mods.Common.Widgets
sealed class ChangeSelectionAction : IEditorAction
{
[TranslationReference("x", "y", "width", "height")]
[FluentReference("x", "y", "width", "height")]
const string SelectedArea = "notification-selected-area";
[TranslationReference("id")]
[FluentReference("id")]
const string SelectedActor = "notification-selected-actor";
[TranslationReference]
[FluentReference]
const string ClearedSelection = "notification-cleared-selection";
public string Text { get; }
@@ -308,15 +308,15 @@ namespace OpenRA.Mods.Common.Widgets
};
if (selection.Area != null)
Text = TranslationProvider.GetString(SelectedArea, Translation.Arguments(
Text = FluentProvider.GetString(SelectedArea, FluentBundle.Arguments(
"x", selection.Area.TopLeft.X,
"y", selection.Area.TopLeft.Y,
"width", selection.Area.BottomRight.X - selection.Area.TopLeft.X,
"height", selection.Area.BottomRight.Y - selection.Area.TopLeft.Y));
else if (selection.Actor != null)
Text = TranslationProvider.GetString(SelectedActor, Translation.Arguments("id", selection.Actor.ID));
Text = FluentProvider.GetString(SelectedActor, FluentBundle.Arguments("id", selection.Actor.ID));
else
Text = TranslationProvider.GetString(ClearedSelection);
Text = FluentProvider.GetString(ClearedSelection);
}
public void Execute()
@@ -337,7 +337,7 @@ namespace OpenRA.Mods.Common.Widgets
sealed class RemoveSelectedActorAction : IEditorAction
{
[TranslationReference("name", "id")]
[FluentReference("name", "id")]
const string RemovedActor = "notification-removed-actor";
public string Text { get; }
@@ -360,8 +360,8 @@ namespace OpenRA.Mods.Common.Widgets
Actor = defaultBrush.Selection.Actor
};
Text = TranslationProvider.GetString(RemovedActor,
Translation.Arguments("name", actor.Info.Name, "id", actor.ID));
Text = FluentProvider.GetString(RemovedActor,
FluentBundle.Arguments("name", actor.Info.Name, "id", actor.ID));
}
public void Execute()
@@ -384,7 +384,7 @@ namespace OpenRA.Mods.Common.Widgets
sealed class RemoveActorAction : IEditorAction
{
[TranslationReference("name", "id")]
[FluentReference("name", "id")]
const string RemovedActor = "notification-removed-actor";
public string Text { get; }
@@ -397,8 +397,8 @@ namespace OpenRA.Mods.Common.Widgets
this.editorActorLayer = editorActorLayer;
this.actor = actor;
Text = TranslationProvider.GetString(RemovedActor,
Translation.Arguments("name", actor.Info.Name, "id", actor.ID));
Text = FluentProvider.GetString(RemovedActor,
FluentBundle.Arguments("name", actor.Info.Name, "id", actor.ID));
}
public void Execute()
@@ -419,7 +419,7 @@ namespace OpenRA.Mods.Common.Widgets
sealed class MoveActorAction : IEditorAction
{
[TranslationReference("id", "x1", "y1", "x2", "y2")]
[FluentReference("id", "x1", "y1", "x2", "y2")]
const string MovedActor = "notification-moved-actor";
public string Text { get; private set; }
@@ -466,13 +466,13 @@ namespace OpenRA.Mods.Common.Widgets
to = worldRenderer.Viewport.ViewToWorld(pixelTo + pixelOffset) + cellOffset;
layer.MoveActor(actor, to);
Text = TranslationProvider.GetString(MovedActor, Translation.Arguments("id", actor.ID, "x1", from.X, "y1", from.Y, "x2", to.X, "y2", to.Y));
Text = FluentProvider.GetString(MovedActor, FluentBundle.Arguments("id", actor.ID, "x1", from.X, "y1", from.Y, "x2", to.X, "y2", to.Y));
}
}
sealed class RemoveResourceAction : IEditorAction
{
[TranslationReference("type")]
[FluentReference("type")]
const string RemovedResource = "notification-removed-resource";
public string Text { get; }
@@ -487,7 +487,7 @@ namespace OpenRA.Mods.Common.Widgets
this.resourceLayer = resourceLayer;
this.cell = cell;
Text = TranslationProvider.GetString(RemovedResource, Translation.Arguments("type", resourceType));
Text = FluentProvider.GetString(RemovedResource, FluentBundle.Arguments("type", resourceType));
}
public void Execute()

View File

@@ -98,10 +98,10 @@ namespace OpenRA.Mods.Common.Widgets
class PaintMarkerTileEditorAction : IEditorAction
{
[TranslationReference("amount", "type")]
[FluentReference("amount", "type")]
const string AddedMarkerTiles = "notification-added-marker-tiles";
[TranslationReference("amount")]
[FluentReference("amount")]
const string RemovedMarkerTiles = "notification-removed-marker-tiles";
public string Text { get; private set; }
@@ -150,15 +150,15 @@ namespace OpenRA.Mods.Common.Widgets
}
if (type != null)
Text = TranslationProvider.GetString(AddedMarkerTiles, Translation.Arguments("amount", paintTiles.Count, "type", type));
Text = FluentProvider.GetString(AddedMarkerTiles, FluentBundle.Arguments("amount", paintTiles.Count, "type", type));
else
Text = TranslationProvider.GetString(RemovedMarkerTiles, Translation.Arguments("amount", paintTiles.Count));
Text = FluentProvider.GetString(RemovedMarkerTiles, FluentBundle.Arguments("amount", paintTiles.Count));
}
}
class ClearSelectedMarkerTilesEditorAction : IEditorAction
{
[TranslationReference("amount", "type")]
[FluentReference("amount", "type")]
const string ClearedSelectedMarkerTiles = "notification-cleared-selected-marker-tiles";
public string Text { get; }
@@ -176,7 +176,7 @@ namespace OpenRA.Mods.Common.Widgets
tiles = new HashSet<CPos>(markerLayerOverlay.Tiles[tile]);
Text = TranslationProvider.GetString(ClearedSelectedMarkerTiles, Translation.Arguments("amount", tiles.Count, "type", tile));
Text = FluentProvider.GetString(ClearedSelectedMarkerTiles, FluentBundle.Arguments("amount", tiles.Count, "type", tile));
}
public void Execute()
@@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets
class ClearAllMarkerTilesEditorAction : IEditorAction
{
[TranslationReference("amount")]
[FluentReference("amount")]
const string ClearedAllMarkerTiles = "notification-cleared-all-marker-tiles";
public string Text { get; }
@@ -213,7 +213,7 @@ namespace OpenRA.Mods.Common.Widgets
var allTilesCount = tiles.Values.Select(x => x.Count).Sum();
Text = TranslationProvider.GetString(ClearedAllMarkerTiles, Translation.Arguments("amount", allTilesCount));
Text = FluentProvider.GetString(ClearedAllMarkerTiles, FluentBundle.Arguments("amount", allTilesCount));
}
public void Execute()

View File

@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets
sealed class AddResourcesEditorAction : IEditorAction
{
[TranslationReference("amount", "type")]
[FluentReference("amount", "type")]
const string AddedResource = "notification-added-resource";
public string Text { get; private set; }
@@ -168,7 +168,7 @@ namespace OpenRA.Mods.Common.Widgets
resourceLayer.ClearResources(resourceCell.Cell);
resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceLayer.GetMaxDensity(resourceCell.NewResourceType));
cellResources.Add(resourceCell);
Text = TranslationProvider.GetString(AddedResource, Translation.Arguments("amount", cellResources.Count, "type", resourceType));
Text = FluentProvider.GetString(AddedResource, FluentBundle.Arguments("amount", cellResources.Count, "type", resourceType));
}
}
}

View File

@@ -172,7 +172,7 @@ namespace OpenRA.Mods.Common.Widgets
sealed class PaintTileEditorAction : IEditorAction
{
[TranslationReference("id")]
[FluentReference("id")]
const string AddedTile = "notification-added-tile";
public string Text { get; }
@@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.Widgets
var terrainInfo = (ITemplatedTerrainInfo)map.Rules.TerrainInfo;
terrainTemplate = terrainInfo.Templates[template];
Text = TranslationProvider.GetString(AddedTile, Translation.Arguments("id", terrainTemplate.Id));
Text = FluentProvider.GetString(AddedTile, FluentBundle.Arguments("id", terrainTemplate.Id));
}
public void Execute()
@@ -244,7 +244,7 @@ namespace OpenRA.Mods.Common.Widgets
sealed class FloodFillEditorAction : IEditorAction
{
[TranslationReference("id")]
[FluentReference("id")]
const string FilledTile = "notification-filled-tile";
public string Text { get; }
@@ -264,7 +264,7 @@ namespace OpenRA.Mods.Common.Widgets
var terrainInfo = (ITemplatedTerrainInfo)map.Rules.TerrainInfo;
terrainTemplate = terrainInfo.Templates[template];
Text = TranslationProvider.GetString(FilledTile, Translation.Arguments("id", terrainTemplate.Id));
Text = FluentProvider.GetString(FilledTile, FluentBundle.Arguments("id", terrainTemplate.Id));
}
public void Execute()

View File

@@ -44,13 +44,13 @@ namespace OpenRA.Mods.Common.Installer
Action<long> onProgress = null;
if (length < InstallFromSourceLogic.ShowPercentageThreshold)
updateMessage(TranslationProvider.GetString(
updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.CopyingFilename,
Translation.Arguments("filename", displayFilename)));
FluentBundle.Arguments("filename", displayFilename)));
else
onProgress = b => updateMessage(TranslationProvider.GetString(
onProgress = b => updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.CopyingFilenameProgress,
Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
FluentBundle.Arguments("filename", displayFilename, "progress", 100 * b / length)));
InstallerUtils.CopyStream(source, target, length, onProgress);
}

View File

@@ -68,13 +68,13 @@ namespace OpenRA.Mods.Common.Installer
Action<long> onProgress = null;
if (length < InstallFromSourceLogic.ShowPercentageThreshold)
updateMessage(TranslationProvider.GetString(
updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.Extracing,
Translation.Arguments("filename", displayFilename)));
FluentBundle.Arguments("filename", displayFilename)));
else
onProgress = b => updateMessage(TranslationProvider.GetString(
onProgress = b => updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.ExtractingProgress,
Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
FluentBundle.Arguments("filename", displayFilename, "progress", 100 * b / length)));
using (var target = File.OpenWrite(targetPath))
{

View File

@@ -64,9 +64,9 @@ namespace OpenRA.Mods.Common.Installer
{
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
void OnProgress(int percent) => updateMessage(TranslationProvider.GetString(
void OnProgress(int percent) => updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.ExtractingProgress,
Translation.Arguments("filename", displayFilename, "progress", percent)));
FluentBundle.Arguments("filename", displayFilename, "progress", percent)));
reader.ExtractFile(node.Value.Value, target, OnProgress);
}
}

View File

@@ -46,9 +46,9 @@ namespace OpenRA.Mods.Common.Installer
{
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
void OnProgress(int percent) => updateMessage(TranslationProvider.GetString(
void OnProgress(int percent) => updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.ExtractingProgress,
Translation.Arguments("filename", displayFilename, "progress", percent)));
FluentBundle.Arguments("filename", displayFilename, "progress", percent)));
reader.ExtractFile(node.Value.Value, target, OnProgress);
}
}

View File

@@ -61,11 +61,11 @@ namespace OpenRA.Mods.Common.Installer
Action<long> onProgress = null;
if (length < InstallFromSourceLogic.ShowPercentageThreshold)
updateMessage(TranslationProvider.GetString(InstallFromSourceLogic.Extracing, Translation.Arguments("filename", displayFilename)));
updateMessage(FluentProvider.GetString(InstallFromSourceLogic.Extracing, FluentBundle.Arguments("filename", displayFilename)));
else
onProgress = b => updateMessage(TranslationProvider.GetString(
onProgress = b => updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.ExtractingProgress,
Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
FluentBundle.Arguments("filename", displayFilename, "progress", 100 * b / length)));
using (var target = File.OpenWrite(targetPath))
{

View File

@@ -49,9 +49,9 @@ namespace OpenRA.Mods.Common.Installer
using (var targetStream = File.OpenWrite(targetPath))
sourceStream.CopyTo(targetStream);
updateMessage(TranslationProvider.GetString(
updateMessage(FluentProvider.GetString(
InstallFromSourceLogic.ExtractingProgress,
Translation.Arguments("filename", displayFilename, "progress", 100)));
FluentBundle.Arguments("filename", displayFilename, "progress", 100)));
extracted.Add(targetPath);
}

View File

@@ -27,23 +27,23 @@ using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Lint
{
sealed class CheckTranslationReference : ILintPass, ILintMapPass
sealed class CheckFluentReferences : ILintPass, ILintMapPass
{
static readonly Regex TranslationFilenameRegex = new(@"(?<language>[^\/\\]+)\.ftl$");
static readonly Regex FilenameRegex = new(@"(?<language>[^\/\\]+)\.ftl$");
void ILintMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Map map)
{
if (map.TranslationDefinitions == null)
return;
var usedKeys = GetUsedTranslationKeysInMap(map, emitWarning);
var usedKeys = GetUsedFluentKeysInMap(map, emitWarning);
foreach (var context in usedKeys.EmptyKeyContexts)
emitWarning($"Empty key in map translation files required by {context}");
emitWarning($"Empty key in map ftl files required by {context}");
var mapTranslations = FieldLoader.GetValue<string[]>("value", map.TranslationDefinitions.Value);
foreach (var language in GetTranslationLanguages(modData))
foreach (var language in GetModLanguages(modData))
{
// Check keys and variables are not missing across all language files.
// But for maps we don't warn on unused keys. They might be unused on *this* map,
@@ -52,20 +52,20 @@ namespace OpenRA.Mods.Common.Lint
modData.Manifest.Translations.Concat(mapTranslations), map.Open, usedKeys,
language, _ => false, emitError, emitWarning);
var modTranslation = new Translation(language, modData.Manifest.Translations, modData.DefaultFileSystem, _ => { });
var mapTranslation = new Translation(language, mapTranslations, map, error => emitError(error.Message));
var modFluentBundle = new FluentBundle(language, modData.Manifest.Translations, modData.DefaultFileSystem, _ => { });
var mapFluentBundle = new FluentBundle(language, mapTranslations, map, error => emitError(error.Message));
foreach (var group in usedKeys.KeysWithContext)
{
if (modTranslation.HasMessage(group.Key))
if (modFluentBundle.HasMessage(group.Key))
{
if (mapTranslation.HasMessage(group.Key))
emitWarning($"Key `{group.Key}` in `{language}` language in map translation files already exists in mod translations and will not be used.");
if (mapFluentBundle.HasMessage(group.Key))
emitWarning($"Key `{group.Key}` in `{language}` language in map ftl files already exists in mod translations and will not be used.");
}
else if (!mapTranslation.HasMessage(group.Key))
else if (!mapFluentBundle.HasMessage(group.Key))
{
foreach (var context in group)
emitWarning($"Missing key `{group.Key}` in `{language}` language in map translation files required by {context}");
emitWarning($"Missing key `{group.Key}` in `{language}` language in map ftl files required by {context}");
}
}
}
@@ -73,15 +73,14 @@ namespace OpenRA.Mods.Common.Lint
void ILintPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData)
{
var (usedKeys, testedFields) = GetUsedTranslationKeysInMod(modData);
var (usedKeys, testedFields) = GetUsedFluentKeysInMod(modData);
foreach (var context in usedKeys.EmptyKeyContexts)
emitWarning($"Empty key in mod translation files required by {context}");
foreach (var language in GetTranslationLanguages(modData))
foreach (var language in GetModLanguages(modData))
{
Console.WriteLine($"Testing translation: {language}");
var translation = new Translation(language, modData.Manifest.Translations, modData.DefaultFileSystem, error => emitError(error.Message));
Console.WriteLine($"Testing language: {language}");
CheckModWidgets(modData, usedKeys, testedFields);
// With the fully populated keys, check keys and variables are not missing and not unused across all language files.
@@ -99,32 +98,32 @@ namespace OpenRA.Mods.Common.Lint
continue;
foreach (var context in group)
emitWarning($"Missing key `{group.Key}` in `{language}` language in mod translation files required by {context}");
emitWarning($"Missing key `{group.Key}` in `{language}` language in mod ftl files required by {context}");
}
}
// Check if we couldn't test any fields.
const BindingFlags Binding = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
var allTranslatableFields = modData.ObjectCreator.GetTypes().SelectMany(t =>
t.GetFields(Binding).Where(m => Utility.HasAttribute<TranslationReferenceAttribute>(m))).ToArray();
var untestedFields = allTranslatableFields.Except(testedFields);
var allFluentFields = modData.ObjectCreator.GetTypes().SelectMany(t =>
t.GetFields(Binding).Where(m => Utility.HasAttribute<FluentReferenceAttribute>(m))).ToArray();
var untestedFields = allFluentFields.Except(testedFields);
foreach (var field in untestedFields)
emitError(
$"Lint pass ({nameof(CheckTranslationReference)}) lacks the know-how to test translatable field " +
$"Lint pass ({nameof(CheckFluentReferences)}) lacks the know-how to test translatable field " +
$"`{field.ReflectedType.Name}.{field.Name}` - previous warnings may be incorrect");
}
static IEnumerable<string> GetTranslationLanguages(ModData modData)
static IEnumerable<string> GetModLanguages(ModData modData)
{
return modData.Manifest.Translations
.Select(filename => TranslationFilenameRegex.Match(filename).Groups["language"].Value)
.Select(filename => FilenameRegex.Match(filename).Groups["language"].Value)
.Distinct()
.OrderBy(l => l);
}
static TranslationKeys GetUsedTranslationKeysInRuleset(Ruleset rules)
static Keys GetUsedFluentKeysInRuleset(Ruleset rules)
{
var usedKeys = new TranslationKeys();
var usedKeys = new Keys();
foreach (var actorInfo in rules.Actors)
{
foreach (var traitInfo in actorInfo.Value.TraitInfos<TraitInfo>())
@@ -132,12 +131,12 @@ namespace OpenRA.Mods.Common.Lint
var traitType = traitInfo.GetType();
foreach (var field in Utility.GetFields(traitType))
{
var translationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(field, true).SingleOrDefault();
if (translationReference == null)
var fluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(field, true).SingleOrDefault();
if (fluentReference == null)
continue;
foreach (var key in LintExts.GetFieldValues(traitInfo, field, translationReference.DictionaryReference))
usedKeys.Add(key, translationReference, $"Actor `{actorInfo.Key}` trait `{traitType.Name[..^4]}.{field.Name}`");
foreach (var key in LintExts.GetFieldValues(traitInfo, field, fluentReference.DictionaryReference))
usedKeys.Add(key, fluentReference, $"Actor `{actorInfo.Key}` trait `{traitType.Name[..^4]}.{field.Name}`");
}
}
}
@@ -149,12 +148,12 @@ namespace OpenRA.Mods.Common.Lint
var warheadType = warhead.GetType();
foreach (var field in Utility.GetFields(warheadType))
{
var translationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(field, true).SingleOrDefault();
if (translationReference == null)
var fluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(field, true).SingleOrDefault();
if (fluentReference == null)
continue;
foreach (var key in LintExts.GetFieldValues(warhead, field, translationReference.DictionaryReference))
usedKeys.Add(key, translationReference, $"Weapon `{weapon.Key}` warhead `{warheadType.Name[..^7]}.{field.Name}`");
foreach (var key in LintExts.GetFieldValues(warhead, field, fluentReference.DictionaryReference))
usedKeys.Add(key, fluentReference, $"Weapon `{weapon.Key}` warhead `{warheadType.Name[..^7]}.{field.Name}`");
}
}
}
@@ -162,40 +161,40 @@ namespace OpenRA.Mods.Common.Lint
return usedKeys;
}
static TranslationKeys GetUsedTranslationKeysInMap(Map map, Action<string> emitWarning)
static Keys GetUsedFluentKeysInMap(Map map, Action<string> emitWarning)
{
var usedKeys = GetUsedTranslationKeysInRuleset(map.Rules);
var usedKeys = GetUsedFluentKeysInRuleset(map.Rules);
var luaScriptInfo = map.Rules.Actors[SystemActors.World].TraitInfoOrDefault<LuaScriptInfo>();
if (luaScriptInfo != null)
{
// Matches expressions such as:
// UserInterface.Translate("translation-key")
// UserInterface.Translate("translation-key\"with-escape")
// UserInterface.Translate("translation-key", { ["attribute"] = foo })
// UserInterface.Translate("translation-key", { ["attribute\"-with-escape"] = foo })
// UserInterface.Translate("translation-key", { ["attribute1"] = foo, ["attribute2"] = bar })
// UserInterface.Translate("translation-key", tableVariable)
// UserInterface.Translate("fluent-key")
// UserInterface.Translate("fluent-key\"with-escape")
// UserInterface.Translate("fluent-key", { ["attribute"] = foo })
// UserInterface.Translate("fluent-key", { ["attribute\"-with-escape"] = foo })
// UserInterface.Translate("fluent-key", { ["attribute1"] = foo, ["attribute2"] = bar })
// UserInterface.Translate("fluent-key", tableVariable)
// Extracts groups for the 'key' and each 'attr'.
// If the table isn't inline like in the last example, extracts it as 'variable'.
const string UserInterfaceTranslatePattern =
@"UserInterface\s*\.\s*Translate\s*\(" + // UserInterface.Translate(
@"\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // "translation-key"
@"\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // "fluent-key"
@"(,\s*({\s*\[\s*""(?<attr>(?:[^""\\]|\\.)*?)""\s*\]\s*=\s*.*?" + // { ["attribute1"] = foo
@"(\s*,\s*\[\s*""(?<attr>(?:[^""\\]|\\.)*?)""\s*\]\s*=\s*.*?)*\s*}\s*)" + // , ["attribute2"] = bar }
"|\\s*,\\s*(?<variable>.*?))?" + // tableVariable
@"\)"; // )
var translateRegex = new Regex(UserInterfaceTranslatePattern);
// The script in mods/common/scripts/utils.lua defines some helpers which accept a translation key
// The script in mods/common/scripts/utils.lua defines some helpers which accept a fluent key
// Matches expressions such as:
// AddPrimaryObjective(Player, "translation-key")
// AddSecondaryObjective(Player, "translation-key")
// AddPrimaryObjective(Player, "translation-key\"with-escape")
// AddPrimaryObjective(Player, "fluent-key")
// AddSecondaryObjective(Player, "fluent-key")
// AddPrimaryObjective(Player, "fluent-key\"with-escape")
// Extracts groups for the 'key'.
const string AddObjectivePattern =
@"(AddPrimaryObjective|AddSecondaryObjective)\s*\(" + // AddPrimaryObjective(
@".*?\s*,\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // Player, "translation-key"
@".*?\s*,\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // Player, "fluent-key"
@"\)"; // )
var objectiveRegex = new Regex(AddObjectivePattern);
@@ -210,7 +209,8 @@ namespace OpenRA.Mods.Common.Lint
IEnumerable<Match> matches = translateRegex.Matches(scriptText);
if (luaScriptInfo.Scripts.Contains("utils.lua"))
matches = matches.Concat(objectiveRegex.Matches(scriptText));
var scriptTranslations = matches.Select(m =>
var references = matches.Select(m =>
{
var key = m.Groups["key"].Value.Replace(@"\""", @"""");
var attrs = m.Groups["attr"].Captures.Select(c => c.Value.Replace(@"\""", @"""")).ToArray();
@@ -218,10 +218,11 @@ namespace OpenRA.Mods.Common.Lint
var line = scriptText.Take(m.Index).Count(x => x == '\n') + 1;
return (Key: key, Attrs: attrs, Variable: variable, Line: line);
}).ToArray();
foreach (var (key, attrs, variable, line) in scriptTranslations)
foreach (var (key, attrs, variable, line) in references)
{
var context = $"Script {script}:{line}";
usedKeys.Add(key, new TranslationReferenceAttribute(attrs), context);
usedKeys.Add(key, new FluentReferenceAttribute(attrs), context);
if (variable != "")
{
@@ -239,22 +240,22 @@ namespace OpenRA.Mods.Common.Lint
return usedKeys;
}
static (TranslationKeys UsedKeys, List<FieldInfo> TestedFields) GetUsedTranslationKeysInMod(ModData modData)
static (Keys UsedKeys, List<FieldInfo> TestedFields) GetUsedFluentKeysInMod(ModData modData)
{
var usedKeys = GetUsedTranslationKeysInRuleset(modData.DefaultRules);
var usedKeys = GetUsedFluentKeysInRuleset(modData.DefaultRules);
var testedFields = new List<FieldInfo>();
testedFields.AddRange(
modData.ObjectCreator.GetTypes()
.Where(t => t.IsSubclassOf(typeof(TraitInfo)) || t.IsSubclassOf(typeof(Warhead)))
.SelectMany(t => t.GetFields().Where(f => f.HasAttribute<TranslationReferenceAttribute>())));
.SelectMany(t => t.GetFields().Where(f => f.HasAttribute<FluentReferenceAttribute>())));
// HACK: Need to hardcode the custom loader for GameSpeeds.
var gameSpeeds = modData.Manifest.Get<GameSpeeds>();
var gameSpeedNameField = typeof(GameSpeed).GetField(nameof(GameSpeed.Name));
var gameSpeedTranslationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(gameSpeedNameField, true)[0];
var gameSpeedFluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(gameSpeedNameField, true)[0];
testedFields.Add(gameSpeedNameField);
foreach (var speed in gameSpeeds.Speeds.Values)
usedKeys.Add(speed.Name, gameSpeedTranslationReference, $"`{nameof(GameSpeed)}.{nameof(GameSpeed.Name)}`");
usedKeys.Add(speed.Name, gameSpeedFluentReference, $"`{nameof(GameSpeed)}.{nameof(GameSpeed.Name)}`");
// TODO: linter does not work with LoadUsing
foreach (var actorInfo in modData.DefaultRules.Actors)
@@ -262,12 +263,12 @@ namespace OpenRA.Mods.Common.Lint
foreach (var info in actorInfo.Value.TraitInfos<ResourceRendererInfo>())
{
var resourceTypeNameField = typeof(ResourceRendererInfo.ResourceTypeInfo).GetField(nameof(ResourceRendererInfo.ResourceTypeInfo.Name));
var resourceTypeTranslationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(resourceTypeNameField, true)[0];
var resourceTypeFluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(resourceTypeNameField, true)[0];
testedFields.Add(resourceTypeNameField);
foreach (var resourceTypes in info.ResourceTypes)
usedKeys.Add(
resourceTypes.Value.Name,
resourceTypeTranslationReference,
resourceTypeFluentReference,
$"`{nameof(ResourceRendererInfo.ResourceTypeInfo)}.{nameof(ResourceRendererInfo.ResourceTypeInfo.Name)}`");
}
}
@@ -281,47 +282,48 @@ namespace OpenRA.Mods.Common.Lint
if (!field.IsLiteral)
continue;
var translationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(field, true).SingleOrDefault();
if (translationReference == null)
var fluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(field, true).SingleOrDefault();
if (fluentReference == null)
continue;
testedFields.Add(field);
var keys = LintExts.GetFieldValues(null, field, translationReference.DictionaryReference);
var keys = LintExts.GetFieldValues(null, field, fluentReference.DictionaryReference);
foreach (var key in keys)
usedKeys.Add(key, translationReference, $"`{field.ReflectedType.Name}.{field.Name}`");
usedKeys.Add(key, fluentReference, $"`{field.ReflectedType.Name}.{field.Name}`");
}
}
return (usedKeys, testedFields);
}
static void CheckModWidgets(ModData modData, TranslationKeys usedKeys, List<FieldInfo> testedFields)
static void CheckModWidgets(ModData modData, Keys usedKeys, List<FieldInfo> testedFields)
{
var chromeLayoutNodes = BuildChromeTree(modData);
var widgetTypes = modData.ObjectCreator.GetTypes()
.Where(t => t.Name.EndsWith("Widget", StringComparison.InvariantCulture) && t.IsSubclassOf(typeof(Widget)))
.ToList();
var translationReferencesByWidgetField = widgetTypes.SelectMany(t =>
var fluentReferencesByWidgetField = widgetTypes.SelectMany(t =>
{
var widgetName = t.Name[..^6];
return Utility.GetFields(t)
.Select(f =>
{
var attribute = Utility.GetCustomAttributes<TranslationReferenceAttribute>(f, true).SingleOrDefault();
return (WidgetName: widgetName, FieldName: f.Name, TranslationReference: attribute);
var attribute = Utility.GetCustomAttributes<FluentReferenceAttribute>(f, true).SingleOrDefault();
return (WidgetName: widgetName, FieldName: f.Name, FluentReference: attribute);
})
.Where(x => x.TranslationReference != null);
.Where(x => x.FluentReference != null);
})
.ToDictionary(
x => (x.WidgetName, x.FieldName),
x => x.TranslationReference);
x => x.FluentReference);
testedFields.AddRange(widgetTypes.SelectMany(
t => Utility.GetFields(t).Where(Utility.HasAttribute<TranslationReferenceAttribute>)));
t => Utility.GetFields(t).Where(Utility.HasAttribute<FluentReferenceAttribute>)));
foreach (var node in chromeLayoutNodes)
CheckChrome(node, translationReferencesByWidgetField, usedKeys);
CheckChrome(node, fluentReferencesByWidgetField, usedKeys);
}
static MiniYamlNode[] BuildChromeTree(ModData modData)
@@ -336,38 +338,38 @@ namespace OpenRA.Mods.Common.Lint
static void CheckChrome(
MiniYamlNode rootNode,
Dictionary<(string WidgetName, string FieldName), TranslationReferenceAttribute> translationReferencesByWidgetField,
TranslationKeys usedKeys)
Dictionary<(string WidgetName, string FieldName), FluentReferenceAttribute> fluentReferencesByWidgetField,
Keys usedKeys)
{
var nodeType = rootNode.Key.Split('@')[0];
foreach (var childNode in rootNode.Value.Nodes)
{
var childType = childNode.Key.Split('@')[0];
if (!translationReferencesByWidgetField.TryGetValue((nodeType, childType), out var translationReference))
if (!fluentReferencesByWidgetField.TryGetValue((nodeType, childType), out var reference))
continue;
var key = childNode.Value.Value;
usedKeys.Add(key, translationReference, $"Widget `{rootNode.Key}` field `{childType}` in {rootNode.Location}");
usedKeys.Add(key, reference, $"Widget `{rootNode.Key}` field `{childType}` in {rootNode.Location}");
}
foreach (var childNode in rootNode.Value.Nodes)
if (childNode.Key == "Children")
foreach (var n in childNode.Value.Nodes)
CheckChrome(n, translationReferencesByWidgetField, usedKeys);
CheckChrome(n, fluentReferencesByWidgetField, usedKeys);
}
static HashSet<string> CheckKeys(
IEnumerable<string> translationFiles, Func<string, Stream> openFile, TranslationKeys usedKeys,
IEnumerable<string> paths, Func<string, Stream> openFile, Keys usedKeys,
string language, Func<string, bool> checkUnusedKeysForFile,
Action<string> emitError, Action<string> emitWarning)
{
var keyWithAttrs = new HashSet<string>();
foreach (var file in translationFiles)
foreach (var path in paths)
{
if (!file.EndsWith($"{language}.ftl", StringComparison.Ordinal))
if (!path.EndsWith($"{language}.ftl", StringComparison.Ordinal))
continue;
var stream = openFile(file);
var stream = openFile(path);
using (var reader = new StreamReader(stream))
{
var parser = new LinguiniParser(reader);
@@ -388,9 +390,9 @@ namespace OpenRA.Mods.Common.Lint
foreach (var (node, attributeName) in nodeAndAttributeNames)
{
keyWithAttrs.Add(attributeName == null ? key : $"{key}.{attributeName}");
if (checkUnusedKeysForFile(file))
CheckUnusedKey(key, attributeName, file, usedKeys, emitWarning);
CheckVariables(node, key, attributeName, file, usedKeys, emitError, emitWarning);
if (checkUnusedKeysForFile(path))
CheckUnusedKey(key, attributeName, path, usedKeys, emitWarning);
CheckVariables(node, key, attributeName, path, usedKeys, emitError, emitWarning);
}
}
}
@@ -398,7 +400,7 @@ namespace OpenRA.Mods.Common.Lint
return keyWithAttrs;
static void CheckUnusedKey(string key, string attribute, string file, TranslationKeys usedKeys, Action<string> emitWarning)
static void CheckUnusedKey(string key, string attribute, string file, Keys usedKeys, Action<string> emitWarning)
{
var isAttribute = !string.IsNullOrEmpty(attribute);
var keyWithAtrr = isAttribute ? $"{key}.{attribute}" : key;
@@ -410,7 +412,7 @@ namespace OpenRA.Mods.Common.Lint
}
static void CheckVariables(
Pattern node, string key, string attribute, string file, TranslationKeys usedKeys,
Pattern node, string key, string attribute, string file, Keys usedKeys,
Action<string> emitError, Action<string> emitWarning)
{
var isAttribute = !string.IsNullOrEmpty(attribute);
@@ -456,26 +458,26 @@ namespace OpenRA.Mods.Common.Lint
}
}
class TranslationKeys
class Keys
{
readonly HashSet<string> keys = new();
readonly List<(string Key, string Context)> keysWithContext = new();
readonly Dictionary<string, HashSet<string>> requiredVariablesByKey = new();
readonly List<string> contextForEmptyKeys = new();
public void Add(string key, TranslationReferenceAttribute translationReference, string context)
public void Add(string key, FluentReferenceAttribute fluentReference, string context)
{
if (key == null)
{
if (!translationReference.Optional)
if (!fluentReference.Optional)
contextForEmptyKeys.Add(context);
return;
}
if (translationReference.RequiredVariableNames != null && translationReference.RequiredVariableNames.Length > 0)
if (fluentReference.RequiredVariableNames != null && fluentReference.RequiredVariableNames.Length > 0)
{
var rv = requiredVariablesByKey.GetOrAdd(key, _ => new HashSet<string>());
rv.UnionWith(translationReference.RequiredVariableNames);
rv.UnionWith(fluentReference.RequiredVariableNames);
}
keys.Add(key);

View File

@@ -18,7 +18,7 @@ using OpenRA.FileSystem;
namespace OpenRA.Mods.Common.Lint
{
sealed class CheckTranslationSyntax : ILintPass, ILintMapPass
sealed class CheckFluentSyntax : ILintPass, ILintMapPass
{
void ILintMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Map map)
{
@@ -33,11 +33,11 @@ namespace OpenRA.Mods.Common.Lint
Run(emitError, emitWarning, modData.DefaultFileSystem, modData.Manifest.Translations);
}
static void Run(Action<string> emitError, Action<string> emitWarning, IReadOnlyFileSystem fileSystem, string[] translations)
static void Run(Action<string> emitError, Action<string> emitWarning, IReadOnlyFileSystem fileSystem, string[] paths)
{
foreach (var file in translations)
foreach (var path in paths)
{
var stream = fileSystem.Open(file);
var stream = fileSystem.Open(path);
using (var reader = new StreamReader(stream))
{
var ids = new List<string>();
@@ -46,12 +46,12 @@ namespace OpenRA.Mods.Common.Lint
foreach (var entry in resource.Entries)
{
if (entry is Junk junk)
emitError($"{junk.GetId()}: {junk.AsStr()} in {file} {junk.Content}.");
emitError($"{junk.GetId()}: {junk.AsStr()} in {path} {junk.Content}.");
if (entry is AstMessage message)
{
if (ids.Contains(message.Id.Name.ToString()))
emitWarning($"Duplicate ID `{message.Id.Name}` in {file}.");
emitWarning($"Duplicate ID `{message.Id.Name}` in {path}.");
ids.Add(message.Id.Name.ToString());
}

View File

@@ -34,9 +34,9 @@ namespace OpenRA.Mods.Common.Scripting.Global
luaLabel.GetColor = () => c;
}
[Desc("Translates text into the users language. The translation key must be added to the language files (*.ftl). " +
[Desc("Formats a language string for a given string key defined in the language files (*.ftl). " +
"Args can be passed to be substituted into the resulting message.")]
public string Translate(string translationKey, [ScriptEmmyTypeOverride("{ string: any }")] LuaTable args = null)
public string Translate(string key, [ScriptEmmyTypeOverride("{ string: any }")] LuaTable args = null)
{
if (args != null)
{
@@ -48,17 +48,17 @@ namespace OpenRA.Mods.Common.Scripting.Global
{
if (!kv.Key.TryGetClrValue<string>(out var variable) || !kv.Value.TryGetClrValue<object>(out var value))
throw new LuaException(
"Translation arguments requires a table of [\"string\"]=value pairs. " +
"String arguments requires a table of [\"string\"]=value pairs. " +
$"Received {kv.Key.WrappedClrType().Name},{kv.Value.WrappedClrType().Name}");
argumentDictionary.Add(variable, value);
}
}
return TranslationProvider.GetString(translationKey, argumentDictionary);
return FluentProvider.GetString(key, argumentDictionary);
}
return TranslationProvider.GetString(translationKey);
return FluentProvider.GetString(key);
}
}
}

View File

@@ -188,7 +188,7 @@ namespace OpenRA.Mods.Common.Scripting
if (tooltip == null)
return null;
return TranslationProvider.GetString(tooltip.Info.Name);
return FluentProvider.GetString(tooltip.Info.Name);
}
}

View File

@@ -27,142 +27,142 @@ namespace OpenRA.Mods.Common.Server
{
public class LobbyCommands : ServerTrait, IInterpretCommand, INotifyServerStart, INotifyServerEmpty, IClientJoined, OpenRA.Server.ITick
{
[TranslationReference]
[FluentReference]
const string CustomRules = "notification-custom-rules";
[TranslationReference]
[FluentReference]
const string OnlyHostStartGame = "notification-admin-start-game";
[TranslationReference]
[FluentReference]
const string NoStartUntilRequiredSlotsFull = "notification-no-start-until-required-slots-full";
[TranslationReference]
[FluentReference]
const string NoStartWithoutPlayers = "notification-no-start-without-players";
[TranslationReference]
[FluentReference]
const string TwoHumansRequired = "notification-two-humans-required";
[TranslationReference]
[FluentReference]
const string InsufficientEnabledSpawnPoints = "notification-insufficient-enabled-spawn-points";
[TranslationReference("command")]
[FluentReference("command")]
const string MalformedCommand = "notification-malformed-command";
[TranslationReference]
[FluentReference]
const string KickNone = "notification-kick-none";
[TranslationReference]
[FluentReference]
const string NoKickSelf = "notification-kick-self";
[TranslationReference]
[FluentReference]
const string NoKickGameStarted = "notification-no-kick-game-started";
[TranslationReference("admin", "player")]
[FluentReference("admin", "player")]
const string AdminKicked = "notification-admin-kicked";
[TranslationReference("player")]
[FluentReference("player")]
const string Kicked = "notification-kicked";
[TranslationReference("admin", "player")]
[FluentReference("admin", "player")]
const string TempBan = "notification-temp-ban";
[TranslationReference]
[FluentReference]
const string NoTransferAdmin = "notification-admin-transfer-admin";
[TranslationReference]
[FluentReference]
const string EmptySlot = "notification-empty-slot";
[TranslationReference("admin", "player")]
[FluentReference("admin", "player")]
const string MoveSpectators = "notification-move-spectators";
[TranslationReference("player", "name")]
[FluentReference("player", "name")]
const string Nick = "notification-nick-changed";
[TranslationReference]
[FluentReference]
const string StateUnchangedReady = "notification-state-unchanged-ready";
[TranslationReference("command")]
[FluentReference("command")]
const string StateUnchangedGameStarted = "notification-state-unchanged-game-started";
[TranslationReference("faction")]
[FluentReference("faction")]
const string InvalidFactionSelected = "notification-invalid-faction-selected";
[TranslationReference("factions")]
[FluentReference("factions")]
const string SupportedFactions = "notification-supported-factions";
[TranslationReference]
[FluentReference]
const string RequiresHost = "notification-requires-host";
[TranslationReference]
[FluentReference]
const string InvalidBotSlot = "notification-invalid-bot-slot";
[TranslationReference]
[FluentReference]
const string InvalidBotType = "notification-invalid-bot-type";
[TranslationReference]
[FluentReference]
const string HostChangeMap = "notification-admin-change-map";
[TranslationReference]
[FluentReference]
const string UnknownMap = "notification-unknown-map";
[TranslationReference]
[FluentReference]
const string SearchingMap = "notification-searching-map";
[TranslationReference]
[FluentReference]
const string NotAdmin = "notification-admin-change-configuration";
[TranslationReference]
[FluentReference]
const string InvalidConfigurationCommand = "notification-invalid-configuration-command";
[TranslationReference("option")]
[FluentReference("option")]
const string OptionLocked = "notification-option-locked";
[TranslationReference("player", "map")]
[FluentReference("player", "map")]
const string ChangedMap = "notification-changed-map";
[TranslationReference]
[FluentReference]
const string MapBotsDisabled = "notification-map-bots-disabled";
[TranslationReference("player", "name", "value")]
[FluentReference("player", "name", "value")]
const string ValueChanged = "notification-option-changed";
[TranslationReference]
[FluentReference]
const string NoMoveSpectators = "notification-admin-move-spectators";
[TranslationReference]
[FluentReference]
const string AdminOption = "notification-admin-option";
[TranslationReference("raw")]
[FluentReference("raw")]
const string NumberTeams = "notification-error-number-teams";
[TranslationReference]
[FluentReference]
const string AdminClearSpawn = "notification-admin-clear-spawn";
[TranslationReference]
[FluentReference]
const string SpawnOccupied = "notification-spawn-occupied";
[TranslationReference]
[FluentReference]
const string SpawnLocked = "notification-spawn-locked";
[TranslationReference]
[FluentReference]
const string AdminLobbyInfo = "notification-admin-lobby-info";
[TranslationReference]
[FluentReference]
const string InvalidLobbyInfo = "notification-invalid-lobby-info";
[TranslationReference]
[FluentReference]
const string AdminKick = "notification-admin-kick";
[TranslationReference]
[FluentReference]
const string SlotClosed = "notification-slot-closed";
[TranslationReference("player")]
[FluentReference("player")]
const string NewAdmin = "notification-new-admin";
[TranslationReference]
[FluentReference]
const string YouWereKicked = "notification-you-were-kicked";
[TranslationReference]
[FluentReference]
const string VoteKickDisabled = "notification-vote-kick-disabled";
readonly IDictionary<string, Func<S, Connection, Session.Client, string, bool>> commandHandlers =
@@ -224,7 +224,7 @@ namespace OpenRA.Mods.Common.Server
if (server.State == ServerState.GameStarted)
{
server.SendLocalizedMessageTo(conn, StateUnchangedGameStarted, Translation.Arguments("command", command));
server.SendLocalizedMessageTo(conn, StateUnchangedGameStarted, FluentBundle.Arguments("command", command));
return false;
}
else if (client.State == Session.ClientState.Ready && !(command.StartsWith("state", StringComparison.Ordinal) || command == "startgame"))
@@ -303,7 +303,7 @@ namespace OpenRA.Mods.Common.Server
{
if (!Enum<Session.ClientState>.TryParse(s, false, out var state))
{
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "state"));
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "state"));
return true;
}
@@ -399,7 +399,7 @@ namespace OpenRA.Mods.Common.Server
return true;
}
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "allow_spectate"));
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "allow_spectate"));
return true;
}
@@ -488,7 +488,7 @@ namespace OpenRA.Mods.Common.Server
var parts = s.Split(' ');
if (parts.Length < 3)
{
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "slot_bot"));
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "slot_bot"));
return true;
}
@@ -652,7 +652,7 @@ namespace OpenRA.Mods.Common.Server
server.SyncLobbyInfo();
server.SendLocalizedMessage(ChangedMap, Translation.Arguments("player", client.Name, "map", server.Map.Title));
server.SendLocalizedMessage(ChangedMap, FluentBundle.Arguments("player", client.Name, "map", server.Map.Title));
if ((server.LobbyInfo.GlobalSettings.MapStatus & Session.MapStatus.UnsafeCustomRules) != 0)
server.SendLocalizedMessage(CustomRules);
@@ -722,7 +722,7 @@ namespace OpenRA.Mods.Common.Server
if (option.IsLocked)
{
server.SendLocalizedMessageTo(conn, OptionLocked, Translation.Arguments("option", option.Name));
server.SendLocalizedMessageTo(conn, OptionLocked, FluentBundle.Arguments("option", option.Name));
return true;
}
@@ -739,7 +739,7 @@ namespace OpenRA.Mods.Common.Server
oo.Value = oo.PreferredValue = split[1];
server.SyncLobbyGlobalSettings();
server.SendLocalizedMessage(ValueChanged, Translation.Arguments("player", client.Name, "name", option.Name, "value", option.Label(split[1])));
server.SendLocalizedMessage(ValueChanged, FluentBundle.Arguments("player", client.Name, "name", option.Name, "value", option.Label(split[1])));
foreach (var c in server.LobbyInfo.Clients)
c.State = Session.ClientState.NotReady;
@@ -768,7 +768,7 @@ namespace OpenRA.Mods.Common.Server
foreach (var o in allOptions)
{
if (o.DefaultValue != server.LobbyInfo.GlobalSettings.LobbyOptions[o.Id].Value)
server.SendLocalizedMessage(ValueChanged, Translation.Arguments(
server.SendLocalizedMessage(ValueChanged, FluentBundle.Arguments(
"player", client.Name,
"name", o.Name,
"value", o.Label(o.DefaultValue)));
@@ -805,7 +805,7 @@ namespace OpenRA.Mods.Common.Server
if (!Exts.TryParseInt32Invariant(raw, out var teamCount))
{
server.SendLocalizedMessageTo(conn, NumberTeams, Translation.Arguments("raw", raw));
server.SendLocalizedMessageTo(conn, NumberTeams, FluentBundle.Arguments("raw", raw));
return true;
}
@@ -850,7 +850,7 @@ namespace OpenRA.Mods.Common.Server
var split = s.Split(' ');
if (split.Length < 2)
{
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "kick"));
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "kick"));
return true;
}
@@ -877,14 +877,14 @@ namespace OpenRA.Mods.Common.Server
}
Log.Write("server", $"Kicking client {kickClientID}.");
server.SendLocalizedMessage(AdminKicked, Translation.Arguments("admin", client.Name, "player", kickClient.Name));
server.SendLocalizedMessage(AdminKicked, FluentBundle.Arguments("admin", client.Name, "player", kickClient.Name));
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
server.DropClient(kickConn);
if (bool.TryParse(split[1], out var tempBan) && tempBan)
{
Log.Write("server", $"Temporarily banning client {kickClientID} ({kickClient.IPAddress}).");
server.SendLocalizedMessage(TempBan, Translation.Arguments("admin", client.Name, "player", kickClient.Name));
server.SendLocalizedMessage(TempBan, FluentBundle.Arguments("admin", client.Name, "player", kickClient.Name));
server.TempBans.Add(kickClient.IPAddress);
}
@@ -902,7 +902,7 @@ namespace OpenRA.Mods.Common.Server
var split = s.Split(' ');
if (split.Length != 2)
{
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "vote_kick"));
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "vote_kick"));
return true;
}
@@ -930,14 +930,14 @@ namespace OpenRA.Mods.Common.Server
if (!bool.TryParse(split[1], out var vote))
{
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "vote_kick"));
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "vote_kick"));
return true;
}
if (server.VoteKickTracker.VoteKick(conn, client, kickConn, kickClient, kickClientID, vote))
{
Log.Write("server", $"Kicking client {kickClientID}.");
server.SendLocalizedMessage(Kicked, Translation.Arguments("player", kickClient.Name));
server.SendLocalizedMessage(Kicked, FluentBundle.Arguments("player", kickClient.Name));
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
server.DropClient(kickConn);
@@ -980,7 +980,7 @@ namespace OpenRA.Mods.Common.Server
foreach (var b in bots)
b.BotControllerClientIndex = newAdminId;
server.SendLocalizedMessage(NewAdmin, Translation.Arguments("player", newAdminClient.Name));
server.SendLocalizedMessage(NewAdmin, FluentBundle.Arguments("player", newAdminClient.Name));
Log.Write("server", $"{newAdminClient.Name} is now the admin.");
server.SyncLobbyClients();
@@ -1014,7 +1014,7 @@ namespace OpenRA.Mods.Common.Server
targetClient.Handicap = 0;
targetClient.Color = Color.White;
targetClient.State = Session.ClientState.NotReady;
server.SendLocalizedMessage(MoveSpectators, Translation.Arguments("admin", client.Name, "player", targetClient.Name));
server.SendLocalizedMessage(MoveSpectators, FluentBundle.Arguments("admin", client.Name, "player", targetClient.Name));
Log.Write("server", $"{client.Name} moved {targetClient.Name} to spectators.");
server.SyncLobbyClients();
CheckAutoStart(server);
@@ -1032,7 +1032,7 @@ namespace OpenRA.Mods.Common.Server
return true;
Log.Write("server", $"Player@{conn.EndPoint} is now known as {sanitizedName}.");
server.SendLocalizedMessage(Nick, Translation.Arguments("player", client.Name, "name", sanitizedName));
server.SendLocalizedMessage(Nick, FluentBundle.Arguments("player", client.Name, "name", sanitizedName));
client.Name = sanitizedName;
server.SyncLobbyClients();
@@ -1062,8 +1062,8 @@ namespace OpenRA.Mods.Common.Server
var faction = parts[1];
if (!factions.Contains(faction))
{
server.SendLocalizedMessageTo(conn, InvalidFactionSelected, Translation.Arguments("faction", faction));
server.SendLocalizedMessageTo(conn, SupportedFactions, Translation.Arguments("factions", factions.JoinWith(", ")));
server.SendLocalizedMessageTo(conn, InvalidFactionSelected, FluentBundle.Arguments("faction", faction));
server.SendLocalizedMessageTo(conn, SupportedFactions, FluentBundle.Arguments("factions", factions.JoinWith(", ")));
return true;
}

View File

@@ -30,22 +30,22 @@ namespace OpenRA.Mods.Common.Server
// 1 second (in milliseconds) minimum delay between pings
const int RateLimitInterval = 1000;
[TranslationReference]
[FluentReference]
const string NoPortForward = "notification-no-port-forward";
[TranslationReference]
[FluentReference]
const string BlacklistedTitle = "notification-blacklisted-server-name";
[TranslationReference]
[FluentReference]
const string InvalidErrorCode = "notification-invalid-error-code";
[TranslationReference]
[FluentReference]
const string Connected = "notification-master-server-connected";
[TranslationReference]
[FluentReference]
const string Error = "notification-master-server-error";
[TranslationReference]
[FluentReference]
const string GameOffline = "notification-game-offline";
static readonly Beacon LanGameBeacon;

View File

@@ -18,16 +18,16 @@ namespace OpenRA.Mods.Common.Server
{
public class PlayerPinger : ServerTrait, ITick
{
[TranslationReference]
[FluentReference]
const string PlayerDropped = "notification-player-dropped";
[TranslationReference("player")]
[FluentReference("player")]
const string ConnectionProblems = "notification-connection-problems";
[TranslationReference("player")]
[FluentReference("player")]
const string Timeout = "notification-timeout-dropped";
[TranslationReference("player", "timeout")]
[FluentReference("player", "timeout")]
const string TimeoutIn = "notification-timeout-dropped-in";
const int PingInterval = 5000; // Ping every 5 seconds
@@ -69,13 +69,13 @@ namespace OpenRA.Mods.Common.Server
{
if (!c.TimeoutMessageShown && c.TimeSinceLastResponse > PingInterval * 2)
{
server.SendLocalizedMessage(ConnectionProblems, Translation.Arguments("player", client.Name));
server.SendLocalizedMessage(ConnectionProblems, FluentBundle.Arguments("player", client.Name));
c.TimeoutMessageShown = true;
}
}
else
{
server.SendLocalizedMessage(Timeout, Translation.Arguments("player", client.Name));
server.SendLocalizedMessage(Timeout, FluentBundle.Arguments("player", client.Name));
server.DropClient(c);
}
}

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly int BuildPaletteOrder = 9999;
[Desc("Text shown in the production tooltip.")]
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string Description;
public static string GetInitialFaction(ActorInfo ai, string defaultFaction)

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when selecting a primary building.")]
public readonly string SelectionNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when selecting a primary building.")]
public readonly string SelectionTextNotification = null;

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when a unit is delivered.")]
public readonly string ReadyAudio = "Reinforce";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when a unit is delivered.")]
public readonly string ReadyTextNotification = null;

View File

@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when setting a new rallypoint.")]
public readonly string Notification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when setting a new rallypoint.")]
public readonly string TextNotification = null;

View File

@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Voice line to play when repairs are started.")]
public readonly string RepairingNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Transient text message to display when repairs are started.")]
public readonly string RepairingTextNotification = null;

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string EnabledSpeech = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string EnabledTextNotification = null;
[NotificationReference("Sounds")]
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string DisabledSpeech = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string DisabledTextNotification = null;
public override object Create(ActorInitializer init) { return new ToggleConditionOnOrder(this); }

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when the crate is collected.")]
public readonly string Notification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when the crate is collected.")]
public readonly string TextNotification = null;

View File

@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
public class EncyclopediaInfo : TraitInfo
{
[Desc("Explains the purpose in the in-game encyclopedia.")]
[TranslationReference]
[FluentReference]
public readonly string Description;
[Desc("Number for ordering the list.")]

View File

@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Sounds")]
public readonly string LevelUpNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string LevelUpTextNotification = null;
public override object Create(ActorInitializer init) { return new GainsExperience(init, this); }

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification type to play.")]
public readonly string Notification = "BaseAttack";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display.")]
public readonly string TextNotification = null;
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
"Won't play a notification to allies if this is null.")]
public readonly string AllyNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display to allies when under attack.")]
public readonly string AllyTextNotification = null;

View File

@@ -32,10 +32,10 @@ namespace OpenRA.Mods.Common.Traits
public class ConquestVictoryConditions : ITick, INotifyWinStateChanged, INotifyTimeLimit
{
[TranslationReference("player")]
[FluentReference("player")]
const string PlayerIsVictorious = "notification-player-is-victorious";
[TranslationReference("player")]
[FluentReference("player")]
const string PlayerIsDefeated = "notification-player-is-defeated";
readonly ConquestVictoryConditionsInfo info;
@@ -105,7 +105,7 @@ namespace OpenRA.Mods.Common.Traits
if (info.SuppressNotifications)
return;
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, Translation.Arguments("player", player.ResolvedPlayerName));
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, FluentBundle.Arguments("player", player.ResolvedPlayerName));
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Traits
if (info.SuppressNotifications)
return;
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, Translation.Arguments("player", player.ResolvedPlayerName));
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, FluentBundle.Arguments("player", player.ResolvedPlayerName));
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)

View File

@@ -20,11 +20,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Attach this to the player actor.")]
public class DeveloperModeInfo : TraitInfo, ILobbyOptions
{
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the developer mode checkbox in the lobby.")]
public readonly string CheckboxLabel = "checkbox-debug-menu.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the developer mode checkbox in the lobby.")]
public readonly string CheckboxDescription = "checkbox-debug-menu.description";
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
public class DeveloperMode : IResolveOrder, ISync, INotifyCreated, IUnlocksRenderPlayer
{
[TranslationReference("cheat", "player", "suffix")]
[FluentReference("cheat", "player", "suffix")]
const string CheatUsed = "notification-cheat-used";
readonly DeveloperModeInfo info;
@@ -275,8 +275,8 @@ namespace OpenRA.Mods.Common.Traits
return;
}
var arguments = Translation.Arguments("cheat", order.OrderString, "player", self.Owner.ResolvedPlayerName, "suffix", debugSuffix);
TextNotificationsManager.Debug(TranslationProvider.GetString(CheatUsed, arguments));
var arguments = FluentBundle.Arguments("cheat", order.OrderString, "player", self.Owner.ResolvedPlayerName, "suffix", debugSuffix);
TextNotificationsManager.Debug(FluentProvider.GetString(CheatUsed, arguments));
}
bool IUnlocksRenderPlayer.RenderPlayerUnlocked => Enabled;

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification type to play.")]
public readonly string Notification = "HarvesterAttack";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display.")]
public readonly string TextNotification = null;

View File

@@ -22,12 +22,12 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Internal id for this checkbox.")]
public readonly string ID = null;
[TranslationReference]
[FluentReference]
[FieldLoader.Require]
[Desc("Display name for this checkbox.")]
public readonly string Label = null;
[TranslationReference]
[FluentReference]
[Desc("Description name for this checkbox.")]
public readonly string Description = null;

View File

@@ -54,19 +54,19 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string WinNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string WinTextNotification = null;
[NotificationReference("Speech")]
public readonly string LoseNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string LoseTextNotification = null;
[NotificationReference("Speech")]
public readonly string LeaveNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string LeaveTextNotification = null;
public override object Create(ActorInitializer init) { return new MissionObjectives(init.Self.Owner, this); }

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Internal id for this bot.")]
public readonly string Type = null;
[TranslationReference]
[FluentReference]
[Desc("Human-readable name this bot uses.")]
public readonly string Name = null;

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play after building placement if new construction options are available.")]
public readonly string NewOptionsNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display after building placement if new construction options are available.")]
public readonly string NewOptionsTextNotification = null;
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play if building placement is not possible.")]
public readonly string CannotPlaceNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display if building placement is not possible.")]
public readonly string CannotPlaceTextNotification = null;

View File

@@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when the player does not have any funds.")]
public readonly string InsufficientFundsNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when the player does not have any funds.")]
public readonly string InsufficientFundsTextNotification = null;

View File

@@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string ReadyAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Notification displayed when production is complete.")]
public readonly string ReadyTextNotification = null;
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string BlockedAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Notification displayed when you can't train another actor",
"when the build limit exceeded or the exit is jammed.")]
public readonly string BlockedTextNotification = null;
@@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string LimitedAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Notification displayed when you can't queue another actor",
"when the queue length limit is exceeded.")]
public readonly string LimitedTextNotification = null;
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string QueuedAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Notification displayed when user clicks on the build palette icon.")]
public readonly string QueuedTextNotification = null;
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string OnHoldAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Notification displayed when player right-clicks on the build palette icon.")]
public readonly string OnHoldTextNotification = null;
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string CancelledAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Notification displayed when player right-clicks on a build palette icon that is already on hold.")]
public readonly string CancelledTextNotification = null;

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Internal id for this tech level.")]
public readonly string Id;
[TranslationReference]
[FluentReference]
[Desc("Name shown in the lobby options.")]
public readonly string Name;

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech to play for the warning.")]
public readonly string Notification = "SilosNeeded";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text to display for the warning.")]
public readonly string TextNotification = null;

View File

@@ -46,10 +46,10 @@ namespace OpenRA.Mods.Common.Traits
public class StrategicVictoryConditions : ITick, ISync, INotifyWinStateChanged, INotifyTimeLimit
{
[TranslationReference("player")]
[FluentReference("player")]
const string PlayerIsVictorious = "notification-player-is-victorious";
[TranslationReference("player")]
[FluentReference("player")]
const string PlayerIsDefeated = "notification-player-is-defeated";
readonly StrategicVictoryConditionsInfo info;
@@ -151,7 +151,7 @@ namespace OpenRA.Mods.Common.Traits
if (info.SuppressNotifications)
return;
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, Translation.Arguments("player", player.ResolvedPlayerName));
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, FluentBundle.Arguments("player", player.ResolvedPlayerName));
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
@@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Traits
if (info.SuppressNotifications)
return;
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, Translation.Arguments("player", player.ResolvedPlayerName));
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, FluentBundle.Arguments("player", player.ResolvedPlayerName));
Game.RunAfterDelay(info.NotificationDelay, () =>
{
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly string SpeechNotification = null;
[Desc("The text notification to display when the player is low power.")]
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string TextNotification = null;
public override object Create(ActorInitializer init) { return new PowerManager(init.Self, this); }

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when dropping the unit.")]
public readonly string ReadyAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when dropping the unit.")]
public readonly string ReadyTextNotification = null;

View File

@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
{
const string CommandName = "custom-terrain";
[TranslationReference]
[FluentReference]
const string CommandDescription = "description-custom-terrain-debug-overlay";
public bool Enabled;

View File

@@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when a bridge is repaired.")]
public readonly string RepairNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when a bridge is repaired.")]
public readonly string RepairTextNotification = null;

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification played when starting to repair a unit.")]
public readonly string StartRepairingNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification displayed when starting to repair a unit.")]
public readonly string StartRepairingTextNotification = null;
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification played when repairing a unit is done.")]
public readonly string FinishRepairingNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification displayed when repairing a unit is done.")]
public readonly string FinishRepairingTextNotification = null;

View File

@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play.")]
public readonly string Notification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display.")]
public readonly string TextNotification = null;

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
public readonly string Notification = "UnitLost";
[Desc("Text notification to display.")]
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string TextNotification = null;
public readonly bool NotifyAll = false;

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
[Desc("Speech notification to play.")]
public readonly string Notification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display.")]
public readonly string TextNotification = null;

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
[Desc("Speech notification to play to the new owner.")]
public readonly string Notification = "BuildingCaptured";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display to the new owner.")]
public readonly string TextNotification = null;
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
[Desc("Speech notification to play to the old owner.")]
public readonly string LoseNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display to the old owner.")]
public readonly string LoseTextNotification = null;

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when entering the drop zone.")]
public readonly string ReinforcementsArrivedSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when entering the drop zone.")]
public readonly string ReinforcementsArrivedTextNotification = null;

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string ReadyAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification displayed when production is activated.")]
public readonly string ReadyTextNotification = null;
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string BlockedAudio = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification displayed when the exit is jammed.")]
public readonly string BlockedTextNotification = null;

View File

@@ -30,10 +30,10 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Palette used for the icon.")]
public readonly string IconPalette = "chrome";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string Name = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string Description = null;
[Desc("Allow multiple instances of the same support power.")]
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string DetectedSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string DetectedTextNotification = null;
public readonly string BeginChargeSound = null;
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string BeginChargeSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string BeginChargeTextNotification = null;
public readonly string EndChargeSound = null;
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string EndChargeSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string EndChargeTextNotification = null;
public readonly string SelectTargetSound = null;
@@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string SelectTargetSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string SelectTargetTextNotification = null;
public readonly string InsufficientPowerSound = null;
@@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string InsufficientPowerSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string InsufficientPowerTextNotification = null;
public readonly string LaunchSound = null;
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string LaunchSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string LaunchTextNotification = null;
public readonly string IncomingSound = null;
@@ -109,7 +109,7 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string IncomingSpeechNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string IncomingTextNotification = null;
[Desc("Defines to which players the timer is shown.")]

View File

@@ -177,8 +177,8 @@ namespace OpenRA.Mods.Common.Traits
Key = key;
TotalTicks = info.ChargeInterval;
remainingSubTicks = info.StartFullyCharged ? 0 : TotalTicks * 100;
Name = info.Name == null ? string.Empty : TranslationProvider.GetString(info.Name);
Description = info.Description == null ? string.Empty : TranslationProvider.GetString(info.Description);
Name = info.Name == null ? string.Empty : FluentProvider.GetString(info.Name);
Description = info.Description == null ? string.Empty : FluentProvider.GetString(info.Description);
Manager = manager;
}

View File

@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
public abstract class TooltipInfoBase : ConditionalTraitInfo, Requires<IMouseBoundsInfo>
{
[FieldLoader.Require]
[TranslationReference]
[FluentReference]
public readonly string Name;
}
@@ -31,22 +31,22 @@ namespace OpenRA.Mods.Common.Traits
{
[Desc("An optional generic name (i.e. \"Soldier\" or \"Structure\")" +
"to be shown to chosen players.")]
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string GenericName;
[Desc("Prefix generic tooltip name with 'Ally/Neutral/EnemyPrefix'.")]
public readonly bool GenericStancePrefix = true;
[Desc("Prefix to display in the tooltip for allied units.")]
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string AllyPrefix = "label-tooltip-prefix.ally";
[Desc("Prefix to display in the tooltip for neutral units.")]
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string NeutralPrefix;
[Desc("Prefix to display in the tooltip for enemy units.")]
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string EnemyPrefix = "label-tooltip-prefix.enemy";
[Desc("Player stances that the generic name should be shown to.")]
@@ -60,19 +60,19 @@ namespace OpenRA.Mods.Common.Traits
public string TooltipForPlayerStance(PlayerRelationship relationship)
{
if (relationship == PlayerRelationship.None || !GenericVisibility.HasRelationship(relationship))
return TranslationProvider.GetString(Name);
return FluentProvider.GetString(Name);
var genericName = string.IsNullOrEmpty(GenericName) ? "" : TranslationProvider.GetString(GenericName);
var genericName = string.IsNullOrEmpty(GenericName) ? "" : FluentProvider.GetString(GenericName);
if (GenericStancePrefix)
{
if (!string.IsNullOrEmpty(AllyPrefix) && relationship == PlayerRelationship.Ally)
return TranslationProvider.GetString(AllyPrefix) + " " + genericName;
return FluentProvider.GetString(AllyPrefix) + " " + genericName;
if (!string.IsNullOrEmpty(NeutralPrefix) && relationship == PlayerRelationship.Neutral)
return TranslationProvider.GetString(NeutralPrefix) + " " + genericName;
return FluentProvider.GetString(NeutralPrefix) + " " + genericName;
if (!string.IsNullOrEmpty(EnemyPrefix) && relationship == PlayerRelationship.Enemy)
return TranslationProvider.GetString(EnemyPrefix) + " " + genericName;
return FluentProvider.GetString(EnemyPrefix) + " " + genericName;
}
return genericName;

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
public class TooltipDescriptionInfo : ConditionalTraitInfo
{
[FieldLoader.Require]
[TranslationReference]
[FluentReference]
[Desc("Text shown in tooltip.")]
public readonly string Description;
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
: base(info)
{
this.self = self;
TooltipText = TranslationProvider.GetString(info.Description);
TooltipText = FluentProvider.GetString(info.Description);
}
public bool IsTooltipVisible(Player forPlayer)

View File

@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when transforming.")]
public readonly string TransformNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when transforming.")]
public readonly string TransformTextNotification = null;
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when the transformation is blocked.")]
public readonly string NoTransformNotification = null;
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
[Desc("Text notification to display when the transformation is blocked.")]
public readonly string NoTransformTextNotification = null;

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
{
const string CommandName = "triggers";
[TranslationReference]
[FluentReference]
const string CommandDescription = "description-cell-triggers-overlay";
bool enabled;

View File

@@ -24,13 +24,13 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Configuration options for the lobby player color picker. Attach this to the world actor.")]
public class ColorPickerManagerInfo : TraitInfo<ColorPickerManager>, IColorPickerManagerInfo
{
[TranslationReference]
[FluentReference]
const string PlayerColorTerrain = "notification-player-color-terrain";
[TranslationReference]
[FluentReference]
const string PlayerColorPlayer = "notification-player-color-player";
[TranslationReference]
[FluentReference]
const string InvalidPlayerColor = "notification-invalid-player-color";
[Desc("Minimum and maximum saturation levels that are valid for use.")]

View File

@@ -21,11 +21,11 @@ namespace OpenRA.Mods.Common.Traits
[TraitLocation(SystemActors.World)]
public class CrateSpawnerInfo : TraitInfo, ILobbyOptions
{
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the crates checkbox in the lobby.")]
public readonly string CheckboxLabel = "checkbox-crates.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the crates checkbox in the lobby.")]
public readonly string CheckboxDescription = "checkbox-crates.description";

View File

@@ -146,12 +146,12 @@ namespace OpenRA.Mods.Common.Traits
sealed class OpenMapAction : IEditorAction
{
[TranslationReference]
[FluentReference]
const string Opened = "notification-opened";
public OpenMapAction()
{
Text = TranslationProvider.GetString(Opened);
Text = FluentProvider.GetString(Opened);
}
public void Execute()

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly ActorInfo Info;
public string Tooltip =>
(tooltip == null ? " < " + Info.Name + " >" : TranslationProvider.GetString(tooltip.Name)) + "\n" + Owner.Name + " (" + Owner.Faction + ")"
(tooltip == null ? " < " + Info.Name + " >" : FluentProvider.GetString(tooltip.Name)) + "\n" + Owner.Name + " (" + Owner.Faction + ")"
+ "\nID: " + ID + "\nType: " + Info.Name;
public string Type => reference.Type;

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
{
const string CommandName = "exits-overlay";
[TranslationReference]
[FluentReference]
const string CommandDescription = "description-exits-overlay";
public readonly SpriteFont Font;

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
{
const string CommandName = "hpf";
[TranslationReference]
[FluentReference]
const string CommandDescription = "description-hpf-debug-overlay";
readonly HierarchicalPathFinderOverlayInfo info;

View File

@@ -18,11 +18,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Controls the build radius checkboxes in the lobby options.")]
public class MapBuildRadiusInfo : TraitInfo, ILobbyOptions
{
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the ally build radius checkbox in the lobby.")]
public readonly string AllyBuildRadiusCheckboxLabel = "checkbox-ally-build-radius.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the ally build radius checkbox in the lobby.")]
public readonly string AllyBuildRadiusCheckboxDescription = "checkbox-ally-build-radius.description";
@@ -38,11 +38,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Display order for the ally build radius checkbox in the lobby.")]
public readonly int AllyBuildRadiusCheckboxDisplayOrder = 0;
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the build radius checkbox in the lobby.")]
public readonly string BuildRadiusCheckboxLabel = "checkbox-build-radius.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the build radius checkbox in the lobby.")]
public readonly string BuildRadiusCheckboxDescription = "checkbox-build-radius.description";

View File

@@ -18,11 +18,11 @@ namespace OpenRA.Mods.Common.Traits
[TraitLocation(SystemActors.World)]
public class MapCreepsInfo : TraitInfo, ILobbyOptions
{
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the creeps checkbox in the lobby.")]
public readonly string CheckboxLabel = "dropdown-map-creeps.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the creeps checkbox in the lobby.")]
public readonly string CheckboxDescription = "dropdown-map-creeps.description";

View File

@@ -19,11 +19,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Controls the game speed, tech level, and short game lobby options.")]
public class MapOptionsInfo : TraitInfo, ILobbyOptions, IRulesetLoaded
{
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the short game checkbox in the lobby.")]
public readonly string ShortGameCheckboxLabel = "checkbox-short-game.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the short game checkbox in the lobby.")]
public readonly string ShortGameCheckboxDescription = "checkbox-short-game.description";
@@ -39,11 +39,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Display order for the short game checkbox in the lobby.")]
public readonly int ShortGameCheckboxDisplayOrder = 0;
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the tech level option in the lobby.")]
public readonly string TechLevelDropdownLabel = "dropdown-tech-level.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the tech level option in the lobby.")]
public readonly string TechLevelDropdownDescription = "dropdown-tech-level.description";
@@ -59,11 +59,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Display order for the tech level option in the lobby.")]
public readonly int TechLevelDropdownDisplayOrder = 0;
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the game speed option in the lobby.")]
public readonly string GameSpeedDropdownLabel = "dropdown-game-speed.label";
[TranslationReference]
[FluentReference]
[Desc("Description of the game speed option in the lobby.")]
public readonly string GameSpeedDropdownDescription = "dropdown-game-speed.description";
@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Traits
techLevels, TechLevel, TechLevelDropdownLocked);
var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>();
var speeds = gameSpeeds.Speeds.ToDictionary(s => s.Key, s => TranslationProvider.GetString(s.Value.Name));
var speeds = gameSpeeds.Speeds.ToDictionary(s => s.Key, s => FluentProvider.GetString(s.Value.Name));
// NOTE: This is just exposing the UI, the backend logic for this option is hardcoded in World.
yield return new LobbyOption(map, "gamespeed",

View File

@@ -25,11 +25,11 @@ namespace OpenRA.Mods.Common.Traits
{
public readonly WDist InitialExploreRange = WDist.FromCells(5);
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the spawn positions checkbox in the lobby.")]
public readonly string SeparateTeamSpawnsCheckboxLabel = "checkbox-separate-team-spawns.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the spawn positions checkbox in the lobby.")]
public readonly string SeparateTeamSpawnsCheckboxDescription = "checkbox-separate-team-spawns.description";

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Internal class ID.")]
public readonly string Class = "none";
[TranslationReference]
[FluentReference]
[Desc("Exposed via the UI to the player.")]
public readonly string ClassName = "Unlabeled";

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
{
const string CommandName = "path-debug";
[TranslationReference]
[FluentReference]
const string CommandDescription = "description-path-debug-overlay";
sealed class Record : PathSearch.IRecorder, IEnumerable<(CPos Source, CPos Destination, int CostSoFar, int EstimatedRemainingCost)>

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
[FieldLoader.Require]
[Desc("Resource name used by tooltips.")]
[TranslationReference]
[FluentReference]
public readonly string Name = null;
public ResourceTypeInfo(MiniYaml yaml)
@@ -273,7 +273,7 @@ namespace OpenRA.Mods.Common.Traits
if (info == null)
return null;
return TranslationProvider.GetString(info.Name);
return FluentProvider.GetString(info.Name);
}
IEnumerable<string> IResourceRenderer.ResourceTypes => Info.ResourceTypes.Keys;

View File

@@ -23,11 +23,11 @@ namespace OpenRA.Mods.Common.Traits
public readonly string ID = null;
[FieldLoader.Require]
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for this option.")]
public readonly string Label = null;
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for this option.")]
public readonly string Description = null;
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly string Default = null;
[FieldLoader.Require]
[TranslationReference(dictionaryReference: LintDictionaryReference.Values)]
[FluentReference(dictionaryReference: LintDictionaryReference.Values)]
[Desc("Options to choose from.")]
public readonly Dictionary<string, string> Values = null;

View File

@@ -25,11 +25,11 @@ namespace OpenRA.Mods.Common.Traits
{
public readonly string StartingUnitsClass = "none";
[TranslationReference]
[FluentReference]
[Desc("Descriptive label for the starting units option in the lobby.")]
public readonly string DropdownLabel = "dropdown-starting-units.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description for the starting units option in the lobby.")]
public readonly string DropdownDescription = "dropdown-starting-units.description";

View File

@@ -20,19 +20,19 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")]
public readonly string Notification = "StartGame";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string TextNotification = null;
[NotificationReference("Speech")]
public readonly string LoadedNotification = "GameLoaded";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string LoadedTextNotification = null;
[NotificationReference("Speech")]
public readonly string SavedNotification = "GameSaved";
[TranslationReference(optional: true)]
[FluentReference(optional: true)]
public readonly string SavedTextNotification = null;
public override object Create(ActorInitializer init) { return new StartGameNotification(this); }

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits
{
const string CommandName = "terrain-geometry";
[TranslationReference]
[FluentReference]
const string CommandDescription = "description-terrain-geometry-overlay";
public bool Enabled;

View File

@@ -22,11 +22,11 @@ namespace OpenRA.Mods.Common.Traits
[Desc("This trait allows setting a time limit on matches. Attach this to the World actor.")]
public class TimeLimitManagerInfo : TraitInfo, ILobbyOptions, IRulesetLoaded
{
[TranslationReference]
[FluentReference]
[Desc("Label that will be shown for the time limit option in the lobby.")]
public readonly string TimeLimitLabel = "dropdown-time-limit.label";
[TranslationReference]
[FluentReference]
[Desc("Tooltip description that will be shown for the time limit option in the lobby.")]
public readonly string TimeLimitDescription = "dropdown-time-limit.description";
@@ -77,10 +77,10 @@ namespace OpenRA.Mods.Common.Traits
throw new YamlException("TimeLimitDefault must be a value from TimeLimitOptions");
}
[TranslationReference]
[FluentReference]
const string NoTimeLimit = "options-time-limit.no-limit";
[TranslationReference("minutes")]
[FluentReference("minutes")]
const string TimeLimitOption = "options-time-limit.options";
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(MapPreview map)
@@ -88,9 +88,9 @@ namespace OpenRA.Mods.Common.Traits
var timelimits = TimeLimitOptions.ToDictionary(m => m.ToStringInvariant(), m =>
{
if (m == 0)
return TranslationProvider.GetString(NoTimeLimit);
return FluentProvider.GetString(NoTimeLimit);
else
return TranslationProvider.GetString(TimeLimitOption, Translation.Arguments("minutes", m));
return FluentProvider.GetString(TimeLimitOption, FluentBundle.Arguments("minutes", m));
});
yield return new LobbyOption(map, "timelimit", TimeLimitLabel, TimeLimitDescription, TimeLimitDropdownVisible, TimeLimitDisplayOrder,
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.Common.Traits
public class TimeLimitManager : INotifyTimeLimit, ITick, IWorldLoaded
{
[TranslationReference]
[FluentReference]
const string TimeLimitExpired = "notification-time-limit-expired";
readonly TimeLimitManagerInfo info;
@@ -182,7 +182,7 @@ namespace OpenRA.Mods.Common.Traits
countdownLabel.GetText = () => null;
if (!info.SkipTimerExpiredNotification)
TextNotificationsManager.AddSystemLine(TranslationProvider.GetString(TimeLimitExpired));
TextNotificationsManager.AddSystemLine(FluentProvider.GetString(TimeLimitExpired));
}
}
}

View File

@@ -334,11 +334,11 @@ namespace OpenRA.Mods.Common.UpdateRules
return string.Join("\n", messages.Select(m => prefix + $" {separator} {m.Replace("\n", "\n " + prefix)}"));
}
public static bool IsAlreadyTranslated(string translation)
public static bool IsAlreadyExtracted(string key)
{
if (translation == translation.ToLowerInvariant() && translation.Any(c => c == '-') && translation.All(c => c != ' '))
if (key == key.ToLowerInvariant() && key.Any(c => c == '-') && key.All(c => c != ' '))
{
Console.WriteLine($"Skipping {translation} because it is already translated.");
Console.WriteLine($"Skipping {key} because it is already extracted.");
return true;
}

View File

@@ -11,7 +11,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using OpenRA.FileSystem;
@@ -37,11 +36,11 @@ namespace OpenRA.Mods.Common.UtilityCommands
// HACK: The engine code assumes that Game.modData is set.
var modData = Game.ModData = utility.ModData;
var translatableFields = modData.ObjectCreator.GetTypes()
var widgetInfos = modData.ObjectCreator.GetTypes()
.Where(t => t.Name.EndsWith("Widget", StringComparison.InvariantCulture) && t.IsSubclassOf(typeof(Widget)))
.ToDictionary(
t => t.Name[..^6],
t => t.GetFields().Where(f => f.HasAttribute<TranslationReferenceAttribute>()).Select(f => f.Name).ToArray())
t => t.GetFields().Where(f => f.HasAttribute<FluentReferenceAttribute>()).Select(f => f.Name).ToArray())
.Where(t => t.Value.Length > 0)
.ToDictionary(t => t.Key, t => t.Value);
@@ -53,12 +52,12 @@ namespace OpenRA.Mods.Common.UtilityCommands
var fluentPackage = modData.ModFiles.OpenPackage(fluentFolder);
var fluentPath = Path.Combine(fluentPackage.Name, "chrome/en.ftl");
var unsortedCandidates = new List<TranslationCandidate>();
var groupedCandidates = new Dictionary<HashSet<string>, List<TranslationCandidate>>();
var unsortedCandidates = new List<ExtractionCandidate>();
var groupedCandidates = new Dictionary<HashSet<string>, List<ExtractionCandidate>>();
var yamlSet = new YamlFileSet();
// Get all translations.
// Get all string candidates.
foreach (var chrome in layout)
{
modData.ModFiles.TryGetPackageContaining(chrome, out var chromePackage, out var chromeName);
@@ -67,40 +66,40 @@ namespace OpenRA.Mods.Common.UtilityCommands
var yaml = MiniYaml.FromFile(chromePath, false).ConvertAll(n => new MiniYamlNodeBuilder(n));
yamlSet.Add(((IReadWritePackage)chromePackage, chromeName, yaml));
var translationCandidates = new List<TranslationCandidate>();
var extractionCandidates = new List<ExtractionCandidate>();
foreach (var node in yaml)
{
if (node.Key != null)
{
var nodeSplit = node.Key.Split('@');
var nodeId = nodeSplit.Length > 1 ? ClearContainersAndToLower(nodeSplit[1]) : null;
FromChromeLayout(node, translatableFields, nodeId, ref translationCandidates);
FromChromeLayout(node, widgetInfos, nodeId, ref extractionCandidates);
}
}
if (translationCandidates.Count > 0)
if (extractionCandidates.Count > 0)
{
var chromeFilename = chrome.Split('/').Last();
groupedCandidates[new HashSet<string>() { chromeFilename }] = new List<TranslationCandidate>();
for (var i = 0; i < translationCandidates.Count; i++)
groupedCandidates[new HashSet<string>() { chromeFilename }] = new List<ExtractionCandidate>();
for (var i = 0; i < extractionCandidates.Count; i++)
{
var candidate = translationCandidates[i];
var candidate = extractionCandidates[i];
candidate.Chrome = chromeFilename;
unsortedCandidates.Add(candidate);
}
}
}
// Join matching translations.
// Join matching candidates.
foreach (var candidate in unsortedCandidates)
{
HashSet<string> foundHash = null;
TranslationCandidate found = default;
foreach (var (hash, translation) in groupedCandidates)
ExtractionCandidate found = default;
foreach (var (hash, candidates) in groupedCandidates)
{
foreach (var c in translation)
foreach (var c in candidates)
{
if (c.Key == candidate.Key && c.Type == candidate.Type && c.Translation == candidate.Translation)
if (c.Key == candidate.Key && c.Type == candidate.Type && c.Value == candidate.Value)
{
foundHash = hash;
found = c;
@@ -127,7 +126,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (nHash.Key != null)
groupedCandidates[nHash.Key].Add(candidate);
else
groupedCandidates[newHash] = new List<TranslationCandidate>() { candidate };
groupedCandidates[newHash] = new List<ExtractionCandidate>() { candidate };
}
var startWithNewline = File.Exists(fluentPath);
@@ -136,7 +135,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (!startWithNewline)
Directory.CreateDirectory(Path.GetDirectoryName(fluentPath));
// Write to translation files.
// Write output .ftl files.
using (var fluentWriter = new StreamWriter(fluentPath, append: true))
{
foreach (var (chromeFilename, candidates) in groupedCandidates.OrderBy(t => string.Join(',', t.Key)))
@@ -151,30 +150,28 @@ namespace OpenRA.Mods.Common.UtilityCommands
fluentWriter.WriteLine("## " + string.Join(", ", chromeFilename));
// Pushing blocks of translations to string first allows for fancier formatting.
// Pushing blocks to string first allows for fancier formatting.
var build = "";
foreach (var grouping in candidates.GroupBy(t => t.Key))
{
if (grouping.Count() == 1)
{
var candidate = grouping.First();
var translationKey = candidate.Key;
if (candidate.Type == "text")
translationKey = $"{translationKey}";
else
translationKey = $"{translationKey}-" + candidate.Type.Replace("text", "");
var key = candidate.Key;
if (candidate.Type != "text")
key = $"{key}-" + candidate.Type.Replace("text", "");
build += $"{translationKey} = {candidate.Translation}\n";
build += $"{key} = {candidate.Value}\n";
foreach (var node in candidate.Nodes)
node.Value.Value = translationKey;
node.Value.Value = key;
}
else
{
if (build.Length > 1 && build.Substring(build.Length - 2, 2) != "\n\n")
build += "\n";
var translationKey = grouping.Key;
build += $"{translationKey} =\n";
var key = grouping.Key;
build += $"{key} =\n";
foreach (var candidate in grouping)
{
var type = candidate.Type;
@@ -186,9 +183,9 @@ namespace OpenRA.Mods.Common.UtilityCommands
type = type.Replace("text", "");
}
build += $" .{type} = {candidate.Translation}\n";
build += $" .{type} = {candidate.Value}\n";
foreach (var node in candidate.Nodes)
node.Value.Value = $"{translationKey}.{type}";
node.Value.Value = $"{key}.{type}";
}
build += "\n";
@@ -203,20 +200,20 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
struct TranslationCandidate
struct ExtractionCandidate
{
public string Chrome;
public readonly string Key;
public readonly string Type;
public readonly string Translation;
public readonly string Value;
public readonly List<MiniYamlNodeBuilder> Nodes;
public TranslationCandidate(string key, string type, string translation, MiniYamlNodeBuilder node)
public ExtractionCandidate(string key, string type, string value, MiniYamlNodeBuilder node)
{
Chrome = null;
Key = key;
Type = type;
Translation = translation;
Value = value;
Nodes = new List<MiniYamlNodeBuilder>() { node };
}
}
@@ -245,88 +242,69 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
static void FromChromeLayout(
MiniYamlNodeBuilder node, Dictionary<string, string[]> translatables, string container, ref List<TranslationCandidate> translations)
MiniYamlNodeBuilder node, Dictionary<string, string[]> widgetInfos, string container, ref List<ExtractionCandidate> candidates)
{
var nodeSplit = node.Key.Split('@');
var nodeType = nodeSplit[0];
var widgetType = nodeSplit[0];
var nodeId = nodeSplit.Length > 1 ? ClearContainersAndToLower(nodeSplit[1]) : null;
if ((nodeType == "Background" || nodeType == "Container") && nodeId != null)
if ((widgetType == "Background" || widgetType == "Container") && nodeId != null)
container = nodeId;
// Get translatable types.
var validChildTypes = new List<(MiniYamlNodeBuilder Node, string Type, string Value)>();
foreach (var childNode in node.Value.Nodes)
{
if (translatables.TryGetValue(nodeType, out var fieldName))
if (widgetInfos.TryGetValue(widgetType, out var fieldName))
{
var childType = childNode.Key.Split('@')[0];
if (fieldName.Contains(childType)
&& !string.IsNullOrEmpty(childNode.Value.Value)
&& !UpdateUtils.IsAlreadyTranslated(childNode.Value.Value)
&& !UpdateUtils.IsAlreadyExtracted(childNode.Value.Value)
&& childNode.Value.Value.Any(char.IsLetterOrDigit))
{
var translationValue = childNode.Value.Value
var value = childNode.Value.Value
.Replace("\\n", "\n ")
.Replace("{", "<")
.Replace("}", ">")
.Trim().Trim('\n');
validChildTypes.Add((childNode, childType.ToLowerInvariant(), translationValue));
validChildTypes.Add((childNode, childType.ToLowerInvariant(), value));
}
}
}
// Generate translation key.
// Generate string key.
if (validChildTypes.Count > 0)
{
nodeType = ClearTypesAndToLower(nodeType);
widgetType = ClearTypesAndToLower(widgetType);
var translationKey = nodeType;
var key = widgetType;
if (!string.IsNullOrEmpty(container))
{
var containerType = string.Join('-', container.Split('_').Exclude(nodeType).Where(s => !string.IsNullOrEmpty(s)));
var containerType = string.Join('-', container.Split('_').Exclude(widgetType).Where(s => !string.IsNullOrEmpty(s)));
if (!string.IsNullOrEmpty(containerType))
translationKey = $"{translationKey}-{containerType}";
key = $"{key}-{containerType}";
}
if (!string.IsNullOrEmpty(nodeId))
{
nodeId = string.Join('-', nodeId.Split('_')
.Except(string.IsNullOrEmpty(container) ? new string[] { nodeType } : container.Split('_').Append(nodeType))
.Except(string.IsNullOrEmpty(container) ? new string[] { widgetType } : container.Split('_').Append(widgetType))
.Where(s => !string.IsNullOrEmpty(s)));
if (!string.IsNullOrEmpty(nodeId))
translationKey = $"{translationKey}-{nodeId}";
key = $"{key}-{nodeId}";
}
foreach (var (childNode, childType, translationValue) in validChildTypes)
translations.Add(new TranslationCandidate(translationKey, childType, translationValue.Trim().Trim('\n'), childNode));
foreach (var (childNode, childType, childValue) in validChildTypes)
candidates.Add(new ExtractionCandidate(key, childType, childValue.Trim().Trim('\n'), childNode));
}
// Recursive.
foreach (var childNode in node.Value.Nodes)
if (childNode.Key == "Children")
foreach (var n in childNode.Value.Nodes)
FromChromeLayout(n, translatables, container, ref translations);
}
/// <summary>This is a helper method to find untranslated strings in chrome layouts.</summary>
public static void FindUntranslatedStringFields(ModData modData)
{
var types = modData.ObjectCreator.GetTypes();
foreach (var (type, fields) in types
.Where(t => t.Name.EndsWith("Widget", StringComparison.InvariantCulture) && t.IsSubclassOf(typeof(Widget)))
.ToDictionary(
t => t.Name[..^6],
t => t
.GetFields()
.Where(f => f.Name != "Id" && f.IsPublic && f.FieldType == typeof(string) && !f.HasAttribute<TranslationReferenceAttribute>())
.Distinct()
.Select(f => f.Name)
.ToList()))
if (fields.Count > 0)
Console.WriteLine($"{type}Widget:\n {string.Join("\n ", fields)}");
FromChromeLayout(n, widgetInfos, container, ref candidates);
}
}
}

View File

@@ -33,17 +33,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
return true;
}
[Desc("Extract translatable strings that are not yet localized.")]
[Desc("Extract fluent strings that are not yet localized.")]
void IUtilityCommand.Run(Utility utility, string[] args)
{
// HACK: The engine code assumes that Game.modData is set.
var modData = Game.ModData = utility.ModData;
var translatables = modData.ObjectCreator.GetTypes()
var traitInfos = modData.ObjectCreator.GetTypes()
.Where(t => t.Name.EndsWith("Info", StringComparison.InvariantCulture) && t.IsSubclassOf(typeof(TraitInfo)))
.ToDictionary(
t => t.Name[..^4],
t => t.GetFields().Where(f => f.HasAttribute<TranslationReferenceAttribute>()).Select(f => f.Name).ToArray())
t => t.GetFields().Where(f => f.HasAttribute<FluentReferenceAttribute>()).Select(f => f.Name).ToArray())
.Where(t => t.Value.Length > 0)
.ToDictionary(t => t.Key, t => t.Value);
@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
var fluentPackage = modData.ModFiles.OpenPackage(modData.Manifest.Id + "|languages");
ExtractFromFile(Path.Combine(fluentPackage.Name, "rules/en.ftl"), modRules, translatables);
ExtractFromFile(Path.Combine(fluentPackage.Name, "rules/en.ftl"), modRules, traitInfos);
modRules.Save();
// Extract from maps.
@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
mapRules.AddRange(UpdateUtils.LoadInternalMapYaml(modData, package, mapRulesNode.Value, new HashSet<string>()));
const string Enftl = "en.ftl";
ExtractFromFile(Path.Combine(package.Name, Enftl), mapRules, translatables, () =>
ExtractFromFile(Path.Combine(package.Name, Enftl), mapRules, traitInfos, () =>
{
var node = yaml.NodeWithKeyOrDefault("Translations");
if (node != null)
@@ -102,26 +102,26 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
static void ExtractFromFile(string fluentPath, YamlFileSet yamlSet, Dictionary<string, string[]> translatables, Action addTranslation = null)
static void ExtractFromFile(string fluentPath, YamlFileSet yamlSet, Dictionary<string, string[]> traitInfos, Action addAction = null)
{
var unsortedCandidates = new List<TranslationCandidate>();
var groupedCandidates = new Dictionary<HashSet<string>, List<TranslationCandidate>>();
var unsortedCandidates = new List<ExtractionCandidate>();
var groupedCandidates = new Dictionary<HashSet<string>, List<ExtractionCandidate>>();
// Get all translations.
foreach (var (_, file, nodes) in yamlSet)
// Get all string candidates.
foreach (var (_, file, actors) in yamlSet)
{
var translationCandidates = new List<TranslationCandidate>();
foreach (var actor in nodes)
var candidates = new List<ExtractionCandidate>();
foreach (var actor in actors)
if (actor.Key != null)
ExtractFromActor(actor, translatables, ref translationCandidates);
ExtractFromActor(actor, traitInfos, ref candidates);
if (translationCandidates.Count > 0)
if (candidates.Count > 0)
{
var ruleFilename = file.Split('/').Last();
groupedCandidates[new HashSet<string>() { ruleFilename }] = new List<TranslationCandidate>();
for (var i = 0; i < translationCandidates.Count; i++)
groupedCandidates[new HashSet<string>() { ruleFilename }] = new List<ExtractionCandidate>();
for (var i = 0; i < candidates.Count; i++)
{
var candidate = translationCandidates[i];
var candidate = candidates[i];
candidate.Filename = ruleFilename;
unsortedCandidates.Add(candidate);
}
@@ -131,16 +131,16 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (unsortedCandidates.Count == 0)
return;
// Join matching translations.
// Join matching candidates.
foreach (var candidate in unsortedCandidates)
{
HashSet<string> foundHash = null;
TranslationCandidate found = default;
foreach (var (hash, translation) in groupedCandidates)
ExtractionCandidate found = default;
foreach (var (hash, candidates) in groupedCandidates)
{
foreach (var c in translation)
foreach (var c in candidates)
{
if (c.Actor == candidate.Actor && c.Key == candidate.Key && c.Translation == candidate.Translation)
if (c.Actor == candidate.Actor && c.Key == candidate.Key && c.Value == candidate.Value)
{
foundHash = hash;
found = c;
@@ -167,17 +167,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (nHash.Key != null)
groupedCandidates[nHash.Key].Add(candidate);
else
groupedCandidates[newHash] = new List<TranslationCandidate>() { candidate };
groupedCandidates[newHash] = new List<ExtractionCandidate>() { candidate };
}
addTranslation?.Invoke();
addAction?.Invoke();
// StreamWriter can't create new directories.
var startWithNewline = File.Exists(fluentPath);
if (!startWithNewline)
Directory.CreateDirectory(Path.GetDirectoryName(fluentPath));
// Write to translation files.
// Write output .ftl files.
using (var fluentWriter = new StreamWriter(fluentPath, true))
{
foreach (var (filename, candidates) in groupedCandidates.OrderBy(t => string.Join(',', t.Key)))
@@ -192,32 +192,32 @@ namespace OpenRA.Mods.Common.UtilityCommands
fluentWriter.WriteLine("## " + string.Join(", ", filename));
// Pushing blocks of translations to string first allows for fancier formatting.
// Pushing blocks to string first allows for fancier formatting.
var build = "";
foreach (var grouping in candidates.GroupBy(t => t.Actor))
{
if (grouping.Count() == 1)
{
var candidate = grouping.First();
var translationKey = $"{candidate.Actor}-{candidate.Key}";
build += $"{translationKey} = {candidate.Translation}\n";
var key = $"{candidate.Actor}-{candidate.Key}";
build += $"{key} = {candidate.Value}\n";
foreach (var node in candidate.Nodes)
node.Value.Value = translationKey;
node.Value.Value = key;
}
else
{
if (build.Length > 1 && build.Substring(build.Length - 2, 2) != "\n\n")
build += "\n";
var translationKey = grouping.Key;
build += $"{translationKey} =\n";
var key = grouping.Key;
build += $"{key} =\n";
foreach (var candidate in grouping)
{
var type = candidate.Key;
build += $" .{type} = {candidate.Translation}\n";
build += $" .{type} = {candidate.Value}\n";
foreach (var node in candidate.Nodes)
node.Value.Value = $"{translationKey}.{type}";
node.Value.Value = $"{key}.{type}";
}
build += "\n";
@@ -229,20 +229,20 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
struct TranslationCandidate
struct ExtractionCandidate
{
public string Filename;
public readonly string Actor;
public readonly string Key;
public readonly string Translation;
public readonly string Value;
public readonly List<MiniYamlNodeBuilder> Nodes;
public TranslationCandidate(string actor, string key, string translation, MiniYamlNodeBuilder node)
public ExtractionCandidate(string actor, string key, string value, MiniYamlNodeBuilder node)
{
Filename = null;
Actor = actor;
Key = key;
Translation = translation;
Value = value;
Nodes = new List<MiniYamlNodeBuilder>() { node };
}
}
@@ -279,7 +279,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
return s.ToString();
}
static void ExtractFromActor(MiniYamlNodeBuilder actor, Dictionary<string, string[]> translatables, ref List<TranslationCandidate> translations)
static void ExtractFromActor(MiniYamlNodeBuilder actor, Dictionary<string, string[]> traitInfos, ref List<ExtractionCandidate> candidates)
{
if (actor.Value?.Nodes == null)
return;
@@ -291,7 +291,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
var traitSplit = trait.Key.Split('@');
var traitInfo = traitSplit[0];
if (!translatables.TryGetValue(traitInfo, out var translatableType) || trait.Value?.Nodes == null)
if (!traitInfos.TryGetValue(traitInfo, out var type) || trait.Value?.Nodes == null)
continue;
foreach (var property in trait.Value.Nodes)
@@ -300,14 +300,14 @@ namespace OpenRA.Mods.Common.UtilityCommands
continue;
var propertyType = property.Key.Split('@')[0];
if (!translatableType.Contains(propertyType))
if (!type.Contains(propertyType))
continue;
var propertyValue = property.Value.Value;
if (string.IsNullOrEmpty(propertyValue) || UpdateUtils.IsAlreadyTranslated(propertyValue) || !propertyValue.Any(char.IsLetterOrDigit))
if (string.IsNullOrEmpty(propertyValue) || UpdateUtils.IsAlreadyExtracted(propertyValue) || !propertyValue.Any(char.IsLetterOrDigit))
continue;
var translationValue = propertyValue
var value = propertyValue
.Replace("\\n", "\n ")
.Trim().Trim('\n');
@@ -315,12 +315,12 @@ namespace OpenRA.Mods.Common.UtilityCommands
var key = traitInfo;
if (traitInfo == nameof(Buildable))
{
translations.Add(new TranslationCandidate(actorName, ToLower(propertyType), translationValue, property));
candidates.Add(new ExtractionCandidate(actorName, ToLower(propertyType), value, property));
continue;
}
else if (traitInfo == nameof(Encyclopedia))
{
translations.Add(new TranslationCandidate(actorName, ToLower(traitInfo), translationValue, property));
candidates.Add(new ExtractionCandidate(actorName, ToLower(traitInfo), value, property));
continue;
}
else if (traitInfo == nameof(Tooltip) || traitInfo == nameof(EditorOnlyTooltipInfo)[..^4])
@@ -330,7 +330,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
else
key = propertyType;
translations.Add(new TranslationCandidate(actorName, ToLower(key), translationValue, property));
candidates.Add(new ExtractionCandidate(actorName, ToLower(key), value, property));
continue;
}
@@ -339,7 +339,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
key += $"-{ToLower(propertyType)}";
translations.Add(new TranslationCandidate(actorName, key.ToLowerInvariant(), translationValue, property));
candidates.Add(new ExtractionCandidate(actorName, key.ToLowerInvariant(), value, property));
}
}
}

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Widgets
public bool DisableKeyRepeat = false;
public bool DisableKeySound = false;
[TranslationReference]
[FluentReference]
public string Text = "";
public TextAlign Align = TextAlign.Center;
public int LeftMargin = 5;
@@ -55,11 +55,11 @@ namespace OpenRA.Mods.Common.Widgets
protected Lazy<TooltipContainerWidget> tooltipContainer;
[TranslationReference]
[FluentReference]
public string TooltipText;
public Func<string> GetTooltipText;
[TranslationReference]
[FluentReference]
public string TooltipDesc;
public Func<string> GetTooltipDesc;
@@ -77,9 +77,9 @@ namespace OpenRA.Mods.Common.Widgets
{
ModRules = modData.DefaultRules;
var textCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? TranslationProvider.GetString(s) : "");
var tooltipTextCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? TranslationProvider.GetString(s) : "");
var tooltipDescCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? TranslationProvider.GetString(s) : "");
var textCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? FluentProvider.GetString(s) : "");
var tooltipTextCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? FluentProvider.GetString(s) : "");
var tooltipDescCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? FluentProvider.GetString(s) : "");
GetText = () => textCache.Update(Text);
GetColor = () => TextColor;

View File

@@ -36,11 +36,11 @@ namespace OpenRA.Mods.Common.Widgets
var cancelButton = prompt.GetOrNull<ButtonWidget>("CANCEL_BUTTON");
var otherButton = prompt.GetOrNull<ButtonWidget>("OTHER_BUTTON");
var titleMessage = TranslationProvider.GetString(title, titleArguments);
var titleMessage = FluentProvider.GetString(title, titleArguments);
prompt.Get<LabelWidget>("PROMPT_TITLE").GetText = () => titleMessage;
var headerTemplate = prompt.Get<LabelWidget>("PROMPT_TEXT");
var textMessage = TranslationProvider.GetString(text, textArguments);
var textMessage = FluentProvider.GetString(text, textArguments);
var headerLines = textMessage.Split('\n');
var headerHeight = 0;
foreach (var l in headerLines)
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Widgets
if (!string.IsNullOrEmpty(confirmText))
{
var confirmTextMessage = TranslationProvider.GetString(confirmText);
var confirmTextMessage = FluentProvider.GetString(confirmText);
confirmButton.GetText = () => confirmTextMessage;
}
}
@@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Widgets
if (!string.IsNullOrEmpty(cancelText))
{
var cancelTextMessage = TranslationProvider.GetString(cancelText);
var cancelTextMessage = FluentProvider.GetString(cancelText);
cancelButton.GetText = () => cancelTextMessage;
}
}
@@ -98,7 +98,7 @@ namespace OpenRA.Mods.Common.Widgets
if (!string.IsNullOrEmpty(otherText))
{
var otherTextMessage = TranslationProvider.GetString(otherText);
var otherTextMessage = FluentProvider.GetString(otherText);
otherButton.GetText = () => otherTextMessage;
}
}
@@ -114,10 +114,10 @@ namespace OpenRA.Mods.Common.Widgets
Func<bool> doValidate = null;
ButtonWidget acceptButton = null, cancelButton = null;
var titleMessage = TranslationProvider.GetString(title);
var titleMessage = FluentProvider.GetString(title);
panel.Get<LabelWidget>("PROMPT_TITLE").GetText = () => titleMessage;
var promptMessage = TranslationProvider.GetString(prompt);
var promptMessage = FluentProvider.GetString(prompt);
panel.Get<LabelWidget>("PROMPT_TEXT").GetText = () => promptMessage;
var input = panel.Get<TextFieldWidget>("INPUT_TEXT");
@@ -147,7 +147,7 @@ namespace OpenRA.Mods.Common.Widgets
acceptButton = panel.Get<ButtonWidget>("ACCEPT_BUTTON");
if (!string.IsNullOrEmpty(acceptText))
{
var acceptTextMessage = TranslationProvider.GetString(acceptText);
var acceptTextMessage = FluentProvider.GetString(acceptText);
acceptButton.GetText = () => acceptTextMessage;
}
@@ -163,7 +163,7 @@ namespace OpenRA.Mods.Common.Widgets
cancelButton = panel.Get<ButtonWidget>("CANCEL_BUTTON");
if (!string.IsNullOrEmpty(cancelText))
{
var cancelTextMessage = TranslationProvider.GetString(cancelText);
var cancelTextMessage = FluentProvider.GetString(cancelText);
cancelButton.GetText = () => cancelTextMessage;
}

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Widgets
public Func<string> GetImageCollection;
public Func<Sprite> GetSprite;
[TranslationReference]
[FluentReference]
public string TooltipText;
readonly Lazy<TooltipContainerWidget> tooltipContainer;
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Widgets
{
GetImageName = () => ImageName;
GetImageCollection = () => ImageCollection;
var tooltipCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? TranslationProvider.GetString(s) : "");
var tooltipCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? FluentProvider.GetString(s) : "");
GetTooltipText = () => tooltipCache.Update(TooltipText);
tooltipContainer = Exts.Lazy(() =>
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Widgets
public class LabelWidget : Widget
{
[TranslationReference]
[FluentReference]
public string Text = null;
public TextAlign Align = TextAlign.Left;
public TextVAlign VAlign = TextVAlign.Middle;
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Widgets
[ObjectCreator.UseCtor]
public LabelWidget(ModData modData)
{
var textCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? TranslationProvider.GetString(s) : "");
var textCache = new CachedTransform<string, string>(s => !string.IsNullOrEmpty(s) ? FluentProvider.GetString(s) : "");
GetText = () => textCache.Update(Text);
GetColor = () => TextColor;
GetContrastColorDark = () => ContrastColorDark;

View File

@@ -35,10 +35,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Unknown = 16
}
[TranslationReference("length")]
[FluentReference("length")]
const string LengthInSeconds = "label-length-in-seconds";
[TranslationReference]
[FluentReference]
const string AllPackages = "label-all-packages";
readonly string[] allowedExtensions;
@@ -96,7 +96,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
this.modData = modData;
panel = widget;
allPackages = TranslationProvider.GetString(AllPackages);
allPackages = FluentProvider.GetString(AllPackages);
var colorPickerPalettes = world.WorldActor.TraitsImplementing<IProvidesAssetBrowserColorPickerPalettes>()
.SelectMany(p => p.ColorPickerPaletteNames)
@@ -238,7 +238,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (frameText != null)
{
var soundLength = new CachedTransform<double, string>(p =>
TranslationProvider.GetString(LengthInSeconds, Translation.Arguments("length", Math.Round(p, 3))));
FluentProvider.GetString(LengthInSeconds, FluentBundle.Arguments("length", Math.Round(p, 3))));
frameText.GetText = () =>
{

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ConnectionLogic : ChromeLogic
{
[TranslationReference("endpoint")]
[FluentReference("endpoint")]
const string ConnectingToEndpoint = "label-connecting-to-endpoint";
readonly Action onConnect;
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var panel = widget;
panel.Get<ButtonWidget>("ABORT_BUTTON").OnClick = () => { CloseWindow(); onAbort(); };
var connectingDesc = TranslationProvider.GetString(ConnectingToEndpoint, Translation.Arguments("endpoint", endpoint));
var connectingDesc = FluentProvider.GetString(ConnectingToEndpoint, FluentBundle.Arguments("endpoint", endpoint));
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () => connectingDesc;
}
@@ -87,16 +87,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class ConnectionFailedLogic : ChromeLogic
{
[TranslationReference("target")]
[FluentReference("target")]
const string CouldNotConnectToTarget = "label-could-not-connect-to-target";
[TranslationReference]
[FluentReference]
const string UnknownError = "label-unknown-error";
[TranslationReference]
[FluentReference]
const string PasswordRequired = "label-password-required";
[TranslationReference]
[FluentReference]
const string ConnectionFailed = "label-connection-failed";
readonly PasswordFieldWidget passwordField;
@@ -130,17 +130,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
onRetry(pass);
};
var connectingDescText = TranslationProvider.GetString(CouldNotConnectToTarget, Translation.Arguments("target", connection.Target));
var connectingDescText = FluentProvider.GetString(CouldNotConnectToTarget, FluentBundle.Arguments("target", connection.Target));
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () => connectingDescText;
var connectionError = widget.Get<LabelWidget>("CONNECTION_ERROR");
var connectionErrorText = orderManager.ServerError != null
? TranslationProvider.GetString(orderManager.ServerError)
: connection.ErrorMessage ?? TranslationProvider.GetString(UnknownError);
? FluentProvider.GetString(orderManager.ServerError)
: connection.ErrorMessage ?? FluentProvider.GetString(UnknownError);
connectionError.GetText = () => connectionErrorText;
var panelTitle = widget.Get<LabelWidget>("TITLE");
var panelTitleText = orderManager.AuthenticationFailed ? TranslationProvider.GetString(PasswordRequired) : TranslationProvider.GetString(ConnectionFailed);
var panelTitleText = orderManager.AuthenticationFailed ? FluentProvider.GetString(PasswordRequired) : FluentProvider.GetString(ConnectionFailed);
panelTitle.GetText = () => panelTitleText;
passwordField = panel.GetOrNull<PasswordFieldWidget>("PASSWORD");
@@ -182,7 +182,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class ConnectionSwitchModLogic : ChromeLogic
{
[TranslationReference]
[FluentReference]
const string ModSwitchFailed = "notification-mod-switch-failed";
[ObjectCreator.UseCtor]

View File

@@ -21,13 +21,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ActorEditLogic : ChromeLogic
{
[TranslationReference]
[FluentReference]
const string DuplicateActorId = "label-duplicate-actor-id";
[TranslationReference]
[FluentReference]
const string EnterActorId = "label-actor-id";
[TranslationReference]
[FluentReference]
const string Owner = "label-actor-owner";
// Error states define overlapping bits to simplify panel reflow logic
@@ -94,8 +94,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
actorIDErrorLabel.IsVisible = () => actorIDStatus != ActorIDStatus.Normal;
actorIDErrorLabel.GetText = () =>
actorIDStatus == ActorIDStatus.Duplicate || nextActorIDStatus == ActorIDStatus.Duplicate
? TranslationProvider.GetString(DuplicateActorId)
: TranslationProvider.GetString(EnterActorId);
? FluentProvider.GetString(DuplicateActorId)
: FluentProvider.GetString(EnterActorId);
okButton.IsDisabled = () => !IsValid() || editActorPreview == null || !editActorPreview.IsDirty;
okButton.OnClick = Save;
@@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
initialActorID = actorIDField.Text = SelectedActor.ID;
var font = Game.Renderer.Fonts[typeLabel.Font];
var truncatedType = WidgetUtils.TruncateText(TranslationProvider.GetString(SelectedActor.DescriptiveName), typeLabel.Bounds.Width, font);
var truncatedType = WidgetUtils.TruncateText(FluentProvider.GetString(SelectedActor.DescriptiveName), typeLabel.Bounds.Width, font);
typeLabel.GetText = () => truncatedType;
actorIDField.CursorPosition = SelectedActor.ID.Length;
@@ -180,7 +180,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Add owner dropdown
var ownerContainer = dropdownOptionTemplate.Clone();
var owner = TranslationProvider.GetString(Owner);
var owner = FluentProvider.GetString(Owner);
ownerContainer.Get<LabelWidget>("LABEL").GetText = () => owner;
var ownerDropdown = ownerContainer.Get<DropDownButtonWidget>("OPTION");
var selectedOwner = SelectedActor.Owner;
@@ -439,10 +439,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
sealed class EditActorEditorAction : IEditorAction
{
[TranslationReference("name", "id")]
[FluentReference("name", "id")]
const string EditedActor = "notification-edited-actor";
[TranslationReference("name", "old-id", "new-id")]
[FluentReference("name", "old-id", "new-id")]
const string EditedActorId = "notification-edited-actor-id";
public string Text { get; private set; }
@@ -454,7 +454,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
Actor = actor;
this.handles = handles;
Text = TranslationProvider.GetString(EditedActor, Translation.Arguments("name", actor.Info.Name, "id", actor.ID));
Text = FluentProvider.GetString(EditedActor, FluentBundle.Arguments("name", actor.Info.Name, "id", actor.ID));
}
public void Execute()
@@ -466,7 +466,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var after = Actor;
if (before != after)
Text = TranslationProvider.GetString(EditedActorId, Translation.Arguments("name", after.Info.Name, "old-id", before.ID, "new-id", after.ID));
Text = FluentProvider.GetString(EditedActorId, FluentBundle.Arguments("name", after.Info.Name, "old-id", before.ID, "new-id", after.ID));
}
public void Do()

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ActorSelectorLogic : CommonSelectorLogic
{
[TranslationReference("actorType")]
[FluentReference("actorType")]
const string ActorTypeTooltip = "label-actor-type";
sealed class ActorSelectorActor
@@ -112,12 +112,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var tooltip = a.TraitInfos<EditorOnlyTooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault) as TooltipInfoBase
?? a.TraitInfos<TooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault);
var actorType = TranslationProvider.GetString(ActorTypeTooltip, Translation.Arguments("actorType", a.Name));
var actorType = FluentProvider.GetString(ActorTypeTooltip, FluentBundle.Arguments("actorType", a.Name));
var searchTerms = new List<string>() { a.Name };
if (tooltip != null)
{
var actorName = TranslationProvider.GetString(tooltip.Name);
var actorName = FluentProvider.GetString(tooltip.Name);
searchTerms.Add(actorName);
allActorsTemp.Add(new ActorSelectorActor(a, editorData.Categories, searchTerms.ToArray(), actorName + $"\n{actorType}"));
}

View File

@@ -19,16 +19,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public abstract class CommonSelectorLogic : ChromeLogic
{
[TranslationReference]
[FluentReference]
const string None = "options-common-selector.none";
[TranslationReference]
[FluentReference]
const string SearchResults = "options-common-selector.search-results";
[TranslationReference]
[FluentReference]
const string All = "options-common-selector.all";
[TranslationReference]
[FluentReference]
const string Multiple = "options-common-selector.multiple";
protected readonly Widget Widget;
@@ -73,10 +73,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Editor.DefaultBrush.SelectionChanged += HandleSelectionChanged;
var none = TranslationProvider.GetString(None);
var searchResults = TranslationProvider.GetString(SearchResults);
var all = TranslationProvider.GetString(All);
var multiple = TranslationProvider.GetString(Multiple);
var none = FluentProvider.GetString(None);
var searchResults = FluentProvider.GetString(SearchResults);
var all = FluentProvider.GetString(All);
var multiple = FluentProvider.GetString(Multiple);
var categorySelector = widget.Get<DropDownButtonWidget>("CATEGORIES_DROPDOWN");
categorySelector.GetText = () =>

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class MapEditorSelectionLogic : ChromeLogic
{
[TranslationReference]
[FluentReference]
const string AreaSelection = "label-area-selection";
readonly EditorViewportControllerWidget editor;
@@ -151,7 +151,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var resourceValueInRegion = editorResourceLayer.CalculateRegionValue(selectedRegion);
var areaSelectionLabel =
$"{TranslationProvider.GetString(AreaSelection)} ({DimensionsAsString(selectionSize)}) " +
$"{FluentProvider.GetString(AreaSelection)} ({DimensionsAsString(selectionSize)}) " +
$"{PositionAsString(selectedRegion.TopLeft)} : {PositionAsString(selectedRegion.BottomRight)}";
AreaEditTitle.GetText = () => areaSelectionLabel;

View File

@@ -22,14 +22,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class MapMarkerTilesLogic : ChromeLogic
{
[TranslationReference]
const string MarkerMirrorModeNoneTranslation = "mirror-mode.none";
[FluentReference]
const string MarkerMirrorModeNone = "mirror-mode.none";
[TranslationReference]
const string MarkerMirrorModeFlipTranslation = "mirror-mode.flip";
[FluentReference]
const string MarkerMirrorModeFlip = "mirror-mode.flip";
[TranslationReference]
const string MarkerMirrorModeRotateTranslation = "mirror-mode.rotate";
[FluentReference]
const string MarkerMirrorModeRotate = "mirror-mode.rotate";
readonly EditorActionManager editorActionManager;
readonly MarkerLayerOverlay markerLayerTrait;
@@ -130,13 +130,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
switch (markerLayerTrait.MirrorMode)
{
case MarkerTileMirrorMode.None:
return TranslationProvider.GetString(MarkerMirrorModeNoneTranslation);
return FluentProvider.GetString(MarkerMirrorModeNone);
case MarkerTileMirrorMode.Flip:
return TranslationProvider.GetString(MarkerMirrorModeFlipTranslation);
return FluentProvider.GetString(MarkerMirrorModeFlip);
case MarkerTileMirrorMode.Rotate:
return TranslationProvider.GetString(MarkerMirrorModeRotateTranslation);
return FluentProvider.GetString(MarkerMirrorModeRotate);
default:
throw new ArgumentException($"Couldn't find translation for marker tile mirror mode '{markerLayerTrait.MirrorMode}'");
throw new ArgumentException($"Couldn't find fluent string for marker tile mirror mode '{markerLayerTrait.MirrorMode}'");
}
};
@@ -221,13 +221,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
switch (mode)
{
case MarkerTileMirrorMode.None:
return TranslationProvider.GetString(MarkerMirrorModeNoneTranslation);
return FluentProvider.GetString(MarkerMirrorModeNone);
case MarkerTileMirrorMode.Flip:
return TranslationProvider.GetString(MarkerMirrorModeFlipTranslation);
return FluentProvider.GetString(MarkerMirrorModeFlip);
case MarkerTileMirrorMode.Rotate:
return TranslationProvider.GetString(MarkerMirrorModeRotateTranslation);
return FluentProvider.GetString(MarkerMirrorModeRotate);
default:
throw new ArgumentException($"Couldn't find translation for marker tile mirror mode '{mode}'");
throw new ArgumentException($"Couldn't find fluent string for marker tile mirror mode '{mode}'");
}
};

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class MapToolsLogic : ChromeLogic
{
[TranslationReference]
[FluentReference]
const string MarkerTiles = "label-tool-marker-tiles";
enum MapTool
@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
toolPanels.Add(MapTool.MarkerTiles, markerToolPanel);
toolsDropdown.OnMouseDown = _ => ShowToolsDropDown(toolsDropdown);
toolsDropdown.GetText = () => TranslationProvider.GetString(toolNames[selectedTool]);
toolsDropdown.GetText = () => FluentProvider.GetString(toolNames[selectedTool]);
toolsDropdown.Disabled = true; // TODO: Enable if new tools are added
}
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
() => selectedTool == tool,
() => SelectTool(tool));
item.Get<LabelWidget>("LABEL").GetText = () => TranslationProvider.GetString(toolNames[tool]);
item.Get<LabelWidget>("LABEL").GetText = () => FluentProvider.GetString(toolNames[tool]);
return item;
}

View File

@@ -44,37 +44,37 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
}
[TranslationReference]
[FluentReference]
const string SaveMapFailedTitle = "dialog-save-map-failed.title";
[TranslationReference]
[FluentReference]
const string SaveMapFailedPrompt = "dialog-save-map-failed.prompt";
[TranslationReference]
[FluentReference]
const string SaveMapFailedConfirm = "dialog-save-map-failed.confirm";
[TranslationReference]
[FluentReference]
const string Unpacked = "label-unpacked-map";
[TranslationReference]
[FluentReference]
const string OverwriteMapFailedTitle = "dialog-overwrite-map-failed.title";
[TranslationReference]
[FluentReference]
const string OverwriteMapFailedPrompt = "dialog-overwrite-map-failed.prompt";
[TranslationReference]
[FluentReference]
const string OverwriteMapFailedConfirm = "dialog-overwrite-map-failed.confirm";
[TranslationReference]
[FluentReference]
const string OverwriteMapOutsideEditTitle = "dialog-overwrite-map-outside-edit.title";
[TranslationReference]
[FluentReference]
const string OverwriteMapOutsideEditPrompt = "dialog-overwrite-map-outside-edit.prompt";
[TranslationReference]
[FluentReference]
const string SaveMapMapOutsideConfirm = "dialog-overwrite-map-outside-edit.confirm";
[TranslationReference]
[FluentReference]
const string SaveCurrentMap = "notification-save-current-map";
[ObjectCreator.UseCtor]
@@ -171,7 +171,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var fileTypes = new Dictionary<MapFileType, MapFileTypeInfo>()
{
{ MapFileType.OraMap, new MapFileTypeInfo { Extension = ".oramap", UiLabel = ".oramap" } },
{ MapFileType.Unpacked, new MapFileTypeInfo { Extension = "", UiLabel = $"({TranslationProvider.GetString(Unpacked)})" } }
{ MapFileType.Unpacked, new MapFileTypeInfo { Extension = "", UiLabel = $"({FluentProvider.GetString(Unpacked)})" } }
};
var typeDropdown = widget.Get<DropDownButtonWidget>("TYPE_DROPDOWN");

View File

@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var label = item.Get<LabelWithTooltipWidget>("TITLE");
var name = actor.TraitInfos<TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault)?.Name;
if (!string.IsNullOrEmpty(name))
WidgetUtils.TruncateLabelToTooltip(label, TranslationProvider.GetString(name));
WidgetUtils.TruncateLabelToTooltip(label, FluentProvider.GetString(name));
if (firstItem == null)
{
@@ -159,7 +159,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var info = actor.TraitInfoOrDefault<EncyclopediaInfo>();
if (info != null && !string.IsNullOrEmpty(info.Description))
text += WidgetUtils.WrapText(TranslationProvider.GetString(info.Description) + "\n\n", descriptionLabel.Bounds.Width, descriptionFont);
text += WidgetUtils.WrapText(FluentProvider.GetString(info.Description) + "\n\n", descriptionLabel.Bounds.Width, descriptionFont);
var height = descriptionFont.Measure(text).Y;
descriptionLabel.GetText = () => text;
@@ -175,7 +175,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var actorTooltip = actor.TraitInfos<TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault);
if (actorTooltip != null)
return TranslationProvider.GetString(actorTooltip.Name);
return FluentProvider.GetString(actorTooltip.Name);
}
return name;

View File

@@ -21,43 +21,43 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class GameSaveBrowserLogic : ChromeLogic
{
[TranslationReference]
[FluentReference]
const string RenameSaveTitle = "dialog-rename-save.title";
[TranslationReference]
[FluentReference]
const string RenameSavePrompt = "dialog-rename-save.prompt";
[TranslationReference]
[FluentReference]
const string RenameSaveAccept = "dialog-rename-save.confirm";
[TranslationReference]
[FluentReference]
const string DeleteSaveTitle = "dialog-delete-save.title";
[TranslationReference("save")]
[FluentReference("save")]
const string DeleteSavePrompt = "dialog-delete-save.prompt";
[TranslationReference]
[FluentReference]
const string DeleteSaveAccept = "dialog-delete-save.confirm";
[TranslationReference]
[FluentReference]
const string DeleteAllSavesTitle = "dialog-delete-all-saves.title";
[TranslationReference("count")]
[FluentReference("count")]
const string DeleteAllSavesPrompt = "dialog-delete-all-saves.prompt";
[TranslationReference]
[FluentReference]
const string DeleteAllSavesAccept = "dialog-delete-all-saves.confirm";
[TranslationReference("savePath")]
[FluentReference("savePath")]
const string SaveDeletionFailed = "notification-save-deletion-failed";
[TranslationReference]
[FluentReference]
const string OverwriteSaveTitle = "dialog-overwrite-save.title";
[TranslationReference("file")]
[FluentReference("file")]
const string OverwriteSavePrompt = "dialog-overwrite-save.prompt";
[TranslationReference]
[FluentReference]
const string OverwriteSaveAccpet = "dialog-overwrite-save.confirm";
readonly Widget panel;
@@ -173,7 +173,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteSaveTitle,
text: DeleteSavePrompt,
textArguments: Translation.Arguments("save", Path.GetFileNameWithoutExtension(selectedSave)),
textArguments: FluentBundle.Arguments("save", Path.GetFileNameWithoutExtension(selectedSave)),
onConfirm: () =>
{
Delete(selectedSave);
@@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteAllSavesTitle,
text: DeleteAllSavesPrompt,
textArguments: Translation.Arguments("count", games.Count),
textArguments: FluentBundle.Arguments("count", games.Count),
onConfirm: () =>
{
foreach (var s in games.ToList())
@@ -293,7 +293,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
catch (Exception ex)
{
TextNotificationsManager.Debug(TranslationProvider.GetString(SaveDeletionFailed, Translation.Arguments("savePath", savePath)));
TextNotificationsManager.Debug(FluentProvider.GetString(SaveDeletionFailed, FluentBundle.Arguments("savePath", savePath)));
Log.Write("debug", ex.ToString());
return;
}
@@ -373,7 +373,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ConfirmationDialogs.ButtonPrompt(modData,
title: OverwriteSaveTitle,
text: OverwriteSavePrompt,
textArguments: Translation.Arguments("file", saveTextField.Text),
textArguments: FluentBundle.Arguments("file", saveTextField.Text),
onConfirm: Inner,
confirmText: OverwriteSaveAccpet,
onCancel: () => { });

View File

@@ -38,13 +38,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return;
var tooltip = armyUnit.TooltipInfo;
var name = tooltip != null ? TranslationProvider.GetString(tooltip.Name) : armyUnit.ActorInfo.Name;
var name = tooltip != null ? FluentProvider.GetString(tooltip.Name) : armyUnit.ActorInfo.Name;
var buildable = armyUnit.BuildableInfo;
nameLabel.GetText = () => name;
var nameSize = font.Measure(name);
var desc = string.IsNullOrEmpty(buildable.Description) ? "" : TranslationProvider.GetString(buildable.Description);
var desc = string.IsNullOrEmpty(buildable.Description) ? "" : FluentProvider.GetString(buildable.Description);
descLabel.GetText = () => desc;
var descSize = descFont.Measure(desc);
descLabel.Bounds.Width = descSize.X;

Some files were not shown because too many files have changed in this diff Show More