diff --git a/RomRepoMgr.Core/Models/RomSetModel.cs b/RomRepoMgr.Core/Models/RomSetModel.cs index bb31fa7..527d43f 100644 --- a/RomRepoMgr.Core/Models/RomSetModel.cs +++ b/RomRepoMgr.Core/Models/RomSetModel.cs @@ -42,5 +42,6 @@ namespace RomRepoMgr.Core.Models public long TotalRoms { get; set; } public long HaveRoms { get; set; } public long MissRoms { get; set; } + public long Id { get; set; } } } \ No newline at end of file diff --git a/RomRepoMgr.Core/Workers/DatImporter.cs b/RomRepoMgr.Core/Workers/DatImporter.cs index 20a1955..50be15e 100644 --- a/RomRepoMgr.Core/Workers/DatImporter.cs +++ b/RomRepoMgr.Core/Workers/DatImporter.cs @@ -464,6 +464,7 @@ namespace RomRepoMgr.Core.Workers { RomSet = new RomSetModel { + Id = romSet.Id, Author = romSet.Author, Comment = romSet.Comment, Date = romSet.Date, diff --git a/RomRepoMgr/ViewModels/MainWindowViewModel.cs b/RomRepoMgr/ViewModels/MainWindowViewModel.cs index fe88a28..36f9f84 100644 --- a/RomRepoMgr/ViewModels/MainWindowViewModel.cs +++ b/RomRepoMgr/ViewModels/MainWindowViewModel.cs @@ -30,6 +30,8 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Threading; +using MessageBox.Avalonia; +using MessageBox.Avalonia.Enums; using ReactiveUI; using RomRepoMgr.Core.EventArgs; using RomRepoMgr.Core.Models; @@ -41,6 +43,8 @@ namespace RomRepoMgr.ViewModels { readonly MainWindow _view; + RomSetModel _selectedRomSet; + public MainWindowViewModel(MainWindow view, List romSets) { _view = view; @@ -50,6 +54,7 @@ namespace RomRepoMgr.ViewModels ImportDatCommand = ReactiveCommand.Create(ExecuteImportDatCommand); ImportDatFolderCommand = ReactiveCommand.Create(ExecuteImportDatFolderCommand); ImportRomFolderCommand = ReactiveCommand.Create(ExecuteImportRomFolderCommand); + DeleteRomSetCommand = ReactiveCommand.Create(ExecuteDeleteRomSetCommand); RomSets = new ObservableCollection(romSets); } @@ -79,6 +84,13 @@ namespace RomRepoMgr.ViewModels public ReactiveCommand ImportDatCommand { get; } public ReactiveCommand ImportDatFolderCommand { get; } public ReactiveCommand ImportRomFolderCommand { get; } + public ReactiveCommand DeleteRomSetCommand { get; } + + public RomSetModel SelectedRomSet + { + get => _selectedRomSet; + set => this.RaiseAndSetIfChanged(ref _selectedRomSet, value); + } internal async void ExecuteSettingsCommand() { @@ -177,5 +189,29 @@ namespace RomRepoMgr.ViewModels dialog.DataContext = importRomFolderViewModel; await dialog.ShowDialog(_view); } + + async void ExecuteDeleteRomSetCommand() + { + if(SelectedRomSet == null) + return; + + ButtonResult result = await MessageBoxManager.GetMessageBoxStandardWindow("Delete ROM set", + string. + Format("Are you sure you want to delete the ROM set {0}?", + SelectedRomSet.Name), ButtonEnum.YesNo, + Icon.Database). + ShowDialog(_view); + + if(result == ButtonResult.No) + return; + + var dialog = new RemoveDat(); + var removeDatViewModel = new RemoveDatViewModel(dialog, SelectedRomSet.Id); + dialog.DataContext = removeDatViewModel; + await dialog.ShowDialog(_view); + + RomSets.Remove(SelectedRomSet); + SelectedRomSet = null; + } } } \ No newline at end of file diff --git a/RomRepoMgr/ViewModels/RemoveDatViewModel.cs b/RomRepoMgr/ViewModels/RemoveDatViewModel.cs new file mode 100644 index 0000000..502403c --- /dev/null +++ b/RomRepoMgr/ViewModels/RemoveDatViewModel.cs @@ -0,0 +1,114 @@ +/****************************************************************************** +// RomRepoMgr - ROM repository manager +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright © 2020 Natalia Portillo +*******************************************************************************/ + +using System.IO; +using System.Threading.Tasks; +using Avalonia.Threading; +using JetBrains.Annotations; +using ReactiveUI; +using RomRepoMgr.Core; +using RomRepoMgr.Database; +using RomRepoMgr.Database.Models; +using RomRepoMgr.Views; + +namespace RomRepoMgr.ViewModels +{ + public sealed class RemoveDatViewModel : ViewModelBase + { + readonly long _romSetId; + readonly RemoveDat _view; + string _statusMessage; + + public RemoveDatViewModel(RemoveDat view, long romSetId) + { + _view = view; + _romSetId = romSetId; + } + + [NotNull] + public string Title => "Removing ROM set..."; + + public string StatusMessage + { + get => _statusMessage; + set => this.RaiseAndSetIfChanged(ref _statusMessage, value); + } + + internal void OnOpened() => Task.Run(() => + { + Dispatcher.UIThread.Post(() => StatusMessage = "Retrieving ROM set from database..."); + + RomSet romSet = Context.Singleton.RomSets.Find(_romSetId); + + if(romSet == null) + return; + + Dispatcher.UIThread.Post(() => StatusMessage = "Removing ROM set from database..."); + + Context.Singleton.RomSets.Remove(romSet); + + Dispatcher.UIThread.Post(() => StatusMessage = "Saving changes to database..."); + + Context.Singleton.SaveChanges(); + + Dispatcher.UIThread.Post(() => StatusMessage = "Removing DAT file from repo..."); + + byte[] sha384Bytes = new byte[48]; + string sha384 = romSet.Sha384; + + for(int i = 0; i < 48; i++) + { + if(sha384[i * 2] >= 0x30 && + sha384[i * 2] <= 0x39) + sha384Bytes[i] = (byte)((sha384[i * 2] - 0x30) * 0x10); + else if(sha384[i * 2] >= 0x41 && + sha384[i * 2] <= 0x46) + sha384Bytes[i] = (byte)((sha384[i * 2] - 0x37) * 0x10); + else if(sha384[i * 2] >= 0x61 && + sha384[i * 2] <= 0x66) + sha384Bytes[i] = (byte)((sha384[i * 2] - 0x57) * 0x10); + + if(sha384[(i * 2) + 1] >= 0x30 && + sha384[(i * 2) + 1] <= 0x39) + sha384Bytes[i] += (byte)(sha384[(i * 2) + 1] - 0x30); + else if(sha384[(i * 2) + 1] >= 0x41 && + sha384[(i * 2) + 1] <= 0x46) + sha384Bytes[i] += (byte)(sha384[(i * 2) + 1] - 0x37); + else if(sha384[(i * 2) + 1] >= 0x61 && + sha384[(i * 2) + 1] <= 0x66) + sha384Bytes[i] += (byte)(sha384[(i * 2) + 1] - 0x57); + } + + string datHash32 = Base32.ToBase32String(sha384Bytes); + string datFilesPath = Path.Combine(Settings.Settings.Current.RepositoryPath, "datfiles"); + string compressedDatPath = Path.Combine(datFilesPath, datHash32 + ".lz"); + + if(File.Exists(compressedDatPath)) + File.Delete(compressedDatPath); + + Dispatcher.UIThread.Post(_view.Close); + }); + } +} \ No newline at end of file diff --git a/RomRepoMgr/ViewModels/SplashWindowViewModel.cs b/RomRepoMgr/ViewModels/SplashWindowViewModel.cs index 20ca306..a55db75 100644 --- a/RomRepoMgr/ViewModels/SplashWindowViewModel.cs +++ b/RomRepoMgr/ViewModels/SplashWindowViewModel.cs @@ -370,6 +370,7 @@ namespace RomRepoMgr.ViewModels ThenBy(r => r.Date).ThenBy(r => r.Description).ThenBy(r => r.Comment). ThenBy(r => r.Filename).Select(r => new RomSetModel { + Id = r.Id, Author = r.Author, Comment = r.Comment, Date = r.Date, diff --git a/RomRepoMgr/Views/MainWindow.xaml b/RomRepoMgr/Views/MainWindow.xaml index ee6b1c8..4686254 100644 --- a/RomRepoMgr/Views/MainWindow.xaml +++ b/RomRepoMgr/Views/MainWindow.xaml @@ -19,6 +19,10 @@ + + + @@ -29,7 +33,8 @@ - + diff --git a/RomRepoMgr/Views/RemoveDat.xaml b/RomRepoMgr/Views/RemoveDat.xaml new file mode 100644 index 0000000..3f06acc --- /dev/null +++ b/RomRepoMgr/Views/RemoveDat.xaml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RomRepoMgr/Views/RemoveDat.xaml.cs b/RomRepoMgr/Views/RemoveDat.xaml.cs new file mode 100644 index 0000000..666e114 --- /dev/null +++ b/RomRepoMgr/Views/RemoveDat.xaml.cs @@ -0,0 +1,45 @@ +/****************************************************************************** +// RomRepoMgr - ROM repository manager +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// --[ 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 . +// +// ---------------------------------------------------------------------------- +// Copyright © 2020 Natalia Portillo +*******************************************************************************/ + +using System; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using RomRepoMgr.ViewModels; + +namespace RomRepoMgr.Views +{ + public sealed class RemoveDat : Window + { + public RemoveDat() => InitializeComponent(); + + void InitializeComponent() => AvaloniaXamlLoader.Load(this); + + protected override void OnOpened(EventArgs e) + { + base.OnOpened(e); + (DataContext as RemoveDatViewModel)?.OnOpened(); + } + } +} \ No newline at end of file