Added a localized description for release types.

This commit is contained in:
2025-12-14 16:40:09 +00:00
parent 98a0caa737
commit a3ec57902f
7 changed files with 296 additions and 59 deletions

View File

@@ -41,6 +41,7 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Aaru.Localization;
namespace Aaru.CommonTypes.AaruMetadata; namespace Aaru.CommonTypes.AaruMetadata;
@@ -48,16 +49,28 @@ namespace Aaru.CommonTypes.AaruMetadata;
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ReleaseType public enum ReleaseType
{ {
[LocalizedDescription(nameof(UI.ReleaseType_Retail))]
Retail, Retail,
[LocalizedDescription(nameof(UI.ReleaseType_Bundle))]
Bundle, Bundle,
[LocalizedDescription(nameof(UI.ReleaseType_Coverdisc))]
Coverdisc, Coverdisc,
[LocalizedDescription(nameof(UI.ReleaseType_Subscription))]
Subscription, Subscription,
[LocalizedDescription(nameof(UI.ReleaseType_Demo))]
Demo, Demo,
[LocalizedDescription(nameof(UI.ReleaseType_OEM))]
OEM, OEM,
[LocalizedDescription(nameof(UI.ReleaseType_Shareware))]
Shareware, Shareware,
[LocalizedDescription(nameof(UI.ReleaseType_FOSS))]
FOSS, FOSS,
[LocalizedDescription(nameof(UI.ReleaseType_Adware))]
Adware, Adware,
[LocalizedDescription(nameof(UI.ReleaseType_Donationware))]
Donationware, Donationware,
[LocalizedDescription(nameof(UI.ReleaseType_DigitalDownload))]
DigitalDownload, DigitalDownload,
[LocalizedDescription(nameof(UI.ReleaseType_SaaS))]
SaaS SaaS
} }

View File

