Implemented the .NET generator
- Added .NET generator setting for the namespace to use - Added .NET generator setting to choose the default culture - Added get child section method to section processor - Added util to convert any string to a verbatim string literal - Removed redundant variables on exceptions
This commit is contained in:
		
							parent
							
								
									547a22bfd2
								
							
						
					
					
						commit
						630f014c1a
					
				@ -10,6 +10,8 @@ public static class SettingNames
 | 
			
		||||
    public static readonly string GENERATOR_MODE = "Generator Mode";
 | 
			
		||||
    public static readonly string GENERATOR_DOTNET_ENABLED = "Generator .NET Enabled";
 | 
			
		||||
    public static readonly string GENERATOR_DOTNET_DESTINATION_PATH = "Generator .NET Destination Path";
 | 
			
		||||
    public static readonly string GENERATOR_DOTNET_NAMESPACE = "Generator .NET Namespace";
 | 
			
		||||
    public static readonly string GENERATOR_DOTNET_DEFAULT_CULTURE = "Generator .NET Default Culture";
 | 
			
		||||
    public static readonly string GENERATOR_GODOT_ENABLED = "Generator Godot Enabled";
 | 
			
		||||
    public static readonly string GENERATOR_GODOT_DESTINATION_PATH = "Generator Godot Destination Path";
 | 
			
		||||
}
 | 
			
		||||
