diff --git a/Aaru.Tui/Aaru.Tui.csproj b/Aaru.Tui/Aaru.Tui.csproj
index f0b98a888..4db8eebc7 100644
--- a/Aaru.Tui/Aaru.Tui.csproj
+++ b/Aaru.Tui/Aaru.Tui.csproj
@@ -13,6 +13,8 @@
+
+
diff --git a/Aaru.Tui/App.axaml b/Aaru.Tui/App.axaml
index 5e0c9a5d5..ae591df8d 100644
--- a/Aaru.Tui/App.axaml
+++ b/Aaru.Tui/App.axaml
@@ -2,8 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:console="https://github.com/jinek/consolonia"
x:Class="Aaru.Tui.App"
- RequestedThemeVariant="Dark">
+ RequestedThemeVariant="Light">
-
+
\ No newline at end of file
diff --git a/Aaru.Tui/App.axaml.cs b/Aaru.Tui/App.axaml.cs
index 766e539b7..ade758311 100644
--- a/Aaru.Tui/App.axaml.cs
+++ b/Aaru.Tui/App.axaml.cs
@@ -28,12 +28,50 @@
using Aaru.Tui.ViewModels.Windows;
using Aaru.Tui.Views.Windows;
using Avalonia;
-using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
+using Prism.DryIoc;
namespace Aaru.Tui;
-public class App : Application
+public class App : PrismApplication
+{
+ ///
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+
+ base.Initialize();
+ }
+
+ ///
+ protected override void RegisterTypes(IContainerRegistry containerRegistry)
+ {
+ // Register your Services, Views, Dialogs, etc. here
+
+ // Views - Region Navigation
+ containerRegistry.RegisterForNavigation();
+ containerRegistry.RegisterForNavigation();
+ containerRegistry.RegisterForNavigation();
+ }
+
+ ///
+ protected override AvaloniaObject CreateShell() => Container.Resolve();
+
+
+ /// Called after Initialize.
+ protected override void OnInitialized()
+ {
+ // Register Views to the Region it will appear in. Don't register them in the ViewModel.
+ IRegionManager regionManager = Container.Resolve();
+
+ // WARNING: Prism v11.0.0
+ // - DataTemplates MUST define a DataType or else an XAML error will be thrown
+ // - Error: DataTemplate inside of DataTemplates must have a DataType set
+ regionManager.RegisterViewWithRegion("ContentRegion", typeof(FileView));
+ }
+}
+
+/*public class App : Application
{
public override void Initialize()
{
@@ -52,4 +90,4 @@ public class App : Application
base.OnFrameworkInitializationCompleted();
}
-}
\ No newline at end of file
+}*/
\ No newline at end of file
diff --git a/Aaru.Tui/ViewModels/ViewModelBase.cs b/Aaru.Tui/ViewModels/ViewModelBase.cs
index 51804c672..72bdbe706 100644
--- a/Aaru.Tui/ViewModels/ViewModelBase.cs
+++ b/Aaru.Tui/ViewModels/ViewModelBase.cs
@@ -29,4 +29,30 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace Aaru.Tui.ViewModels;
-public class ViewModelBase : ObservableObject;
\ No newline at end of file
+public class ViewModelBase : ObservableObject, IRegionAware
+{
+ ///
+ /// Called to determine if this instance can handle the navigation request.
+ /// Don't call this directly, use .
+ ///
+ /// The navigation context.
+ /// if this instance accepts the navigation request; otherwise, .
+ public virtual bool IsNavigationTarget(NavigationContext navigationContext) =>
+
+ // Auto-allow navigation
+ OnNavigatingTo(navigationContext);
+
+ /// Called when the implementer is being navigated away from.
+ /// The navigation context.
+ public virtual void OnNavigatedFrom(NavigationContext navigationContext) {}
+
+ /// Called when the implementer has been navigated to.
+ /// The navigation context.
+ public virtual void OnNavigatedTo(NavigationContext navigationContext) {}
+
+ /// Navigation validation checker.
+ /// Override for Prism 7.2's IsNavigationTarget.
+ /// The navigation context.
+ /// if this instance accepts the navigation request; otherwise, .
+ public virtual bool OnNavigatingTo(NavigationContext navigationContext) => true;
+}
\ No newline at end of file
diff --git a/Aaru.Tui/ViewModels/Windows/FileViewViewModel.cs b/Aaru.Tui/ViewModels/Windows/FileViewViewModel.cs
new file mode 100644
index 000000000..ee0055155
--- /dev/null
+++ b/Aaru.Tui/ViewModels/Windows/FileViewViewModel.cs
@@ -0,0 +1,479 @@
+using System.Collections.ObjectModel;
+using System.Reflection;
+using System.Text;
+using System.Windows.Input;
+using Aaru.CommonTypes;
+using Aaru.CommonTypes.Enums;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Core;
+using Aaru.Helpers;
+using Aaru.Tui.Models;
+using Aaru.Tui.Views.Windows;
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Media;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using Humanizer;
+using Humanizer.Bytes;
+using Spectre.Console;
+using Color = Avalonia.Media.Color;
+
+namespace Aaru.Tui.ViewModels.Windows;
+
+public sealed partial class FileViewViewModel : ViewModelBase
+{
+ readonly IRegionManager _regionManager;
+ [ObservableProperty]
+ string _copyright;
+ [ObservableProperty]
+ string _currentPath;
+ [ObservableProperty]
+ ObservableCollection _files = [];
+ [ObservableProperty]
+ string _informationalVersion;
+ [ObservableProperty]
+ bool _isStatusVisible;
+ FileModel? _selectedFile;
+ [ObservableProperty]
+ string _status;
+
+ public FileViewViewModel(IRegionManager regionManager)
+ {
+ ExitCommand = new RelayCommand(Exit);
+ SectorViewCommand = new RelayCommand(SectorView);
+ GoToPathCommand = new AsyncRelayCommand(GoToPathAsync);
+ HelpCommand = new AsyncRelayCommand(HelpAsync);
+ OpenSelectedFileCommand = new RelayCommand(OpenSelectedFile, CanOpenSelectedFile);
+ _regionManager = regionManager;
+
+ InformationalVersion =
+ Assembly.GetExecutingAssembly()
+ .GetCustomAttribute()
+ ?.InformationalVersion ??
+ "?.?.?";
+
+ Copyright = Assembly.GetExecutingAssembly().GetCustomAttribute()?.Copyright ?? "";
+ Status = Localization.Resources.Loading;
+ }
+
+ public FileModel? SelectedFile
+ {
+ get => _selectedFile;
+ set
+ {
+ SetProperty(ref _selectedFile, value);
+ OnPropertyChanged(nameof(IsFileInfoAvailable));
+ OnPropertyChanged(nameof(SelectedFileIsNotDirectory));
+ OnPropertyChanged(nameof(SelectedFileLength));
+ OnPropertyChanged(nameof(SelectedFileCreationTime));
+ OnPropertyChanged(nameof(SelectedFileLastWriteTime));
+ OnPropertyChanged(nameof(SelectedFileAttributes));
+ OnPropertyChanged(nameof(SelectedFileUnixMode));
+ OnPropertyChanged(nameof(SelectedFileHasInformation));
+ OnPropertyChanged(nameof(SelectedFileInformation));
+ }
+ }
+
+ public ICommand OpenSelectedFileCommand { get; }
+ public ICommand ExitCommand { get; }
+ public ICommand SectorViewCommand { get; }
+ public ICommand GoToPathCommand { get; }
+ public ICommand HelpCommand { get; }
+ public bool IsFileInfoAvailable => SelectedFile?.FileInfo != null;
+ public bool SelectedFileIsNotDirectory => SelectedFile?.IsDirectory == false;
+ public long? SelectedFileLength => SelectedFile?.IsDirectory == false ? SelectedFile?.FileInfo?.Length : 0;
+ public DateTime? SelectedFileCreationTime => SelectedFile?.FileInfo?.CreationTime;
+ public DateTime? SelectedFileLastWriteTime => SelectedFile?.FileInfo?.LastWriteTime;
+ public string? SelectedFileAttributes => SelectedFile?.FileInfo?.Attributes.ToString();
+ public string? SelectedFileUnixMode => SelectedFile?.FileInfo?.UnixFileMode.ToString();
+ public bool SelectedFileHasInformation => SelectedFile?.Information != null;
+
+ public string? SelectedFileInformation => SelectedFile?.Information;
+
+ Task HelpAsync() =>
+ /* var dialog = new MainHelpDialog
+ {
+ DataContext = new MainHelpDialogViewModel(null!)
+ };
+
+ // Set the dialog reference after creation
+ ((MainHelpDialogViewModel)dialog.DataContext!)._dialog = dialog;
+
+ return dialog.ShowDialog(_view);*/
+ Task.CompletedTask;
+
+ Task GoToPathAsync() =>
+ /* var dialog = new GoToPathDialog
+ {
+ DataContext = new GoToPathDialogViewModel(null!)
+ };
+
+ // Set the dialog reference after creation
+ ((GoToPathDialogViewModel)dialog.DataContext!)._dialog = dialog;
+
+ bool? result = await dialog.ShowDialog(_view);
+
+ if(result == true)
+ {
+ var viewModel = (GoToPathDialogViewModel)dialog.DataContext;
+
+ if(viewModel.Path is not null && Directory.Exists(viewModel.Path))
+ {
+ Environment.CurrentDirectory = viewModel.Path;
+ LoadFiles();
+ }
+ }*/
+ Task.CompletedTask;
+
+ void SectorView()
+ {
+ if(SelectedFile?.ImageFormat is null) return;
+
+ var parameters = new NavigationParameters
+ {
+ {
+ "imageFormat", SelectedFile.ImageFormat
+ },
+ {
+ "filePath", SelectedFile.Path
+ }
+ };
+
+ _regionManager.RequestNavigate("ContentRegion", nameof(HexViewWindow), parameters);
+ }
+
+ void Exit()
+ {
+ var lifetime = Application.Current!.ApplicationLifetime as IControlledApplicationLifetime;
+ lifetime!.Shutdown();
+ }
+
+ ///
+ public override void OnNavigatedTo(NavigationContext navigationContext)
+ {
+ LoadFiles();
+ }
+
+ public void LoadComplete()
+ {
+ LoadFiles();
+ }
+
+ public void LoadFiles()
+ {
+ IsStatusVisible = true;
+ Status = Localization.Resources.Loading;
+ CurrentPath = Directory.GetCurrentDirectory();
+ Files.Clear();
+
+ var parentDirectory = new FileModel
+ {
+ Filename = "..",
+ Path = Path.GetRelativePath(CurrentPath, ".."),
+ ForegroundBrush =
+ new SolidColorBrush(Color.Parse(DirColorsParser.Instance.DirectoryColor ??
+ DirColorsParser.Instance.NormalColor)),
+ IsDirectory = true
+ };
+
+ Files.Add(parentDirectory);
+
+ foreach(FileModel model in Directory.GetDirectories(CurrentPath, "*", SearchOption.TopDirectoryOnly)
+ .Select(directory => new FileModel
+ {
+ Path = directory,
+ Filename = Path.GetFileName(directory),
+ ForegroundBrush =
+ new SolidColorBrush(Color.Parse(DirColorsParser.Instance
+ .DirectoryColor ??
+ DirColorsParser.Instance.NormalColor)),
+ IsDirectory = true
+ }))
+ Files.Add(model);
+
+ foreach(string file in Directory.GetFiles(CurrentPath, "*", SearchOption.TopDirectoryOnly))
+ {
+ var model = new FileModel
+ {
+ Path = file,
+ Filename = Path.GetFileName(file)
+ };
+
+ string extension = Path.GetExtension(file);
+
+ model.ForegroundBrush =
+ new SolidColorBrush(Color.Parse(DirColorsParser.Instance.ExtensionColors.TryGetValue(extension,
+ out string? hex)
+ ? hex
+ : DirColorsParser.Instance.NormalColor));
+
+ Files.Add(model);
+ }
+
+ _ = Task.Run(Worker);
+ }
+
+ void Worker()
+ {
+ IsStatusVisible = true;
+ Status = Localization.Resources.Loading_file_information;
+
+ foreach(FileModel file in Files)
+ {
+ try
+ {
+ file.FileInfo = new FileInfo(file.Path);
+
+ IFilter inputFilter = PluginRegister.Singleton.GetFilter(file.Path);
+
+ if(inputFilter is null) continue;
+
+ IBaseImage imageFormat = ImageFormat.Detect(inputFilter);
+
+ if(imageFormat is null) continue;
+
+ ErrorNumber opened = imageFormat.Open(inputFilter);
+
+ if(opened != ErrorNumber.NoError) continue;
+
+ StringBuilder sb = new();
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Format_0_version_1_WithMarkup,
+ Markup.Escape(imageFormat.Format),
+ Markup.Escape(imageFormat.Info.Version))
+ .AppendLine();
+ }
+ else
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Format_0_WithMarkup, Markup.Escape(imageFormat.Format))
+ .AppendLine();
+ }
+
+ switch(string.IsNullOrWhiteSpace(imageFormat.Info.Application))
+ {
+ case false when !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion):
+ sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_version_1_WithMarkup,
+ Markup.Escape(imageFormat.Info.Application),
+ Markup.Escape(imageFormat.Info.ApplicationVersion))
+ .AppendLine();
+
+ break;
+ case false:
+ sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.Application))
+ .AppendLine();
+
+ break;
+ }
+
+ sb.AppendFormat(Aaru.Localization.Core.Image_without_headers_is_0_bytes_long,
+ imageFormat.Info.ImageSize)
+ .AppendLine();
+
+ sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_0_sectors, imageFormat.Info.Sectors)
+ .AppendLine();
+
+ sb.AppendFormat(Aaru.Localization.Core.Maximum_sector_size_of_0_bytes, imageFormat.Info.SectorSize)
+ .AppendLine();
+
+ sb.AppendFormat(Aaru.Localization.Core.Would_be_0_humanized,
+ ByteSize.FromBytes(imageFormat.Info.Sectors * imageFormat.Info.SectorSize).Humanize())
+ .AppendLine();
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Created_by_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.Creator))
+ .AppendLine();
+ }
+
+ if(imageFormat.Info.CreationTime != DateTime.MinValue)
+ sb.AppendFormat(Aaru.Localization.Core.Created_on_0, imageFormat.Info.CreationTime).AppendLine();
+
+ if(imageFormat.Info.LastModificationTime != DateTime.MinValue)
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Last_modified_on_0, imageFormat.Info.LastModificationTime)
+ .AppendLine();
+ }
+
+ sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_type_0,
+ imageFormat.Info.MediaType.Humanize())
+ .AppendLine();
+
+ sb.AppendFormat(Aaru.Localization.Core.XML_type_0, imageFormat.Info.MetadataMediaType).AppendLine();
+
+ sb.AppendLine(imageFormat.Info.HasPartitions
+ ? Aaru.Localization.Core.Has_partitions
+ : Aaru.Localization.Core.Doesnt_have_partitions);
+
+ sb.AppendLine(imageFormat.Info.HasSessions
+ ? Aaru.Localization.Core.Has_sessions
+ : Aaru.Localization.Core.Doesnt_have_sessions);
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Comments_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.Comments))
+ .AppendLine();
+ }
+
+ if(imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0)
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Media_is_number_0_on_a_set_of_1_medias,
+ imageFormat.Info.MediaSequence,
+ imageFormat.Info.LastMediaSequence)
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Media_title_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.MediaTitle))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Media_manufacturer_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.MediaManufacturer))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Media_model_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.MediaModel))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Media_serial_number_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.MediaSerialNumber))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Media_barcode_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.MediaBarcode))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Media_part_number_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.MediaPartNumber))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Drive_manufacturer_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.DriveManufacturer))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Drive_model_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.DriveModel))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Drive_serial_number_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.DriveSerialNumber))
+ .AppendLine();
+ }
+
+ if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision))
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Drive_firmware_info_0_WithMarkup,
+ Markup.Escape(imageFormat.Info.DriveFirmwareRevision))
+ .AppendLine();
+ }
+
+ if(imageFormat.Info.Cylinders > 0 &&
+ imageFormat.Info is { Heads: > 0, SectorsPerTrack: > 0 } &&
+ imageFormat.Info.MetadataMediaType != MetadataMediaType.OpticalDisc &&
+ imageFormat is not ITapeImage { IsTape: true })
+ {
+ sb.AppendFormat(Aaru.Localization.Core
+ .Media_geometry_0_cylinders_1_heads_2_sectors_per_track_WithMarkup,
+ imageFormat.Info.Cylinders,
+ imageFormat.Info.Heads,
+ imageFormat.Info.SectorsPerTrack)
+ .AppendLine();
+ }
+
+ if(imageFormat.Info.ReadableMediaTags is { Count: > 0 })
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_media_tags_WithMarkup,
+ imageFormat.Info.ReadableMediaTags.Count)
+ .AppendLine();
+
+ foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.Order())
+ sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] ");
+
+ sb.AppendLine();
+ }
+
+ if(imageFormat.Info.ReadableSectorTags is { Count: > 0 })
+ {
+ sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_sector_tags_WithMarkup,
+ imageFormat.Info.ReadableSectorTags.Count)
+ .AppendLine();
+
+ foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.Order())
+ sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] ");
+
+ sb.AppendLine();
+ }
+
+ file.Information = sb.ToString();
+
+ file.ImageFormat = imageFormat as IMediaImage;
+ }
+ catch(Exception ex)
+ {
+ SentrySdk.CaptureException(ex);
+ }
+ }
+
+ Status = Localization.Resources.Done;
+ IsStatusVisible = false;
+ }
+
+ void OpenSelectedFile()
+ {
+ if(SelectedFile.IsDirectory)
+ {
+ CurrentPath = SelectedFile.Path;
+ Environment.CurrentDirectory = CurrentPath;
+ LoadFiles();
+
+ return;
+ }
+
+ if(SelectedFile.ImageFormat is null) return;
+
+ var parameters = new NavigationParameters
+ {
+ {
+ "imageFormat", SelectedFile.ImageFormat
+ },
+ {
+ "filePath", SelectedFile.Path
+ }
+ };
+
+ _regionManager.RequestNavigate("ContentRegion", nameof(ImageWindow), parameters);
+ }
+
+ bool CanOpenSelectedFile() => SelectedFile != null;
+}
\ No newline at end of file
diff --git a/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs b/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs
index 8c979b613..c7be06cab 100644
--- a/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs
+++ b/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs
@@ -31,6 +31,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.Tui.ViewModels.Dialogs;
using Aaru.Tui.Views.Dialogs;
+using Aaru.Tui.Views.Windows;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using CommunityToolkit.Mvvm.ComponentModel;
@@ -42,22 +43,23 @@ namespace Aaru.Tui.ViewModels.Windows;
public sealed partial class HexViewWindowViewModel : ViewModelBase
{
- private const int BYTES_PER_LINE = 16;
- readonly IMediaImage _imageFormat;
- readonly ManagedWindow _view;
+ private const int BYTES_PER_LINE = 16;
+ readonly IRegionManager _regionManager;
+ readonly ManagedWindow _view;
[ObservableProperty]
ulong _currentSector;
[ObservableProperty]
string _filePath;
[ObservableProperty]
long _fileSize;
+ IMediaImage _imageFormat;
[ObservableProperty]
ObservableCollection _lines = [];
bool _longMode;
- internal HexViewWindowViewModel(ManagedWindow view, IMediaImage imageFormat, string filePath,
- ulong currentSector = 0)
+ internal HexViewWindowViewModel(IRegionManager regionManager)
{
+ _regionManager = regionManager;
ExitCommand = new RelayCommand(Exit);
BackCommand = new RelayCommand(Back);
NextSectorCommand = new RelayCommand(NextSector);
@@ -65,12 +67,6 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase
GoToCommand = new AsyncRelayCommand(GoToAsync);
HelpCommand = new AsyncRelayCommand(HelpAsync);
ToggleLongCommand = new RelayCommand(ToggleLong);
-
- _view = view;
- _imageFormat = imageFormat;
- _currentSector = currentSector;
- FilePath = filePath;
- LoadSector();
}
public ICommand BackCommand { get; }
@@ -81,6 +77,17 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase
public ICommand HelpCommand { get; }
public ICommand ToggleLongCommand { get; }
+ ///
+ public override void OnNavigatedTo(NavigationContext navigationContext)
+ {
+ base.OnNavigatedTo(navigationContext);
+
+ _imageFormat = navigationContext.Parameters.GetValue("imageFormat");
+ FilePath = navigationContext.Parameters.GetValue("filePath");
+
+ LoadSector();
+ }
+
void ToggleLong()
{
_longMode = !_longMode;
@@ -150,7 +157,16 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase
void Back()
{
- _view.Close();
+ IRegion? region = _regionManager.Regions["ContentRegion"];
+ IRegionNavigationService? navigationService = region.NavigationService;
+
+ if(navigationService?.Journal.CanGoBack == true)
+ navigationService.Journal.GoBack();
+ else
+ {
+ // No history - navigate directly to FileView
+ _regionManager.RequestNavigate("ContentRegion", nameof(FileView));
+ }
}
void Exit()
@@ -202,8 +218,6 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase
offset += bytesRead;
}
}
-
- public void LoadComplete() {}
}
public sealed class HexViewLine
diff --git a/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs b/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs
index 7531f799c..be055069a 100644
--- a/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs
+++ b/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs
@@ -31,8 +31,7 @@ using System.Windows.Input;
using Aaru.CommonTypes;
using Aaru.CommonTypes.Interfaces;
using Aaru.Tui.Models;
-using Aaru.Tui.ViewModels.Dialogs;
-using Aaru.Tui.Views.Dialogs;
+using Aaru.Tui.Views.Windows;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using CommunityToolkit.Mvvm.ComponentModel;
@@ -46,12 +45,13 @@ namespace Aaru.Tui.ViewModels.Windows;
public sealed partial class ImageWindowViewModel : ViewModelBase
{
- readonly IMediaImage _imageFormat;
- readonly ManagedWindow _view;
+ readonly IRegionManager _regionManager;
+ readonly ManagedWindow _view;
[ObservableProperty]
public string _filePath;
[ObservableProperty]
string _filesystemInformation;
+ IMediaImage _imageFormat;
[ObservableProperty]
bool _isFilesystemInformationVisible;
[ObservableProperty]
@@ -82,15 +82,12 @@ public sealed partial class ImageWindowViewModel : ViewModelBase
[ObservableProperty]
string? _status;
- public ImageWindowViewModel(ManagedWindow view, IMediaImage imageFormat, string filePath)
+ public ImageWindowViewModel(IRegionManager regionManager)
{
- _imageFormat = imageFormat;
- FilePath = filePath;
- _view = view;
-
- ExitCommand = new RelayCommand(Exit);
- BackCommand = new RelayCommand(Back);
- HelpCommand = new AsyncRelayCommand(HelpAsync);
+ _regionManager = regionManager;
+ ExitCommand = new RelayCommand(Exit);
+ BackCommand = new RelayCommand(Back);
+ HelpCommand = new AsyncRelayCommand(HelpAsync);
}
public FileSystemModelNode? SelectedNode
@@ -153,7 +150,16 @@ public sealed partial class ImageWindowViewModel : ViewModelBase
void Back()
{
- _view.Close();
+ IRegion? region = _regionManager.Regions["ContentRegion"];
+ IRegionNavigationService? navigationService = region.NavigationService;
+
+ if(navigationService?.Journal.CanGoBack == true)
+ navigationService.Journal.GoBack();
+ else
+ {
+ // No history - navigate directly to FileView
+ _regionManager.RequestNavigate("ContentRegion", nameof(FileView));
+ }
}
void Exit()
@@ -162,13 +168,17 @@ public sealed partial class ImageWindowViewModel : ViewModelBase
lifetime!.Shutdown();
}
- public void LoadComplete()
+ ///
+ public override void OnNavigatedTo(NavigationContext navigationContext)
{
+ _imageFormat = navigationContext.Parameters.GetValue("imageFormat");
+ FilePath = navigationContext.Parameters.GetValue("filePath");
+
_ = Task.Run(Worker);
}
- Task HelpAsync()
- {
+ Task HelpAsync() =>
+ /*
var dialog = new ImageHelpDialog
{
DataContext = new ImageHelpDialogViewModel(null!)
@@ -177,8 +187,8 @@ public sealed partial class ImageWindowViewModel : ViewModelBase
// Set the dialog reference after creation
((ImageHelpDialogViewModel)dialog.DataContext!)._dialog = dialog;
- return dialog.ShowDialog(_view);
- }
+ return dialog.ShowDialog(_view);*/
+ Task.CompletedTask;
void Worker()
{
diff --git a/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs b/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs
index 1015a85bf..068288ba3 100644
--- a/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs
+++ b/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs
@@ -25,462 +25,6 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
-using System.Collections.ObjectModel;
-using System.Reflection;
-using System.Text;
-using System.Windows.Input;
-using Aaru.CommonTypes;
-using Aaru.CommonTypes.Enums;
-using Aaru.CommonTypes.Interfaces;
-using Aaru.Core;
-using Aaru.Helpers;
-using Aaru.Tui.Models;
-using Aaru.Tui.ViewModels.Dialogs;
-using Aaru.Tui.Views.Dialogs;
-using Aaru.Tui.Views.Windows;
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Media;
-using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
-using Humanizer;
-using Humanizer.Bytes;
-using Spectre.Console;
-using Color = Avalonia.Media.Color;
-
namespace Aaru.Tui.ViewModels.Windows;
-public sealed partial class MainWindowViewModel : ViewModelBase
-{
- readonly Window _view;
- [ObservableProperty]
- string _copyright;
- [ObservableProperty]
- string _currentPath;
- [ObservableProperty]
- ObservableCollection _files = [];
- [ObservableProperty]
- string _informationalVersion;
- [ObservableProperty]
- bool _isStatusVisible;
- FileModel? _selectedFile;
- [ObservableProperty]
- string _status;
-
- public MainWindowViewModel(Window view)
- {
- _view = view;
- ExitCommand = new RelayCommand(Exit);
- SectorViewCommand = new RelayCommand(SectorView);
- GoToPathCommand = new AsyncRelayCommand(GoToPathAsync);
- HelpCommand = new AsyncRelayCommand(HelpAsync);
- OpenSelectedFileCommand = new RelayCommand(OpenSelectedFile, CanOpenSelectedFile);
-
- InformationalVersion =
- Assembly.GetExecutingAssembly()
- .GetCustomAttribute()
- ?.InformationalVersion ??
- "?.?.?";
-
- Copyright = Assembly.GetExecutingAssembly().GetCustomAttribute()?.Copyright ?? "";
- Status = Localization.Resources.Loading;
- }
-
- public FileModel? SelectedFile
- {
- get => _selectedFile;
- set
- {
- SetProperty(ref _selectedFile, value);
- OnPropertyChanged(nameof(IsFileInfoAvailable));
- OnPropertyChanged(nameof(SelectedFileIsNotDirectory));
- OnPropertyChanged(nameof(SelectedFileLength));
- OnPropertyChanged(nameof(SelectedFileCreationTime));
- OnPropertyChanged(nameof(SelectedFileLastWriteTime));
- OnPropertyChanged(nameof(SelectedFileAttributes));
- OnPropertyChanged(nameof(SelectedFileUnixMode));
- OnPropertyChanged(nameof(SelectedFileHasInformation));
- OnPropertyChanged(nameof(SelectedFileInformation));
- }
- }
-
- public ICommand OpenSelectedFileCommand { get; }
- public ICommand ExitCommand { get; }
- public ICommand SectorViewCommand { get; }
- public ICommand GoToPathCommand { get; }
- public ICommand HelpCommand { get; }
- public bool IsFileInfoAvailable => SelectedFile?.FileInfo != null;
- public bool SelectedFileIsNotDirectory => SelectedFile?.IsDirectory == false;
- public long? SelectedFileLength => SelectedFile?.IsDirectory == false ? SelectedFile?.FileInfo?.Length : 0;
- public DateTime? SelectedFileCreationTime => SelectedFile?.FileInfo?.CreationTime;
- public DateTime? SelectedFileLastWriteTime => SelectedFile?.FileInfo?.LastWriteTime;
- public string? SelectedFileAttributes => SelectedFile?.FileInfo?.Attributes.ToString();
- public string? SelectedFileUnixMode => SelectedFile?.FileInfo?.UnixFileMode.ToString();
- public bool SelectedFileHasInformation => SelectedFile?.Information != null;
-
- public string? SelectedFileInformation => SelectedFile?.Information;
-
- Task HelpAsync()
- {
- var dialog = new MainHelpDialog
- {
- DataContext = new MainHelpDialogViewModel(null!)
- };
-
- // Set the dialog reference after creation
- ((MainHelpDialogViewModel)dialog.DataContext!)._dialog = dialog;
-
- return dialog.ShowDialog(_view);
- }
-
- async Task GoToPathAsync()
- {
- var dialog = new GoToPathDialog
- {
- DataContext = new GoToPathDialogViewModel(null!)
- };
-
- // Set the dialog reference after creation
- ((GoToPathDialogViewModel)dialog.DataContext!)._dialog = dialog;
-
- bool? result = await dialog.ShowDialog(_view);
-
- if(result == true)
- {
- var viewModel = (GoToPathDialogViewModel)dialog.DataContext;
-
- if(viewModel.Path is not null && Directory.Exists(viewModel.Path))
- {
- Environment.CurrentDirectory = viewModel.Path;
- LoadFiles();
- }
- }
- }
-
- void SectorView()
- {
- if(SelectedFile?.ImageFormat is null) return;
-
- var view = new HexViewWindow();
-
- var vm = new HexViewWindowViewModel(view, SelectedFile.ImageFormat, SelectedFile.Path);
- view.DataContext = vm;
- view.Show();
- }
-
- void Exit()
- {
- var lifetime = Application.Current!.ApplicationLifetime as IControlledApplicationLifetime;
- lifetime!.Shutdown();
- }
-
- public void LoadComplete()
- {
- LoadFiles();
- }
-
- public void LoadFiles()
- {
- IsStatusVisible = true;
- Status = Localization.Resources.Loading;
- CurrentPath = Directory.GetCurrentDirectory();
- Files.Clear();
-
- var parentDirectory = new FileModel
- {
- Filename = "..",
- Path = Path.GetRelativePath(CurrentPath, ".."),
- ForegroundBrush =
- new SolidColorBrush(Color.Parse(DirColorsParser.Instance.DirectoryColor ??
- DirColorsParser.Instance.NormalColor)),
- IsDirectory = true
- };
-
- Files.Add(parentDirectory);
-
- foreach(FileModel model in Directory.GetDirectories(CurrentPath, "*", SearchOption.TopDirectoryOnly)
- .Select(directory => new FileModel
- {
- Path = directory,
- Filename = Path.GetFileName(directory),
- ForegroundBrush =
- new SolidColorBrush(Color.Parse(DirColorsParser.Instance
- .DirectoryColor ??
- DirColorsParser.Instance.NormalColor)),
- IsDirectory = true
- }))
- Files.Add(model);
-
- foreach(string file in Directory.GetFiles(CurrentPath, "*", SearchOption.TopDirectoryOnly))
- {
- var model = new FileModel
- {
- Path = file,
- Filename = Path.GetFileName(file)
- };
-
- string extension = Path.GetExtension(file);
-
- model.ForegroundBrush =
- new SolidColorBrush(Color.Parse(DirColorsParser.Instance.ExtensionColors.TryGetValue(extension,
- out string? hex)
- ? hex
- : DirColorsParser.Instance.NormalColor));
-
- Files.Add(model);
- }
-
- _ = Task.Run(Worker);
- }
-
- void Worker()
- {
- IsStatusVisible = true;
- Status = Localization.Resources.Loading_file_information;
-
- foreach(FileModel file in Files)
- {
- try
- {
- file.FileInfo = new FileInfo(file.Path);
-
- IFilter inputFilter = PluginRegister.Singleton.GetFilter(file.Path);
-
- if(inputFilter is null) continue;
-
- IBaseImage imageFormat = ImageFormat.Detect(inputFilter);
-
- if(imageFormat is null) continue;
-
- ErrorNumber opened = imageFormat.Open(inputFilter);
-
- if(opened != ErrorNumber.NoError) continue;
-
- StringBuilder sb = new();
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version))
- {
- sb.AppendFormat(Aaru.Localization.Core.Format_0_version_1_WithMarkup,
- Markup.Escape(imageFormat.Format),
- Markup.Escape(imageFormat.Info.Version))
- .AppendLine();
- }
- else
- sb.AppendFormat(Aaru.Localization.Core.Format_0_WithMarkup, Markup.Escape(imageFormat.Format))
- .AppendLine();
-
- switch(string.IsNullOrWhiteSpace(imageFormat.Info.Application))
- {
- case false when !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion):
- sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_version_1_WithMarkup,
- Markup.Escape(imageFormat.Info.Application),
- Markup.Escape(imageFormat.Info.ApplicationVersion))
- .AppendLine();
-
- break;
- case false:
- sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_WithMarkup,
- Markup.Escape(imageFormat.Info.Application))
- .AppendLine();
-
- break;
- }
-
- sb.AppendFormat(Aaru.Localization.Core.Image_without_headers_is_0_bytes_long,
- imageFormat.Info.ImageSize)
- .AppendLine();
-
- sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_0_sectors, imageFormat.Info.Sectors)
- .AppendLine();
-
- sb.AppendFormat(Aaru.Localization.Core.Maximum_sector_size_of_0_bytes, imageFormat.Info.SectorSize)
- .AppendLine();
-
- sb.AppendFormat(Aaru.Localization.Core.Would_be_0_humanized,
- ByteSize.FromBytes(imageFormat.Info.Sectors * imageFormat.Info.SectorSize).Humanize())
- .AppendLine();
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
- sb.AppendFormat(Aaru.Localization.Core.Created_by_0_WithMarkup,
- Markup.Escape(imageFormat.Info.Creator))
- .AppendLine();
-
- if(imageFormat.Info.CreationTime != DateTime.MinValue)
- sb.AppendFormat(Aaru.Localization.Core.Created_on_0, imageFormat.Info.CreationTime).AppendLine();
-
- if(imageFormat.Info.LastModificationTime != DateTime.MinValue)
- sb.AppendFormat(Aaru.Localization.Core.Last_modified_on_0, imageFormat.Info.LastModificationTime)
- .AppendLine();
-
- sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_type_0,
- imageFormat.Info.MediaType.Humanize())
- .AppendLine();
-
- sb.AppendFormat(Aaru.Localization.Core.XML_type_0, imageFormat.Info.MetadataMediaType).AppendLine();
-
- sb.AppendLine(imageFormat.Info.HasPartitions
- ? Aaru.Localization.Core.Has_partitions
- : Aaru.Localization.Core.Doesnt_have_partitions);
-
- sb.AppendLine(imageFormat.Info.HasSessions
- ? Aaru.Localization.Core.Has_sessions
- : Aaru.Localization.Core.Doesnt_have_sessions);
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments))
- sb.AppendFormat(Aaru.Localization.Core.Comments_0_WithMarkup,
- Markup.Escape(imageFormat.Info.Comments))
- .AppendLine();
-
- if(imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0)
- {
- sb.AppendFormat(Aaru.Localization.Core.Media_is_number_0_on_a_set_of_1_medias,
- imageFormat.Info.MediaSequence,
- imageFormat.Info.LastMediaSequence)
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
- {
- sb.AppendFormat(Aaru.Localization.Core.Media_title_0_WithMarkup,
- Markup.Escape(imageFormat.Info.MediaTitle))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
- {
- sb.AppendFormat(Aaru.Localization.Core.Media_manufacturer_0_WithMarkup,
- Markup.Escape(imageFormat.Info.MediaManufacturer))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
- {
- sb.AppendFormat(Aaru.Localization.Core.Media_model_0_WithMarkup,
- Markup.Escape(imageFormat.Info.MediaModel))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
- {
- sb.AppendFormat(Aaru.Localization.Core.Media_serial_number_0_WithMarkup,
- Markup.Escape(imageFormat.Info.MediaSerialNumber))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
- {
- sb.AppendFormat(Aaru.Localization.Core.Media_barcode_0_WithMarkup,
- Markup.Escape(imageFormat.Info.MediaBarcode))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
- {
- sb.AppendFormat(Aaru.Localization.Core.Media_part_number_0_WithMarkup,
- Markup.Escape(imageFormat.Info.MediaPartNumber))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
- {
- sb.AppendFormat(Aaru.Localization.Core.Drive_manufacturer_0_WithMarkup,
- Markup.Escape(imageFormat.Info.DriveManufacturer))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
- {
- sb.AppendFormat(Aaru.Localization.Core.Drive_model_0_WithMarkup,
- Markup.Escape(imageFormat.Info.DriveModel))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
- {
- sb.AppendFormat(Aaru.Localization.Core.Drive_serial_number_0_WithMarkup,
- Markup.Escape(imageFormat.Info.DriveSerialNumber))
- .AppendLine();
- }
-
- if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision))
- {
- sb.AppendFormat(Aaru.Localization.Core.Drive_firmware_info_0_WithMarkup,
- Markup.Escape(imageFormat.Info.DriveFirmwareRevision))
- .AppendLine();
- }
-
- if(imageFormat.Info.Cylinders > 0 &&
- imageFormat.Info is { Heads: > 0, SectorsPerTrack: > 0 } &&
- imageFormat.Info.MetadataMediaType != MetadataMediaType.OpticalDisc &&
- imageFormat is not ITapeImage { IsTape: true })
- {
- sb.AppendFormat(Aaru.Localization.Core
- .Media_geometry_0_cylinders_1_heads_2_sectors_per_track_WithMarkup,
- imageFormat.Info.Cylinders,
- imageFormat.Info.Heads,
- imageFormat.Info.SectorsPerTrack)
- .AppendLine();
- }
-
- if(imageFormat.Info.ReadableMediaTags is { Count: > 0 })
- {
- sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_media_tags_WithMarkup,
- imageFormat.Info.ReadableMediaTags.Count)
- .AppendLine();
-
- foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.Order())
- sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] ");
-
- sb.AppendLine();
- }
-
- if(imageFormat.Info.ReadableSectorTags is { Count: > 0 })
- {
- sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_sector_tags_WithMarkup,
- imageFormat.Info.ReadableSectorTags.Count)
- .AppendLine();
-
- foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.Order())
- sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] ");
-
- sb.AppendLine();
- }
-
- file.Information = sb.ToString();
-
- file.ImageFormat = imageFormat as IMediaImage;
- }
- catch(Exception ex)
- {
- SentrySdk.CaptureException(ex);
- }
- }
-
- Status = Localization.Resources.Done;
- IsStatusVisible = false;
- }
-
- void OpenSelectedFile()
- {
- if(SelectedFile.IsDirectory)
- {
- CurrentPath = SelectedFile.Path;
- Environment.CurrentDirectory = CurrentPath;
- LoadFiles();
-
- return;
- }
-
- if(SelectedFile.ImageFormat is null) return;
-
- var imageWindow = new ImageWindow();
-
- var imageViewModel = new ImageWindowViewModel(imageWindow, SelectedFile.ImageFormat, SelectedFile.Path);
-
- imageWindow.DataContext = imageViewModel;
- imageWindow.Show();
- }
-
- bool CanOpenSelectedFile() => SelectedFile != null;
-}
\ No newline at end of file
+public sealed class MainWindowViewModel {}
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/FileView.axaml b/Aaru.Tui/Views/Windows/FileView.axaml
new file mode 100644
index 000000000..ad8b42ff8
--- /dev/null
+++ b/Aaru.Tui/Views/Windows/FileView.axaml
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/FileView.axaml.cs b/Aaru.Tui/Views/Windows/FileView.axaml.cs
new file mode 100644
index 000000000..b0ea35f2e
--- /dev/null
+++ b/Aaru.Tui/Views/Windows/FileView.axaml.cs
@@ -0,0 +1,60 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// Component : Text User Interface.
+//
+// --[ 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 © 2011-2025 Natalia Portillo
+// ****************************************************************************/
+
+using Aaru.Tui.ViewModels.Windows;
+using Avalonia.Controls;
+using Avalonia.Input;
+
+namespace Aaru.Tui.Views.Windows;
+
+public partial class FileView : UserControl
+{
+ public FileView()
+ {
+ InitializeComponent();
+ }
+
+ private void ListBox_OnKeyDown(object sender, KeyEventArgs e)
+ {
+ if(e.Key == Key.Enter)
+ {
+ if(DataContext is FileViewViewModel vm && vm.OpenSelectedFileCommand.CanExecute(null))
+ {
+ vm.OpenSelectedFileCommand.Execute(null);
+ e.Handled = true;
+ }
+ }
+ }
+
+ ///
+ protected override void OnDataContextChanged(EventArgs e)
+ {
+ base.OnDataContextChanged(e);
+
+ (DataContext as FileViewViewModel)?.LoadComplete();
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/HexViewWindow.axaml b/Aaru.Tui/Views/Windows/HexViewWindow.axaml
index b0a595ecc..c93d3493e 100644
--- a/Aaru.Tui/Views/Windows/HexViewWindow.axaml
+++ b/Aaru.Tui/Views/Windows/HexViewWindow.axaml
@@ -1,12 +1,12 @@
-
+
@@ -101,4 +101,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs b/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs
index 68b9b66d7..766223741 100644
--- a/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs
+++ b/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs
@@ -25,25 +25,14 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
-using Aaru.Tui.ViewModels.Windows;
-using Avalonia.Interactivity;
-using Iciclecreek.Avalonia.WindowManager;
+using Avalonia.Controls;
namespace Aaru.Tui.Views.Windows;
-public partial class HexViewWindow : ManagedWindow
+public partial class HexViewWindow : UserControl
{
public HexViewWindow()
{
InitializeComponent();
}
-
-
- ///
- protected override void OnLoaded(RoutedEventArgs e)
- {
- base.OnLoaded(e);
-
- (DataContext as HexViewWindowViewModel)?.LoadComplete();
- }
}
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/ImageWindow.axaml b/Aaru.Tui/Views/Windows/ImageWindow.axaml
index e1a9019b5..e6886cefa 100644
--- a/Aaru.Tui/Views/Windows/ImageWindow.axaml
+++ b/Aaru.Tui/Views/Windows/ImageWindow.axaml
@@ -1,17 +1,17 @@
-
+
@@ -174,4 +174,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs b/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs
index 173a06bfa..74420cefc 100644
--- a/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs
+++ b/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs
@@ -25,24 +25,14 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
-using Aaru.Tui.ViewModels.Windows;
-using Avalonia.Interactivity;
-using Iciclecreek.Avalonia.WindowManager;
+using Avalonia.Controls;
namespace Aaru.Tui.Views.Windows;
-public partial class ImageWindow : ManagedWindow
+public partial class ImageWindow : UserControl
{
public ImageWindow()
{
InitializeComponent();
}
-
- ///
- protected override void OnLoaded(RoutedEventArgs e)
- {
- base.OnLoaded(e);
-
- (DataContext as ImageWindowViewModel)?.LoadComplete();
- }
}
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/MainWindow.axaml b/Aaru.Tui/Views/Windows/MainWindow.axaml
index 596619b92..fc705ae36 100644
--- a/Aaru.Tui/Views/Windows/MainWindow.axaml
+++ b/Aaru.Tui/Views/Windows/MainWindow.axaml
@@ -1,195 +1,15 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/Aaru.Tui/Views/Windows/MainWindow.axaml.cs b/Aaru.Tui/Views/Windows/MainWindow.axaml.cs
index 5f48c01e9..66b99987d 100644
--- a/Aaru.Tui/Views/Windows/MainWindow.axaml.cs
+++ b/Aaru.Tui/Views/Windows/MainWindow.axaml.cs
@@ -25,39 +25,15 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
-using Aaru.Tui.ViewModels.Windows;
using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Interactivity;
namespace Aaru.Tui.Views.Windows;
+/// Main window view.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
-
- public MainWindow(object? dataContext) : this() => DataContext = dataContext;
-
- private void ListBox_OnKeyDown(object sender, KeyEventArgs e)
- {
- if(e.Key == Key.Enter)
- {
- if(DataContext is MainWindowViewModel vm && vm.OpenSelectedFileCommand.CanExecute(null))
- {
- vm.OpenSelectedFileCommand.Execute(null);
- e.Handled = true;
- }
- }
- }
-
- ///
- protected override void OnLoaded(RoutedEventArgs e)
- {
- base.OnLoaded(e);
-
- (DataContext as MainWindowViewModel)?.LoadComplete();
- }
}
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 65c79e360..7d0f0462b 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -39,6 +39,8 @@
+
+