2020-04-17 21:45:50 +01:00
|
|
|
// /***************************************************************************
|
|
|
|
|
// Aaru Data Preservation Suite
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Filename : MediaDumpViewModel.cs
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
//
|
|
|
|
|
// Component : GUI view models.
|
|
|
|
|
//
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// View model and code for the media dump 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/>.
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2022-12-03 16:07:10 +00:00
|
|
|
// Copyright © 2011-2023 Natalia Portillo
|
2020-04-17 21:45:50 +01:00
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
2020-04-16 19:28:39 +01:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
2022-11-14 01:38:50 +00:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2020-04-16 19:28:39 +01:00
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reactive;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
2022-03-26 16:52:00 +00:00
|
|
|
using System.Threading.Tasks;
|
2020-04-16 19:28:39 +01:00
|
|
|
using System.Xml.Serialization;
|
|
|
|
|
using Aaru.CommonTypes;
|
|
|
|
|
using Aaru.CommonTypes.Enums;
|
|
|
|
|
using Aaru.CommonTypes.Interfaces;
|
|
|
|
|
using Aaru.CommonTypes.Metadata;
|
|
|
|
|
using Aaru.Core;
|
|
|
|
|
using Aaru.Core.Devices.Dumping;
|
|
|
|
|
using Aaru.Core.Logging;
|
|
|
|
|
using Aaru.Core.Media.Info;
|
|
|
|
|
using Aaru.Devices;
|
|
|
|
|
using Aaru.Gui.Models;
|
2022-11-19 21:10:41 +00:00
|
|
|
using Aaru.Localization;
|
2020-04-16 19:28:39 +01:00
|
|
|
using Avalonia.Controls;
|
|
|
|
|
using Avalonia.Threading;
|
|
|
|
|
using DynamicData;
|
2020-07-22 13:20:25 +01:00
|
|
|
using JetBrains.Annotations;
|
2020-04-16 19:28:39 +01:00
|
|
|
using MessageBox.Avalonia;
|
|
|
|
|
using MessageBox.Avalonia.Enums;
|
|
|
|
|
using ReactiveUI;
|
|
|
|
|
using Schemas;
|
|
|
|
|
using DeviceInfo = Aaru.Core.Devices.Info.DeviceInfo;
|
|
|
|
|
using MediaType = Aaru.CommonTypes.MediaType;
|
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
namespace Aaru.Gui.ViewModels.Windows;
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public sealed class MediaDumpViewModel : ViewModelBase
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
readonly string _devicePath;
|
|
|
|
|
readonly Window _view;
|
|
|
|
|
bool _closeVisible;
|
|
|
|
|
string _destination;
|
|
|
|
|
bool _destinationEnabled;
|
|
|
|
|
Device _dev;
|
|
|
|
|
Dump _dumper;
|
|
|
|
|
string _encodingEnabled;
|
|
|
|
|
bool _encodingVisible;
|
|
|
|
|
bool _existingMetadata;
|
|
|
|
|
bool _force;
|
|
|
|
|
string _formatReadOnly;
|
|
|
|
|
string _log;
|
|
|
|
|
bool _optionsVisible;
|
|
|
|
|
string _outputPrefix;
|
|
|
|
|
bool _persistent;
|
|
|
|
|
bool _progress1Visible;
|
|
|
|
|
bool _progress2Indeterminate;
|
|
|
|
|
double _progress2MaxValue;
|
|
|
|
|
string _progress2Text;
|
|
|
|
|
double _progress2Value;
|
|
|
|
|
bool _progress2Visible;
|
|
|
|
|
bool _progressIndeterminate;
|
|
|
|
|
double _progressMaxValue;
|
|
|
|
|
string _progressText;
|
|
|
|
|
double _progressValue;
|
|
|
|
|
bool _progressVisible;
|
|
|
|
|
Resume _resume;
|
|
|
|
|
double _retries;
|
|
|
|
|
EncodingModel _selectedEncoding;
|
|
|
|
|
ImagePluginModel _selectedPlugin;
|
|
|
|
|
CICMMetadataType _sidecar;
|
|
|
|
|
double _skipped;
|
|
|
|
|
bool _startVisible;
|
|
|
|
|
bool _stopEnabled;
|
|
|
|
|
bool _stopOnError;
|
|
|
|
|
bool _stopVisible;
|
|
|
|
|
bool _track1Pregap;
|
|
|
|
|
bool _track1PregapVisible;
|
|
|
|
|
bool _trim;
|
|
|
|
|
bool _useResume;
|
|
|
|
|
bool _useSidecar;
|
|
|
|
|
|
|
|
|
|
public MediaDumpViewModel(string devicePath, DeviceInfo deviceInfo, Window view,
|
|
|
|
|
[CanBeNull] ScsiInfo scsiInfo = null)
|
|
|
|
|
{
|
|
|
|
|
_view = view;
|
|
|
|
|
DestinationEnabled = true;
|
|
|
|
|
StartVisible = true;
|
|
|
|
|
CloseVisible = true;
|
|
|
|
|
OptionsVisible = true;
|
|
|
|
|
StartCommand = ReactiveCommand.Create(ExecuteStartCommand);
|
|
|
|
|
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
|
|
|
|
StopCommand = ReactiveCommand.Create(ExecuteStopCommand);
|
|
|
|
|
DestinationCommand = ReactiveCommand.Create(ExecuteDestinationCommand);
|
|
|
|
|
PluginsList = new ObservableCollection<ImagePluginModel>();
|
|
|
|
|
Encodings = new ObservableCollection<EncodingModel>();
|
|
|
|
|
|
|
|
|
|
// Defaults
|
|
|
|
|
StopOnError = false;
|
|
|
|
|
Force = false;
|
|
|
|
|
Persistent = true;
|
|
|
|
|
Resume = true;
|
|
|
|
|
Track1Pregap = false;
|
|
|
|
|
Sidecar = true;
|
|
|
|
|
Trim = true;
|
|
|
|
|
ExistingMetadata = false;
|
|
|
|
|
Retries = 5;
|
|
|
|
|
Skipped = 512;
|
|
|
|
|
|
|
|
|
|
MediaType mediaType;
|
|
|
|
|
|
|
|
|
|
if(scsiInfo != null)
|
|
|
|
|
mediaType = scsiInfo.MediaType;
|
|
|
|
|
else
|
|
|
|
|
switch(deviceInfo.Type)
|
|
|
|
|
{
|
|
|
|
|
case DeviceType.SecureDigital:
|
|
|
|
|
mediaType = MediaType.SecureDigital;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case DeviceType.MMC:
|
|
|
|
|
mediaType = MediaType.MMC;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if(deviceInfo.IsPcmcia)
|
|
|
|
|
mediaType = MediaType.PCCardTypeII;
|
|
|
|
|
else if(deviceInfo.IsCompactFlash)
|
|
|
|
|
mediaType = MediaType.CompactFlash;
|
|
|
|
|
else
|
|
|
|
|
mediaType = MediaType.GENERIC_HDD;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
PluginBase plugins = GetPluginBase.Instance;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
foreach(IWritableImage plugin in
|
2020-04-16 19:28:39 +01:00
|
|
|
plugins.WritableImages.Values.Where(p => p.SupportedMediaTypes.Contains(mediaType)))
|
2022-03-06 13:29:38 +00:00
|
|
|
PluginsList.Add(new ImagePluginModel
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
Plugin = plugin
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Encodings.AddRange(Encoding.GetEncodings().Select(info => new EncodingModel
|
|
|
|
|
{
|
|
|
|
|
Name = info.Name,
|
|
|
|
|
DisplayName = info.GetEncoding().EncodingName
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
Encodings.AddRange(Claunia.Encoding.Encoding.GetEncodings().Select(info => new EncodingModel
|
|
|
|
|
{
|
|
|
|
|
Name = info.Name,
|
|
|
|
|
DisplayName = info.DisplayName
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
switch(mediaType)
|
|
|
|
|
{
|
|
|
|
|
case MediaType.CD:
|
|
|
|
|
case MediaType.CDDA:
|
|
|
|
|
case MediaType.CDG:
|
|
|
|
|
case MediaType.CDEG:
|
|
|
|
|
case MediaType.CDI:
|
|
|
|
|
case MediaType.CDROM:
|
|
|
|
|
case MediaType.CDROMXA:
|
|
|
|
|
case MediaType.CDPLUS:
|
|
|
|
|
case MediaType.CDMO:
|
|
|
|
|
case MediaType.CDR:
|
|
|
|
|
case MediaType.CDRW:
|
|
|
|
|
case MediaType.CDMRW:
|
|
|
|
|
case MediaType.VCD:
|
|
|
|
|
case MediaType.SVCD:
|
|
|
|
|
case MediaType.PCD:
|
|
|
|
|
case MediaType.DDCD:
|
|
|
|
|
case MediaType.DDCDR:
|
|
|
|
|
case MediaType.DDCDRW:
|
|
|
|
|
case MediaType.DTSCD:
|
|
|
|
|
case MediaType.CDMIDI:
|
|
|
|
|
case MediaType.CDV:
|
|
|
|
|
case MediaType.CDIREADY:
|
|
|
|
|
case MediaType.FMTOWNS:
|
|
|
|
|
case MediaType.PS1CD:
|
|
|
|
|
case MediaType.PS2CD:
|
|
|
|
|
case MediaType.MEGACD:
|
|
|
|
|
case MediaType.SATURNCD:
|
|
|
|
|
case MediaType.GDROM:
|
|
|
|
|
case MediaType.GDR:
|
|
|
|
|
case MediaType.MilCD:
|
|
|
|
|
case MediaType.SuperCDROM2:
|
|
|
|
|
case MediaType.JaguarCD:
|
|
|
|
|
case MediaType.ThreeDO:
|
|
|
|
|
case MediaType.PCFX:
|
|
|
|
|
case MediaType.NeoGeoCD:
|
|
|
|
|
case MediaType.CDTV:
|
|
|
|
|
case MediaType.CD32:
|
|
|
|
|
case MediaType.Playdia:
|
|
|
|
|
case MediaType.Pippin:
|
|
|
|
|
case MediaType.VideoNow:
|
|
|
|
|
case MediaType.VideoNowColor:
|
|
|
|
|
case MediaType.VideoNowXp:
|
|
|
|
|
case MediaType.CVD:
|
|
|
|
|
Track1PregapVisible = true;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
Track1PregapVisible = false;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_devicePath = devicePath;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-19 21:10:41 +00:00
|
|
|
public string OutputFormatLabel => UI.Output_format;
|
|
|
|
|
public string ChooseLabel => UI.ButtonLabel_Choose;
|
|
|
|
|
public string StopOnErrorLabel => UI.Stop_media_dump_on_first_error;
|
|
|
|
|
public string ForceLabel => UI.Continue_dumping_whatever_happens;
|
|
|
|
|
public string RetriesLabel => UI.Retry_passes;
|
|
|
|
|
public string PersistentLabel => UI.Try_to_recover_partial_or_incorrect_data;
|
|
|
|
|
public string ResumeLabel => UI.Create_use_resume_mapfile;
|
|
|
|
|
public string Track1PregapLabel => UI.Try_to_read_track_1_pregap;
|
|
|
|
|
public string SkippedLabel => UI.Skipped_sectors_on_error;
|
|
|
|
|
public string SidecarLabel => UI.Create_CICM_XML_metadata_sidecar;
|
|
|
|
|
public string TrimLabel => UI.Trim_errors_from_skipped_sectors;
|
|
|
|
|
public string ExistingMetadataLabel => UI.Take_metadata_from_existing_CICM_XML_sidecar;
|
|
|
|
|
public string EncodingLabel => UI.Encoding_to_use_on_metadata_sidecar_creation;
|
|
|
|
|
public string DestinationLabel => UI.Writing_image_to;
|
|
|
|
|
public string LogLabel => UI.Title_Log;
|
|
|
|
|
public string StartLabel => UI.ButtonLabel_Start;
|
|
|
|
|
public string CloseLabel => UI.ButtonLabel_Close;
|
|
|
|
|
public string StopLabel => UI.ButtonLabel_Stop;
|
2022-11-16 21:40:54 +00:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public ReactiveCommand<Unit, Unit> StartCommand { get; }
|
|
|
|
|
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
|
|
|
|
public ReactiveCommand<Unit, Unit> StopCommand { get; }
|
2022-03-26 16:52:00 +00:00
|
|
|
public ReactiveCommand<Unit, Task> DestinationCommand { get; }
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public ObservableCollection<ImagePluginModel> PluginsList { get; }
|
|
|
|
|
public ObservableCollection<EncodingModel> Encodings { get; }
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public string Title { get; }
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool OptionsVisible
|
|
|
|
|
{
|
|
|
|
|
get => _optionsVisible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _optionsVisible, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ImagePluginModel SelectedPlugin
|
|
|
|
|
{
|
|
|
|
|
get => _selectedPlugin;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this.RaiseAndSetIfChanged(ref _selectedPlugin, value);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Destination = "";
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(value is null)
|
|
|
|
|
{
|
|
|
|
|
DestinationEnabled = false;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
DestinationEnabled = true;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(!value.Plugin.SupportedOptions.Any())
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
// Hide options
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/* TODO: Plugin options
|
|
|
|
|
grpOptions.Visible = true;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var stkOptions = new StackLayout
|
|
|
|
|
{
|
|
|
|
|
Orientation = Orientation.Vertical
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach((string name, Type type, string description, object @default) option in plugin.SupportedOptions)
|
|
|
|
|
switch(option.type.ToString())
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
case "System.Boolean":
|
|
|
|
|
var optBoolean = new CheckBox();
|
|
|
|
|
optBoolean.ID = "opt" + option.name;
|
|
|
|
|
optBoolean.Text = option.description;
|
|
|
|
|
optBoolean.Checked = (bool)option.@default;
|
|
|
|
|
stkOptions.Items.Add(optBoolean);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case "System.SByte":
|
|
|
|
|
case "System.Int16":
|
|
|
|
|
case "System.Int32":
|
|
|
|
|
case "System.Int64":
|
|
|
|
|
var stkNumber = new StackLayout();
|
|
|
|
|
stkNumber.Orientation = Orientation.Horizontal;
|
|
|
|
|
var optNumber = new NumericStepper();
|
|
|
|
|
optNumber.ID = "opt" + option.name;
|
|
|
|
|
optNumber.Value = Convert.ToDouble(option.@default);
|
|
|
|
|
stkNumber.Items.Add(optNumber);
|
|
|
|
|
var lblNumber = new Label();
|
|
|
|
|
lblNumber.Text = option.description;
|
|
|
|
|
stkNumber.Items.Add(lblNumber);
|
|
|
|
|
stkOptions.Items.Add(stkNumber);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case "System.Byte":
|
|
|
|
|
case "System.UInt16":
|
|
|
|
|
case "System.UInt32":
|
|
|
|
|
case "System.UInt64":
|
|
|
|
|
var stkUnsigned = new StackLayout();
|
|
|
|
|
stkUnsigned.Orientation = Orientation.Horizontal;
|
|
|
|
|
var optUnsigned = new NumericStepper();
|
|
|
|
|
optUnsigned.ID = "opt" + option.name;
|
|
|
|
|
optUnsigned.MinValue = 0;
|
|
|
|
|
optUnsigned.Value = Convert.ToDouble(option.@default);
|
|
|
|
|
stkUnsigned.Items.Add(optUnsigned);
|
|
|
|
|
var lblUnsigned = new Label();
|
|
|
|
|
lblUnsigned.Text = option.description;
|
|
|
|
|
stkUnsigned.Items.Add(lblUnsigned);
|
|
|
|
|
stkOptions.Items.Add(stkUnsigned);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case "System.Single":
|
|
|
|
|
case "System.Double":
|
|
|
|
|
var stkFloat = new StackLayout();
|
|
|
|
|
stkFloat.Orientation = Orientation.Horizontal;
|
|
|
|
|
var optFloat = new NumericStepper();
|
|
|
|
|
optFloat.ID = "opt" + option.name;
|
|
|
|
|
optFloat.DecimalPlaces = 2;
|
|
|
|
|
optFloat.Value = Convert.ToDouble(option.@default);
|
|
|
|
|
stkFloat.Items.Add(optFloat);
|
|
|
|
|
var lblFloat = new Label();
|
|
|
|
|
lblFloat.Text = option.description;
|
|
|
|
|
stkFloat.Items.Add(lblFloat);
|
|
|
|
|
stkOptions.Items.Add(stkFloat);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case "System.Guid":
|
|
|
|
|
// TODO
|
|
|
|
|
break;
|
|
|
|
|
case "System.String":
|
|
|
|
|
var stkString = new StackLayout();
|
|
|
|
|
stkString.Orientation = Orientation.Horizontal;
|
|
|
|
|
var lblString = new Label();
|
|
|
|
|
lblString.Text = option.description;
|
|
|
|
|
stkString.Items.Add(lblString);
|
|
|
|
|
var optString = new TextBox();
|
|
|
|
|
optString.ID = "opt" + option.name;
|
|
|
|
|
optString.Text = (string)option.@default;
|
|
|
|
|
stkString.Items.Add(optString);
|
|
|
|
|
stkOptions.Items.Add(stkString);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
grpOptions.Content = stkOptions;
|
|
|
|
|
*/
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public string FormatReadOnly
|
|
|
|
|
{
|
|
|
|
|
get => _formatReadOnly;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _formatReadOnly, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public string Destination
|
|
|
|
|
{
|
|
|
|
|
get => _destination;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _destination, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool DestinationEnabled
|
|
|
|
|
{
|
|
|
|
|
get => _destinationEnabled;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _destinationEnabled, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool StopOnError
|
|
|
|
|
{
|
|
|
|
|
get => _stopOnError;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _stopOnError, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Force
|
|
|
|
|
{
|
|
|
|
|
get => _force;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _force, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public double Retries
|
|
|
|
|
{
|
|
|
|
|
get => _retries;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _retries, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool Persistent
|
|
|
|
|
{
|
|
|
|
|
get => _persistent;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _persistent, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Resume
|
|
|
|
|
{
|
|
|
|
|
get => _useResume;
|
|
|
|
|
set
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
this.RaiseAndSetIfChanged(ref _useResume, value);
|
|
|
|
|
|
2022-11-15 01:35:06 +00:00
|
|
|
if(!value)
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if(_outputPrefix != null)
|
2022-11-15 01:35:06 +00:00
|
|
|
CheckResumeFile().GetAwaiter().GetResult();
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Track1Pregap
|
|
|
|
|
{
|
|
|
|
|
get => _track1Pregap;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _track1Pregap, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Track1PregapVisible
|
|
|
|
|
{
|
|
|
|
|
get => _track1PregapVisible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _track1PregapVisible, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public double Skipped
|
|
|
|
|
{
|
|
|
|
|
get => _skipped;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _skipped, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool Sidecar
|
|
|
|
|
{
|
|
|
|
|
get => _useSidecar;
|
|
|
|
|
set
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
this.RaiseAndSetIfChanged(ref _useSidecar, value);
|
|
|
|
|
EncodingVisible = value;
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool EncodingVisible
|
|
|
|
|
{
|
|
|
|
|
get => _encodingVisible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _encodingVisible, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Trim
|
|
|
|
|
{
|
|
|
|
|
get => _trim;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _trim, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool ExistingMetadata
|
|
|
|
|
{
|
|
|
|
|
get => _existingMetadata;
|
|
|
|
|
set
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
this.RaiseAndSetIfChanged(ref _existingMetadata, value);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(value == false)
|
|
|
|
|
{
|
|
|
|
|
_sidecar = null;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var dlgMetadata = new OpenFileDialog
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
Title = UI.Dialog_Choose_existing_metadata_sidecar
|
2022-03-06 13:29:38 +00:00
|
|
|
};
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-15 01:35:06 +00:00
|
|
|
dlgMetadata.Filters?.Add(new FileDialogFilter
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
Name = UI.Dialog_CICM_XML_metadata,
|
2022-03-06 13:29:38 +00:00
|
|
|
Extensions = new List<string>(new[]
|
|
|
|
|
{
|
|
|
|
|
".xml"
|
|
|
|
|
})
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
string[] result = dlgMetadata.ShowAsync(_view).Result;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(result?.Length != 1)
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
ExistingMetadata = false;
|
|
|
|
|
|
|
|
|
|
return;
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var sidecarXs = new XmlSerializer(typeof(CICMMetadataType));
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var sr = new StreamReader(result[0]);
|
|
|
|
|
_sidecar = (CICMMetadataType)sidecarXs.Deserialize(sr);
|
|
|
|
|
sr.Close();
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
// ReSharper disable AssignmentIsFullyDiscarded
|
|
|
|
|
_ = MessageBoxManager.
|
|
|
|
|
|
|
|
|
|
// ReSharper restore AssignmentIsFullyDiscarded
|
2022-11-19 21:10:41 +00:00
|
|
|
GetMessageBoxStandardWindow(UI.Title_Error, UI.Incorrect_metadata_sidecar_file, ButtonEnum.Ok,
|
2022-03-06 13:29:38 +00:00
|
|
|
Icon.Error).ShowDialog(_view).Result;
|
|
|
|
|
|
|
|
|
|
ExistingMetadata = false;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public EncodingModel SelectedEncoding
|
|
|
|
|
{
|
|
|
|
|
get => _selectedEncoding;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _selectedEncoding, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public string EncodingEnabled
|
|
|
|
|
{
|
|
|
|
|
get => _encodingEnabled;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _encodingEnabled, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool ProgressVisible
|
|
|
|
|
{
|
|
|
|
|
get => _progressVisible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public string Log
|
|
|
|
|
{
|
|
|
|
|
get => _log;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _log, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool Progress1Visible
|
|
|
|
|
{
|
|
|
|
|
get => _progress1Visible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progress1Visible, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public string ProgressText
|
|
|
|
|
{
|
|
|
|
|
get => _progressText;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progressText, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public double ProgressValue
|
|
|
|
|
{
|
|
|
|
|
get => _progressValue;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progressValue, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public double ProgressMaxValue
|
|
|
|
|
{
|
|
|
|
|
get => _progressMaxValue;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progressMaxValue, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool ProgressIndeterminate
|
|
|
|
|
{
|
|
|
|
|
get => _progressIndeterminate;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progressIndeterminate, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool Progress2Visible
|
|
|
|
|
{
|
|
|
|
|
get => _progress2Visible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progress2Visible, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public string Progress2Text
|
|
|
|
|
{
|
|
|
|
|
get => _progress2Text;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progress2Text, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public double Progress2Value
|
|
|
|
|
{
|
|
|
|
|
get => _progress2Value;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progress2Value, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public double Progress2MaxValue
|
|
|
|
|
{
|
|
|
|
|
get => _progress2MaxValue;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progress2MaxValue, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool Progress2Indeterminate
|
|
|
|
|
{
|
|
|
|
|
get => _progress2Indeterminate;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _progress2Indeterminate, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool StartVisible
|
|
|
|
|
{
|
|
|
|
|
get => _startVisible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _startVisible, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool CloseVisible
|
|
|
|
|
{
|
|
|
|
|
get => _closeVisible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _closeVisible, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool StopVisible
|
|
|
|
|
{
|
|
|
|
|
get => _stopVisible;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _stopVisible, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
public bool StopEnabled
|
|
|
|
|
{
|
|
|
|
|
get => _stopEnabled;
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _stopEnabled, value);
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-26 16:52:00 +00:00
|
|
|
async Task ExecuteDestinationCommand()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
if(SelectedPlugin is null)
|
|
|
|
|
return;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var dlgDestination = new SaveFileDialog
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
Title = UI.Dialog_Choose_destination_file
|
2022-03-06 13:29:38 +00:00
|
|
|
};
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-15 01:35:06 +00:00
|
|
|
dlgDestination.Filters?.Add(new FileDialogFilter
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
Name = SelectedPlugin.Plugin.Name,
|
|
|
|
|
Extensions = SelectedPlugin.Plugin.KnownExtensions.ToList()
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
string result = await dlgDestination.ShowAsync(_view);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(result is null)
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
Destination = "";
|
|
|
|
|
_outputPrefix = null;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(string.IsNullOrEmpty(Path.GetExtension(result)))
|
|
|
|
|
result += SelectedPlugin.Plugin.KnownExtensions.First();
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Destination = result;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_outputPrefix = Path.Combine(Path.GetDirectoryName(result) ?? "", Path.GetFileNameWithoutExtension(result));
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Resume = true;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-26 16:52:00 +00:00
|
|
|
async Task CheckResumeFile()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
_resume = null;
|
|
|
|
|
var xs = new XmlSerializer(typeof(Resume));
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
try
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
var sr = new StreamReader(_outputPrefix + ".resume.xml");
|
|
|
|
|
_resume = (Resume)xs.Deserialize(sr);
|
|
|
|
|
sr.Close();
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
catch
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
await MessageBoxManager.
|
2022-11-19 21:10:41 +00:00
|
|
|
GetMessageBoxStandardWindow(UI.Title_Error, UI.Incorrect_resume_file_cannot_use_it, ButtonEnum.Ok,
|
2022-03-06 13:29:38 +00:00
|
|
|
Icon.Error).ShowDialog(_view);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Resume = false;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(_resume == null ||
|
|
|
|
|
_resume.NextBlock <= _resume.LastBlock ||
|
2022-11-15 15:58:43 +00:00
|
|
|
(_resume.BadBlocks.Count != 0 && !_resume.Tape))
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
await MessageBoxManager.
|
2022-11-19 21:10:41 +00:00
|
|
|
GetMessageBoxStandardWindow(UI.Title_Warning,
|
|
|
|
|
UI.Media_already_dumped_correctly_please_choose_another_destination,
|
2022-03-06 13:29:38 +00:00
|
|
|
ButtonEnum.Ok, Icon.Warning).ShowDialog(_view);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Resume = false;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
void ExecuteCloseCommand() => _view.Close();
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
internal void ExecuteStopCommand()
|
|
|
|
|
{
|
|
|
|
|
StopEnabled = false;
|
|
|
|
|
_dumper?.Abort();
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
void ExecuteStartCommand()
|
|
|
|
|
{
|
|
|
|
|
Log = "";
|
|
|
|
|
CloseVisible = false;
|
|
|
|
|
StartVisible = false;
|
|
|
|
|
StopVisible = true;
|
|
|
|
|
StopEnabled = true;
|
|
|
|
|
ProgressVisible = true;
|
|
|
|
|
DestinationEnabled = false;
|
|
|
|
|
OptionsVisible = false;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-19 21:10:41 +00:00
|
|
|
UpdateStatus(UI.Opening_device);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-26 20:18:01 +00:00
|
|
|
_dev = Device.Create(_devicePath, out ErrorNumber devErrno);
|
|
|
|
|
|
|
|
|
|
switch(_dev)
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-26 20:18:01 +00:00
|
|
|
case null:
|
2022-11-19 21:10:41 +00:00
|
|
|
StoppingErrorMessage(string.Format(UI.Error_0_opening_device, devErrno));
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-26 20:18:01 +00:00
|
|
|
return;
|
|
|
|
|
case Devices.Remote.Device remoteDev:
|
2022-03-26 19:35:13 +00:00
|
|
|
Statistics.AddRemote(remoteDev.RemoteApplication, remoteDev.RemoteVersion,
|
|
|
|
|
remoteDev.RemoteOperatingSystem, remoteDev.RemoteOperatingSystemVersion,
|
|
|
|
|
remoteDev.RemoteArchitecture);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-26 20:18:01 +00:00
|
|
|
break;
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2022-03-26 20:18:01 +00:00
|
|
|
|
|
|
|
|
if(_dev.Error)
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
StoppingErrorMessage(string.Format(UI.Error_0_opening_device, _dev.LastError));
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Statistics.AddDevice(_dev);
|
|
|
|
|
Statistics.AddCommand("dump-media");
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(SelectedPlugin is null)
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
StoppingErrorMessage(UI.Cannot_open_output_plugin);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
Encoding encoding = null;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:20:28 +00:00
|
|
|
if(SelectedEncoding is not null)
|
2020-04-16 19:28:39 +01:00
|
|
|
try
|
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
encoding = Claunia.Encoding.Encoding.GetEncoding(SelectedEncoding.Name);
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
catch(ArgumentException)
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
StoppingErrorMessage(UI.Specified_encoding_is_not_supported);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
Dictionary<string, string> parsedOptions = new();
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/* TODO: Options
|
|
|
|
|
if(grpOptions.Content is StackLayout stkFormatOptions)
|
|
|
|
|
foreach(Control option in stkFormatOptions.Children)
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
string value;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
switch(option)
|
2020-04-16 19:28:39 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
case CheckBox optBoolean:
|
|
|
|
|
value = optBoolean.Checked?.ToString();
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case NumericStepper optNumber:
|
|
|
|
|
value = optNumber.Value.ToString(CultureInfo.CurrentCulture);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
case TextBox optString:
|
|
|
|
|
value = optString.Text;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
break;
|
|
|
|
|
default: continue;
|
|
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
string key = option.ID.Substring(3);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
parsedOptions.Add(key, value);
|
|
|
|
|
}
|
|
|
|
|
*/
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var dumpLog = new DumpLog(_outputPrefix + ".log", _dev, false);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-19 21:10:41 +00:00
|
|
|
dumpLog.WriteLine(UI.Output_image_format_0, SelectedPlugin.Name);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
var errorLog = new ErrorLog(_outputPrefix + ".error.log");
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-07 07:36:44 +00:00
|
|
|
_dumper = new Dump(Resume, _dev, _devicePath, SelectedPlugin.Plugin, (ushort)Retries, Force, false, Persistent,
|
|
|
|
|
StopOnError, _resume, dumpLog, encoding, _outputPrefix, Destination, parsedOptions, _sidecar,
|
|
|
|
|
(uint)Skipped, ExistingMetadata == false, Trim == false, Track1Pregap, true, false,
|
|
|
|
|
DumpSubchannel.Any, 0, false, false, false, false, false, true, errorLog, false, 64, true,
|
2022-04-14 13:11:48 +01:00
|
|
|
true, false, 10);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
new Thread(DoWork).Start();
|
|
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-26 16:52:00 +00:00
|
|
|
async void DoWork()
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
_dumper.UpdateStatus += UpdateStatus;
|
|
|
|
|
_dumper.ErrorMessage += ErrorMessage;
|
|
|
|
|
_dumper.StoppingErrorMessage += StoppingErrorMessage;
|
|
|
|
|
_dumper.PulseProgress += PulseProgress;
|
|
|
|
|
_dumper.InitProgress += InitProgress;
|
|
|
|
|
_dumper.UpdateProgress += UpdateProgress;
|
|
|
|
|
_dumper.EndProgress += EndProgress;
|
|
|
|
|
_dumper.InitProgress2 += InitProgress2;
|
|
|
|
|
_dumper.UpdateProgress2 += UpdateProgress2;
|
|
|
|
|
_dumper.EndProgress2 += EndProgress2;
|
|
|
|
|
|
|
|
|
|
_dumper.Start();
|
|
|
|
|
|
|
|
|
|
_dev.Close();
|
|
|
|
|
|
2022-03-26 16:52:00 +00:00
|
|
|
await WorkFinished();
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-26 16:52:00 +00:00
|
|
|
async Task WorkFinished() => await Dispatcher.UIThread.InvokeAsync(() =>
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
CloseVisible = true;
|
|
|
|
|
StopVisible = false;
|
|
|
|
|
Progress1Visible = false;
|
|
|
|
|
Progress2Visible = false;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void EndProgress2() => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Progress2Visible = false;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-07 07:36:44 +00:00
|
|
|
async void UpdateProgress2(string text, long current, long maximum) => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Progress2Text = text;
|
|
|
|
|
Progress2Indeterminate = false;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-07 07:36:44 +00:00
|
|
|
Progress2MaxValue = maximum;
|
|
|
|
|
Progress2Value = current;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void InitProgress2() => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Progress2Visible = true;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void EndProgress() => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Progress1Visible = false;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-07 07:36:44 +00:00
|
|
|
async void UpdateProgress(string text, long current, long maximum) => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
ProgressText = text;
|
|
|
|
|
ProgressIndeterminate = false;
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-07 07:36:44 +00:00
|
|
|
ProgressMaxValue = maximum;
|
|
|
|
|
ProgressValue = current;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void InitProgress() => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Progress1Visible = true;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void PulseProgress(string text) => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
ProgressText = text;
|
|
|
|
|
ProgressIndeterminate = true;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void StoppingErrorMessage(string text) => await Dispatcher.UIThread.InvokeAsync(async () =>
|
|
|
|
|
{
|
|
|
|
|
ErrorMessage(text);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-19 21:10:41 +00:00
|
|
|
await MessageBoxManager.GetMessageBoxStandardWindow(UI.Title_Error, $"{text}", ButtonEnum.Ok, Icon.Error).
|
2022-03-06 13:29:38 +00:00
|
|
|
ShowDialog(_view);
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-03-26 16:52:00 +00:00
|
|
|
await WorkFinished();
|
2022-03-06 13:29:38 +00:00
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void ErrorMessage(string text) => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Log += text + Environment.NewLine;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
|
2022-11-14 01:38:50 +00:00
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
async void UpdateStatus(string text) => await Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
|
|
{
|
|
|
|
|
Log += text + Environment.NewLine;
|
|
|
|
|
});
|
2020-04-16 19:28:39 +01:00
|
|
|
}
|