@@ -0,0 +1,90 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : LocalizedEnumHelper.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Helper class for working with localized enum values.
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General public License for more details.
//
// You should have received a copy of the GNU General public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
namespace Aaru.Gui.Helpers;
/// <summary>Helper class for working with localized enum values</summary>
public static class LocalizedEnumHelper
{
/// <summary>Gets the localized description for an enum value</summary>
/// <param name="value">The enum value</param>
/// <returns>The localized description, or the enum value's name if no description is found</returns>
[NotNull]
public static string GetLocalizedDescription([NotNull] Enum value)
{
FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
if(fieldInfo == null) return value.ToString();
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
/// <summary>Gets all values of an enum type wrapped with their localized descriptions</summary>
/// <typeparam name="T">The enum type</typeparam>
/// <returns>A collection of LocalizedEnumValue wrappers</returns>
[NotNull]
public static IEnumerable<LocalizedEnumValue<T>> GetLocalizedValues<T>() where T : struct, Enum
{
return Enum.GetValues<T>().Select(static value => new LocalizedEnumValue<T>(value));
}
}
/// <summary>Wrapper class for an enum value with its localized description</summary>
/// <typeparam name="T">The enum type</typeparam>
public class LocalizedEnumValue<T> where T : struct, Enum
{
/// <summary>Initializes a new instance of the LocalizedEnumValue class</summary>
/// <param name="value">The enum value</param>
public LocalizedEnumValue(T value)
{
Value = value;
Description = LocalizedEnumHelper.GetLocalizedDescription(value);
}
/// <summary>Gets the enum value</summary>
public T Value { get; }
/// <summary>Gets the localized description</summary>
public string Description { get; }
/// <summary>Returns the localized description as the string representation</summary>
public override string ToString() => Description;
}

View File

@@ -37,6 +37,7 @@ using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Aaru.CommonTypes.AaruMetadata; using Aaru.CommonTypes.AaruMetadata;
using Aaru.Gui.Helpers;
using Aaru.Gui.Localization; using Aaru.Gui.Localization;
using Aaru.Localization; using Aaru.Localization;
using Avalonia; using Avalonia;
@@ -128,7 +129,7 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
ObservableCollection<RequiredOperatingSystemViewModel> _requiredOperatingSystems = []; ObservableCollection<RequiredOperatingSystemViewModel> _requiredOperatingSystems = [];
[ObservableProperty] [ObservableProperty]
ReleaseType? _selectedReleaseType; LocalizedEnumValue<ReleaseType> _selectedReleaseType;
[ObservableProperty] [ObservableProperty]
string _serialNumber; string _serialNumber;
@@ -159,13 +160,14 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
// Available enum values for ComboBoxes // Available enum values for ComboBoxes
[NotNull] [NotNull]
public IEnumerable<ReleaseType> AvailableReleaseTypes => Enum.GetValues<ReleaseType>(); public IEnumerable<LocalizedEnumValue<ReleaseType>> AvailableReleaseTypes =>
LocalizedEnumHelper.GetLocalizedValues<ReleaseType>();
[NotNull] [NotNull]
public IEnumerable<Language> AvailableLanguages => Enum.GetValues<Language>(); public IEnumerable<Language> AvailableLanguages => Enum.GetValues<Language>();
[NotNull] [NotNull]
public IEnumerable<Architecture> AvailableArchitectures => Enum.GetValues<Architecture>(); public IEnumerable<Architecture> AvailableArchitectures => Enum.GetValues<Architecture>();
[NotNull] [NotNull]
public IEnumerable<BarcodeType> AvailableBarcodeTypes => Enum.GetValues<BarcodeType>(); public IEnumerable<BarcodeType> AvailableBarcodeTypes => Enum.GetValues<BarcodeType>();
void LoadMetadata([NotNull] string path) void LoadMetadata([NotNull] string path)
{ {
@@ -179,12 +181,16 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
Metadata metadata = metadataJson.AaruMetadata; Metadata metadata = metadataJson.AaruMetadata;
// Basic fields // Basic fields
Name = metadata.Name; Name = metadata.Name;
Version = metadata.Version; Version = metadata.Version;
SelectedReleaseType = metadata.Release;
ReleaseDate = metadata.ReleaseDate; SelectedReleaseType = metadata.Release.HasValue
PartNumber = metadata.PartNumber; ? new LocalizedEnumValue<ReleaseType>(metadata.Release.Value)
SerialNumber = metadata.SerialNumber; : null;
ReleaseDate = metadata.ReleaseDate;
PartNumber = metadata.PartNumber;
SerialNumber = metadata.SerialNumber;
// String lists // String lists
LoadStringList(metadata.Developers, Developers); LoadStringList(metadata.Developers, Developers);
@@ -202,19 +208,16 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
// Complex objects // Complex objects
if(metadata.Barcodes != null) if(metadata.Barcodes != null)
{ foreach(Barcode barcode in metadata.Barcodes)
foreach(Barcode barcode in metadata.Barcodes) Barcodes.Add(new BarcodeViewModel(barcode)); Barcodes.Add(new BarcodeViewModel(barcode));
}
if(metadata.Magazines != null) if(metadata.Magazines != null)
{ foreach(Magazine magazine in metadata.Magazines)
foreach(Magazine magazine in metadata.Magazines) Magazines.Add(new MagazineViewModel(magazine)); Magazines.Add(new MagazineViewModel(magazine));
}
if(metadata.Books != null) if(metadata.Books != null)
{ foreach(Book book in metadata.Books)
foreach(Book book in metadata.Books) Books.Add(new BookViewModel(book)); Books.Add(new BookViewModel(book));
}
if(metadata.RequiredOperatingSystems != null) if(metadata.RequiredOperatingSystems != null)
{ {
@@ -223,39 +226,32 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
} }
if(metadata.UserManuals != null) if(metadata.UserManuals != null)
{ foreach(UserManual manual in metadata.UserManuals)
foreach(UserManual manual in metadata.UserManuals) UserManuals.Add(new UserManualViewModel(manual)); UserManuals.Add(new UserManualViewModel(manual));
}
if(metadata.OpticalDiscs != null) if(metadata.OpticalDiscs != null)
{ foreach(OpticalDisc disc in metadata.OpticalDiscs)
foreach(OpticalDisc disc in metadata.OpticalDiscs) OpticalDiscs.Add(new OpticalDiscViewModel(disc)); OpticalDiscs.Add(new OpticalDiscViewModel(disc));
}
if(metadata.Advertisements != null) if(metadata.Advertisements != null)
{ foreach(Advertisement ad in metadata.Advertisements)
foreach(Advertisement ad in metadata.Advertisements) Advertisements.Add(new AdvertisementViewModel(ad)); Advertisements.Add(new AdvertisementViewModel(ad));
}
if(metadata.LinearMedias != null) if(metadata.LinearMedias != null)
{ foreach(LinearMedia media in metadata.LinearMedias)
foreach(LinearMedia media in metadata.LinearMedias) LinearMedias.Add(new LinearMediaViewModel(media)); LinearMedias.Add(new LinearMediaViewModel(media));
}
if(metadata.PciCards != null) if(metadata.PciCards != null)
{ foreach(Pci pci in metadata.PciCards)
foreach(Pci pci in metadata.PciCards) PciCards.Add(new PciViewModel(pci)); PciCards.Add(new PciViewModel(pci));
}
if(metadata.BlockMedias != null) if(metadata.BlockMedias != null)
{ foreach(BlockMedia media in metadata.BlockMedias)
foreach(BlockMedia media in metadata.BlockMedias) BlockMedias.Add(new BlockMediaViewModel(media)); BlockMedias.Add(new BlockMediaViewModel(media));
}
if(metadata.AudioMedias != null) if(metadata.AudioMedias != null)
{ foreach(AudioMedia media in metadata.AudioMedias)
foreach(AudioMedia media in metadata.AudioMedias) AudioMedias.Add(new AudioMediaViewModel(media)); AudioMedias.Add(new AudioMediaViewModel(media));
}
} }
catch(Exception ex) catch(Exception ex)
{ {
@@ -292,7 +288,7 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
{ {
Name = Name, Name = Name,
Version = Version, Version = Version,
Release = SelectedReleaseType, Release = SelectedReleaseType?.Value,
ReleaseDate = ReleaseDate, ReleaseDate = ReleaseDate,
PartNumber = PartNumber, PartNumber = PartNumber,
SerialNumber = SerialNumber, SerialNumber = SerialNumber,
@@ -313,16 +309,13 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
RequiredOperatingSystems.Any() RequiredOperatingSystems.Any()
? [..RequiredOperatingSystems.Select(static os => os.ToModel())] ? [..RequiredOperatingSystems.Select(static os => os.ToModel())]
: null, : null,
UserManuals = UserManuals.Any() ? [..UserManuals.Select(static um => um.ToModel())] : null, UserManuals = UserManuals.Any() ? [..UserManuals.Select(static um => um.ToModel())] : null,
OpticalDiscs = OpticalDiscs = OpticalDiscs.Any() ? [..OpticalDiscs.Select(static od => od.ToModel())] : null,
OpticalDiscs.Any() ? [..OpticalDiscs.Select(static od => od.ToModel())] : null, Advertisements = Advertisements.Any() ? [..Advertisements.Select(static a => a.ToModel())] : null,
Advertisements = LinearMedias = LinearMedias.Any() ? [..LinearMedias.Select(static lm => lm.ToModel())] : null,
Advertisements.Any() ? [..Advertisements.Select(static a => a.ToModel())] : null, PciCards = PciCards.Any() ? [..PciCards.Select(static p => p.ToModel())] : null,
LinearMedias = BlockMedias = BlockMedias.Any() ? [..BlockMedias.Select(static bm => bm.ToModel())] : null,
LinearMedias.Any() ? [..LinearMedias.Select(static lm => lm.ToModel())] : null, AudioMedias = AudioMedias.Any() ? [..AudioMedias.Select(static am => am.ToModel())] : null
PciCards = PciCards.Any() ? [..PciCards.Select(static p => p.ToModel())] : null,
BlockMedias = BlockMedias.Any() ? [..BlockMedias.Select(static bm => bm.ToModel())] : null,
AudioMedias = AudioMedias.Any() ? [..AudioMedias.Select(static am => am.ToModel())] : null
}; };
var metadataJson = new MetadataJson var metadataJson = new MetadataJson
@@ -346,10 +339,7 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
[ [
new FilePickerFileType(GUI.FileType_JSON) new FilePickerFileType(GUI.FileType_JSON)
{ {
Patterns = Patterns = ["*.json"]
[
"*.json"
]
} }
], ],
DefaultExtension = "json" DefaultExtension = "json"
@@ -601,6 +591,7 @@ public sealed partial class BookViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
string _editorial; string _editorial;
[ObservableProperty] [ObservableProperty]
string _name; string _name;
@@ -610,6 +601,7 @@ public sealed partial class BookViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
string _pageSize; string _pageSize;
[ObservableProperty] [ObservableProperty]
DateTime? _publicationDate; DateTime? _publicationDate;

View File

@@ -6891,5 +6891,77 @@ namespace Aaru.Localization {
return ResourceManager.GetString("AaruFormat_images_version_1_x_are_read_only", resourceCulture); return ResourceManager.GetString("AaruFormat_images_version_1_x_are_read_only", resourceCulture);
} }
} }
public static string ReleaseType_Retail {
get {
return ResourceManager.GetString("ReleaseType_Retail", resourceCulture);
}
}
public static string ReleaseType_Bundle {
get {
return ResourceManager.GetString("ReleaseType_Bundle", resourceCulture);
}
}
public static string ReleaseType_Coverdisc {
get {
return ResourceManager.GetString("ReleaseType_Coverdisc", resourceCulture);
}
}
public static string ReleaseType_Subscription {
get {
return ResourceManager.GetString("ReleaseType_Subscription", resourceCulture);
}
}
public static string ReleaseType_Demo {
get {
return ResourceManager.GetString("ReleaseType_Demo", resourceCulture);
}
}
public static string ReleaseType_OEM {
get {
return ResourceManager.GetString("ReleaseType_OEM", resourceCulture);
}
}
public static string ReleaseType_Shareware {
get {
return ResourceManager.GetString("ReleaseType_Shareware", resourceCulture);
}
}
public static string ReleaseType_FOSS {
get {
return ResourceManager.GetString("ReleaseType_FOSS", resourceCulture);
}
}
public static string ReleaseType_Adware {
get {
return ResourceManager.GetString("ReleaseType_Adware", resourceCulture);
}
}
public static string ReleaseType_Donationware {
get {
return ResourceManager.GetString("ReleaseType_Donationware", resourceCulture);
}
}
public static string ReleaseType_DigitalDownload {
get {
return ResourceManager.GetString("ReleaseType_DigitalDownload", resourceCulture);
}
}
public static string ReleaseType_SaaS {
get {
return ResourceManager.GetString("ReleaseType_SaaS", resourceCulture);
}
}
} }
} }

