From 017bbd99ddccc7025a6657f267b3b679ad71b154 Mon Sep 17 00:00:00 2001 From: Flaky Date: Sat, 10 Jan 2026 16:32:13 +0000 Subject: [PATCH] implement exporting --- UI/ViewModels/MainWindowViewModel.cs | 22 ++++++++++++++++++++++ UI/Views/MainWindow.axaml | 4 ++-- UI/Views/MainWindow.axaml.cs | 28 +++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/UI/ViewModels/MainWindowViewModel.cs b/UI/ViewModels/MainWindowViewModel.cs index cf616b0..60f5349 100644 --- a/UI/ViewModels/MainWindowViewModel.cs +++ b/UI/ViewModels/MainWindowViewModel.cs @@ -1,11 +1,14 @@ using System; using System.Collections.ObjectModel; using System.Diagnostics; +using System.IO; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using CommunityToolkit.Mvvm.ComponentModel; +using TagHierarchyManager.Common; +using TagHierarchyManager.Exporters; using TagHierarchyManager.Models; using TagHierarchyManager.UI.Assets; using TagHierarchyManager.UI.Views; @@ -104,6 +107,25 @@ public partial class MainWindowViewModel : ViewModelBase } } + private static IExporter PickExporterFromFileExt(string path) + { + string fileExt = Path.GetExtension(path); + + // ReSharper disable once ConvertIfStatementToReturnStatement + if (fileExt == FileTypes.MusicBeeTagHierarchyTemplate.FileExtension) return new MusicBeeTagHierarchyExporter(); + + throw new NotSupportedException($"File extension '{fileExt}' is not supported."); + } + + public async Task ExportAsync(string path) + { + IExporter exporter = PickExporterFromFileExt(path); + this.StatusBlockText = "Exporting..."; + string exportContent = exporter.ExportDatabase(this.Database); + await File.WriteAllTextAsync(path, exportContent); + this.StatusBlockText = "Export complete."; + } + private void TagDatabase_TagAdded(object? sender, Tag _) => this.OnPropertyChanged(nameof(TotalTags)); private void TagDatabase_TagDeleted(object? sender, (int id, string name) _) => this.OnPropertyChanged(nameof(TotalTags)); diff --git a/UI/Views/MainWindow.axaml b/UI/Views/MainWindow.axaml index 9f1a1c0..addc3fd 100644 --- a/UI/Views/MainWindow.axaml +++ b/UI/Views/MainWindow.axaml @@ -12,9 +12,9 @@ @@ -30,7 +30,7 @@ - + diff --git a/UI/Views/MainWindow.axaml.cs b/UI/Views/MainWindow.axaml.cs index 873fb24..b080d27 100644 --- a/UI/Views/MainWindow.axaml.cs +++ b/UI/Views/MainWindow.axaml.cs @@ -22,6 +22,11 @@ public partial class MainWindow : Window Patterns = ["*.thdb"] }; + private static FilePickerFileType MusicBeeTagHierarchy { get; } = new("MusicBee tag hierarchy template") + { + Patterns = ["*.txt"] + }; + public void OpenAboutWindow(object? sender, RoutedEventArgs e) => new AboutWindow().ShowDialog(this); public void MenuItemQuit_Click(object? sender, RoutedEventArgs e) => this.Close(); @@ -49,13 +54,14 @@ public partial class MainWindow : Window public async void MenuItemNew_Click(object? sender, RoutedEventArgs e) { + if (this.ViewModel.Database is null) return; try { var file = await this.StorageProvider.SaveFilePickerAsync( new FilePickerSaveOptions { Title = "Create a new tag database...", - FileTypeChoices = [TagDatabaseFileType] + FileTypeChoices = [MusicBeeTagHierarchy] }); if (file == null) return; var path = file.TryGetLocalPath(); @@ -66,6 +72,26 @@ public partial class MainWindow : Window throw; // TODO handle exception } } + + public async void MenuItemExport_Click(object? sender, RoutedEventArgs e) + { + try + { + var file = await this.StorageProvider.SaveFilePickerAsync( + new FilePickerSaveOptions + { + Title = "Export tag database...", + FileTypeChoices = [MusicBeeTagHierarchy] + }); + if (file == null) return; + var path = file.TryGetLocalPath(); + await this.ViewModel.ExportAsync(path); + } + catch (Exception ex) + { + throw; // TODO handle exception + } + } public async void ButtonSave_Click(object? sender, RoutedEventArgs e) { -- 2.51.2