mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add contextual menu for images.
This commit is contained in:
@@ -35,7 +35,6 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Aaru.CommonTypes;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.CommonTypes.Structs;
|
||||
@@ -49,7 +48,6 @@ using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
using Eto.Serialization.Xaml;
|
||||
using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes;
|
||||
using ImageFormat = Aaru.Core.ImageFormat;
|
||||
|
||||
namespace Aaru.Gui.Forms
|
||||
{
|
||||
@@ -190,105 +188,6 @@ namespace Aaru.Gui.Forms
|
||||
|
||||
if(selectedItem.Values.Length < 4)
|
||||
return;
|
||||
|
||||
/*
|
||||
if(selectedItem.Values[3] is pnlImageInfo imageInfo)
|
||||
{
|
||||
var image = selectedItem.Values[5] as IMediaImage;
|
||||
|
||||
// TODO: Global pool of forms
|
||||
treeImagesMenu.Items.Add(new SeparatorMenuItem());
|
||||
|
||||
menuItem = new ButtonMenuItem
|
||||
{
|
||||
Text = "Calculate entropy"
|
||||
};
|
||||
|
||||
menuItem.Click += (a, b) =>
|
||||
{
|
||||
new frmImageEntropy(image).Show();
|
||||
};
|
||||
|
||||
treeImagesMenu.Items.Add(menuItem);
|
||||
|
||||
menuItem = new ButtonMenuItem
|
||||
{
|
||||
Text = "Verify"
|
||||
};
|
||||
|
||||
menuItem.Click += (a, b) =>
|
||||
{
|
||||
new frmImageVerify(image).Show();
|
||||
};
|
||||
|
||||
treeImagesMenu.Items.Add(menuItem);
|
||||
|
||||
menuItem = new ButtonMenuItem
|
||||
{
|
||||
Text = "Checksum"
|
||||
};
|
||||
|
||||
menuItem.Click += (a, b) =>
|
||||
{
|
||||
new frmImageChecksum(image).Show();
|
||||
};
|
||||
|
||||
treeImagesMenu.Items.Add(menuItem);
|
||||
|
||||
menuItem = new ButtonMenuItem
|
||||
{
|
||||
Text = "Convert to..."
|
||||
};
|
||||
|
||||
menuItem.Click += (a, b) =>
|
||||
{
|
||||
new frmImageConvert(image, selectedItem.Values[2] as string).Show();
|
||||
};
|
||||
|
||||
treeImagesMenu.Items.Add(menuItem);
|
||||
|
||||
menuItem = new ButtonMenuItem
|
||||
{
|
||||
Text = "Create CICM XML sidecar..."
|
||||
};
|
||||
|
||||
menuItem.Click += (a, b) =>
|
||||
{
|
||||
// TODO: Pass thru chosen default encoding
|
||||
new frmImageSidecar(image, selectedItem.Values[2] as string, ((IFilter)selectedItem.Values[4]).Id,
|
||||
null).Show();
|
||||
};
|
||||
|
||||
treeImagesMenu.Items.Add(menuItem);
|
||||
|
||||
menuItem = new ButtonMenuItem
|
||||
{
|
||||
Text = "View sectors"
|
||||
};
|
||||
|
||||
menuItem.Click += (a, b) =>
|
||||
{
|
||||
new frmPrintHex(image).Show();
|
||||
};
|
||||
|
||||
treeImagesMenu.Items.Add(menuItem);
|
||||
|
||||
if(!image.Info.ReadableMediaTags.Any())
|
||||
return;
|
||||
|
||||
menuItem = new ButtonMenuItem
|
||||
{
|
||||
Text = "Decode media tags"
|
||||
};
|
||||
|
||||
menuItem.Click += (a, b) =>
|
||||
{
|
||||
new frmDecodeMediaTags(image).Show();
|
||||
};
|
||||
|
||||
treeImagesMenu.Items.Add(menuItem);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// TODO
|
||||
@@ -304,272 +203,6 @@ namespace Aaru.Gui.Forms
|
||||
Application.Instance.Quit();
|
||||
}
|
||||
|
||||
protected void OnMenuOpen(object sender, EventArgs e)
|
||||
{
|
||||
// TODO: Extensions
|
||||
var dlgOpenImage = new OpenFileDialog
|
||||
{
|
||||
Title = "Choose image to open"
|
||||
};
|
||||
|
||||
DialogResult result = dlgOpenImage.ShowDialog(this);
|
||||
|
||||
if(result != DialogResult.Ok)
|
||||
return;
|
||||
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = filtersList.GetFilter(dlgOpenImage.FileName);
|
||||
|
||||
if(inputFilter == null)
|
||||
{
|
||||
Eto.Forms.MessageBox.Show("Cannot open specified file.", MessageBoxType.Error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
IMediaImage imageFormat = ImageFormat.Detect(inputFilter);
|
||||
|
||||
if(imageFormat == null)
|
||||
{
|
||||
Eto.Forms.MessageBox.Show("Image format not identified.", MessageBoxType.Error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AaruConsole.WriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id);
|
||||
|
||||
try
|
||||
{
|
||||
if(!imageFormat.Open(inputFilter))
|
||||
{
|
||||
Eto.Forms.MessageBox.Show("Unable to open image format", MessageBoxType.Error);
|
||||
AaruConsole.ErrorWriteLine("Unable to open image format");
|
||||
AaruConsole.ErrorWriteLine("No error given");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: SVG
|
||||
Stream logo =
|
||||
ResourceHandler.
|
||||
GetResourceStream($"Aaru.Gui.Assets.Logos.Media.{imageFormat.Info.MediaType}.png");
|
||||
|
||||
var imageGridItem = new TreeGridItem
|
||||
{
|
||||
Values = new object[]
|
||||
{
|
||||
logo == null ? null : new Bitmap(logo),
|
||||
$"{Path.GetFileName(dlgOpenImage.FileName)} ({imageFormat.Info.MediaType})",
|
||||
dlgOpenImage.FileName, null, inputFilter, imageFormat
|
||||
}
|
||||
};
|
||||
|
||||
List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
|
||||
Core.Partitions.AddSchemesToStats(partitions);
|
||||
|
||||
bool checkraw = false;
|
||||
List<string> idPlugins;
|
||||
IFilesystem plugin;
|
||||
PluginBase plugins = GetPluginBase.Instance;
|
||||
|
||||
if(partitions.Count == 0)
|
||||
{
|
||||
AaruConsole.DebugWriteLine("Analyze command", "No partitions found");
|
||||
|
||||
checkraw = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine("{0} partitions found.", partitions.Count);
|
||||
|
||||
foreach(string scheme in partitions.Select(p => p.Scheme).Distinct().OrderBy(s => s))
|
||||
{
|
||||
var schemeGridItem = new TreeGridItem
|
||||
{
|
||||
Values = new object[]
|
||||
{
|
||||
nullImage, // TODO: Add icons to partition schemes
|
||||
scheme
|
||||
}
|
||||
};
|
||||
|
||||
foreach(Partition partition in partitions.
|
||||
Where(p => p.Scheme == scheme).OrderBy(p => p.Start))
|
||||
{
|
||||
var partitionGridItem = new TreeGridItem
|
||||
{
|
||||
Values = new object[]
|
||||
{
|
||||
nullImage, // TODO: Add icons to partition schemes
|
||||
$"{partition.Name} ({partition.Type})", null, new pnlPartition(partition)
|
||||
}
|
||||
};
|
||||
|
||||
AaruConsole.WriteLine("Identifying filesystem on partition");
|
||||
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, partition);
|
||||
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("Filesystem not identified");
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
plugin.GetInformation(imageFormat, partition, out string information, null);
|
||||
|
||||
var fsPlugin = plugin as IReadOnlyFilesystem;
|
||||
|
||||
if(fsPlugin != null)
|
||||
{
|
||||
Errno error =
|
||||
fsPlugin.Mount(imageFormat, partition, null,
|
||||
new Dictionary<string, string>(), null);
|
||||
|
||||
if(error != Errno.NoError)
|
||||
fsPlugin = null;
|
||||
}
|
||||
|
||||
var filesystemGridItem = new TreeGridItem
|
||||
{
|
||||
Values = new object[]
|
||||
{
|
||||
nullImage, // TODO: Add icons to filesystems
|
||||
plugin.XmlFsType.VolumeName is null ? $"{plugin.XmlFsType.Type}"
|
||||
: $"{plugin.XmlFsType.VolumeName} ({plugin.XmlFsType.Type})",
|
||||
fsPlugin, new pnlFilesystem(plugin.XmlFsType, information)
|
||||
}
|
||||
};
|
||||
|
||||
if(fsPlugin != null)
|
||||
{
|
||||
Statistics.AddCommand("ls");
|
||||
filesystemGridItem.Children.Add(placeholderItem);
|
||||
}
|
||||
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
partitionGridItem.Children.Add(filesystemGridItem);
|
||||
}
|
||||
}
|
||||
|
||||
schemeGridItem.Children.Add(partitionGridItem);
|
||||
}
|
||||
|
||||
imageGridItem.Children.Add(schemeGridItem);
|
||||
}
|
||||
}
|
||||
|
||||
if(checkraw)
|
||||
{
|
||||
var wholePart = new Partition
|
||||
{
|
||||
Name = "Whole device", Length = imageFormat.Info.Sectors,
|
||||
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
|
||||
};
|
||||
|
||||
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
|
||||
|
||||
if(idPlugins.Count == 0)
|
||||
AaruConsole.WriteLine("Filesystem not identified");
|
||||
else
|
||||
{
|
||||
AaruConsole.WriteLine($"Identified by {idPlugins.Count} plugins");
|
||||
|
||||
foreach(string pluginName in idPlugins)
|
||||
if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
|
||||
{
|
||||
plugin.GetInformation(imageFormat, wholePart, out string information, null);
|
||||
|
||||
var fsPlugin = plugin as IReadOnlyFilesystem;
|
||||
|
||||
if(fsPlugin != null)
|
||||
{
|
||||
Errno error = fsPlugin.Mount(imageFormat, wholePart, null,
|
||||
new Dictionary<string, string>(), null);
|
||||
|
||||
if(error != Errno.NoError)
|
||||
fsPlugin = null;
|
||||
}
|
||||
|
||||
var filesystemGridItem = new TreeGridItem
|
||||
{
|
||||
Values = new object[]
|
||||
{
|
||||
nullImage, // TODO: Add icons to filesystems
|
||||
plugin.XmlFsType.VolumeName is null ? $"{plugin.XmlFsType.Type}"
|
||||
: $"{plugin.XmlFsType.VolumeName} ({plugin.XmlFsType.Type})",
|
||||
fsPlugin, new pnlFilesystem(plugin.XmlFsType, information)
|
||||
}
|
||||
};
|
||||
|
||||
if(fsPlugin != null)
|
||||
{
|
||||
Statistics.AddCommand("ls");
|
||||
filesystemGridItem.Children.Add(placeholderItem);
|
||||
}
|
||||
|
||||
Statistics.AddFilesystem(plugin.XmlFsType.Type);
|
||||
imageGridItem.Children.Add(filesystemGridItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
imagesRoot.Children.Add(imageGridItem);
|
||||
treeImages.ReloadData();
|
||||
|
||||
Statistics.AddMediaFormat(imageFormat.Format);
|
||||
Statistics.AddMedia(imageFormat.Info.MediaType, false);
|
||||
Statistics.AddFilter(inputFilter.Name);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Eto.Forms.MessageBox.Show("Unable to open image format", MessageBoxType.Error);
|
||||
AaruConsole.ErrorWriteLine("Unable to open image format");
|
||||
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message);
|
||||
AaruConsole.DebugWriteLine("Image-info command", "Stack trace: {0}", ex.StackTrace);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Eto.Forms.MessageBox.Show("Exception reading file", MessageBoxType.Error);
|
||||
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
|
||||
AaruConsole.DebugWriteLine("Image-info command", ex.StackTrace);
|
||||
}
|
||||
|
||||
Statistics.AddCommand("image-info");
|
||||
}
|
||||
|
||||
protected void OnMenuAbout(object sender, EventArgs e)
|
||||
{
|
||||
var dlgAbout = new AboutDialog
|
||||
{
|
||||
Developers = new[]
|
||||
{
|
||||
"Natalia Portillo", "Michael Drüing"
|
||||
},
|
||||
License = "This program is free software: you can redistribute it and/or modify\n" +
|
||||
"it under the terms of the GNU General public License as\n" +
|
||||
"published by the Free Software Foundation, either version 3 of the\n" +
|
||||
"License, or (at your option) any later version.\n\n" +
|
||||
"This program is distributed in the hope that it will be useful,\n" +
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
|
||||
"GNU General public License for more details.\n\n" +
|
||||
"You should have received a copy of the GNU General public License\n" +
|
||||
"along with this program. If not, see <http://www.gnu.org/licenses/>.",
|
||||
ProgramName = "The Disc Image Chef", Website = new Uri("https://github.com/claunia"),
|
||||
WebsiteLabel = "Source code on..."
|
||||
};
|
||||
|
||||
dlgAbout.ShowDialog(this);
|
||||
}
|
||||
|
||||
protected void OnMenuQuit(object sender, EventArgs e) => Application.Instance.Quit();
|
||||
|
||||
protected void OnDeviceRefresh(object sender, EventArgs e) => RefreshDevices();
|
||||
|
||||
protected override void OnLoadComplete(EventArgs e)
|
||||
|
||||
@@ -15,5 +15,6 @@ namespace Aaru.Gui.Models
|
||||
public ObservableCollection<RootModel> PartitionSchemesOrFileSystems { get; }
|
||||
public IMediaImage Image { get; set; }
|
||||
public ImageInfoViewModel ViewModel { get; set; }
|
||||
public IFilter Filter { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -829,6 +829,8 @@ namespace Aaru.Gui.ViewModels
|
||||
{
|
||||
_viewSectorWindow = null;
|
||||
};
|
||||
|
||||
_viewSectorWindow.Show();
|
||||
}
|
||||
|
||||
protected void ExecuteDecodeMediaTagCommand()
|
||||
@@ -849,6 +851,8 @@ namespace Aaru.Gui.ViewModels
|
||||
{
|
||||
_decodeMediaTagsWindow = null;
|
||||
};
|
||||
|
||||
_decodeMediaTagsWindow.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,11 +38,109 @@ namespace Aaru.Gui.ViewModels
|
||||
readonly ImagesRootModel _imagesRoot;
|
||||
readonly MainWindow _view;
|
||||
ConsoleWindow _consoleWindow;
|
||||
|
||||
public object _contentPanel;
|
||||
bool _devicesSupported;
|
||||
public object _treeViewSelectedItem;
|
||||
public int count = 0;
|
||||
|
||||
void ExecuteCalculateEntropyCommand()
|
||||
{
|
||||
if(!(TreeViewSelectedItem is ImageModel imageModel))
|
||||
return;
|
||||
|
||||
var imageEntropyWindow = new ImageEntropyWindow();
|
||||
imageEntropyWindow.DataContext = new ImageEntropyViewModel(imageModel.Image, imageEntropyWindow);
|
||||
|
||||
imageEntropyWindow.Closed += (sender, args) =>
|
||||
{
|
||||
imageEntropyWindow = null;
|
||||
};
|
||||
|
||||
imageEntropyWindow.Show();
|
||||
}
|
||||
|
||||
void ExecuteVerifyImageCommand()
|
||||
{
|
||||
if(!(TreeViewSelectedItem is ImageModel imageModel))
|
||||
return;
|
||||
|
||||
var imageVerifyWindow = new ImageVerifyWindow();
|
||||
imageVerifyWindow.DataContext = new ImageVerifyViewModel(imageModel.Image, imageVerifyWindow);
|
||||
|
||||
imageVerifyWindow.Closed += (sender, args) =>
|
||||
{
|
||||
imageVerifyWindow = null;
|
||||
};
|
||||
|
||||
imageVerifyWindow.Show();
|
||||
}
|
||||
|
||||
void ExecuteChecksumImageCommand()
|
||||
{
|
||||
if(!(TreeViewSelectedItem is ImageModel imageModel))
|
||||
return;
|
||||
|
||||
var imageChecksumWindow = new ImageChecksumWindow();
|
||||
imageChecksumWindow.DataContext = new ImageChecksumViewModel(imageModel.Image, imageChecksumWindow);
|
||||
|
||||
imageChecksumWindow.Closed += (sender, args) =>
|
||||
{
|
||||
imageChecksumWindow = null;
|
||||
};
|
||||
|
||||
imageChecksumWindow.Show();
|
||||
}
|
||||
|
||||
void ExecuteConvertImageCommand()
|
||||
{
|
||||
if(!(TreeViewSelectedItem is ImageModel imageModel))
|
||||
return;
|
||||
|
||||
var imageConvertWindow = new ImageConvertWindow();
|
||||
imageConvertWindow.DataContext = new ImageConvertViewModel(imageModel.Image, imageModel.Path, imageConvertWindow);
|
||||
|
||||
imageConvertWindow.Closed += (sender, args) =>
|
||||
{
|
||||
imageConvertWindow = null;
|
||||
};
|
||||
|
||||
imageConvertWindow.Show();
|
||||
}
|
||||
|
||||
void ExecuteCreateSidecarCommand()
|
||||
{
|
||||
if(!(TreeViewSelectedItem is ImageModel imageModel))
|
||||
return;
|
||||
|
||||
var imageSidecarWindow = new ImageSidecarWindow();
|
||||
|
||||
// TODO: Pass thru chosen default encoding
|
||||
imageSidecarWindow.DataContext =
|
||||
new ImageSidecarViewModel(imageModel.Image, imageModel.Path, imageModel.Filter.Id, null, imageSidecarWindow);
|
||||
|
||||
imageSidecarWindow.Show();
|
||||
}
|
||||
|
||||
void ExecuteViewImageSectorsCommand()
|
||||
{
|
||||
if(!(TreeViewSelectedItem is ImageModel imageModel))
|
||||
return;
|
||||
|
||||
new ViewSectorWindow
|
||||
{
|
||||
DataContext = new ViewSectorViewModel(imageModel.Image)
|
||||
}.Show();
|
||||
}
|
||||
|
||||
void ExecuteDecodeImageMediaTagsCommand()
|
||||
{
|
||||
if(!(TreeViewSelectedItem is ImageModel imageModel))
|
||||
return;
|
||||
|
||||
new DecodeMediaTagsWindow
|
||||
{
|
||||
DataContext = new DecodeMediaTagsViewModel(imageModel.Image)
|
||||
}.Show();
|
||||
}
|
||||
|
||||
public MainWindowViewModel(MainWindow view)
|
||||
{
|
||||
@@ -53,7 +151,14 @@ namespace Aaru.Gui.ViewModels
|
||||
ExitCommand = ReactiveCommand.Create(ExecuteExitCommand);
|
||||
SettingsCommand = ReactiveCommand.Create(ExecuteSettingsCommand);
|
||||
ConsoleCommand = ReactiveCommand.Create(ExecuteConsoleCommand);
|
||||
OpenCommand = ReactiveCommand.Create(ExecuteOpenCommand);
|
||||
OpenCommand = ReactiveCommand.Create(ExecuteOpenCommand);
|
||||
CalculateEntropyCommand = ReactiveCommand.Create(ExecuteCalculateEntropyCommand);
|
||||
VerifyImageCommand = ReactiveCommand.Create(ExecuteVerifyImageCommand);
|
||||
ChecksumImageCommand = ReactiveCommand.Create(ExecuteChecksumImageCommand);
|
||||
ConvertImageCommand = ReactiveCommand.Create(ExecuteConvertImageCommand);
|
||||
CreateSidecarCommand = ReactiveCommand.Create(ExecuteCreateSidecarCommand);
|
||||
ViewImageSectorsCommand = ReactiveCommand.Create(ExecuteViewImageSectorsCommand);
|
||||
DecodeImageMediaTagsCommand = ReactiveCommand.Create(ExecuteDecodeImageMediaTagsCommand);
|
||||
_view = view;
|
||||
TreeRoot = new ObservableCollection<RootModel>();
|
||||
_assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
|
||||
@@ -115,6 +220,13 @@ namespace Aaru.Gui.ViewModels
|
||||
public ReactiveCommand<Unit, Unit> ExitCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> SettingsCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> OpenCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CalculateEntropyCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> VerifyImageCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ChecksumImageCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ConvertImageCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CreateSidecarCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ViewImageSectorsCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> DecodeImageMediaTagsCommand { get; }
|
||||
|
||||
public object ContentPanel
|
||||
{
|
||||
@@ -268,7 +380,8 @@ namespace Aaru.Gui.ViewModels
|
||||
? _genericOpticalIcon
|
||||
: _genericFolderIcon,
|
||||
FileName = Path.GetFileName(result[0]), Image = imageFormat,
|
||||
ViewModel = new ImageInfoViewModel(result[0], inputFilter, imageFormat, _view)
|
||||
ViewModel = new ImageInfoViewModel(result[0], inputFilter, imageFormat, _view),
|
||||
Filter = inputFilter
|
||||
};
|
||||
|
||||
// TODO: pnlImageInfo
|
||||
|
||||
@@ -52,6 +52,17 @@
|
||||
<TreeDataTemplate DataType="models:ImageModel"
|
||||
ItemsSource="{Binding PartitionSchemesOrFileSystems}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel.ContextMenu>
|
||||
<ContextMenu>
|
||||
<Button Command="{Binding CalculateEntropyCommand}"><TextBlock Text="Calculate entropy"/></Button>
|
||||
<Button Command="{Binding VerifyImageCommand}"><TextBlock Text="Verify"/></Button>
|
||||
<Button Command="{Binding ChecksumImageCommand}"><TextBlock Text="Checksum"/></Button>
|
||||
<Button Command="{Binding ConvertImageCommand}"><TextBlock Text="Convert to..."/></Button>
|
||||
<Button Command="{Binding CreateSidecarCommand}"><TextBlock Text="Create CICM XML sidecar..."/></Button>
|
||||
<Button Command="{Binding ViewImageSectorsCommand}"><TextBlock Text="View sectors"/></Button>
|
||||
<Button Command="{Binding DecodeImageMediaTagsCommand}"><TextBlock Text="Decode media tags"/></Button>
|
||||
</ContextMenu>
|
||||
</StackPanel.ContextMenu>
|
||||
<Image Width="24" Height="24" Source="{Binding Icon}" />
|
||||
<TextBlock Text="{Binding FileName}" />
|
||||
</StackPanel>
|
||||
|
||||
Reference in New Issue
Block a user