From 7599d57f21888c062c053a5c52a853ffbf685daa Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 14 Dec 2025 18:54:07 +0000 Subject: [PATCH] Refactor ViewModel constructors and ToModel methods to preserve original model state --- .../Windows/MetadataEditorViewModel.cs | 300 ++++++++++-------- 1 file changed, 172 insertions(+), 128 deletions(-) diff --git a/Aaru.Gui/ViewModels/Windows/MetadataEditorViewModel.cs b/Aaru.Gui/ViewModels/Windows/MetadataEditorViewModel.cs index fd668ca62..eaa2690da 100644 --- a/Aaru.Gui/ViewModels/Windows/MetadataEditorViewModel.cs +++ b/Aaru.Gui/ViewModels/Windows/MetadataEditorViewModel.cs @@ -160,17 +160,20 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase // Available enum values for ComboBoxes [NotNull] - public IEnumerable> AvailableReleaseTypes => - LocalizedEnumHelper.GetLocalizedValues().OrderBy(static x => x.Description); + public IEnumerable> AvailableReleaseTypes => LocalizedEnumHelper + .GetLocalizedValues() + .OrderBy(static x => x.Description); [NotNull] public IEnumerable> AvailableLanguages => LocalizedEnumHelper.GetLocalizedValues().OrderBy(static x => x.Description); [NotNull] - public IEnumerable> AvailableArchitectures => - LocalizedEnumHelper.GetLocalizedValues().OrderBy(static x => x.Description); + public IEnumerable> AvailableArchitectures => LocalizedEnumHelper + .GetLocalizedValues() + .OrderBy(static x => x.Description); [NotNull] - public IEnumerable> AvailableBarcodeTypes => - LocalizedEnumHelper.GetLocalizedValues().OrderBy(static x => x.Description); + public IEnumerable> AvailableBarcodeTypes => LocalizedEnumHelper + .GetLocalizedValues() + .OrderBy(static x => x.Description); void LoadMetadata([NotNull] string path) { @@ -207,9 +210,8 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase // Enum lists if(metadata.Languages != null) - { - foreach(Language lang in metadata.Languages) Languages.Add(new LocalizedEnumValue(lang)); - } + foreach(Language lang in metadata.Languages) + Languages.Add(new LocalizedEnumValue(lang)); if(metadata.Architectures != null) { @@ -219,19 +221,16 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase // Complex objects if(metadata.Barcodes != null) - { - foreach(Barcode barcode in metadata.Barcodes) Barcodes.Add(new BarcodeViewModel(barcode)); - } + foreach(Barcode barcode in metadata.Barcodes) + Barcodes.Add(new BarcodeViewModel(barcode)); if(metadata.Magazines != null) - { - foreach(Magazine magazine in metadata.Magazines) Magazines.Add(new MagazineViewModel(magazine)); - } + foreach(Magazine magazine in metadata.Magazines) + Magazines.Add(new MagazineViewModel(magazine)); if(metadata.Books != null) - { - foreach(Book book in metadata.Books) Books.Add(new BookViewModel(book)); - } + foreach(Book book in metadata.Books) + Books.Add(new BookViewModel(book)); if(metadata.RequiredOperatingSystems != null) { @@ -240,39 +239,32 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase } if(metadata.UserManuals != null) - { - foreach(UserManual manual in metadata.UserManuals) UserManuals.Add(new UserManualViewModel(manual)); - } + foreach(UserManual manual in metadata.UserManuals) + UserManuals.Add(new UserManualViewModel(manual)); if(metadata.OpticalDiscs != null) - { - foreach(OpticalDisc disc in metadata.OpticalDiscs) OpticalDiscs.Add(new OpticalDiscViewModel(disc)); - } + foreach(OpticalDisc disc in metadata.OpticalDiscs) + OpticalDiscs.Add(new OpticalDiscViewModel(disc)); if(metadata.Advertisements != null) - { - foreach(Advertisement ad in metadata.Advertisements) Advertisements.Add(new AdvertisementViewModel(ad)); - } + foreach(Advertisement ad in metadata.Advertisements) + Advertisements.Add(new AdvertisementViewModel(ad)); if(metadata.LinearMedias != null) - { - foreach(LinearMedia media in metadata.LinearMedias) LinearMedias.Add(new LinearMediaViewModel(media)); - } + foreach(LinearMedia media in metadata.LinearMedias) + LinearMedias.Add(new LinearMediaViewModel(media)); if(metadata.PciCards != null) - { - foreach(Pci pci in metadata.PciCards) PciCards.Add(new PciViewModel(pci)); - } + foreach(Pci pci in metadata.PciCards) + PciCards.Add(new PciViewModel(pci)); if(metadata.BlockMedias != null) - { - foreach(BlockMedia media in metadata.BlockMedias) BlockMedias.Add(new BlockMediaViewModel(media)); - } + foreach(BlockMedia media in metadata.BlockMedias) + BlockMedias.Add(new BlockMediaViewModel(media)); if(metadata.AudioMedias != null) - { - foreach(AudioMedia media in metadata.AudioMedias) AudioMedias.Add(new AudioMediaViewModel(media)); - } + foreach(AudioMedia media in metadata.AudioMedias) + AudioMedias.Add(new AudioMediaViewModel(media)); } catch(Exception ex) { @@ -455,9 +447,8 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase void AddLanguage(object parameter) { if(parameter is LocalizedEnumValue langValue) - { - if(!Languages.Any(l => l.Value == langValue.Value)) Languages.Add(langValue); - } + if(!Languages.Any(l => l.Value == langValue.Value)) + Languages.Add(langValue); } [RelayCommand] @@ -467,9 +458,8 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase void AddArchitecture(object parameter) { if(parameter is LocalizedEnumValue archValue) - { - if(!Architectures.Any(a => a.Value == archValue.Value)) Architectures.Add(archValue); - } + if(!Architectures.Any(a => a.Value == archValue.Value)) + Architectures.Add(archValue); } [RelayCommand] @@ -570,6 +560,8 @@ public sealed partial class BarcodeViewModel : ObservableObject public sealed partial class MagazineViewModel : ObservableObject { + readonly Magazine _originalModel; + [ObservableProperty] string _editorial; [ObservableProperty] @@ -587,10 +579,11 @@ public sealed partial class MagazineViewModel : ObservableObject [ObservableProperty] DateTime? _publicationDate; - public MagazineViewModel() {} + public MagazineViewModel() => _originalModel = new Magazine(); public MagazineViewModel([NotNull] Magazine magazine) { + _originalModel = magazine; Name = magazine.Name; Editorial = magazine.Editorial; PublicationDate = magazine.PublicationDate; @@ -600,19 +593,24 @@ public sealed partial class MagazineViewModel : ObservableObject } [NotNull] - public Magazine ToModel() => new() + public Magazine ToModel() { - Name = Name, - Editorial = Editorial, - PublicationDate = PublicationDate, - Number = Number, - Pages = Pages, - PageSize = PageSize - }; + // Update only the editable fields, preserve all others (Barcodes, Cover, Languages, Scan) + _originalModel.Name = Name; + _originalModel.Editorial = Editorial; + _originalModel.PublicationDate = PublicationDate; + _originalModel.Number = Number; + _originalModel.Pages = Pages; + _originalModel.PageSize = PageSize; + + return _originalModel; + } } public sealed partial class BookViewModel : ObservableObject { + readonly Book _originalModel; + [ObservableProperty] string _author; @@ -632,10 +630,11 @@ public sealed partial class BookViewModel : ObservableObject [ObservableProperty] DateTime? _publicationDate; - public BookViewModel() {} + public BookViewModel() => _originalModel = new Book(); public BookViewModel([NotNull] Book book) { + _originalModel = book; Name = book.Name; Editorial = book.Editorial; Author = book.Author; @@ -645,15 +644,18 @@ public sealed partial class BookViewModel : ObservableObject } [NotNull] - public Book ToModel() => new() + public Book ToModel() { - Name = Name, - Editorial = Editorial, - Author = Author, - PublicationDate = PublicationDate, - Pages = Pages, - PageSize = PageSize - }; + // Update only the editable fields, preserve all others (Barcodes, Cover, Languages, Scan) + _originalModel.Name = Name; + _originalModel.Editorial = Editorial; + _originalModel.Author = Author; + _originalModel.PublicationDate = PublicationDate; + _originalModel.Pages = Pages; + _originalModel.PageSize = PageSize; + + return _originalModel; + } } public sealed partial class RequiredOperatingSystemViewModel : ObservableObject @@ -685,31 +687,39 @@ public sealed partial class RequiredOperatingSystemViewModel : ObservableObject public sealed partial class UserManualViewModel : ObservableObject { + readonly UserManual _originalModel; + [ObservableProperty] uint _pages; [ObservableProperty] string _pageSize; - public UserManualViewModel() {} + public UserManualViewModel() => _originalModel = new UserManual(); public UserManualViewModel([NotNull] UserManual manual) { - Pages = manual.Pages; - PageSize = manual.PageSize; + _originalModel = manual; + Pages = manual.Pages; + PageSize = manual.PageSize; } [NotNull] - public UserManual ToModel() => new() + public UserManual ToModel() { - Pages = Pages, - PageSize = PageSize - }; + // Update only the editable fields, preserve all others (Language, Scan) + _originalModel.Pages = Pages; + _originalModel.PageSize = PageSize; + + return _originalModel; + } } // Simplified ViewModels for complex media types (can be expanded as needed) public sealed partial class OpticalDiscViewModel : ObservableObject { + readonly OpticalDisc _originalModel; + [ObservableProperty] string _discSubType; @@ -721,52 +731,64 @@ public sealed partial class OpticalDiscViewModel : ObservableObject [ObservableProperty] string _serialNumber; - public OpticalDiscViewModel() {} + public OpticalDiscViewModel() => _originalModel = new OpticalDisc(); public OpticalDiscViewModel([NotNull] OpticalDisc disc) { - PartNumber = disc.PartNumber; - SerialNumber = disc.SerialNumber; - DiscType = disc.DiscType; - DiscSubType = disc.DiscSubType; + _originalModel = disc; + PartNumber = disc.PartNumber; + SerialNumber = disc.SerialNumber; + DiscType = disc.DiscType; + DiscSubType = disc.DiscSubType; } [NotNull] - public OpticalDisc ToModel() => new() + public OpticalDisc ToModel() { - PartNumber = PartNumber, - SerialNumber = SerialNumber, - DiscType = DiscType, - DiscSubType = DiscSubType - }; + // Update only the editable fields, preserve all others + _originalModel.PartNumber = PartNumber; + _originalModel.SerialNumber = SerialNumber; + _originalModel.DiscType = DiscType; + _originalModel.DiscSubType = DiscSubType; + + return _originalModel; + } } public sealed partial class AdvertisementViewModel : ObservableObject { + readonly Advertisement _originalModel; + [ObservableProperty] string _manufacturer; [ObservableProperty] string _product; - public AdvertisementViewModel() {} + public AdvertisementViewModel() => _originalModel = new Advertisement(); public AdvertisementViewModel([NotNull] Advertisement ad) { - Manufacturer = ad.Manufacturer; - Product = ad.Product; + _originalModel = ad; + Manufacturer = ad.Manufacturer; + Product = ad.Product; } [NotNull] - public Advertisement ToModel() => new() + public Advertisement ToModel() { - Manufacturer = Manufacturer, - Product = Product - }; + // Update only the editable fields, preserve all others (File, FileSize, Frames, Duration, etc.) + _originalModel.Manufacturer = Manufacturer; + _originalModel.Product = Product; + + return _originalModel; + } } public sealed partial class LinearMediaViewModel : ObservableObject { + readonly LinearMedia _originalModel; + [ObservableProperty] string _manufacturer; @@ -778,51 +800,63 @@ public sealed partial class LinearMediaViewModel : ObservableObject [ObservableProperty] string _serialNumber; - public LinearMediaViewModel() {} + public LinearMediaViewModel() => _originalModel = new LinearMedia(); public LinearMediaViewModel([NotNull] LinearMedia media) { - PartNumber = media.PartNumber; - SerialNumber = media.SerialNumber; - Manufacturer = media.Manufacturer; - Model = media.Model; + _originalModel = media; + PartNumber = media.PartNumber; + SerialNumber = media.SerialNumber; + Manufacturer = media.Manufacturer; + Model = media.Model; } [NotNull] - public LinearMedia ToModel() => new() + public LinearMedia ToModel() { - PartNumber = PartNumber, - SerialNumber = SerialNumber, - Manufacturer = Manufacturer, - Model = Model - }; + // Update only the editable fields, preserve all others + _originalModel.PartNumber = PartNumber; + _originalModel.SerialNumber = SerialNumber; + _originalModel.Manufacturer = Manufacturer; + _originalModel.Model = Model; + + return _originalModel; + } } public sealed partial class PciViewModel : ObservableObject { + readonly Pci _originalModel; + [ObservableProperty] ushort _deviceID; [ObservableProperty] ushort _vendorID; - public PciViewModel() {} + public PciViewModel() => _originalModel = new Pci(); public PciViewModel([NotNull] Pci pci) { - VendorID = pci.VendorID; - DeviceID = pci.DeviceID; + _originalModel = pci; + VendorID = pci.VendorID; + DeviceID = pci.DeviceID; } [NotNull] - public Pci ToModel() => new() + public Pci ToModel() { - VendorID = VendorID, - DeviceID = DeviceID - }; + // Update only the editable fields, preserve all others + _originalModel.VendorID = VendorID; + _originalModel.DeviceID = DeviceID; + + return _originalModel; + } } public sealed partial class BlockMediaViewModel : ObservableObject { + readonly BlockMedia _originalModel; + [ObservableProperty] string _firmware; [ObservableProperty] @@ -834,28 +868,34 @@ public sealed partial class BlockMediaViewModel : ObservableObject [ObservableProperty] string _serial; - public BlockMediaViewModel() {} + public BlockMediaViewModel() => _originalModel = new BlockMedia(); public BlockMediaViewModel([NotNull] BlockMedia media) { - Manufacturer = media.Manufacturer; - Model = media.Model; - Serial = media.Serial; - Firmware = media.Firmware; + _originalModel = media; + Manufacturer = media.Manufacturer; + Model = media.Model; + Serial = media.Serial; + Firmware = media.Firmware; } [NotNull] - public BlockMedia ToModel() => new() + public BlockMedia ToModel() { - Manufacturer = Manufacturer, - Model = Model, - Serial = Serial, - Firmware = Firmware - }; + // Update only the editable fields, preserve all others + _originalModel.Manufacturer = Manufacturer; + _originalModel.Model = Model; + _originalModel.Serial = Serial; + _originalModel.Firmware = Firmware; + + return _originalModel; + } } public sealed partial class AudioMediaViewModel : ObservableObject { + readonly AudioMedia _originalModel; + [ObservableProperty] string _manufacturer; @@ -868,22 +908,26 @@ public sealed partial class AudioMediaViewModel : ObservableObject [ObservableProperty] string _serialNumber; - public AudioMediaViewModel() {} + public AudioMediaViewModel() => _originalModel = new AudioMedia(); public AudioMediaViewModel([NotNull] AudioMedia media) { - Manufacturer = media.Manufacturer; - Model = media.Model; - PartNumber = media.PartNumber; - SerialNumber = media.SerialNumber; + _originalModel = media; + Manufacturer = media.Manufacturer; + Model = media.Model; + PartNumber = media.PartNumber; + SerialNumber = media.SerialNumber; } [NotNull] - public AudioMedia ToModel() => new() + public AudioMedia ToModel() { - Manufacturer = Manufacturer, - Model = Model, - PartNumber = PartNumber, - SerialNumber = SerialNumber - }; + // Update only the editable fields, preserve all others + _originalModel.Manufacturer = Manufacturer; + _originalModel.Model = Model; + _originalModel.PartNumber = PartNumber; + _originalModel.SerialNumber = SerialNumber; + + return _originalModel; + } } \ No newline at end of file