@ -685,6 +685,154 @@ public static class AppSettings
 | 
			
		||||
    
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region .NET Generator Namespace
 | 
			
		||||
    
 | 
			
		||||
    private static string CACHE_GENERATOR_DOTNET_NAMESPACE = string.Empty;
 | 
			
		||||
    private static bool CACHE_GENERATOR_DOTNET_NAMESPACE_IS_LOADED = false;
 | 
			
		||||
    
 | 
			
		||||
    public static async Task<string> GetGeneratorDotnetNamespace()
 | 
			
		||||
    {
 | 
			
		||||
        // When possible, use the cache:
 | 
			
		||||
        if (CACHE_GENERATOR_DOTNET_NAMESPACE_IS_LOADED)
 | 
			
		||||
            return CACHE_GENERATOR_DOTNET_NAMESPACE;
 | 
			
		||||
 | 
			
		||||
        var generatorDotnetNamespace = "I18N";
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Get the database:
 | 
			
		||||
            await using var db = ProcessorMeta.ServiceProvider.GetRequiredService<DataContext>();
 | 
			
		||||
 | 
			
		||||
            // Check, if the setting is already set:
 | 
			
		||||
            if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.GENERATOR_DOTNET_NAMESPACE) is { } existingSetting)
 | 
			
		||||
            {
 | 
			
		||||
                generatorDotnetNamespace = existingSetting.TextValue;
 | 
			
		||||
                return generatorDotnetNamespace;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Does not exist, so create it:
 | 
			
		||||
            var setting = new Setting
 | 
			
		||||
            {
 | 
			
		||||
                Code = SettingNames.GENERATOR_DOTNET_NAMESPACE,
 | 
			
		||||
                TextValue = generatorDotnetNamespace,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            await db.Settings.AddAsync(setting);
 | 
			
		||||
            await db.SaveChangesAsync();
 | 
			
		||||
            return generatorDotnetNamespace;
 | 
			
		||||
        }
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            CACHE_GENERATOR_DOTNET_NAMESPACE_IS_LOADED = true;
 | 
			
		||||
            CACHE_GENERATOR_DOTNET_NAMESPACE = generatorDotnetNamespace;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static async Task SetGeneratorDotnetNamespace(string updatedNamespace)
 | 
			
		||||
    {
 | 
			
		||||
        // Update the cache:
 | 
			
		||||
        CACHE_GENERATOR_DOTNET_NAMESPACE = updatedNamespace;
 | 
			
		||||
        CACHE_GENERATOR_DOTNET_NAMESPACE_IS_LOADED = true;
 | 
			
		||||
        
 | 
			
		||||
        // Get the database:
 | 
			
		||||
        await using var db = ProcessorMeta.ServiceProvider.GetRequiredService<DataContext>();
 | 
			
		||||
        
 | 
			
		||||
        // Check, if the setting is already set:
 | 
			
		||||
        if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.GENERATOR_DOTNET_NAMESPACE) is { } existingSetting)
 | 
			
		||||
        {
 | 
			
		||||
            existingSetting.TextValue = updatedNamespace;
 | 
			
		||||
            await db.SaveChangesAsync();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Does not exist, so create it:
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            var setting = new Setting
 | 
			
		||||
            {
 | 
			
		||||
                Code = SettingNames.GENERATOR_DOTNET_NAMESPACE,
 | 
			
		||||
                TextValue = updatedNamespace,
 | 
			
		||||
            };
 | 
			
		||||
            
 | 
			
		||||
            await db.Settings.AddAsync(setting);
 | 
			
		||||
            await db.SaveChangesAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
    
 | 
			
		||||
    #region .NET Generator Default Culture
 | 
			
		||||
    
 | 
			
		||||
    private static int CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE = -1;
 | 
			
		||||
    private static bool CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE_IS_LOADED = false;
 | 
			
		||||
    
 | 
			
		||||
    public static async Task<int> GetGeneratorDotnetDefaultCultureIndex()
 | 
			
		||||
    {
 | 
			
		||||
        // When possible, use the cache:
 | 
			
		||||
        if (CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE_IS_LOADED)
 | 
			
		||||
            return CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE;
 | 
			
		||||
 | 
			
		||||
        var generatorDotnetDefaultCulture = 0;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // Get the database:
 | 
			
		||||
            await using var db = ProcessorMeta.ServiceProvider.GetRequiredService<DataContext>();
 | 
			
		||||
 | 
			
		||||
            // Check, if the setting is already set:
 | 
			
		||||
            if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.GENERATOR_DOTNET_DEFAULT_CULTURE) is { } existingSetting)
 | 
			
		||||
            {
 | 
			
		||||
                generatorDotnetDefaultCulture = existingSetting.IntegerValue;
 | 
			
		||||
                return generatorDotnetDefaultCulture;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Does not exist, so create it:
 | 
			
		||||
            var setting = new Setting
 | 
			
		||||
            {
 | 
			
		||||
                Code = SettingNames.GENERATOR_DOTNET_DEFAULT_CULTURE,
 | 
			
		||||
                IntegerValue = generatorDotnetDefaultCulture,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            await db.Settings.AddAsync(setting);
 | 
			
		||||
            await db.SaveChangesAsync();
 | 
			
		||||
            return generatorDotnetDefaultCulture;
 | 
			
		||||
        }
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE_IS_LOADED = true;
 | 
			
		||||
            CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE = generatorDotnetDefaultCulture;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static async Task SetGeneratorDotnetDefaultCultureIndex(int updatedCulture)
 | 
			
		||||
    {
 | 
			
		||||
        // Update the cache:
 | 
			
		||||
        CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE = updatedCulture;
 | 
			
		||||
        CACHE_GENERATOR_DOTNET_DEFAULT_CULTURE_IS_LOADED = true;
 | 
			
		||||
        
 | 
			
		||||
        // Get the database:
 | 
			
		||||
        await using var db = ProcessorMeta.ServiceProvider.GetRequiredService<DataContext>();
 | 
			
		||||
        
 | 
			
		||||
        // Check, if the setting is already set:
 | 
			
		||||
        if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.GENERATOR_DOTNET_DEFAULT_CULTURE) is { } existingSetting)
 | 
			
		||||
        {
 | 
			
		||||
            existingSetting.IntegerValue = updatedCulture;
 | 
			
		||||
            await db.SaveChangesAsync();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Does not exist, so create it:
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            var setting = new Setting
 | 
			
		||||
            {
 | 
			
		||||
                Code = SettingNames.GENERATOR_DOTNET_DEFAULT_CULTURE,
 | 
			
		||||
                IntegerValue = updatedCulture,
 | 
			
		||||
            };
 | 
			
		||||
            
 | 
			
		||||
            await db.Settings.AddAsync(setting);
 | 
			
		||||
            await db.SaveChangesAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #endregion
 | 
			
		||||
 | 
			
		||||
    #region Godot Generator Enabled/Disabled
 | 
			
		||||
    
 | 
			
		||||
    private static bool CACHE_GENERATOR_GODOT_ENABLED = true;
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ public static class DeepL
 | 
			
		||||
        
 | 
			
		||||
            return new DeepLUsage(true, usage.Character!.Count, usage.Character.Limit);
 | 
			
		||||
        }
 | 
			
		||||
        catch (AuthorizationException e)
 | 
			
		||||
        catch (AuthorizationException)
 | 
			
		||||
        {
 | 
			
		||||
            DEEPL_NOT_AVAILABLE = true;
 | 
			
		||||
            return new DeepLUsage(false, 0, 1, true);
 | 
			
		||||
@ -63,7 +63,7 @@ public static class DeepL
 | 
			
		||||
            
 | 
			
		||||
            return translation.Text;
 | 
			
		||||
        }
 | 
			
		||||
        catch (AuthorizationException e)
 | 
			
		||||
        catch (AuthorizationException)
 | 
			
		||||
        {
 | 
			
		||||
            DEEPL_NOT_AVAILABLE = true;
 | 
			
		||||
            return string.Empty;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										141
									
								
								I18N Commander/Processor/Generators/DotnetBigFile.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								I18N Commander/Processor/Generators/DotnetBigFile.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
			
		||||
using System.Text;
 | 
			
		||||
using DataModel.Database;
 | 
			
		||||
 | 
			
		||||
namespace Processor.Generators;
 | 
			
		||||
 | 
			
		||||
public class DotnetBigFile : IGenerator
 | 
			
		||||
{
 | 
			
		||||
    private static readonly List<string> CULTURE_CODES = new();
 | 
			
		||||
    private static int DEFAULT_CULTURE_INDEX = -1; 
 | 
			
		||||
 | 
			
		||||
    public async Task GenerateAsync()
 | 
			
		||||
    {
 | 
			
		||||
        const string filename = "I18N.cs";
 | 
			
		||||
        
 | 
			
		||||
        var destPath = await AppSettings.GetGeneratorDotnetDestinationPath();
 | 
			
		||||
        destPath = Environment.ExpandEnvironmentVariables(destPath);
 | 
			
		||||
        
 | 
			
		||||
        var pathFinal = Path.Join(destPath, filename);
 | 
			
		||||
        var pathTemp = Path.Join(destPath, filename + ".gen");
 | 
			
		||||
        if(File.Exists(pathTemp))
 | 
			
		||||
            File.Delete(pathTemp);
 | 
			
		||||
 | 
			
		||||
        CULTURE_CODES.Clear();
 | 
			
		||||
        var cultures = await AppSettings.GetCultureInfos();
 | 
			
		||||
        foreach (var (code, _) in cultures)
 | 
			
		||||
            CULTURE_CODES.Add(code);
 | 
			
		||||
 | 
			
		||||
        DEFAULT_CULTURE_INDEX = await AppSettings.GetGeneratorDotnetDefaultCultureIndex();
 | 
			
		||||
        DEFAULT_CULTURE_INDEX -= 1; // 1-based to 0-based
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            await using var fileStream = new FileStream(pathTemp, FileMode.CreateNew, FileAccess.Write, FileShare.None);
 | 
			
		||||
            await using var writer = new StreamWriter(fileStream, Encoding.UTF8);
 | 
			
		||||
 | 
			
		||||
            await writer.WriteLineAsync($"namespace {await AppSettings.GetGeneratorDotnetNamespace()};");
 | 
			
		||||
            await this.CreateStaticClass(writer, "I18N", 0, async (streamWriter, indention) =>
 | 
			
		||||
            {
 | 
			
		||||
                var indentionString = this.AddIndention(indention);
 | 
			
		||||
                var buildTime = DateTime.UtcNow;
 | 
			
		||||
                await writer.WriteLineAsync($"{indentionString}public static readonly string BUILD_TIME = \"{buildTime:yyyy.MM.dd HH:mm:ss}\";");
 | 
			
		||||
                await writer.WriteLineAsync($"{indentionString}public static readonly long BUILD_TIME_TICKS = {buildTime.Ticks};");
 | 
			
		||||
                await writer.WriteLineAsync();
 | 
			
		||||
                await writer.WriteLineAsync($"{indentionString}private static int PREVIOUS_CULTURE = -1;");
 | 
			
		||||
                
 | 
			
		||||
                // Go through the first layer of sections:
 | 
			
		||||
                var sections = await SectionProcessor.LoadLayer(0);
 | 
			
		||||
                foreach (var section in sections)
 | 
			
		||||
                    await this.TransformSection(writer, indention, section);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        finally
 | 
			
		||||
        {
 | 
			
		||||
            if(new FileInfo(pathTemp).Length > 0)
 | 
			
		||||
            {
 | 
			
		||||
                if(File.Exists(pathFinal))
 | 
			
		||||
                    File.Delete(pathFinal);
 | 
			
		||||
                
 | 
			
		||||
                File.Move(pathTemp, pathFinal);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private string AddIndention(int indention) => new string(' ', indention * 3);
 | 
			
		||||
 | 
			
		||||
    private async Task TransformSection(TextWriter writer, int indention, Section section)
 | 
			
		||||
    {
 | 
			
		||||
        await this.CreateStaticClass(writer, section.DataKey, indention, async (_, innerIndention) =>
 | 
			
		||||
        {
 | 
			
		||||
            var textElements = section.TextElements;
 | 
			
		||||
            foreach (var textElement in textElements)
 | 
			
		||||
                    await this.TransformTextElement(writer, innerIndention, textElement);
 | 
			
		||||
 | 
			
		||||
            var childSections = await SectionProcessor.GetChildSections(section.DataKey);
 | 
			
		||||
            foreach (var childSection in childSections)
 | 
			
		||||
                await this.TransformSection(writer, innerIndention, childSection);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private async Task TransformTextElement(TextWriter writer, int indention, TextElement textElement)
 | 
			
		||||
    {
 | 
			
		||||
        var indentionString = this.AddIndention(indention);
 | 
			
		||||
        var indentionPropString = this.AddIndention(indention + 1);
 | 
			
		||||
        var indentionPropInner1String = this.AddIndention(indention + 2);
 | 
			
		||||
        var indentionPropInner2String = this.AddIndention(indention + 3);
 | 
			
		||||
        var indentionPropInner3String = this.AddIndention(indention + 4);
 | 
			
		||||
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionString}private static string E_{textElement.Code}_CACHE = \"\";");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionString}public static string E_{textElement.Code}");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionString}{{");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropString}get");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropString}{{");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner1String}var currentCulture = CultureInfo.CurrentCulture.Name;");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner1String}if(PREVIOUS_CULTURE == currentCulture.GetHashCode())");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner2String}return E_{textElement.Code}_CACHE;");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner1String}else");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner1String}{{");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner2String}PREVIOUS_CULTURE = currentCulture.GetHashCode();");
 | 
			
		||||
        for (var cultureIndex = 0; cultureIndex < CULTURE_CODES.Count; cultureIndex++)
 | 
			
		||||
        {
 | 
			
		||||
            if(cultureIndex == 0)
 | 
			
		||||
                await writer.WriteLineAsync($"{indentionPropInner2String}if (currentCulture.StartsWith(\"{CULTURE_CODES[cultureIndex]}\", StringComparison.InvariantCultureIgnoreCase))");
 | 
			
		||||
            else
 | 
			
		||||
                await writer.WriteLineAsync($"{indentionPropInner2String}else if (currentCulture.StartsWith(\"{CULTURE_CODES[cultureIndex]}\", StringComparison.InvariantCultureIgnoreCase))");
 | 
			
		||||
            
 | 
			
		||||
            await writer.WriteLineAsync($"{indentionPropInner2String}{{");
 | 
			
		||||
            var cultureTranslation = textElement.Translations.FirstOrDefault(x => x.Culture == CULTURE_CODES[cultureIndex]);
 | 
			
		||||
            var cultureText = cultureTranslation?.Text ?? string.Empty;
 | 
			
		||||
            await writer.WriteLineAsync($"{indentionPropInner3String}var text = @\"{Utils.MadeVerbatimStringLiteral(cultureText)}\";");
 | 
			
		||||
            await writer.WriteLineAsync($"{indentionPropInner3String}E_{textElement.Code}_CACHE = text;");
 | 
			
		||||
            await writer.WriteLineAsync($"{indentionPropInner3String}return text;");
 | 
			
		||||
            await writer.WriteLineAsync($"{indentionPropInner2String}}}");            
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Add the default case:
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner2String}else");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner2String}{{");
 | 
			
		||||
        var defaultCultureTranslation = textElement.Translations.FirstOrDefault(x => x.Culture == CULTURE_CODES[DEFAULT_CULTURE_INDEX]);
 | 
			
		||||
        var defaultCultureText = defaultCultureTranslation?.Text ?? string.Empty;
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner3String}var text = @\"{Utils.MadeVerbatimStringLiteral(defaultCultureText)}\";");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner3String}E_{textElement.Code}_CACHE = text;");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner3String}return text;");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner2String}}}");
 | 
			
		||||
        
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropInner1String}}}");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionPropString}}}");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionString}}}");
 | 
			
		||||
        await writer.WriteLineAsync();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private async Task CreateStaticClass(TextWriter writer, string name, int indention, Func<TextWriter, int, Task> content)    
 | 
			
		||||
    {
 | 
			
		||||
        var indentionString = this.AddIndention(indention);
 | 
			
		||||
 | 
			
		||||
        await writer.WriteLineAsync(indentionString);
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionString}public static class {name}");
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionString}{{");
 | 
			
		||||
        await content(writer, indention + 1);
 | 
			
		||||
        await writer.WriteLineAsync($"{indentionString}}}");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								I18N Commander/Processor/Generators/Generator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								I18N Commander/Processor/Generators/Generator.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
namespace Processor.Generators;
 | 
			
		||||
 | 
			
		||||
public static class Generator
 | 
			
		||||
{
 | 
			
		||||
    private static readonly Dictionary<Type, IGenerator> GENERATORS = new();
 | 
			
		||||
    private static readonly IGenerator VOID_GENERATOR = new VoidGenerator();
 | 
			
		||||
 | 
			
		||||
    public static IGenerator Get(Type genType) => genType switch
 | 
			
		||||
    {
 | 
			
		||||
        Type.DOTNET => GENERATORS.ContainsKey(genType) ? GENERATORS[genType] : GENERATORS[genType] = new DotnetBigFile(),
 | 
			
		||||
      
 | 
			
		||||
        _ => VOID_GENERATOR,
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    public static async Task TriggerAllAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var dotnetEnabled = await AppSettings.GetGeneratorDotnetEnabled();
 | 
			
		||||
        var godotEnabled = await AppSettings.GetGeneratorGodotEnabled();
 | 
			
		||||
 | 
			
		||||
        if (dotnetEnabled)
 | 
			
		||||
            await Generator.Get(Type.DOTNET).GenerateAsync();
 | 
			
		||||
        
 | 
			
		||||
        if(godotEnabled)
 | 
			
		||||
            await Generator.Get(Type.GODOT).GenerateAsync();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								I18N Commander/Processor/Generators/IGenerator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								I18N Commander/Processor/Generators/IGenerator.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
namespace Processor.Generators;
 | 
			
		||||
 | 
			
		||||
public interface IGenerator
 | 
			
		||||
{
 | 
			
		||||
    public Task GenerateAsync();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								I18N Commander/Processor/Generators/Type.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								I18N Commander/Processor/Generators/Type.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
namespace Processor.Generators;
 | 
			
		||||
 | 
			
		||||
public enum Type
 | 
			
		||||
{
 | 
			
		||||
    NONE,
 | 
			
		||||
    
 | 
			
		||||
    DOTNET,
 | 
			
		||||
    GODOT,
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								I18N Commander/Processor/Generators/VoidGenerator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								I18N Commander/Processor/Generators/VoidGenerator.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
namespace Processor.Generators;
 | 
			
		||||
 | 
			
		||||
public class VoidGenerator : IGenerator
 | 
			
		||||
{
 | 
			
		||||
    public Task GenerateAsync() => Task.CompletedTask;
 | 
			
		||||
}
 | 
			
		||||
@ -198,4 +198,12 @@ public static class SectionProcessor
 | 
			
		||||
        
 | 
			
		||||
        return $"Section's path: {path}";
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static async Task<List<Section>> GetChildSections(string sectionKey)
 | 
			
		||||
    {
 | 
			
		||||
        await using var db = ProcessorMeta.ServiceProvider.GetRequiredService<DataContext>();
 | 
			
		||||
        var section = await db.Sections.FirstAsync(n => n.DataKey == sectionKey);
 | 
			
		||||
        
 | 
			
		||||
        return await db.Sections.Where(n => n.Parent == section).ToListAsync();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -124,7 +124,7 @@ public static class TextElementProcessor
 | 
			
		||||
            // Save the changes:
 | 
			
		||||
            await db.SaveChangesAsync();
 | 
			
		||||
        }
 | 
			
		||||
        catch (DbUpdateException updateException)
 | 
			
		||||
        catch (DbUpdateException)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
using System.Linq.Expressions;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
 | 
			
		||||
namespace Processor;
 | 
			
		||||
@ -46,4 +47,25 @@ internal static class Utils
 | 
			
		||||
 | 
			
		||||
        return code;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static string MadeVerbatimStringLiteral(string text)
 | 
			
		||||
    {
 | 
			
		||||
        IEnumerable<char> ConvertAll(string source)
 | 
			
		||||
        {
 | 
			
		||||
            foreach(var c in source)
 | 
			
		||||
                if(c == '"')
 | 
			
		||||
                {
 | 
			
		||||
                    yield return '"';
 | 
			
		||||
                    yield return '"';
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    yield return c;
 | 
			
		||||
        }
 | 
			
		||||
	
 | 
			
		||||
        var sb = new StringBuilder();
 | 
			
		||||
        foreach(var c in ConvertAll(text))
 | 
			
		||||
            sb.Append(c);
 | 
			
		||||
		
 | 
			
		||||
        return sb.ToString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
using DataModel.Database;
 | 
			
		||||
using Processor;
 | 
			
		||||
using Processor.Generators;
 | 
			
		||||
using UI_WinForms.Dialogs;
 | 
			
		||||
using UI_WinForms.Resources;
 | 
			
		||||
 | 
			
		||||
@ -293,8 +294,10 @@ public partial class SectionTree : UserControl
 | 
			
		||||
        selectedNode.Name = alteredSection.Result.DataKey; // [sic] name is the key
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void buttonGenerate_Click(object sender, EventArgs e)
 | 
			
		||||
    private async void buttonGenerate_Click(object sender, EventArgs e)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        this.buttonGenerate.Enabled = false;
 | 
			
		||||
        await Generator.TriggerAllAsync();
 | 
			
		||||
        this.buttonGenerate.Enabled = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -523,6 +523,82 @@ public sealed partial class Setting : UserControl
 | 
			
		||||
        return new Setting(settingData);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static async Task<Setting> ShowGeneratorDotnetNamespaceSettingAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var currentSetting = await AppSettings.GetGeneratorDotnetNamespace();
 | 
			
		||||
        
 | 
			
		||||
        var settingData = new SettingUIData(
 | 
			
		||||
            Icon: Icons.icons8_code_512,
 | 
			
		||||
            SettingName: () => "Generator: .NET Namespace",
 | 
			
		||||
            ChangeNeedsRestart: false,
 | 
			
		||||
            SettingExplanation: () => "The namespace for the .NET I18N files.",
 | 
			
		||||
            SettingExplanationLink: () => (string.Empty, string.Empty),
 | 
			
		||||
            SetupDataControl: (changeTrigger) =>
 | 
			
		||||
            {
 | 
			
		||||
                // Set up a textbox:
 | 
			
		||||
                var textbox = new TextBox();
 | 
			
		||||
                textbox.Text = currentSetting;
 | 
			
		||||
                textbox.TextChanged += async (sender, args) => await AppSettings.SetGeneratorDotnetNamespace(textbox.Text);
 | 
			
		||||
                textbox.TextChanged += (sender, args) => changeTrigger();
 | 
			
		||||
                textbox.Dock = DockStyle.Fill;
 | 
			
		||||
                textbox.Margin = new Padding(0, 13, 0, 13);
 | 
			
		||||
                return textbox;
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return new Setting(settingData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static async Task<Setting> ShowGeneratorDotnetDefaultCultureSettingAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var currentSourceCultureIndex = await AppSettings.GetGeneratorDotnetDefaultCultureIndex();
 | 
			
		||||
        
 | 
			
		||||
        // We load the corresponding culture for that index. As dropdown items, we show
 | 
			
		||||
        // all other available cultures:
 | 
			
		||||
        var allCultures = await AppSettings.GetCultureInfos();
 | 
			
		||||
 | 
			
		||||
        // Attention: We have to store the culture's index, because the index is not
 | 
			
		||||
        // continuous and can change when the user adds or removes a culture!
 | 
			
		||||
        var settingData = new SettingUIData(
 | 
			
		||||
            Icon: Icons.icons8_code_512,
 | 
			
		||||
            SettingName: () => "Generator: .NET Default Culture",
 | 
			
		||||
            ChangeNeedsRestart: false,
 | 
			
		||||
            SettingExplanation: () => "The default culture for the .NET, which is used when no culture is specified or available.",
 | 
			
		||||
            SettingExplanationLink: () => (string.Empty, string.Empty),
 | 
			
		||||
            SetupDataControl: (changeTrigger) =>
 | 
			
		||||
            {
 | 
			
		||||
                var dropdown = new ComboBox();
 | 
			
		||||
                var currentCultureDropdownIndex = 0;
 | 
			
		||||
                for (var n = 0; n < allCultures.Count; n++)
 | 
			
		||||
                {
 | 
			
		||||
                    var cultureInfo = allCultures[n];
 | 
			
		||||
                    if(cultureInfo.Index == currentSourceCultureIndex)
 | 
			
		||||
                        currentCultureDropdownIndex = n;
 | 
			
		||||
 | 
			
		||||
                    dropdown.Items.Add(new ComboBoxItem($"{cultureInfo.Index}.: {cultureInfo.Code}", cultureInfo.Index));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                dropdown.SelectedIndex = currentCultureDropdownIndex;
 | 
			
		||||
                
 | 
			
		||||
                // Setup the change event handler:
 | 
			
		||||
                dropdown.SelectedValueChanged += async (sender, args) =>
 | 
			
		||||
                {
 | 
			
		||||
                    if(dropdown.SelectedItem is ComboBoxItem selectedItem)
 | 
			
		||||
                        await AppSettings.SetGeneratorDotnetDefaultCultureIndex(selectedItem.CultureIndex);
 | 
			
		||||
                };
 | 
			
		||||
                dropdown.SelectedValueChanged += (sender, args) => changeTrigger();
 | 
			
		||||
                
 | 
			
		||||
                // Apply the desired layout:
 | 
			
		||||
                dropdown.Dock = DockStyle.Fill;
 | 
			
		||||
                dropdown.DropDownStyle = ComboBoxStyle.DropDownList;
 | 
			
		||||
                
 | 
			
		||||
                return dropdown;
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
        
 | 
			
		||||
        return new Setting(settingData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static async Task<Setting> ShowGeneratorGodotEnabledSettingAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var currentSetting = await AppSettings.GetGeneratorGodotEnabled();
 | 
			
		||||
@ -614,6 +690,8 @@ public sealed partial class Setting : UserControl
 | 
			
		||||
    {
 | 
			
		||||
        yield return ShowGeneratorGodotDestinationPathSettingAsync();
 | 
			
		||||
        yield return ShowGeneratorGodotEnabledSettingAsync();
 | 
			
		||||
        yield return ShowGeneratorDotnetDefaultCultureSettingAsync();
 | 
			
		||||
        yield return ShowGeneratorDotnetNamespaceSettingAsync();
 | 
			
		||||
        yield return ShowGeneratorDotnetDestinationPathSettingAsync();
 | 
			
		||||
        yield return ShowGeneratorDotnetEnabledSettingAsync();
 | 
			
		||||
        yield return ShowGeneratorModeSettingAsync();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user