Files
LehrerApp/LehrerApp.TemplateDesigner/PdfImportDialog.axaml.cs
T
2026-08-31 19:56:25 +02:00

90 lines
4.1 KiB
C#

using System.Collections.ObjectModel;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.ComponentModel;
using LehrerApp.Templating;
using System.Runtime.Versioning;
namespace LehrerApp.TemplateDesigner;
public partial class PdfImportDialogViewModel : ObservableObject
{
[ObservableProperty] private string _examplePath = "";
[ObservableProperty] private string _templatePath = "";
[ObservableProperty] private bool _useAi = true;
[ObservableProperty] private string _username = "";
[ObservableProperty] private string _password = "";
[ObservableProperty] private string _status = "Bitte mindestens ein ausgefülltes Beispiel-PDF auswählen.";
[ObservableProperty] private bool _isBusy;
[ObservableProperty] private bool _hasResult;
public ObservableCollection<PdfImportCandidate> Candidates { get; } = [];
public IReadOnlyList<PlaceholderType> PlaceholderTypes { get; } =
[PlaceholderType.Text, PlaceholderType.Multiline, PlaceholderType.Date, PlaceholderType.Number];
public bool CanAnalyze => !IsBusy && File.Exists(ExamplePath) && (!UseAi
|| (!string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password)));
partial void OnExamplePathChanged(string value) => OnPropertyChanged(nameof(CanAnalyze));
partial void OnUseAiChanged(bool value) => OnPropertyChanged(nameof(CanAnalyze));
partial void OnUsernameChanged(string value) => OnPropertyChanged(nameof(CanAnalyze));
partial void OnPasswordChanged(string value) => OnPropertyChanged(nameof(CanAnalyze));
partial void OnIsBusyChanged(bool value) => OnPropertyChanged(nameof(CanAnalyze));
}
[SupportedOSPlatform("windows")]
[SupportedOSPlatform("linux")]
[SupportedOSPlatform("macos")]
public partial class PdfImportDialog : Window
{
private readonly PdfImportDialogViewModel _viewModel = new();
private PdfImportResult? _result;
public PdfImportResult? Result { get; private set; }
public PdfImportDialog() { InitializeComponent(); DataContext = _viewModel; }
private async void OnChooseExample(object? sender, RoutedEventArgs e)
{
var file = await ChoosePdf("Ausgefülltes Beispiel-PDF auswählen");
if (file is not null) _viewModel.ExamplePath = file;
}
private async void OnChooseTemplate(object? sender, RoutedEventArgs e)
{
var file = await ChoosePdf("Leeres Template-PDF auswählen");
if (file is not null) _viewModel.TemplatePath = file;
}
private async Task<string?> ChoosePdf(string title)
{
var files = await StorageProvider.OpenFilePickerAsync(new()
{ Title = title, AllowMultiple = false, FileTypeFilter = [new("PDF-Dateien") { Patterns = ["*.pdf"] }] });
return files.Count == 0 ? null : files[0].Path.LocalPath;
}
private async void OnAnalyze(object? sender, RoutedEventArgs e)
{
_viewModel.IsBusy = true; _viewModel.HasResult = false; _viewModel.Status = "PDF wird lokal analysiert …";
try
{
_result = await new PdfImportPipeline().BuildAsync(_viewModel.ExamplePath,
string.IsNullOrWhiteSpace(_viewModel.TemplatePath) ? null : _viewModel.TemplatePath,
_viewModel.UseAi ? _viewModel.Username : null, _viewModel.UseAi ? _viewModel.Password : null);
_viewModel.Candidates.Clear();
foreach (var candidate in _result.Candidates) _viewModel.Candidates.Add(candidate);
_viewModel.HasResult = true;
_viewModel.Status = $"{_viewModel.Candidates.Count} variable Textbereiche erkannt. Bitte Zuordnung prüfen und bestätigen.";
}
catch (Exception ex) { _viewModel.Status = $"Import fehlgeschlagen: {ex.Message}"; }
finally { _viewModel.IsBusy = false; }
}
private void OnAccept(object? sender, RoutedEventArgs e)
{
if (_result is null) return;
var document = new PdfImportPipeline().Extract(_viewModel.ExamplePath);
Result = new PdfImportPipeline().BuildResult(_viewModel.ExamplePath, document, _viewModel.Candidates);
Close(true);
}
private void OnCancel(object? sender, RoutedEventArgs e) => Close(false);
}