Migrate statistics from Eto.Forms to Avalonia.

This commit is contained in:
2020-04-10 18:52:50 +01:00
parent a2de64894a
commit e5415ce609
18 changed files with 924 additions and 696 deletions

View File

@@ -23,6 +23,7 @@
<PackageReference Include="Claunia.Encoding" Version="1.7.0" />
<PackageReference Include="Eto.Forms" Version="2.5.0" />
<PackageReference Include="Eto.Serialization.Xaml" Version="2.5.0" />
<PackageReference Include="MessageBox.Avalonia" Version="0.9.6.1" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.3.0" />
<PackageReference Include="Avalonia" Version="0.9.7" />
<PackageReference Include="Avalonia.Desktop" Version="0.9.7" />

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!--
// /***************************************************************************
// The Disc Image Chef
// ============================================================================
//
// Filename : dlgStatistics.xeto
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Statistics dialog.
//
// ==[ Description ] ==========================================================
//
// Defines the structure for the statistics dialog.
//
// ==[ 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-2020 Natalia Portillo
// ****************************************************************************/
-->
<Dialog xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Statistics" ClientSize="460, 160" Padding="10">
<StackLayout Orientation="Vertical">
<TabControl>
<TabPage ID="tabCommands" Text="Commands" Visible="False">
<StackLayout Orientation="Vertical">
<Label ID="lblAnalyze" Visible="False"/>
<Label ID="lblChecksum" Visible="False"/>
<Label ID="lblCompare" Visible="False"/>
<Label ID="lblConvertImage" Visible="False"/>
<Label ID="lblCreateSidecar" Visible="False"/>
<Label ID="lblDecode" Visible="False"/>
<Label ID="lblDeviceInfo" Visible="False"/>
<Label ID="lblDeviceReport" Visible="False"/>
<Label ID="lblDumpMedia" Visible="False"/>
<Label ID="lblEntropy" Visible="False"/>
<Label ID="lblFormats" Visible="False"/>
<Label ID="lblImageInfo" Visible="False"/>
<Label ID="lblMediaInfo" Visible="False"/>
<Label ID="lblMediaScan" Visible="False"/>
<Label ID="lblPrintHex" Visible="False"/>
<Label ID="lblVerify" Visible="False"/>
</StackLayout>
</TabPage>
<TabPage ID="tabFilters" Text="Filters" Visible="False">
<TreeGridView ID="treeFilters"/>
</TabPage>
<TabPage ID="tabFormats" Text="Formats" Visible="False">
<TreeGridView ID="treeFormats"/>
</TabPage>
<TabPage ID="tabPartitions" Text="Partitions" Visible="False">
<TreeGridView ID="treePartitions"/>
</TabPage>
<TabPage ID="tabFilesystems" Text="Filesystems" Visible="False">
<TreeGridView ID="treeFilesystems"/>
</TabPage>
<TabPage ID="tabDevices" Text="Devices" Visible="False">
<TreeGridView ID="treeDevices"/>
</TabPage>
<TabPage ID="tabMedias" Text="Medias" Visible="False">
<TreeGridView ID="treeMedias"/>
</TabPage>
</TabControl>
<StackLayoutItem HorizontalAlignment="Right">
<Button ID="btnClose" Click="OnBtnClose" Text="Close"/>
</StackLayoutItem>
</StackLayout>
</Dialog>

View File