View File

@@ -3446,4 +3446,40 @@ Probadores:
<data name="AaruFormat_images_version_1_x_are_read_only" xml:space="preserve"> <data name="AaruFormat_images_version_1_x_are_read_only" xml:space="preserve">
<value>Las imágenes AaruFormat versión 1.x son de sólo lectura, conviértala primero a una versión más moderna.</value> <value>Las imágenes AaruFormat versión 1.x son de sólo lectura, conviértala primero a una versión más moderna.</value>
</data> </data>
<data name="ReleaseType_Retail" xml:space="preserve">
<value>Comercial</value>
</data>
<data name="ReleaseType_Bundle" xml:space="preserve">
<value>Paquete</value>
</data>
<data name="ReleaseType_Coverdisc" xml:space="preserve">
<value>Disco de Portada</value>
</data>
<data name="ReleaseType_Subscription" xml:space="preserve">
<value>Suscripción</value>
</data>
<data name="ReleaseType_Demo" xml:space="preserve">
<value>Demostración</value>
</data>
<data name="ReleaseType_OEM" xml:space="preserve">
<value>OEM</value>
</data>
<data name="ReleaseType_Shareware" xml:space="preserve">
<value>Shareware</value>
</data>
<data name="ReleaseType_FOSS" xml:space="preserve">
<value>FOSS (Software Libre/Código Abierto)</value>
</data>
<data name="ReleaseType_Adware" xml:space="preserve">
<value>Adware</value>
</data>
<data name="ReleaseType_Donationware" xml:space="preserve">
<value>Donationware</value>
</data>
<data name="ReleaseType_DigitalDownload" xml:space="preserve">
<value>Descarga Digital</value>
</data>
<data name="ReleaseType_SaaS" xml:space="preserve">
<value>SaaS (Software como Servicio)</value>
</data>
</root> </root>

