[GUI] Remove old unused code.

This commit is contained in:
2025-11-19 04:22:11 +00:00
parent 239af54b75
commit b748f54dca
8 changed files with 9 additions and 1337 deletions

View File

@@ -69,7 +69,7 @@ public sealed class App : Application
desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown;
// Close splash window
desktop.MainWindow.Close();
desktop.MainWindow?.Close();
// Create and show main window
desktop.MainWindow = new MainWindow();
@@ -84,23 +84,23 @@ public sealed class App : Application
{
if(ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime
{
MainWindow: OldMainWindow
MainWindow: MainWindow
{
DataContext: OldMainWindowViewModel mainWindowViewModel
DataContext: MainWindowViewModel mainWindowViewModel
}
})
return;
mainWindowViewModel.About();
mainWindowViewModel.AboutCommand.Execute(null);
}
void OnQuitClicked(object sender, EventArgs args)
{
if(ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime
{
MainWindow: OldMainWindow
MainWindow: MainWindow
{
DataContext: OldMainWindowViewModel mainWindowViewModel
DataContext: MainWindowViewModel mainWindowViewModel
}
})
return;
@@ -112,13 +112,13 @@ public sealed class App : Application
{
if(ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime
{
MainWindow: OldMainWindow
MainWindow: MainWindow
{
DataContext: OldMainWindowViewModel mainWindowViewModel
DataContext: MainWindowViewModel mainWindowViewModel
}
})
return;
mainWindowViewModel.SettingsAsync();
_ = mainWindowViewModel.SettingsAsync();
}
}

View File

@@ -1,49 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : DeviceModel.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI data models.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains information about a device.
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System.Collections.ObjectModel;
using Aaru.Gui.ViewModels.Panels;
using Avalonia.Media.Imaging;
namespace Aaru.Gui.Models;
public sealed class DeviceModel
{
public DeviceModel() => Media = [];
public Bitmap Icon { get; set; }
public string Name { get; set; }
public string Path { get; set; }
public DeviceInfoViewModel ViewModel { get; set; }
public ObservableCollection<MediaModel> Media { get; }
}

View File

@@ -1,42 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : DevicesRootModel.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI data models.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains the list of devices.
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System.Collections.ObjectModel;
namespace Aaru.Gui.Models;
public sealed class DevicesRootModel : RootModel
{
public DevicesRootModel() => Devices = [];
public ObservableCollection<DeviceModel> Devices { get; }
}

View File

@@ -1,42 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : ImagesRootModel.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI data models.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains information opened images root.
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System.Collections.ObjectModel;
namespace Aaru.Gui.Models;
public sealed class ImagesRootModel : RootModel
{
public ImagesRootModel() => Images = [];
public ObservableCollection<ImageModel> Images { get; }
}

View File

@@ -1,46 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : MediaModel.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI data models.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains information about physical media.
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using Aaru.Gui.ViewModels.Panels;
using Avalonia.Media.Imaging;
namespace Aaru.Gui.Models;
public sealed class MediaModel
{
public Bitmap Icon { get; set; }
public string Name { get; set; }
public string DevicePath { get; set; }
public bool NonRemovable { get; set; }
public bool NoMediaInserted { get; set; }
public MediaInfoViewModel ViewModel { get; set; }
}

View File