@@ -1,519 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : dlgStatistics.xeto.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Statistics dialog.
//
// --[ Description ] ----------------------------------------------------------
//
// Implements the statistics dialog.
//
// --[ 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-2020 Natalia Portillo
// ****************************************************************************/
using System;
using System.Linq;
using Aaru.Database;
using Aaru.Database.Models;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace Aaru.Gui.Dialogs
{
public class dlgStatistics : Dialog
{
public dlgStatistics()
{
XamlReader.Load(this);
var ctx = AaruContext.Create(Settings.Settings.LocalDbPath);
if(ctx.Commands.Any())
{
if(ctx.Commands.Any(c => c.Name == "analyze"))
{
ulong count = ctx.Commands.Where(c => c.Name == "analyze" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "analyze" && !c.Synchronized);
lblAnalyze.Visible = true;
lblAnalyze.Text = $"You have called the Analyze command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "checksum"))
{
ulong count = ctx.Commands.Where(c => c.Name == "checksum" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "checksum" && !c.Synchronized);
lblChecksum.Visible = true;
lblChecksum.Text = $"You have called the Checksum command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "compare"))
{
ulong count = ctx.Commands.Where(c => c.Name == "compare" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "compare" && !c.Synchronized);
lblCompare.Visible = true;
lblCompare.Text = $"You have called the Compare command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "convert-image"))
{
ulong count = ctx.Commands.Where(c => c.Name == "convert-image" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "convert-image" && !c.Synchronized);
lblConvertImage.Visible = true;
lblConvertImage.Text = $"You have called the Convert-Image command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "create-sidecar"))
{
ulong count = ctx.Commands.Where(c => c.Name == "create-sidecar" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "create-sidecar" && !c.Synchronized);
lblCreateSidecar.Visible = true;
lblCreateSidecar.Text = $"You have called the Create-Sidecar command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "decode"))
{
ulong count = ctx.Commands.Where(c => c.Name == "decode" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "decode" && !c.Synchronized);
lblDecode.Visible = true;
lblDecode.Text = $"You have called the Decode command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "device-info"))
{
ulong count = ctx.Commands.Where(c => c.Name == "device-info" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "device-info" && !c.Synchronized);
lblDeviceInfo.Visible = true;
lblDeviceInfo.Text = $"You have called the Device-Info command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "device-report"))
{
ulong count = ctx.Commands.Where(c => c.Name == "device-report" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "device-report" && !c.Synchronized);
lblDeviceReport.Visible = true;
lblDeviceReport.Text = $"You have called the Device-Report command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "dump-media"))
{
ulong count = ctx.Commands.Where(c => c.Name == "dump-media" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "dump-media" && !c.Synchronized);
lblDumpMedia.Visible = true;
lblDumpMedia.Text = $"You have called the Dump-Media command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "entropy"))
{
ulong count = ctx.Commands.Where(c => c.Name == "entropy" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "entropy" && !c.Synchronized);
lblEntropy.Visible = true;
lblEntropy.Text = $"You have called the Entropy command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "formats"))
{
ulong count = ctx.Commands.Where(c => c.Name == "formats" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "formats" && !c.Synchronized);
lblFormats.Visible = true;
lblFormats.Text = $"You have called the Formats command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "image-info"))
{
ulong count = ctx.Commands.Where(c => c.Name == "image-info" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "image-info" && !c.Synchronized);
lblImageInfo.Visible = true;
lblImageInfo.Text = $"You have called the Image-Info command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "media-info"))
{
ulong count = ctx.Commands.Where(c => c.Name == "media-info" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "media-info" && !c.Synchronized);
lblMediaInfo.Visible = true;
lblMediaInfo.Text = $"You have called the Media-Info command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "media-scan"))
{
ulong count = ctx.Commands.Where(c => c.Name == "media-scan" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "media-scan" && !c.Synchronized);
lblMediaScan.Visible = true;
lblMediaScan.Text = $"You have called the Media-Scan command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "printhex"))
{
ulong count = ctx.Commands.Where(c => c.Name == "printhex" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "printhex" && !c.Synchronized);
lblPrintHex.Visible = true;
lblPrintHex.Text = $"You have called the Print-Hex command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "verify"))
{
ulong count = ctx.Commands.Where(c => c.Name == "verify" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "verify" && !c.Synchronized);
lblVerify.Visible = true;
lblVerify.Text = $"You have called the Verify command {count} times";
}
tabCommands.Visible = lblAnalyze.Visible || lblChecksum.Visible || lblCompare.Visible ||
lblConvertImage.Visible || lblCreateSidecar.Visible || lblDecode.Visible ||
lblDeviceInfo.Visible || lblDeviceReport.Visible || lblDumpMedia.Visible ||
lblEntropy.Visible || lblFormats.Visible || lblImageInfo.Visible ||
lblMediaInfo.Visible || lblMediaScan.Visible || lblPrintHex.Visible ||
lblVerify.Visible;
}
if(ctx.Filters.Any())
{
tabFilters.Visible = true;
var filterList = new TreeGridItemCollection();
treeFilters.Columns.Add(new GridColumn
{
HeaderText = "Filter", DataCell = new TextBoxCell(0)
});
treeFilters.Columns.Add(new GridColumn
{
HeaderText = "Times found", DataCell = new TextBoxCell(1)
});
treeFilters.AllowMultipleSelection = false;
treeFilters.ShowHeader = true;
treeFilters.DataStore = filterList;
foreach(string nvs in ctx.Filters.Select(n => n.Name).Distinct())
{
ulong count = ctx.Filters.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Filters.LongCount(c => c.Name == nvs && !c.Synchronized);
filterList.Add(new TreeGridItem
{
Values = new object[]
{
nvs, count
}
});
}
}
if(ctx.MediaFormats.Any())
{
tabFormats.Visible = true;
var formatList = new TreeGridItemCollection();
treeFormats.Columns.Add(new GridColumn
{
HeaderText = "Format", DataCell = new TextBoxCell(0)
});
treeFormats.Columns.Add(new GridColumn
{
HeaderText = "Times found", DataCell = new TextBoxCell(1)
});
treeFormats.AllowMultipleSelection = false;
treeFormats.ShowHeader = true;
treeFormats.DataStore = formatList;
foreach(string nvs in ctx.MediaFormats.Select(n => n.Name).Distinct())
{
ulong count = ctx.MediaFormats.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.MediaFormats.LongCount(c => c.Name == nvs && !c.Synchronized);
formatList.Add(new TreeGridItem
{
Values = new object[]
{
nvs, count
}
});
}
}
if(ctx.Partitions.Any())
{
tabPartitions.Visible = true;
var partitionList = new TreeGridItemCollection();
treePartitions.Columns.Add(new GridColumn
{
HeaderText = "Filter", DataCell = new TextBoxCell(0)
});
treePartitions.Columns.Add(new GridColumn
{
HeaderText = "Times found", DataCell = new TextBoxCell(1)
});
treePartitions.AllowMultipleSelection = false;
treePartitions.ShowHeader = true;
treePartitions.DataStore = partitionList;
foreach(string nvs in ctx.Partitions.Select(n => n.Name).Distinct())
{
ulong count = ctx.Partitions.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Partitions.LongCount(c => c.Name == nvs && !c.Synchronized);
partitionList.Add(new TreeGridItem
{
Values = new object[]
{
nvs, count
}
});
}
}
if(ctx.Filesystems.Any())
{
tabFilesystems.Visible = true;
var filesystemList = new TreeGridItemCollection();
treeFilesystems.Columns.Add(new GridColumn
{
HeaderText = "Filesystem", DataCell = new TextBoxCell(0)
});
treeFilesystems.Columns.Add(new GridColumn
{
HeaderText = "Times found", DataCell = new TextBoxCell(1)
});
treeFilesystems.AllowMultipleSelection = false;
treeFilesystems.ShowHeader = true;
treeFilesystems.DataStore = filesystemList;
foreach(string nvs in ctx.Filesystems.Select(n => n.Name).Distinct())
{
ulong count = ctx.Filesystems.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Filesystems.LongCount(c => c.Name == nvs && !c.Synchronized);
filesystemList.Add(new TreeGridItem
{
Values = new object[]
{
nvs, count
}
});
}
}
if(ctx.SeenDevices.Any())
{
tabDevices.Visible = true;
var deviceList = new TreeGridItemCollection();
treeDevices.Columns.Add(new GridColumn
{
HeaderText = "Device", DataCell = new TextBoxCell(0)
});
treeDevices.Columns.Add(new GridColumn
{
HeaderText = "Manufacturer", DataCell = new TextBoxCell(1)
});
treeDevices.Columns.Add(new GridColumn
{
HeaderText = "Revision", DataCell = new TextBoxCell(2)
});
treeDevices.Columns.Add(new GridColumn
{
HeaderText = "Bus", DataCell = new TextBoxCell(3)
});
treeDevices.AllowMultipleSelection = false;
treeDevices.ShowHeader = true;
treeDevices.DataStore = deviceList;
foreach(DeviceStat ds in ctx.SeenDevices.OrderBy(n => n.Manufacturer).ThenBy(n => n.Manufacturer).
ThenBy(n => n.Revision).ThenBy(n => n.Bus))
deviceList.Add(new TreeGridItem
{
Values = new object[]
{
ds.Model, ds.Manufacturer, ds.Revision, ds.Bus
}
});
}
if(!ctx.Medias.Any())
return;
tabMedias.Visible = true;
var mediaList = new TreeGridItemCollection();
treeMedias.Columns.Add(new GridColumn
{
HeaderText = "Media", DataCell = new TextBoxCell(0)
});
treeMedias.Columns.Add(new GridColumn
{
HeaderText = "Times found", DataCell = new TextBoxCell(1)
});
treeMedias.Columns.Add(new GridColumn
{
HeaderText = "Type", DataCell = new TextBoxCell(2)
});
treeMedias.AllowMultipleSelection = false;
treeMedias.ShowHeader = true;
treeMedias.DataStore = mediaList;
foreach(string media in ctx.Medias.OrderBy(ms => ms.Type).Select(ms => ms.Type).Distinct())
{
ulong count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && c.Real).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && c.Real);
if(count > 0)
mediaList.Add(new TreeGridItem
{
Values = new object[]
{
media, count, "real"
}
});
count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && !c.Real).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && !c.Real);
if(count == 0)
continue;
mediaList.Add(new TreeGridItem
{
Values = new object[]
{
media, count, "image"
}
});
}
}
protected void OnBtnClose(object sender, EventArgs e) => Close();
#region XAML controls
TabPage tabCommands;
Label lblAnalyze;
Label lblChecksum;
Label lblCompare;
Label lblConvertImage;
Label lblCreateSidecar;
Label lblDecode;
Label lblDeviceInfo;
Label lblDeviceReport;
Label lblDumpMedia;
Label lblEntropy;
Label lblFormats;
Label lblImageInfo;
Label lblMediaInfo;
Label lblMediaScan;
Label lblPrintHex;
Label lblVerify;
TabPage tabFilters;
TreeGridView treeFilters;
TabPage tabFormats;
TreeGridView treeFormats;
TabPage tabPartitions;
TreeGridView treePartitions;
TabPage tabFilesystems;
TreeGridView treeFilesystems;
TabPage tabDevices;
TreeGridView treeDevices;
TabPage tabMedias;
TreeGridView treeMedias;
#endregion
}
}

View File

@@ -186,8 +186,8 @@ namespace Aaru.Gui.Forms
}
catch(Exception exception)
{
MessageBox.Show("Exception {0} trying to save logfile, details has been sent to console.",
exception.Message);
Eto.Forms.MessageBox.Show("Exception {0} trying to save logfile, details has been sent to console.",
exception.Message);
AaruConsole.ErrorWriteLine("Console", exception.Message);
AaruConsole.ErrorWriteLine("Console", exception.StackTrace);

View File

@@ -377,7 +377,7 @@ namespace Aaru.Gui.Forms
}
catch
{
MessageBox.Show("Incorrect metadata sidecar file...", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Incorrect metadata sidecar file...", MessageBoxType.Error);
chkExistingMetadata.Checked = false;
}
}
@@ -404,7 +404,7 @@ namespace Aaru.Gui.Forms
}
catch
{
MessageBox.Show("Incorrect resume file, cannot use it...", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Incorrect resume file, cannot use it...", MessageBoxType.Error);
chkResume.Checked = false;
return;
@@ -415,8 +415,8 @@ namespace Aaru.Gui.Forms
(_resume.BadBlocks.Count != 0 && !_resume.Tape))
return;
MessageBox.Show("Media already dumped correctly, please choose another destination...",
MessageBoxType.Warning);
Eto.Forms.MessageBox.Show("Media already dumped correctly, please choose another destination...",
MessageBoxType.Warning);
chkResume.Checked = false;
}
@@ -625,7 +625,7 @@ namespace Aaru.Gui.Forms
void StoppingErrorMessage(string text) => Application.Instance.Invoke(() =>
{
ErrorMessage(text);
MessageBox.Show(text, MessageBoxType.Error);
Eto.Forms.MessageBox.Show(text, MessageBoxType.Error);
WorkFinished();
});

View File

@@ -112,7 +112,7 @@ namespace Aaru.Gui.Forms
{
if(!(cmbFormat.SelectedValue is IWritableImage plugin))
{
MessageBox.Show("Error trying to find selected plugin", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Error trying to find selected plugin", MessageBoxType.Error);
return;
}
@@ -126,7 +126,7 @@ namespace Aaru.Gui.Forms
if(!(plugin is IWritableImage outputFormat))
{
MessageBox.Show("Error trying to find selected plugin", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Error trying to find selected plugin", MessageBoxType.Error);
return;
}
@@ -236,8 +236,8 @@ namespace Aaru.Gui.Forms
Application.Instance.Invoke(() =>
{
MessageBox.Show($"Converting image will lose media tag {mediaTag}, not continuing...",
MessageBoxType.Error);
Eto.Forms.MessageBox.Show($"Converting image will lose media tag {mediaTag}, not continuing...",
MessageBoxType.Error);
});
return;
@@ -262,8 +262,8 @@ namespace Aaru.Gui.Forms
Application.Instance.Invoke(() =>
{
MessageBox.Show($"Converting image will lose sector tag {sectorTag}, not continuing...",
MessageBoxType.Error);
Eto.Forms.MessageBox.Show($"Converting image will lose sector tag {sectorTag}, not continuing...",
MessageBoxType.Error);
});
return;
@@ -313,7 +313,8 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.Show($"Error {outputFormat.ErrorMessage} creating output image.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show($"Error {outputFormat.ErrorMessage} creating output image.",
MessageBoxType.Error);
});
AaruConsole.ErrorWriteLine("Error {0} creating output image.", outputFormat.ErrorMessage);
@@ -351,8 +352,9 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.Show($"Error {outputFormat.ErrorMessage} setting metadata, not continuing...",
MessageBoxType.Error);
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} setting metadata, not continuing...",
MessageBoxType.Error);
});
AaruConsole.ErrorWriteLine("not continuing...");
@@ -380,8 +382,9 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.Show($"Error {outputFormat.ErrorMessage} sending tracks list to output image.",
MessageBoxType.Error);
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} sending tracks list to output image.",
MessageBoxType.Error);
});
AaruConsole.ErrorWriteLine("Error {0} sending tracks list to output image.",
@@ -422,8 +425,9 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.Show($"Error {outputFormat.ErrorMessage} writing media tag, not continuing...",
MessageBoxType.Error);
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} writing media tag, not continuing...",
MessageBoxType.Error);
});
AaruConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...",
@@ -530,7 +534,7 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} writing sector {doneSectors}, not continuing...",
MessageBoxType.Error);
});
@@ -636,7 +640,7 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} writing sector {doneSectors}, not continuing...",
MessageBoxType.Error);
});
@@ -745,7 +749,7 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} writing sector {doneSectors}, not continuing...",
MessageBoxType.Error);
});
@@ -827,7 +831,7 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} writing tag, not continuing...",
MessageBoxType.Error);
});
@@ -886,7 +890,7 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} writing tag for sector {doneSectors}, not continuing...",
MessageBoxType.Error);
});
@@ -952,7 +956,9 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.Show("Operation canceled, the output file is not correct.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Operation canceled, the output file is not correct.",
MessageBoxType.Error);
btnClose.Visible = true;
btnStop.Visible = false;
stkProgress.Visible = false;
@@ -965,7 +971,7 @@ namespace Aaru.Gui.Forms
{
Application.Instance.Invoke(() =>
{
MessageBox.
Eto.Forms.MessageBox.
Show($"Error {outputFormat.ErrorMessage} closing output image... Contents are not correct.",
MessageBoxType.Error);
});
@@ -975,9 +981,9 @@ namespace Aaru.Gui.Forms
Application.Instance.Invoke(() =>
{
MessageBox.Show(warning
? "Some warnings happened. Check console for more information. Image should be correct."
: "Image converted successfully.");
Eto.Forms.MessageBox.Show(warning
? "Some warnings happened. Check console for more information. Image should be correct."
: "Image converted successfully.");
btnClose.Visible = true;
btnStop.Visible = false;
@@ -1224,7 +1230,7 @@ namespace Aaru.Gui.Forms
}
catch
{
MessageBox.Show("Incorrect metadata sidecar file...", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Incorrect metadata sidecar file...", MessageBoxType.Error);
}
}
@@ -1265,13 +1271,14 @@ namespace Aaru.Gui.Forms
txtResumeFile.Text = dlgMetadata.FileName;
}
else
MessageBox.Show("Resume file does not contain dump hardware information...", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Resume file does not contain dump hardware information...",
MessageBoxType.Error);
sr.Close();
}
catch
{
MessageBox.Show("Incorrect resume file...", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Incorrect resume file...", MessageBoxType.Error);
}
}

