139 lines
4.1 KiB
C#
139 lines
4.1 KiB
C#
using System.Diagnostics;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Platform.Storage;
|
|
using Avalonia.Threading;
|
|
using XSDVisualiser.Core;
|
|
using XSDVisualiser.Desktop.ViewModels;
|
|
|
|
namespace XSDVisualiser.Desktop.Views;
|
|
|
|
/// <summary>
|
|
/// Header area with actions to open an XSD file and perform file-related utilities.
|
|
/// </summary>
|
|
public partial class HeaderView : UserControl
|
|
{
|
|
private readonly Button? _openBtn;
|
|
|
|
public HeaderView()
|
|
{
|
|
InitializeComponent();
|
|
_openBtn = this.FindControl<Button>("OpenBtn");
|
|
if (_openBtn != null) _openBtn.Click += OpenBtn_Click;
|
|
}
|
|
|
|
private async void OpenBtn_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
if (TopLevel.GetTopLevel(this) is not Window topLevel)
|
|
return;
|
|
|
|
var storageProvider = topLevel.StorageProvider;
|
|
var options = new FilePickerOpenOptions
|
|
{
|
|
AllowMultiple = false,
|
|
Title = "Open XSD file",
|
|
FileTypeFilter =
|
|
[
|
|
new FilePickerFileType("XSD schema")
|
|
{
|
|
Patterns = ["*.xsd"]
|
|
}
|
|
]
|
|
};
|
|
var results = await storageProvider.OpenFilePickerAsync(options);
|
|
if (results.Count <= 0) return;
|
|
|
|
var file = results[0];
|
|
var path = file.TryGetLocalPath();
|
|
if (!string.IsNullOrEmpty(path))
|
|
await ParseAndShowAsync(path!, topLevel);
|
|
else
|
|
Dispatcher.UIThread.Post(() => topLevel.DataContext = new MainWindowViewModel(new SchemaModel
|
|
{ TargetNamespace = "Selected file is not a local file. Please choose a local .xsd." }));
|
|
}
|
|
|
|
private Task ParseAndShowAsync(string path, Window hostWindow)
|
|
{
|
|
return Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
var parser = new XsdSchemaParser();
|
|
var model = parser.Parse(path);
|
|
Dispatcher.UIThread.Post(() =>
|
|
{
|
|
var vm = new MainWindowViewModel(model)
|
|
{
|
|
CurrentFilePath = path
|
|
};
|
|
hostWindow.DataContext = vm;
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Dispatcher.UIThread.Post(() =>
|
|
hostWindow.DataContext = new MainWindowViewModel(new SchemaModel { TargetNamespace = ex.Message }));
|
|
}
|
|
});
|
|
}
|
|
|
|
private async void OnCopyPathClick(object? sender, RoutedEventArgs e)
|
|
{
|
|
var vm = DataContext as MainWindowViewModel;
|
|
var path = vm?.CurrentFilePath;
|
|
if (string.IsNullOrWhiteSpace(path)) return;
|
|
|
|
var topLevel = TopLevel.GetTopLevel(this);
|
|
if (topLevel?.Clipboard != null) await topLevel.Clipboard.SetTextAsync(path);
|
|
}
|
|
|
|
private void OnOpenContainingFolderClick(object? sender, RoutedEventArgs e)
|
|
{
|
|
var vm = DataContext as MainWindowViewModel;
|
|
var path = vm?.CurrentFilePath;
|
|
if (string.IsNullOrWhiteSpace(path)) return;
|
|
var dir = Path.GetDirectoryName(path);
|
|
if (string.IsNullOrWhiteSpace(dir) || !Directory.Exists(dir)) return;
|
|
TryOpenFolder(dir);
|
|
}
|
|
|
|
private static void TryOpenFolder(string dir)
|
|
{
|
|
try
|
|
{
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
var psi = new ProcessStartInfo("explorer.exe", dir)
|
|
{
|
|
UseShellExecute = true
|
|
};
|
|
Process.Start(psi);
|
|
}
|
|
else if (OperatingSystem.IsMacOS())
|
|
{
|
|
Process.Start("open", dir);
|
|
}
|
|
else
|
|
{
|
|
// Linux
|
|
Process.Start("xdg-open", dir);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
try
|
|
{
|
|
var psi = new ProcessStartInfo
|
|
{
|
|
FileName = dir,
|
|
UseShellExecute = true
|
|
};
|
|
Process.Start(psi);
|
|
}
|
|
catch
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
}
|
|
} |