Catalog/imagecatalog/Controls/PathPickerField.axaml.cs

285 lines
9.1 KiB
C#
Raw Normal View History

using Avalonia;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Platform.Storage;
using ImageCatalog_2.Services;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ImageCatalog_2.Controls;
public partial class PathPickerField : UserControl
{
private readonly PickerPreferenceService _pickerPreferenceService;
public static readonly StyledProperty<string> LabelProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(Label), string.Empty);
public static readonly StyledProperty<string> TextProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(Text), string.Empty, defaultBindingMode: BindingMode.TwoWay);
public static readonly StyledProperty<string> WatermarkProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(Watermark), string.Empty);
public static readonly StyledProperty<string> PreferenceKeyProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(PreferenceKey), string.Empty);
public static readonly StyledProperty<string> PickerTitleProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(PickerTitle), string.Empty);
public static readonly StyledProperty<string> FileTypeNameProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(FileTypeName), string.Empty);
public static readonly StyledProperty<string> FilePatternsProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(FilePatterns), string.Empty);
public static readonly StyledProperty<string> DefaultExtensionProperty =
AvaloniaProperty.Register<PathPickerField, string>(nameof(DefaultExtension), string.Empty);
public static readonly StyledProperty<PathPickerSelectionMode> PickerModeProperty =
AvaloniaProperty.Register<PathPickerField, PathPickerSelectionMode>(nameof(PickerMode), PathPickerSelectionMode.Folder);
public static readonly StyledProperty<bool> IsTextReadOnlyProperty =
AvaloniaProperty.Register<PathPickerField, bool>(nameof(IsTextReadOnly), false);
public static readonly StyledProperty<bool> ShowPickerButtonProperty =
AvaloniaProperty.Register<PathPickerField, bool>(nameof(ShowPickerButton), true);
public static readonly StyledProperty<bool> AppendDirectorySeparatorProperty =
AvaloniaProperty.Register<PathPickerField, bool>(nameof(AppendDirectorySeparator), false);
public PathPickerField()
{
_pickerPreferenceService = Program.ServiceProvider.GetRequiredService<PickerPreferenceService>();
InitializeComponent();
}
public string Label
{
get => GetValue(LabelProperty);
set => SetValue(LabelProperty, value);
}
public string Text
{
get => GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public string Watermark
{
get => GetValue(WatermarkProperty);
set => SetValue(WatermarkProperty, value);
}
public string PreferenceKey
{
get => GetValue(PreferenceKeyProperty);
set => SetValue(PreferenceKeyProperty, value);
}
public string PickerTitle
{
get => GetValue(PickerTitleProperty);
set => SetValue(PickerTitleProperty, value);
}
public string FileTypeName
{
get => GetValue(FileTypeNameProperty);
set => SetValue(FileTypeNameProperty, value);
}
public string FilePatterns
{
get => GetValue(FilePatternsProperty);
set => SetValue(FilePatternsProperty, value);
}
public string DefaultExtension
{
get => GetValue(DefaultExtensionProperty);
set => SetValue(DefaultExtensionProperty, value);
}
public PathPickerSelectionMode PickerMode
{
get => GetValue(PickerModeProperty);
set => SetValue(PickerModeProperty, value);
}
public bool IsTextReadOnly
{
get => GetValue(IsTextReadOnlyProperty);
set => SetValue(IsTextReadOnlyProperty, value);
}
public bool ShowPickerButton
{
get => GetValue(ShowPickerButtonProperty);
set => SetValue(ShowPickerButtonProperty, value);
}
public bool AppendDirectorySeparator
{
get => GetValue(AppendDirectorySeparatorProperty);
set => SetValue(AppendDirectorySeparatorProperty, value);
}
private async void PickPath_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
var topLevel = TopLevel.GetTopLevel(this);
var storageProvider = topLevel?.StorageProvider;
if (storageProvider is null)
{
return;
}
var selectedPath = await PickPathAsync(storageProvider);
if (string.IsNullOrWhiteSpace(selectedPath))
{
return;
}
Text = selectedPath;
if (!string.IsNullOrWhiteSpace(PreferenceKey))
{
_pickerPreferenceService.RememberPath(PreferenceKey, selectedPath);
}
}
private void OpenPath_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
PathShellService.OpenInExplorer(Text);
}
private async Task<string?> PickPathAsync(IStorageProvider storageProvider)
{
var suggestedStartLocation = await TryGetSuggestedStartLocationAsync(storageProvider);
var pickerTitle = ResolvePickerTitle();
switch (PickerMode)
{
case PathPickerSelectionMode.Folder:
{
var folders = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = pickerTitle,
SuggestedStartLocation = suggestedStartLocation
});
return folders.Count == 0
? null
: NormalizeSelectedPath(folders[0].Path.LocalPath);
}
case PathPickerSelectionMode.OpenFile:
{
var files = await storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = pickerTitle,
SuggestedStartLocation = suggestedStartLocation,
FileTypeFilter = BuildFileTypes()
});
return files.Count == 0
? null
: files[0].Path.LocalPath;
}
case PathPickerSelectionMode.SaveFile:
{
var file = await storageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
{
Title = pickerTitle,
SuggestedStartLocation = suggestedStartLocation,
DefaultExtension = NormalizeDefaultExtension(DefaultExtension),
FileTypeChoices = BuildFileTypes()
});
return file?.Path.LocalPath;
}
default:
return null;
}
}
private async Task<IStorageFolder?> TryGetSuggestedStartLocationAsync(IStorageProvider storageProvider)
{
if (string.IsNullOrWhiteSpace(PreferenceKey))
{
return null;
}
return await _pickerPreferenceService.TryGetStartFolderAsync(storageProvider, PreferenceKey, Text);
}
private IReadOnlyList<FilePickerFileType> BuildFileTypes()
{
var patterns = (FilePatterns ?? string.Empty)
.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (patterns.Length == 0)
{
return Array.Empty<FilePickerFileType>();
}
var fileTypeName = string.IsNullOrWhiteSpace(FileTypeName)
? "File"
: FileTypeName.Trim();
return
[
new FilePickerFileType(fileTypeName)
{
Patterns = patterns.ToList()
}
];
}
private string ResolvePickerTitle()
{
if (!string.IsNullOrWhiteSpace(PickerTitle))
{
return PickerTitle;
}
var cleanedLabel = string.IsNullOrWhiteSpace(Label)
? "percorso"
: Label.Trim().TrimEnd(':');
return PickerMode == PathPickerSelectionMode.SaveFile
? $"Salva {cleanedLabel.ToLowerInvariant()}"
: $"Seleziona {cleanedLabel.ToLowerInvariant()}";
}
private string NormalizeSelectedPath(string selectedPath)
{
if (PickerMode != PathPickerSelectionMode.Folder || !AppendDirectorySeparator)
{
return selectedPath;
}
if (string.IsNullOrWhiteSpace(selectedPath))
{
return string.Empty;
}
return selectedPath.EndsWith(Path.DirectorySeparatorChar)
|| selectedPath.EndsWith(Path.AltDirectorySeparatorChar)
? selectedPath
: selectedPath + Path.DirectorySeparatorChar;
}
private static string NormalizeDefaultExtension(string extension)
{
if (string.IsNullOrWhiteSpace(extension))
{
return string.Empty;
}
return extension.Trim().TrimStart('.');
}
}