View File

@@ -43,7 +43,6 @@ using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Console;
using Aaru.Core;
using Aaru.Core.Media.Info;
using Aaru.Database;
using Aaru.Devices;
using Aaru.Gui.Dialogs;
using Aaru.Gui.Panels;
@@ -293,7 +292,7 @@ namespace Aaru.Gui.Forms
}
// TODO
void CloseAllImages(object sender, EventArgs eventArgs) => MessageBox.Show("Not yet implemented");
void CloseAllImages(object sender, EventArgs eventArgs) => Eto.Forms.MessageBox.Show("Not yet implemented");
protected override void OnLoad(EventArgs e)
{
@@ -331,7 +330,7 @@ namespace Aaru.Gui.Forms
if(inputFilter == null)
{
MessageBox.Show("Cannot open specified file.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Cannot open specified file.", MessageBoxType.Error);
return;
}
@@ -342,7 +341,7 @@ namespace Aaru.Gui.Forms
if(imageFormat == null)
{
MessageBox.Show("Image format not identified.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Image format not identified.", MessageBoxType.Error);
return;
}
@@ -353,7 +352,7 @@ namespace Aaru.Gui.Forms
{
if(!imageFormat.Open(inputFilter))
{
MessageBox.Show("Unable to open image format", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Unable to open image format", MessageBoxType.Error);
AaruConsole.ErrorWriteLine("Unable to open image format");
AaruConsole.ErrorWriteLine("No error given");
@@ -537,7 +536,7 @@ namespace Aaru.Gui.Forms
}
catch(Exception ex)
{
MessageBox.Show("Unable to open image format", MessageBoxType.Error);
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);
@@ -545,7 +544,7 @@ namespace Aaru.Gui.Forms
}
catch(Exception ex)
{
MessageBox.Show("Exception reading file", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Exception reading file", MessageBoxType.Error);
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}");
AaruConsole.DebugWriteLine("Image-info command", ex.StackTrace);
}
@@ -684,26 +683,6 @@ namespace Aaru.Gui.Forms
protected void OnMenuConsole(object sender, EventArgs e) => new frmConsole().Show();
protected void OnMenuStatistics(object sender, EventArgs e)
{
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())
{
MessageBox.Show("There are no statistics.");
return;
}
new dlgStatistics().ShowModal(this);
}
protected void OnTreeImagesSelectedItemChanged(object sender, EventArgs e)
{
if(!(sender is TreeGridView tree))
@@ -776,8 +755,8 @@ namespace Aaru.Gui.Forms
if(errno != Errno.NoError)
{
MessageBox.Show($"Error {errno} trying to read \"{dirPath}\" of chosen filesystem",
MessageBoxType.Error);
Eto.Forms.MessageBox.Show($"Error {errno} trying to read \"{dirPath}\" of chosen filesystem",
MessageBoxType.Error);
break;
}
@@ -903,8 +882,8 @@ namespace Aaru.Gui.Forms
if(errno != Errno.NoError)
{
MessageBox.Show($"Error {errno} trying to read \"{dirPath}\" of chosen filesystem",
MessageBoxType.Error);
Eto.Forms.MessageBox.Show($"Error {errno} trying to read \"{dirPath}\" of chosen filesystem",
MessageBoxType.Error);
return;
}
@@ -947,8 +926,8 @@ namespace Aaru.Gui.Forms
if(errno != Errno.NoError)
{
MessageBox.Show($"Error {errno} trying to read root directory of chosen filesystem",
MessageBoxType.Error);
Eto.Forms.MessageBox.Show($"Error {errno} trying to read root directory of chosen filesystem",
MessageBoxType.Error);
return;
}

View File

@@ -107,7 +107,7 @@ namespace Aaru.Gui.Forms
if(dev.Error)
{
MessageBox.Show($"Error {dev.LastError} opening device.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show($"Error {dev.LastError} opening device.", MessageBoxType.Error);
btnStop.Visible = false;
btnScan.Visible = true;
btnCancel.Visible = true;
@@ -334,7 +334,7 @@ namespace Aaru.Gui.Forms
void StoppingErrorMessage(string text) => Application.Instance.Invoke(() =>
{
lblProgress.Text = text;
MessageBox.Show(text, MessageBoxType.Error);
Eto.Forms.MessageBox.Show(text, MessageBoxType.Error);
WorkFinished();
});

View File

@@ -0,0 +1,10 @@
namespace Aaru.Gui.Models
{
public class DeviceStatsModel
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string Revision { get; set; }
public string Bus { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace Aaru.Gui.Models
{
public class MediaStatsModel
{
public string Name { get; set; }
public ulong Count { get; set; }
public string Type { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace Aaru.Gui.Models
{
public class NameCountModel
{
public string Name { get; set; }
public ulong Count { get; set; }
}
}

View File

@@ -383,9 +383,9 @@ namespace Aaru.Gui.Panels
string corrected = new string(chars);
result = MessageBox.Show(this, "Unsupported filename",
$"The file name {filename} is not supported on this platform.\nDo you want to rename it to {corrected}?",
MessageBoxButtons.YesNoCancel, MessageBoxType.Warning);
result = Eto.Forms.MessageBox.Show(this, "Unsupported filename",
$"The file name {filename} is not supported on this platform.\nDo you want to rename it to {corrected}?",
MessageBoxButtons.YesNoCancel, MessageBoxType.Warning);
if(result == DialogResult.Cancel)
return;
@@ -400,9 +400,9 @@ namespace Aaru.Gui.Panels
if(File.Exists(outputPath))
{
result = MessageBox.Show(this, "Existing file",
$"A file named {filename} already exists on the destination folder.\nDo you want to overwrite it?",
MessageBoxButtons.YesNoCancel, MessageBoxType.Question);
result = Eto.Forms.MessageBox.Show(this, "Existing file",
$"A file named {filename} already exists on the destination folder.\nDo you want to overwrite it?",
MessageBoxButtons.YesNoCancel, MessageBoxType.Question);
if(result == DialogResult.Cancel)
return;
@@ -416,9 +416,9 @@ namespace Aaru.Gui.Panels
}
catch(IOException)
{
result = MessageBox.Show(this, "Cannot delete",
"Could not delete existing file.\nDo you want to continue?",
MessageBoxButtons.YesNo, MessageBoxType.Warning);
result = Eto.Forms.MessageBox.Show(this, "Cannot delete",
"Could not delete existing file.\nDo you want to continue?",
MessageBoxButtons.YesNo, MessageBoxType.Warning);
if(result == DialogResult.No)
return;
@@ -433,9 +433,9 @@ namespace Aaru.Gui.Panels
if(error != Errno.NoError)
{
result = MessageBox.Show(this, "Error reading file",
$"Error {error} reading file.\nDo you want to continue?",
MessageBoxButtons.YesNo, MessageBoxType.Warning);
result = Eto.Forms.MessageBox.Show(this, "Error reading file",
$"Error {error} reading file.\nDo you want to continue?",
MessageBoxButtons.YesNo, MessageBoxType.Warning);
if(result == DialogResult.No)
return;
@@ -482,9 +482,9 @@ namespace Aaru.Gui.Panels
}
catch(IOException)
{
result = MessageBox.Show(this, "Cannot create file",
"Could not create destination file.\nDo you want to continue?",
MessageBoxButtons.YesNo, MessageBoxType.Warning);
result = Eto.Forms.MessageBox.Show(this, "Cannot create file",
"Could not create destination file.\nDo you want to continue?",
MessageBoxButtons.YesNo, MessageBoxType.Warning);
if(result == DialogResult.No)
return;

View File

@@ -224,7 +224,7 @@ namespace Aaru.Gui.Panels
if(scsiInfo.MediaType == MediaType.GDR ||
scsiInfo.MediaType == MediaType.GDROM)
{
MessageBox.Show("GD-ROM dump support is not yet implemented.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("GD-ROM dump support is not yet implemented.", MessageBoxType.Error);
return;
}
@@ -232,7 +232,7 @@ namespace Aaru.Gui.Panels
if((scsiInfo.MediaType == MediaType.XGD || scsiInfo.MediaType == MediaType.XGD2 ||
scsiInfo.MediaType == MediaType.XGD3) &&
scsiInfo.DeviceInfo.ScsiInquiry?.KreonPresent != true)
MessageBox.Show("Dumping Xbox discs require a Kreon drive.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Dumping Xbox discs require a Kreon drive.", MessageBoxType.Error);
var dumpForm = new frmDump(devicePath, scsiInfo.DeviceInfo, scsiInfo);
dumpForm.Show();
@@ -243,7 +243,7 @@ namespace Aaru.Gui.Panels
if(scsiInfo.MediaType == MediaType.GDR ||
scsiInfo.MediaType == MediaType.GDROM)
{
MessageBox.Show("GD-ROM scan support is not yet implemented.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("GD-ROM scan support is not yet implemented.", MessageBoxType.Error);
return;
}
@@ -251,7 +251,7 @@ namespace Aaru.Gui.Panels
if(scsiInfo.MediaType == MediaType.XGD ||
scsiInfo.MediaType == MediaType.XGD2 ||
scsiInfo.MediaType == MediaType.XGD3)
MessageBox.Show("Scanning Xbox discs is not yet supported.", MessageBoxType.Error);
Eto.Forms.MessageBox.Show("Scanning Xbox discs is not yet supported.", MessageBoxType.Error);
var scanForm = new frmMediaScan(devicePath, scsiInfo.DeviceInfo, scsiInfo);
scanForm.Show();

View File

@@ -1,8 +1,11 @@
using System.Reactive;
using System.Linq;
using System.Reactive;
using Aaru.Database;
using Aaru.Gui.Views;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using MessageBox.Avalonia;
using ReactiveUI;
namespace Aaru.Gui.ViewModels
@@ -13,10 +16,11 @@ namespace Aaru.Gui.ViewModels
public MainWindowViewModel(MainWindow view)
{
AboutCommand = ReactiveCommand.Create(ExecuteAboutCommand);
EncodingsCommand = ReactiveCommand.Create(ExecuteEncodingsCommand);
PluginsCommand = ReactiveCommand.Create(ExecutePluginsCommand);
_view = view;
AboutCommand = ReactiveCommand.Create(ExecuteAboutCommand);
EncodingsCommand = ReactiveCommand.Create(ExecuteEncodingsCommand);
PluginsCommand = ReactiveCommand.Create(ExecutePluginsCommand);
StatisticsCommand = ReactiveCommand.Create(ExecuteStatisticsCommand);
_view = view;
}
public string Greeting => "Welcome to Aaru!";
@@ -25,9 +29,10 @@ namespace Aaru.Gui.ViewModels
!NativeMenu.GetIsNativeMenuExported((Application.Current.ApplicationLifetime as
IClassicDesktopStyleApplicationLifetime)?.MainWindow);
public ReactiveCommand<Unit, Unit> AboutCommand { get; }
public ReactiveCommand<Unit, Unit> EncodingsCommand { get; }
public ReactiveCommand<Unit, Unit> PluginsCommand { get; }
public ReactiveCommand<Unit, Unit> AboutCommand { get; }
public ReactiveCommand<Unit, Unit> EncodingsCommand { get; }
public ReactiveCommand<Unit, Unit> PluginsCommand { get; }
public ReactiveCommand<Unit, Unit> StatisticsCommand { get; }
internal void ExecuteAboutCommand()
{
@@ -49,5 +54,27 @@ namespace Aaru.Gui.ViewModels
dialog.DataContext = new PluginsDialogViewModel(dialog);
dialog.ShowDialog(_view);
}
internal void ExecuteStatisticsCommand()
{
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.GetMessageBoxStandardWindow("Warning", "There are no statistics.").ShowDialog(_view);
return;
}
var dialog = new StatisticsDialog();
dialog.DataContext = new StatisticsDialogViewModel(dialog);
dialog.ShowDialog(_view);
}
}
}

View File

@@ -0,0 +1,636 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using Aaru.Database;
using Aaru.Database.Models;
using Aaru.Gui.Models;
using Aaru.Gui.Views;
using ReactiveUI;
namespace Aaru.Gui.ViewModels
{
public class StatisticsDialogViewModel : ViewModelBase
{
readonly StatisticsDialog _view;
string _analyzeText;
bool _analyzeVisible;
string _checksumText;
bool _checksumVisible;
bool _commandsVisible;
string _compareText;
bool _compareVisible;
string _convertImageText;
bool _convertImageVisible;
string _createSidecarText;
bool _createSidecarVisible;
string _decodeText;
bool _decodeVisible;
string _deviceInfoText;
bool _deviceInfoVisible;
string _deviceReportText;
bool _deviceReportVisible;
bool _devicesVisible;
string _dumpMediaText;
bool _dumpMediaVisible;
string _entropyText;
bool _entropyVisible;
bool _filesystemsVisible;
bool _filtersVisible;
bool _formatsCommandVisible;
string _formatsText;
bool _formatsVisible;
string _imageInfoText;
bool _imageInfoVisible;
string _mediaInfoText;
bool _mediaInfoVisible;
string _mediaScanText;
bool _mediaScanVisible;
bool _mediasVisible;
bool _partitionsVisible;
string _printHexText;
bool _printHexVisible;
string _verifyText;
bool _verifyVisible;
public StatisticsDialogViewModel(StatisticsDialog view)
{
_view = view;
Filters = new ObservableCollection<NameCountModel>();
Formats = new ObservableCollection<NameCountModel>();
Partitions = new ObservableCollection<NameCountModel>();
Filesystems = new ObservableCollection<NameCountModel>();
Devices = new ObservableCollection<DeviceStatsModel>();
Medias = new ObservableCollection<MediaStatsModel>();
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
using var ctx = AaruContext.Create(Settings.Settings.LocalDbPath);
if(ctx.Commands.Any())
{
if(ctx.Commands.Any(c => c.Name == "analyze"))
{
ulong count = ctx.Commands.Where(c => c.Name == "analyze" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "analyze" && !c.Synchronized);
AnalyzeVisible = true;
AnalyzeText = $"You have called the Analyze command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "checksum"))
{
ulong count = ctx.Commands.Where(c => c.Name == "checksum" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "checksum" && !c.Synchronized);
ChecksumVisible = true;
ChecksumText = $"You have called the Checksum command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "compare"))
{
ulong count = ctx.Commands.Where(c => c.Name == "compare" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "compare" && !c.Synchronized);
CompareVisible = true;
CompareText = $"You have called the Compare command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "convert-image"))
{
ulong count = ctx.Commands.Where(c => c.Name == "convert-image" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "convert-image" && !c.Synchronized);
ConvertImageVisible = true;
ConvertImageText = $"You have called the Convert-Image command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "create-sidecar"))
{
ulong count = ctx.Commands.Where(c => c.Name == "create-sidecar" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "create-sidecar" && !c.Synchronized);
CreateSidecarVisible = true;
CreateSidecarText = $"You have called the Create-Sidecar command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "decode"))
{
ulong count = ctx.Commands.Where(c => c.Name == "decode" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "decode" && !c.Synchronized);
DecodeVisible = true;
DecodeText = $"You have called the Decode command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "device-info"))
{
ulong count = ctx.Commands.Where(c => c.Name == "device-info" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "device-info" && !c.Synchronized);
DeviceInfoVisible = true;
DeviceInfoText = $"You have called the Device-Info command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "device-report"))
{
ulong count = ctx.Commands.Where(c => c.Name == "device-report" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "device-report" && !c.Synchronized);
DeviceReportVisible = true;
DeviceReportText = $"You have called the Device-Report command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "dump-media"))
{
ulong count = ctx.Commands.Where(c => c.Name == "dump-media" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "dump-media" && !c.Synchronized);
DumpMediaVisible = true;
DumpMediaText = $"You have called the Dump-Media command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "entropy"))
{
ulong count = ctx.Commands.Where(c => c.Name == "entropy" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "entropy" && !c.Synchronized);
EntropyVisible = true;
EntropyText = $"You have called the Entropy command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "formats"))
{
ulong count = ctx.Commands.Where(c => c.Name == "formats" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "formats" && !c.Synchronized);
FormatsCommandVisible = true;
FormatsCommandText = $"You have called the Formats command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "image-info"))
{
ulong count = ctx.Commands.Where(c => c.Name == "image-info" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "image-info" && !c.Synchronized);
ImageInfoVisible = true;
ImageInfoText = $"You have called the Image-Info command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "media-info"))
{
ulong count = ctx.Commands.Where(c => c.Name == "media-info" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "media-info" && !c.Synchronized);
MediaInfoVisible = true;
MediaInfoText = $"You have called the Media-Info command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "media-scan"))
{
ulong count = ctx.Commands.Where(c => c.Name == "media-scan" && c.Synchronized).
Select(c => c.Count).FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "media-scan" && !c.Synchronized);
MediaScanVisible = true;
MediaScanText = $"You have called the Media-Scan command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "printhex"))
{
ulong count = ctx.Commands.Where(c => c.Name == "printhex" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "printhex" && !c.Synchronized);
PrintHexVisible = true;
PrintHexText = $"You have called the Print-Hex command {count} times";
}
if(ctx.Commands.Any(c => c.Name == "verify"))
{
ulong count = ctx.Commands.Where(c => c.Name == "verify" && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Commands.LongCount(c => c.Name == "verify" && !c.Synchronized);
VerifyVisible = true;
VerifyText = $"You have called the Verify command {count} times";
}
CommandsVisible = AnalyzeVisible || ChecksumVisible || CompareVisible ||
ConvertImageVisible ||
CreateSidecarVisible || DecodeVisible || DeviceInfoVisible ||
DeviceReportVisible ||
DumpMediaVisible || EntropyVisible || FormatsCommandVisible ||
ImageInfoVisible ||
MediaInfoVisible || MediaScanVisible || PrintHexVisible || VerifyVisible;
}
if(ctx.Filters.Any())
{
FiltersVisible = true;
foreach(string nvs in ctx.Filters.Select(n => n.Name).Distinct())
{
ulong count = ctx.Filters.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Filters.LongCount(c => c.Name == nvs && !c.Synchronized);
Filters.Add(new NameCountModel
{
Name = nvs, Count = count
});
}
}
if(ctx.MediaFormats.Any())
{
FormatsVisible = true;
foreach(string nvs in ctx.MediaFormats.Select(n => n.Name).Distinct())
{
ulong count = ctx.MediaFormats.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.MediaFormats.LongCount(c => c.Name == nvs && !c.Synchronized);
Formats.Add(new NameCountModel
{
Name = nvs, Count = count
});
}
}
if(ctx.Partitions.Any())
{
PartitionsVisible = true;
foreach(string nvs in ctx.Partitions.Select(n => n.Name).Distinct())
{
ulong count = ctx.Partitions.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Partitions.LongCount(c => c.Name == nvs && !c.Synchronized);
Partitions.Add(new NameCountModel
{
Name = nvs, Count = count
});
}
}
if(ctx.Filesystems.Any())
{
FilesystemsVisible = true;
foreach(string nvs in ctx.Filesystems.Select(n => n.Name).Distinct())
{
ulong count = ctx.Filesystems.Where(c => c.Name == nvs && c.Synchronized).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Filesystems.LongCount(c => c.Name == nvs && !c.Synchronized);
Filesystems.Add(new NameCountModel
{
Name = nvs, Count = count
});
}
}
if(ctx.SeenDevices.Any())
{
DevicesVisible = true;
foreach(DeviceStat ds in ctx.SeenDevices.OrderBy(n => n.Manufacturer).ThenBy(n => n.Manufacturer).
ThenBy(n => n.Revision).ThenBy(n => n.Bus))
Devices.Add(new DeviceStatsModel
{
Model = ds.Model, Manufacturer = ds.Manufacturer, Revision = ds.Revision, Bus = ds.Bus
});
}
if(!ctx.Medias.Any())
return;
MediasVisible = true;
foreach(string media in ctx.Medias.OrderBy(ms => ms.Type).Select(ms => ms.Type).Distinct())
{
ulong count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && c.Real).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && c.Real);
if(count > 0)
Medias.Add(new MediaStatsModel
{
Name = media, Count = count, Type = "real"
});
count = ctx.Medias.Where(c => c.Type == media && c.Synchronized && !c.Real).Select(c => c.Count).
FirstOrDefault();
count += (ulong)ctx.Medias.LongCount(c => c.Type == media && !c.Synchronized && !c.Real);
if(count == 0)
continue;
Medias.Add(new MediaStatsModel
{
Name = media, Count = count, Type = "image"
});
}
}
public string AnalyzeText
{
get => _analyzeText;
set => this.RaiseAndSetIfChanged(ref _analyzeText, value);
}
public bool AnalyzeVisible
{
get => _analyzeVisible;
set => this.RaiseAndSetIfChanged(ref _analyzeVisible, value);
}
public string ChecksumText
{
get => _checksumText;
set => this.RaiseAndSetIfChanged(ref _checksumText, value);
}
public bool ChecksumVisible
{
get => _checksumVisible;
set => this.RaiseAndSetIfChanged(ref _checksumVisible, value);
}
public string CompareText
{
get => _compareText;
set => this.RaiseAndSetIfChanged(ref _compareText, value);
}
public bool CompareVisible
{
get => _compareVisible;
set => this.RaiseAndSetIfChanged(ref _compareVisible, value);
}
public string ConvertImageText
{
get => _convertImageText;
set => this.RaiseAndSetIfChanged(ref _convertImageText, value);
}
public bool ConvertImageVisible
{
get => _convertImageVisible;
set => this.RaiseAndSetIfChanged(ref _convertImageVisible, value);
}
public string CreateSidecarText
{
get => _createSidecarText;
set => this.RaiseAndSetIfChanged(ref _createSidecarText, value);
}
public bool CreateSidecarVisible
{
get => _createSidecarVisible;
set => this.RaiseAndSetIfChanged(ref _createSidecarVisible, value);
}
public string DecodeText
{
get => _decodeText;
set => this.RaiseAndSetIfChanged(ref _decodeText, value);
}
public bool DecodeVisible
{
get => _decodeVisible;
set => this.RaiseAndSetIfChanged(ref _decodeVisible, value);
}
public string DeviceInfoText
{
get => _deviceInfoText;
set => this.RaiseAndSetIfChanged(ref _deviceInfoText, value);
}
public bool DeviceInfoVisible
{
get => _deviceInfoVisible;
set => this.RaiseAndSetIfChanged(ref _deviceInfoVisible, value);
}
public string DeviceReportText
{
get => _deviceReportText;
set => this.RaiseAndSetIfChanged(ref _deviceReportText, value);
}
public bool DeviceReportVisible
{
get => _deviceReportVisible;
set => this.RaiseAndSetIfChanged(ref _deviceReportVisible, value);
}
public string DumpMediaText
{
get => _dumpMediaText;
set => this.RaiseAndSetIfChanged(ref _dumpMediaText, value);
}
public bool DumpMediaVisible
{
get => _dumpMediaVisible;
set => this.RaiseAndSetIfChanged(ref _dumpMediaVisible, value);
}
public string EntropyText
{
get => _entropyText;
set => this.RaiseAndSetIfChanged(ref _entropyText, value);
}
public bool EntropyVisible
{
get => _entropyVisible;
set => this.RaiseAndSetIfChanged(ref _entropyVisible, value);
}
public string FormatsCommandText
{
get => _formatsText;
set => this.RaiseAndSetIfChanged(ref _formatsText, value);
}
public bool FormatsCommandVisible
{
get => _formatsCommandVisible;
set => this.RaiseAndSetIfChanged(ref _formatsCommandVisible, value);
}
public string ImageInfoText
{
get => _imageInfoText;
set => this.RaiseAndSetIfChanged(ref _imageInfoText, value);
}
public bool ImageInfoVisible
{
get => _imageInfoVisible;
set => this.RaiseAndSetIfChanged(ref _imageInfoVisible, value);
}
public string MediaInfoText
{
get => _mediaInfoText;
set => this.RaiseAndSetIfChanged(ref _mediaInfoText, value);
}
public bool MediaInfoVisible
{
get => _mediaInfoVisible;
set => this.RaiseAndSetIfChanged(ref _mediaInfoVisible, value);
}
public string MediaScanText
{
get => _mediaScanText;
set => this.RaiseAndSetIfChanged(ref _mediaScanText, value);
}
public bool MediaScanVisible
{
get => _mediaScanVisible;
set => this.RaiseAndSetIfChanged(ref _mediaScanVisible, value);
}
public string PrintHexText
{
get => _printHexText;
set => this.RaiseAndSetIfChanged(ref _printHexText, value);
}
public bool PrintHexVisible
{
get => _printHexVisible;
set => this.RaiseAndSetIfChanged(ref _printHexVisible, value);
}
public string VerifyText
{
get => _verifyText;
set => this.RaiseAndSetIfChanged(ref _verifyText, value);
}
public bool VerifyVisible
{
get => _verifyVisible;
set => this.RaiseAndSetIfChanged(ref _verifyVisible, value);
}
public bool CommandsVisible
{
get => _commandsVisible;
set => this.RaiseAndSetIfChanged(ref _commandsVisible, value);
}
public bool FiltersVisible
{
get => _filtersVisible;
set => this.RaiseAndSetIfChanged(ref _filtersVisible, value);
}
public bool PartitionsVisible
{
get => _partitionsVisible;
set => this.RaiseAndSetIfChanged(ref _partitionsVisible, value);
}
public bool FormatsVisible
{
get => _formatsVisible;
set => this.RaiseAndSetIfChanged(ref _formatsVisible, value);
}
public bool FilesystemsVisible
{
get => _filesystemsVisible;
set => this.RaiseAndSetIfChanged(ref _filesystemsVisible, value);
}
public bool DevicesVisible
{
get => _devicesVisible;
set => this.RaiseAndSetIfChanged(ref _devicesVisible, value);
}
public bool MediasVisible
{
get => _mediasVisible;
set => this.RaiseAndSetIfChanged(ref _mediasVisible, value);
}
public string CommandsLabel => "Commands";
public string FilterLabel => "Filter";
public string PartitionLabel => "Partition";
public string PartitionsLabel => "Partitions";
public string FiltersLabel => "Filters";
public string FormatsLabel => "Formats";
public string FormatLabel => "Format";
public string FilesystemsLabel => "Filesystems";
public string FilesystemLabel => "Filesystem";
public string TimesFoundLabel => "Times found";
public string DevicesLabel => "Devices";
public string DeviceLabel => "Device";
public string ManufacturerLabel => "Manufacturer";
public string RevisionLabel => "Revision";
public string BusLabel => "Bus";
public string MediasLabel => "Medias";
public string MediaLabel => "Media";
public string TypeLabel => "Type";
public string Title => "Encodings";
public string CloseLabel => "Close";
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
public ObservableCollection<NameCountModel> Filters { get; }
public ObservableCollection<NameCountModel> Formats { get; }
public ObservableCollection<NameCountModel> Partitions { get; }
public ObservableCollection<NameCountModel> Filesystems { get; }
public ObservableCollection<DeviceStatsModel> Devices { get; }
public ObservableCollection<MediaStatsModel> Medias { get; }
void ExecuteCloseCommand() => _view.Close();
}
}

View File

@@ -21,7 +21,8 @@
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_Encodings" Command="{Binding EncodingsCommand}" />
<MenuItem Header="_Plugins" Command="{Binding PluginsCommand}" /> <MenuItem Header="_Statistics" />
<MenuItem Header="_Plugins" Command="{Binding PluginsCommand}" />
<MenuItem Header="_Statistics" Command="{Binding StatisticsCommand}" />
<Separator IsVisible="{Binding NativeMenuNotSupported}" />
<MenuItem Header="_About" Name="AboutMenuItem" IsVisible="{Binding NativeMenuNotSupported}"
Command="{Binding AboutCommand}" />

View File

@@ -0,0 +1,131 @@
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Aaru.Gui.ViewModels;assembly=Aaru.Gui"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800"
d:DesignHeight="450" Width="550" Height="320" x:Class="Aaru.Gui.Views.StatisticsDialog"
Icon="/Assets/avalonia-logo.ico" CanResize="False" Title="{Binding Title}">
<Design.DataContext>
<vm:StatisticsDialogViewModel />
</Design.DataContext>
<Border Padding="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TabControl Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TabItem IsVisible="{Binding CommandsVisible}">
<TabItem.Header>
<TextBlock Text="{Binding CommandsLabel}" />
</TabItem.Header>
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding AnalyzeText}" IsVisible="{Binding AnalyzeVisible}" />
<TextBlock Text="{Binding ChecksumText}" IsVisible="{Binding ChecksumVisible}" />
<TextBlock Text="{Binding CompareText}" IsVisible="{Binding CompareVisible}" />
<TextBlock Text="{Binding ConvertImageText}" IsVisible="{Binding ConvertImageVisible}" />
<TextBlock Text="{Binding CreateSidecarText}" IsVisible="{Binding CreateSidecarVisible}" />
<TextBlock Text="{Binding DecodeText}" IsVisible="{Binding DecodeVisible}" />
<TextBlock Text="{Binding DeviceInfoText}" IsVisible="{Binding DeviceInfoVisible}" />
<TextBlock Text="{Binding DeviceReportText}" IsVisible="{Binding DeviceReportVisible}" />
<TextBlock Text="{Binding DumpMediaText}" IsVisible="{Binding DumpMediaVisible}" />
<TextBlock Text="{Binding EntropyText}" IsVisible="{Binding EntropyVisible}" />
<TextBlock Text="{Binding FormatsCommandText}" IsVisible="{Binding FormatsCommandVisible}" />
<TextBlock Text="{Binding ImageInfoText}" IsVisible="{Binding ImageInfoVisible}" />
<TextBlock Text="{Binding MediaInfoText}" IsVisible="{Binding MediaInfoVisible}" />
<TextBlock Text="{Binding MediaScanText}" IsVisible="{Binding MediaScanVisible}" />
<TextBlock Text="{Binding PrintHexText}" IsVisible="{Binding PrintHexVisible}" />
<TextBlock Text="{Binding VerifyText}" IsVisible="{Binding VerifyVisible}" />
</StackPanel>
</TabItem>
<TabItem IsVisible="{Binding FiltersVisible}">
<TabItem.Header>
<TextBlock Text="{Binding FiltersLabel}" />
</TabItem.Header>
<DataGrid Items="{Binding Filters}" HorizontalScrollBarVisibility="Visible">
<DataGrid.Columns>
<!-- TODO: Bind header -->
<DataGridTextColumn Header="Filter" Binding="{Binding Name}" Width="Auto" IsReadOnly="True" />
<DataGridTextColumn Header="Times found" Binding="{Binding Count}" Width="Auto"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem IsVisible="{Binding FormatsVisible}">
<TabItem.Header>
<TextBlock Text="{Binding FormatsLabel}" />
</TabItem.Header>
<DataGrid Items="{Binding Formats}" HorizontalScrollBarVisibility="Visible">
<DataGrid.Columns>
<!-- TODO: Bind header -->
<DataGridTextColumn Header="Format" Binding="{Binding Name}" Width="Auto" IsReadOnly="True" />
<DataGridTextColumn Header="Times found" Binding="{Binding Count}" Width="Auto"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem IsVisible="{Binding PartitionsVisible}">
<TabItem.Header>
<TextBlock Text="{Binding PartitionsLabel}" />
</TabItem.Header>
<DataGrid Items="{Binding Partitions}" HorizontalScrollBarVisibility="Visible">
<DataGrid.Columns>
<!-- TODO: Bind header -->
<DataGridTextColumn Header="Partition" Binding="{Binding Name}" Width="Auto"
IsReadOnly="True" />
<DataGridTextColumn Header="Times found" Binding="{Binding Count}" Width="Auto"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem IsVisible="{Binding FilesystemsVisible}">
<TabItem.Header>
<TextBlock Text="{Binding FilesystemsLabel}" />
</TabItem.Header>
<DataGrid Items="{Binding Filesystems}" HorizontalScrollBarVisibility="Visible">
<DataGrid.Columns>
<!-- TODO: Bind header -->
<DataGridTextColumn Header="Filesystem" Binding="{Binding Name}" Width="Auto"
IsReadOnly="True" />
<DataGridTextColumn Header="Times found" Binding="{Binding Count}" Width="Auto"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem IsVisible="{Binding DevicesVisible}">
<TabItem.Header>
<TextBlock Text="{Binding DevicesLabel}" />
</TabItem.Header>
<DataGrid Items="{Binding Devices}" HorizontalScrollBarVisibility="Visible">
<DataGrid.Columns>
<!-- TODO: Bind header -->
<DataGridTextColumn Header="Device" Binding="{Binding Model}" Width="Auto"
IsReadOnly="True" />
<DataGridTextColumn Header="Manufacturer" Binding="{Binding Manufacturer}" Width="Auto"
IsReadOnly="True" />
<DataGridTextColumn Header="Revision" Binding="{Binding Revision}" Width="Auto"
IsReadOnly="True" />
<DataGridTextColumn Header="Bus" Binding="{Binding Bus}" Width="Auto" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem IsVisible="{Binding MediasVisible}">
<TabItem.Header>
<TextBlock Text="{Binding MediasLabel}" />
</TabItem.Header>
<DataGrid Items="{Binding Medias}" HorizontalScrollBarVisibility="Visible">
<DataGrid.Columns>
<!-- TODO: Bind header -->
<DataGridTextColumn Header="Media" Binding="{Binding Name}" Width="Auto" IsReadOnly="True" />
<DataGridTextColumn Header="Times found" Binding="{Binding Count}" Width="Auto"
IsReadOnly="True" />
<DataGridTextColumn Header="Type" Binding="{Binding Type}" Width="Auto" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</TabItem>
</TabControl>
<Button Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center"
Command="{Binding CloseCommand}" Padding="10">
<TextBlock Text="{Binding CloseLabel}" />
</Button>
</Grid>
</Border>
</Window>

View File

@@ -0,0 +1,19 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Aaru.Gui.Views
{
public class StatisticsDialog : Window
{
public StatisticsDialog()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
void InitializeComponent() => AvaloniaXamlLoader.Load(this);
}
}