View File

@@ -3524,4 +3524,40 @@ Do you want to continue?</value>
<data name="AaruFormat_images_version_1_x_are_read_only" xml:space="preserve"> <data name="AaruFormat_images_version_1_x_are_read_only" xml:space="preserve">
<value>AaruFormat images version 1.x are read-only, convert it to a newer version first.</value> <value>AaruFormat images version 1.x are read-only, convert it to a newer version first.</value>
</data> </data>
<data name="ReleaseType_Retail" xml:space="preserve">
<value>Retail</value>
</data>
<data name="ReleaseType_Bundle" xml:space="preserve">
<value>Bundle</value>
</data>
<data name="ReleaseType_Coverdisc" xml:space="preserve">
<value>Cover Disc</value>
</data>
<data name="ReleaseType_Subscription" xml:space="preserve">
<value>Subscription</value>
</data>
<data name="ReleaseType_Demo" xml:space="preserve">
<value>Demo</value>
</data>
<data name="ReleaseType_OEM" xml:space="preserve">
<value>OEM</value>
</data>
<data name="ReleaseType_Shareware" xml:space="preserve">
<value>Shareware</value>
</data>
<data name="ReleaseType_FOSS" xml:space="preserve">
<value>FOSS (Free/Open Source)</value>
</data>
<data name="ReleaseType_Adware" xml:space="preserve">
<value>Adware</value>
</data>
<data name="ReleaseType_Donationware" xml:space="preserve">
<value>Donationware</value>
</data>
<data name="ReleaseType_DigitalDownload" xml:space="preserve">
<value>Digital Download</value>
</data>
<data name="ReleaseType_SaaS" xml:space="preserve">
<value>SaaS (Software as a Service)</value>
</data>
</root> </root>

View File

@@ -1,7 +1,4 @@
<wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" <wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve">
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xml:space="preserve">
<s:String x:Key="/Default/CodeInspection/CppInitialization/DefaultPointerInitializer/@EntryValue">Null</s:String> <s:String x:Key="/Default/CodeInspection/CppInitialization/DefaultPointerInitializer/@EntryValue">Null</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=858398D1_002D7321_002D4763_002D8BAB_002D56BBFEC74E29_002Fd_003Acuetools_002Enet/@EntryIndexedValue">ExplicitlyExcluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=858398D1_002D7321_002D4763_002D8BAB_002D56BBFEC74E29_002Fd_003Acuetools_002Enet/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AnnotateCanBeNullTypeMember/@EntryIndexedValue"></s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AnnotateCanBeNullTypeMember/@EntryIndexedValue"></s:String>
@@ -1046,6 +1043,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Connectix/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Connectix/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=copytape/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=copytape/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=coredump/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=coredump/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Coverdisc/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=CPCDSK/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=CPCDSK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=CPCEMU/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=CPCEMU/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cplus/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Cplus/@EntryIndexedValue">True</s:Boolean>