@@ -1,873 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : MainWindowViewModel.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI view models.
//
// --[ Description ] ----------------------------------------------------------
//
// View model and code for the main window.
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Aaru.CommonTypes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Interop;
using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Core;
using Aaru.Core.Media.Info;
using Aaru.Database;
using Aaru.Devices;
using Aaru.Gui.Models;
using Aaru.Gui.ViewModels.Dialogs;
using Aaru.Gui.ViewModels.Panels;
using Aaru.Gui.Views.Dialogs;
using Aaru.Gui.Views.Panels;
using Aaru.Gui.Views.Windows;
using Aaru.Localization;
using Aaru.Logging;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.Input;
using JetBrains.Annotations;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Spectre.Console;
using Console = Aaru.Gui.Views.Dialogs.Console;
using DeviceInfo = Aaru.Core.Devices.Info.DeviceInfo;
using ImageInfo = Aaru.Gui.Views.Panels.ImageInfo;
using Partition = Aaru.Gui.Views.Panels.Partition;
using PlatformID = Aaru.CommonTypes.Interop.PlatformID;
namespace Aaru.Gui.ViewModels.Windows;
public sealed class OldMainWindowViewModel : ViewModelBase
{
const string MODULE_NAME = "Main Window ViewModel";
readonly DevicesRootModel _devicesRoot;
readonly Bitmap _ejectIcon;
readonly Bitmap _genericFolderIcon;
readonly Bitmap _genericHddIcon;
readonly Bitmap _genericOpticalIcon;
readonly Bitmap _genericTapeIcon;
readonly ImagesRootModel _imagesRoot;
readonly Bitmap _removableIcon;
readonly Bitmap _sdIcon;
readonly Bitmap _usbIcon;
readonly OldMainWindow _view;
Console _console;
object _contentPanel;
bool _devicesSupported;
object _treeViewSelectedItem;
public OldMainWindowViewModel(OldMainWindow view)
{
AboutCommand = new RelayCommand(About);
EncodingsCommand = new RelayCommand(Encodings);
PluginsCommand = new RelayCommand(Plugins);
StatisticsCommand = new RelayCommand(Statistics);
ExitCommand = new RelayCommand(Exit);
SettingsCommand = new AsyncRelayCommand(SettingsAsync);
ConsoleCommand = new RelayCommand(Console);
OpenCommand = new AsyncRelayCommand(OpenAsync);
CalculateEntropyCommand = new RelayCommand(CalculateEntropy);
VerifyImageCommand = new RelayCommand(VerifyImage);
ChecksumImageCommand = new RelayCommand(ChecksumImage);
ConvertImageCommand = new RelayCommand(ConvertImage);
CreateSidecarCommand = new RelayCommand(CreateSidecar);
ViewImageSectorsCommand = new RelayCommand(ViewImageSectors);
DecodeImageMediaTagsCommand = new RelayCommand(DecodeImageMediaTags);
RefreshDevicesCommand = new RelayCommand(RefreshDevices);
_view = view;
TreeRoot = [];
ContentPanel = Greeting;
_imagesRoot = new ImagesRootModel
{
Name = UI.Title_Images
};
TreeRoot.Add(_imagesRoot);
switch(DetectOS.GetRealPlatformID())
{
case PlatformID.Win32NT:
case PlatformID.Linux:
case PlatformID.FreeBSD:
_devicesRoot = new DevicesRootModel
{
Name = UI.Title_Devices
};
TreeRoot.Add(_devicesRoot);
DevicesSupported = true;
break;
}
_genericHddIcon =
new Bitmap(AssetLoader.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-harddisk.png")));
_genericOpticalIcon =
new Bitmap(AssetLoader.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-optical.png")));
_genericTapeIcon =
new Bitmap(AssetLoader.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/media-tape.png")));
_genericFolderIcon =
new Bitmap(AssetLoader.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/inode-directory.png")));
_usbIcon =
new
Bitmap(AssetLoader.Open(new
Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-removable-media-usb.png")));
_removableIcon =
new
Bitmap(AssetLoader.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-removable-media.png")));
_sdIcon =
new Bitmap(AssetLoader.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/media-flash-sd-mmc.png")));
_ejectIcon =
new Bitmap(AssetLoader.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/media-eject.png")));
}
public bool DevicesSupported
{
get => _devicesSupported;
set => SetProperty(ref _devicesSupported, value);
}
public bool NativeMenuSupported
{
get
{
Window mainWindow = (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)
?.MainWindow;
return mainWindow is not null && NativeMenu.GetIsNativeMenuExported(mainWindow);
}
}
[NotNull]
public string Greeting => UI.Welcome_to_Aaru;
public ObservableCollection<RootModel> TreeRoot { get; }
public ICommand AboutCommand { get; }
public ICommand ConsoleCommand { get; }
public ICommand EncodingsCommand { get; }
public ICommand PluginsCommand { get; }
public ICommand StatisticsCommand { get; }
public ICommand ExitCommand { get; }
public ICommand SettingsCommand { get; }
public ICommand OpenCommand { get; }
public ICommand CalculateEntropyCommand { get; }
public ICommand VerifyImageCommand { get; }
public ICommand ChecksumImageCommand { get; }
public ICommand ConvertImageCommand { get; }
public ICommand CreateSidecarCommand { get; }
public ICommand ViewImageSectorsCommand { get; }
public ICommand DecodeImageMediaTagsCommand { get; }
public ICommand RefreshDevicesCommand { get; }
public object ContentPanel
{
get => _contentPanel;
set => SetProperty(ref _contentPanel, value);
}
public object TreeViewSelectedItem
{
get => _treeViewSelectedItem;
set
{
if(value == _treeViewSelectedItem) return;
SetProperty(ref _treeViewSelectedItem, value);
ContentPanel = null;
switch(value)
{
case ImageModel imageModel:
ContentPanel = new ImageInfo
{
DataContext = imageModel.ViewModel
};
break;
case PartitionModel partitionModel:
ContentPanel = new Partition
{
DataContext = partitionModel.ViewModel
};
break;
case FileSystemModel fileSystemModel:
ContentPanel = new FileSystem
{
DataContext = fileSystemModel.ViewModel
};
break;
case SubdirectoryModel subdirectoryModel:
ContentPanel = new Subdirectory
{
DataContext = new SubdirectoryViewModel(subdirectoryModel, _view)
};
break;
case DeviceModel deviceModel:
{
if(deviceModel.ViewModel is null)
{
var dev = Device.Create(deviceModel.Path, out ErrorNumber devErrno);
switch(dev)
{
case null:
ContentPanel = string.Format(UI.Error_0_opening_device, devErrno);
return;
case Devices.Remote.Device remoteDev:
Core.Statistics.AddRemote(remoteDev.RemoteApplication,
remoteDev.RemoteVersion,
remoteDev.RemoteOperatingSystem,
remoteDev.RemoteOperatingSystemVersion,
remoteDev.RemoteArchitecture);
break;
}
if(dev.Error)
{
ContentPanel = string.Format(UI.Error_0_opening_device, dev.LastError);
return;
}
var devInfo = new DeviceInfo(dev);
deviceModel.ViewModel = new DeviceInfoViewModel(devInfo, _view);
if(!dev.IsRemovable)
{
deviceModel.Media.Add(new MediaModel
{
NonRemovable = true,
Name = UI.Non_removable_device_commands_not_yet_implemented
});
}
else
{
// TODO: Removable non-SCSI?
var scsiInfo = new ScsiInfo(dev);
if(!scsiInfo.MediaInserted)
{
deviceModel.Media.Add(new MediaModel
{
NoMediaInserted = true,
Icon = _ejectIcon,
Name = UI.No_media_inserted
});
}
else
{
var mediaResource =
new Uri($"avares://Aaru.Gui/Assets/Logos/Media/{scsiInfo.MediaType}.png");
deviceModel.Media.Add(new MediaModel
{
DevicePath = deviceModel.Path,
Icon = AssetLoader.Exists(mediaResource)
? new Bitmap(AssetLoader.Open(mediaResource))
: null,
Name = $"{scsiInfo.MediaType}",
ViewModel = new MediaInfoViewModel(scsiInfo, deviceModel.Path, _view)
});
}
}
dev.Close();
}
ContentPanel = new Views.Panels.DeviceInfo
{
DataContext = deviceModel.ViewModel
};
break;
}
case MediaModel { NonRemovable: true }:
ContentPanel = UI.Non_removable_device_commands_not_yet_implemented;
break;
case MediaModel { NoMediaInserted: true }:
ContentPanel = UI.No_media_inserted;
break;
case MediaModel mediaModel:
{
if(mediaModel.ViewModel != null)
{
ContentPanel = new MediaInfo
{
DataContext = mediaModel.ViewModel
};
}
break;
}
}
}
}
void CalculateEntropy()
{
if(TreeViewSelectedItem is not ImageModel imageModel) return;
var imageEntropyWindow = new ImageEntropy();
imageEntropyWindow.DataContext = new ImageEntropyViewModel(imageModel.Image, imageEntropyWindow);
imageEntropyWindow.Closed += (_, _) => imageEntropyWindow = null;
imageEntropyWindow.Show();
}
void VerifyImage()
{
if(TreeViewSelectedItem is not ImageModel imageModel) return;
var imageVerifyWindow = new ImageVerify();
imageVerifyWindow.DataContext = new ImageVerifyViewModel(imageModel.Image, imageVerifyWindow);
imageVerifyWindow.Closed += (_, _) => imageVerifyWindow = null;
imageVerifyWindow.Show();
}
void ChecksumImage()
{
if(TreeViewSelectedItem is not ImageModel imageModel) return;
var imageChecksumWindow = new ImageChecksum();
imageChecksumWindow.DataContext = new ImageChecksumViewModel(imageModel.Image, imageChecksumWindow);
imageChecksumWindow.Closed += (_, _) => imageChecksumWindow = null;
imageChecksumWindow.Show();
}
void ConvertImage()
{
if(TreeViewSelectedItem is not ImageModel imageModel) return;
var imageConvertWindow = new ImageConvert();
imageConvertWindow.DataContext =
new ImageConvertViewModel(imageModel.Image, imageModel.Path, imageConvertWindow);
imageConvertWindow.Closed += (_, _) => imageConvertWindow = null;
imageConvertWindow.Show();
}
void CreateSidecar()
{
if(TreeViewSelectedItem is not ImageModel imageModel) return;
var imageSidecarWindow = new ImageSidecar();
// TODO: Pass thru chosen default encoding
imageSidecarWindow.DataContext =
new ImageSidecarViewModel(imageModel.Image,
imageModel.Path,
imageModel.Filter.Id,
null,
imageSidecarWindow);
imageSidecarWindow.Show();
}
void ViewImageSectors()
{
if(TreeViewSelectedItem is not ImageModel imageModel) return;
new ViewSector
{
DataContext = new ViewSectorViewModel(imageModel.Image)
}.Show();
}
void DecodeImageMediaTags()
{
if(TreeViewSelectedItem is not ImageModel imageModel) return;
new DecodeMediaTags
{
DataContext = new DecodeMediaTagsViewModel(imageModel.Image)
}.Show();
}
internal void About()
{
var dialog = new About();
dialog.DataContext = new AboutViewModel(dialog);
dialog.ShowDialog(_view);
}
void Encodings()
{
var dialog = new Encodings();
dialog.DataContext = new EncodingsViewModel(dialog);
dialog.ShowDialog(_view);
}
void Plugins()
{
var dialog = new PluginsDialog();
dialog.DataContext = new PluginsViewModel(dialog);
dialog.ShowDialog(_view);
}
void Statistics()
{
using var ctx = AaruContext.Create(Settings.Settings.LocalDbPath);
if(!ctx.Commands.Any() &&
!ctx.Filesystems.Any() &&
!ctx.Filters.Any() &&
!ctx.MediaFormats.Any() &&
!ctx.Medias.Any() &&
!ctx.Partitions.Any() &&
!ctx.SeenDevices.Any())
{
MessageBoxManager.GetMessageBoxStandard(UI.Title_Warning, UI.There_are_no_statistics)
.ShowWindowDialogAsync(_view);
return;
}
var dialog = new StatisticsDialog();
dialog.DataContext = new StatisticsViewModel(dialog);
dialog.ShowDialog(_view);
}
internal async Task SettingsAsync()
{
var dialog = new SettingsDialog();
dialog.DataContext = new SettingsViewModel(dialog, false);
await dialog.ShowDialog(_view);
}
internal void Exit() =>
(Application.Current?.ApplicationLifetime as ClassicDesktopStyleApplicationLifetime)?.Shutdown();
void Console()
{
if(_console is null)
{
_console = new Console();
_console.DataContext = new ConsoleViewModel(_console);
}
_console.Show();
}
async Task OpenAsync()
{
// TODO: Extensions
IReadOnlyList<IStorageFile> result = await _view.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = UI.Dialog_Choose_image_to_open,
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType>
{
FilePickerFileTypes.All
}
});
if(result.Count != 1) return;
IFilter inputFilter = PluginRegister.Singleton.GetFilter(result[0].Path.AbsolutePath);
if(inputFilter == null)
{
MessageBoxManager.GetMessageBoxStandard(UI.Title_Error,
UI.Cannot_open_specified_file,
ButtonEnum.Ok,
Icon.Error);
return;
}
try
{
if(ImageFormat.Detect(inputFilter) is not IMediaImage imageFormat)
{
MessageBoxManager.GetMessageBoxStandard(UI.Title_Error,
UI.Image_format_not_identified,
ButtonEnum.Ok,
Icon.Error);
return;
}
AaruLogging.WriteLine(UI.Image_format_identified_by_0_1, Markup.Escape(imageFormat.Name), imageFormat.Id);
try
{
ErrorNumber opened = imageFormat.Open(inputFilter);
if(opened != ErrorNumber.NoError)
{
MessageBoxManager.GetMessageBoxStandard(UI.Title_Error,
string.Format(UI.Error_0_opening_image_format, opened),
ButtonEnum.Ok,
Icon.Error);
AaruLogging.Error(UI.Unable_to_open_image_format);
AaruLogging.Error(UI.No_error_given);
return;
}
var mediaResource = new Uri($"avares://Aaru.Gui/Assets/Logos/Media/{imageFormat.Info.MediaType}.png");
var imageModel = new ImageModel
{
Path = result[0].Path.AbsolutePath,
Icon = AssetLoader.Exists(mediaResource)
? new Bitmap(AssetLoader.Open(mediaResource))
: imageFormat.Info.MetadataMediaType == MetadataMediaType.BlockMedia
? _genericHddIcon
: imageFormat.Info.MetadataMediaType == MetadataMediaType.OpticalDisc
? _genericOpticalIcon
: _genericFolderIcon,
FileName = Path.GetFileName(result[0].Path.AbsolutePath),
Image = imageFormat,
ViewModel = new ImageInfoViewModel(result[0].Path.AbsolutePath, inputFilter, imageFormat, _view),
Filter = inputFilter
};
List<CommonTypes.Partition> partitions = Core.Partitions.GetAll(imageFormat);
Core.Partitions.AddSchemesToStats(partitions);
var checkRaw = false;
List<string> idPlugins;
PluginRegister plugins = PluginRegister.Singleton;
if(partitions.Count == 0)
{
AaruLogging.Debug(MODULE_NAME, UI.No_partitions_found);
checkRaw = true;
}
else
{
AaruLogging.WriteLine(UI._0_partitions_found, partitions.Count);
foreach(string scheme in partitions.Select(p => p.Scheme).Distinct().OrderBy(s => s))
{
// TODO: Add icons to partition schemes
var schemeModel = new PartitionSchemeModel
{
Name = scheme
};
foreach(CommonTypes.Partition partition in partitions.Where(p => p.Scheme == scheme)
.OrderBy(p => p.Start))
{
var partitionModel = new PartitionModel
{
// TODO: Add icons to partition types
Name = $"{partition.Name} ({partition.Type})",
Partition = partition,
ViewModel = new PartitionViewModel(partition)
};
AaruLogging.WriteLine(UI.Identifying_filesystems_on_partition);
Core.Filesystems.Identify(imageFormat, out idPlugins, partition);
if(idPlugins.Count == 0)
AaruLogging.WriteLine(UI.Filesystem_not_identified);
else
{
AaruLogging.WriteLine(string.Format(UI.Identified_by_0_plugins, idPlugins.Count));
foreach(string pluginName in idPlugins)
{
if(!plugins.Filesystems.TryGetValue(pluginName, out IFilesystem fs)) continue;
if(fs is null) continue;
fs.GetInformation(imageFormat,
partition,
null,
out string information,
out CommonTypes.AaruMetadata.FileSystem fsMetadata);
var rofs = fs as IReadOnlyFilesystem;
if(rofs != null)
{
ErrorNumber error = rofs.Mount(imageFormat,
partition,
null,
new Dictionary<string, string>(),
null);
if(error != ErrorNumber.NoError) rofs = null;
}
var filesystemModel = new FileSystemModel
{
VolumeName = rofs?.Metadata.VolumeName is null
? fsMetadata.VolumeName is null
? $"{fsMetadata.Type}"
: $"{fsMetadata.VolumeName} ({fsMetadata.Type})"
: $"{rofs.Metadata.VolumeName} ({rofs.Metadata.Type})",
Filesystem = fs,
ReadOnlyFilesystem = rofs,
ViewModel = new FileSystemViewModel(rofs?.Metadata ?? fsMetadata, information)
};
// TODO: Trap expanding item
if(rofs != null)
{
filesystemModel.Roots.Add(new SubdirectoryModel
{
Name = "/",
Path = "",
Plugin = rofs
});
Core.Statistics.AddCommand("ls");
}
Core.Statistics.AddFilesystem(rofs?.Metadata.Type ?? fsMetadata.Type);
partitionModel.FileSystems.Add(filesystemModel);
}
}
schemeModel.Partitions.Add(partitionModel);
}
imageModel.PartitionSchemesOrFileSystems.Add(schemeModel);
}
}
if(checkRaw)
{
var wholePart = new CommonTypes.Partition
{
Name = Localization.Core.Whole_device,
Length = imageFormat.Info.Sectors,
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
};
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
if(idPlugins.Count == 0)
AaruLogging.WriteLine(UI.Filesystem_not_identified);
else
{
AaruLogging.WriteLine(string.Format(UI.Identified_by_0_plugins, idPlugins.Count));
foreach(string pluginName in idPlugins)
{
if(!plugins.Filesystems.TryGetValue(pluginName, out IFilesystem fs)) continue;
if(fs is null) continue;
fs.GetInformation(imageFormat,
wholePart,
null,
out string information,
out CommonTypes.AaruMetadata.FileSystem fsMetadata);
var rofs = fs as IReadOnlyFilesystem;
if(rofs != null)
{
ErrorNumber error = rofs.Mount(imageFormat,
wholePart,
null,
new Dictionary<string, string>(),
null);
if(error != ErrorNumber.NoError) rofs = null;
}
var filesystemModel = new FileSystemModel
{
VolumeName = rofs?.Metadata.VolumeName is null
? fsMetadata.VolumeName is null
? $"{fsMetadata.Type}"
: $"{fsMetadata.VolumeName} ({fsMetadata.Type})"
: $"{rofs.Metadata.VolumeName} ({rofs.Metadata.Type})",
Filesystem = fs,
ReadOnlyFilesystem = rofs,
ViewModel = new FileSystemViewModel(rofs?.Metadata ?? fsMetadata, information)
};
// TODO: Trap expanding item
if(rofs != null)
{
filesystemModel.Roots.Add(new SubdirectoryModel
{
Name = "/",
Path = "",
Plugin = rofs
});
Core.Statistics.AddCommand("ls");
}
Core.Statistics.AddFilesystem(rofs?.Metadata.Type ?? fsMetadata.Type);
imageModel.PartitionSchemesOrFileSystems.Add(filesystemModel);
}
}
}
Core.Statistics.AddMediaFormat(imageFormat.Format);
Core.Statistics.AddMedia(imageFormat.Info.MediaType, false);
Core.Statistics.AddFilter(inputFilter.Name);
_imagesRoot.Images.Add(imageModel);
}
catch(Exception ex)
{
MessageBoxManager.GetMessageBoxStandard(UI.Title_Error,
UI.Unable_to_open_image_format,
ButtonEnum.Ok,
Icon.Error);
AaruLogging.Error(UI.Unable_to_open_image_format);
AaruLogging.Error(Localization.Core.Error_0, ex.Message);
AaruLogging.Exception(ex, Localization.Core.Error_0, ex.Message);
}
}
catch(Exception ex)
{
MessageBoxManager.GetMessageBoxStandard(UI.Title_Error,
UI.Exception_reading_file,
ButtonEnum.Ok,
Icon.Error);
AaruLogging.Error(string.Format(UI.Error_reading_file_0, ex.Message));
AaruLogging.Exception(ex, UI.Error_reading_file_0, ex.Message);
}
Core.Statistics.AddCommand("image-info");
}
internal void LoadComplete() => RefreshDevices();
void RefreshDevices()
{
if(!DevicesSupported) return;
try
{
AaruLogging.WriteLine(UI.Refreshing_devices);
_devicesRoot.Devices.Clear();
foreach(Devices.DeviceInfo device in Device.ListDevices()
.Where(d => d.Supported)
.OrderBy(d => d.Vendor)
.ThenBy(d => d.Model))
{
AaruLogging.Debug(MODULE_NAME,
UI.Found_supported_device_model_0_by_manufacturer_1_on_bus_2_and_path_3,
device.Model,
device.Vendor,
device.Bus,
device.Path);
var deviceModel = new DeviceModel
{
Icon = _genericHddIcon,
Name = $"{device.Vendor} {device.Model} ({device.Bus})",
Path = device.Path
};
var dev = Device.Create(device.Path, out _);
if(dev != null)
{
if(dev is Devices.Remote.Device remoteDev)
{
Core.Statistics.AddRemote(remoteDev.RemoteApplication,
remoteDev.RemoteVersion,
remoteDev.RemoteOperatingSystem,
remoteDev.RemoteOperatingSystemVersion,
remoteDev.RemoteArchitecture);
}
deviceModel.Icon = dev.Type switch
{
DeviceType.ATAPI or DeviceType.SCSI => dev.ScsiType switch
{
PeripheralDeviceTypes.DirectAccess
or PeripheralDeviceTypes.SCSIZonedBlockDevice
or PeripheralDeviceTypes.SimplifiedDevice => dev.IsRemovable
? dev.IsUsb ? _usbIcon : _removableIcon
: _genericHddIcon,
PeripheralDeviceTypes.SequentialAccess => _genericTapeIcon,
PeripheralDeviceTypes.OpticalDevice
or PeripheralDeviceTypes.WriteOnceDevice
or PeripheralDeviceTypes.OCRWDevice => _removableIcon,
PeripheralDeviceTypes.MultiMediaDevice => _genericOpticalIcon,
_ => deviceModel.Icon
},
DeviceType.SecureDigital or DeviceType.MMC => _sdIcon,
DeviceType.NVMe => null,
_ => deviceModel.Icon
};
dev.Close();
}
_devicesRoot.Devices.Add(deviceModel);
}
}
catch(InvalidOperationException ex)
{
AaruLogging.Exception(ex, "Unhandled exception refreshing devices");
}
}
}

View File

@@ -1,217 +0,0 @@
<!--
// /***************************************************************************
// Aaru Data Preservation Suite
//
//
// Filename : MainWindow.xaml
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI windows.
//
// [ Description ]
//
// Main window.
//
// [ 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 <http://www.gnu.org/licenses/>.
//
//
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
-->
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:models="clr-namespace:Aaru.Gui.Models;assembly=Aaru.Gui"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:windows="clr-namespace:Aaru.Gui.ViewModels.Windows"
xmlns:localization="clr-namespace:Aaru.Localization;assembly=Aaru.Localization"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
x:Class="Aaru.Gui.Views.Windows.OldMainWindow"
Icon="/Assets/aaru-logo.png"
Title="Aaru.Gui">
<Design.DataContext>
<windows:OldMainWindowViewModel />
</Design.DataContext>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="{x:Static localization:UI.Menu_File}">
<MenuItem Header="{x:Static localization:UI.Menu_Open}"
Command="{Binding OpenCommand}" />
<Separator />
<MenuItem Header="{x:Static localization:UI.Menu_Settings}"
IsVisible="{Binding !NativeMenuSupported}"
Command="{Binding SettingsCommand}" />
<Separator />
<MenuItem Header="{x:Static localization:UI.Menu_Exit}"
IsVisible="{Binding !NativeMenuSupported}"
Command="{Binding ExitCommand}" />
</MenuItem>
<MenuItem Header="{x:Static localization:UI.Menu_Devices}"
IsVisible="{Binding DevicesSupported}">
<MenuItem Header="{x:Static localization:UI.Menu_Refresh}"
Command="{Binding RefreshDevicesCommand}" />
</MenuItem>
<MenuItem Header="{x:Static localization:UI.Menu_Window}">
<MenuItem Header="{x:Static localization:UI.Menu_Console}"
Command="{Binding ConsoleCommand}" />
</MenuItem>
<MenuItem Header="{x:Static localization:UI.Menu_Help}">
<MenuItem Header="{x:Static localization:UI.Menu_Encodings}"
Command="{Binding EncodingsCommand}" />
<MenuItem Header="{x:Static localization:UI.Menu_Plugins}"
Command="{Binding PluginsCommand}" />
<MenuItem Header="{x:Static localization:UI.Menu_Statistics}"
Command="{Binding StatisticsCommand}" />
<Separator IsVisible="{Binding !NativeMenuSupported}" />
<MenuItem Header="{x:Static localization:UI.Menu_About}"
Name="AboutMenuItem"
IsVisible="{Binding !NativeMenuSupported}"
Command="{Binding AboutCommand}" />
</MenuItem>
</Menu>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /><ColumnDefinition Width="5" /><ColumnDefinition Width="6*" />
</Grid.ColumnDefinitions>
<TreeView ItemsSource="{Binding TreeRoot}"
SelectedItem="{Binding TreeViewSelectedItem}">
<TreeView.DataTemplates>
<TreeDataTemplate DataType="models:DevicesRootModel"
ItemsSource="{Binding Devices}">
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static localization:UI.Menu_Refresh_devices}"
Command="{Binding RefreshDevicesCommand}" />
</ContextMenu>
</StackPanel.ContextMenu>
<Image Width="24"
Height="24"
Source="/Assets/Icons/oxygen/32x32/computer.png" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:ImagesRootModel"
ItemsSource="{Binding Images}">
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static localization:UI.Menu_Close_all_images}"
Command="{Binding CloseAllImages}" />
</ContextMenu>
</StackPanel.ContextMenu>
<Image Width="24"
Height="24"
Source="/Assets/Icons/oxygen/32x32/inode-directory.png" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:ImageModel"
ItemsSource="{Binding PartitionSchemesOrFileSystems}">
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding CalculateEntropyCommand}"
Header="{x:Static localization:UI.ButtonLabel_Calculate_entropy}" />
<MenuItem Command="{Binding VerifyImageCommand}"
Header="{x:Static localization:UI.ButtonLabel_Verify}" />
<MenuItem Command="{Binding ChecksumImageCommand}"
Header="{x:Static localization:UI.ButtonLabel_Checksum}" />
<MenuItem Command="{Binding ConvertImageCommand}"
Header="{x:Static localization:UI.ButtonLabel_Convert_to}" />
<MenuItem Command="{Binding CreateSidecarCommand}"
Header="{x:Static localization:UI.ButtonLabel_Create_Aaru_Metadata_sidecar}" />
<MenuItem Command="{Binding ViewImageSectorsCommand}"
Header="{x:Static localization:UI.ButtonLabel_View_sectors}" />
<MenuItem Command="{Binding DecodeImageMediaTagsCommand}"
Header="{x:Static localization:UI.ButtonLabel_Decode_media_tags}" />
</ContextMenu>
</StackPanel.ContextMenu>
<Image Width="24"
Height="24"
Source="{Binding Icon}" />
<TextBlock Text="{Binding FileName}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:PartitionSchemeModel"
ItemsSource="{Binding Partitions}">
<StackPanel Orientation="Horizontal">
<Image Width="24"
Height="24"
Source="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:PartitionModel"
ItemsSource="{Binding FileSystems}">
<StackPanel Orientation="Horizontal">
<Image Width="24"
Height="24"
Source="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:FileSystemModel"
ItemsSource="{Binding Roots}">
<StackPanel Orientation="Horizontal">
<Image Width="24"
Height="24"
Source="{Binding Icon}" />
<TextBlock Text="{Binding VolumeName}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:SubdirectoryModel"
ItemsSource="{Binding Subdirectories}">
<StackPanel Orientation="Horizontal">
<Image Width="24"
Height="24"
Source="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:DeviceModel"
ItemsSource="{Binding Media}">
<StackPanel Orientation="Horizontal">
<Image Width="24"
Height="24"
Source="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</TreeDataTemplate>
<TreeDataTemplate DataType="models:MediaModel">
<StackPanel Orientation="Horizontal">
<Image Width="24"
Height="24"
Source="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</TreeDataTemplate>
</TreeView.DataTemplates>
</TreeView>
<GridSplitter Grid.Column="1"
Width="5"
HorizontalAlignment="Stretch" />
<ContentControl Grid.Column="2"
Content="{Binding ContentPanel}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch" />
</Grid>
</DockPanel>
</Window>

View File

@@ -1,59 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : MainWindow.xaml.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : GUI windows.
//
// --[ Description ] ----------------------------------------------------------
//
// Main window.
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Gui.ViewModels.Windows;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Aaru.Gui.Views.Windows;
public sealed class OldMainWindow : Window
{
public OldMainWindow()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
void InitializeComponent() => AvaloniaXamlLoader.Load(this);
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
(DataContext as OldMainWindowViewModel)?.LoadComplete();
}
}