mirror of
https://github.com/SabreTools/MPF.git
synced 2026-07-02 17:24:48 +00:00
8
DICUI.Avalonia/App.axaml
Normal file
8
DICUI.Avalonia/App.axaml
Normal file
@@ -0,0 +1,8 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="DICUI.Avalonia.App">
|
||||
<Application.Styles>
|
||||
<StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/>
|
||||
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
24
DICUI.Avalonia/App.axaml.cs
Normal file
24
DICUI.Avalonia/App.axaml.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.MainWindow = new MainWindow();
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
29
DICUI.Avalonia/ComboBoxItems/CategoryComboBoxItem.cs
Normal file
29
DICUI.Avalonia/ComboBoxItems/CategoryComboBoxItem.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using DICUI.Utilities;
|
||||
using DICUI.Web;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single item in the Category combo box
|
||||
/// </summary>
|
||||
public class CategoryComboBoxItem
|
||||
{
|
||||
private object data;
|
||||
|
||||
public CategoryComboBoxItem(DiscCategory? category) => data = category;
|
||||
|
||||
public static implicit operator DiscCategory? (CategoryComboBoxItem item) => item.data as DiscCategory?;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return (data as DiscCategory?).LongName(); }
|
||||
}
|
||||
|
||||
public bool IsChecked { get; set; }
|
||||
|
||||
public DiscCategory? Value
|
||||
{
|
||||
get { return data as DiscCategory?; }
|
||||
}
|
||||
}
|
||||
}
|
||||
35
DICUI.Avalonia/ComboBoxItems/KnownSystemComboBoxItem.cs
Normal file
35
DICUI.Avalonia/ComboBoxItems/KnownSystemComboBoxItem.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Avalonia.Media;
|
||||
using DICUI.Data;
|
||||
using DICUI.Utilities;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single item in the System combo box
|
||||
/// </summary>
|
||||
public class KnownSystemComboBoxItem
|
||||
{
|
||||
private object data;
|
||||
|
||||
public KnownSystemComboBoxItem(KnownSystem? system) => data = system;
|
||||
public KnownSystemComboBoxItem(KnownSystemCategory? category) => data = category;
|
||||
|
||||
public ISolidColorBrush Foreground { get => IsHeader() ? Brushes.Gray : Brushes.Black; }
|
||||
|
||||
public bool IsHeader() => data is KnownSystemCategory?;
|
||||
public bool IsSystem() => data is KnownSystem?;
|
||||
|
||||
public static implicit operator KnownSystem? (KnownSystemComboBoxItem item) => item.data as KnownSystem?;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsHeader())
|
||||
return "---------- " + (data as KnownSystemCategory?).LongName() + " ----------";
|
||||
else
|
||||
return (data as KnownSystem?).LongName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
DICUI.Avalonia/ComboBoxItems/LanguageComboBoxItem.cs
Normal file
29
DICUI.Avalonia/ComboBoxItems/LanguageComboBoxItem.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using DICUI.Utilities;
|
||||
using DICUI.Web;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single item in the Language combo box
|
||||
/// </summary>
|
||||
public class LanguageComboBoxItem
|
||||
{
|
||||
private object data;
|
||||
|
||||
public LanguageComboBoxItem(Language? region) => data = region;
|
||||
|
||||
public static implicit operator Language? (LanguageComboBoxItem item) => item.data as Language?;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return (data as Language?).LongName(); }
|
||||
}
|
||||
|
||||
public bool IsChecked { get; set; }
|
||||
|
||||
public Language? Value
|
||||
{
|
||||
get { return data as Language?; }
|
||||
}
|
||||
}
|
||||
}
|
||||
20
DICUI.Avalonia/ComboBoxItems/MediaTypeComboBoxItem.cs
Normal file
20
DICUI.Avalonia/ComboBoxItems/MediaTypeComboBoxItem.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using DICUI.Data;
|
||||
using DICUI.Utilities;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single item in the MediaType combo box
|
||||
/// </summary>
|
||||
public class MediaTypeComboBoxItem
|
||||
{
|
||||
private MediaType? data;
|
||||
|
||||
public MediaTypeComboBoxItem(MediaType? mediaType) => data = mediaType;
|
||||
|
||||
public static implicit operator MediaType? (MediaTypeComboBoxItem item) => item.data;
|
||||
|
||||
public string Name { get { return data.LongName(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
30
DICUI.Avalonia/ComboBoxItems/RegionComboBoxItem.cs
Normal file
30
DICUI.Avalonia/ComboBoxItems/RegionComboBoxItem.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using DICUI.Utilities;
|
||||
using DICUI.Web;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single item in the Region combo box
|
||||
/// </summary>
|
||||
public class RegionComboBoxItem
|
||||
{
|
||||
private object data;
|
||||
|
||||
public RegionComboBoxItem(Region? region) => data = region;
|
||||
|
||||
public static implicit operator Region? (RegionComboBoxItem item) => item.data as Region?;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return (data as Region?).LongName();
|
||||
}
|
||||
}
|
||||
|
||||
public Region? Value
|
||||
{
|
||||
get { return data as Region?; }
|
||||
}
|
||||
}
|
||||
}
|
||||
55
DICUI.Avalonia/Constants.cs
Normal file
55
DICUI.Avalonia/Constants.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DICUI.Data;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
/// <summary>
|
||||
/// Variables for UI elements
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
public const string StartDumping = "Start Dumping";
|
||||
public const string StopDumping = "Stop Dumping";
|
||||
|
||||
public const int LogWindowMarginFromMainWindow = 40;
|
||||
|
||||
// Private lists of known drive speed ranges
|
||||
private static IReadOnlyList<int> cd { get; } = new List<int> { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 };
|
||||
private static IReadOnlyList<int> dvd { get; } = cd.Where(s => s <= 24).ToList();
|
||||
private static IReadOnlyList<int> bd { get; } = cd.Where(s => s <= 16).ToList();
|
||||
private static IReadOnlyList<int> unknown { get; } = cd; // TODO: All or {1}? Maybe null?
|
||||
|
||||
/// <summary>
|
||||
/// Get list of all drive speeds for a given MediaType
|
||||
/// </summary>
|
||||
/// <param name="type">MediaType? that represents the current item</param>
|
||||
/// <returns>Read-only list of drive speeds</returns>
|
||||
public static IReadOnlyList<int> GetSpeedsForMediaType(MediaType? type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MediaType.CDROM:
|
||||
case MediaType.GDROM:
|
||||
return cd;
|
||||
case MediaType.DVD:
|
||||
case MediaType.HDDVD:
|
||||
case MediaType.NintendoGameCubeGameDisc:
|
||||
case MediaType.NintendoWiiOpticalDisc:
|
||||
return dvd;
|
||||
case MediaType.BluRay:
|
||||
return bd;
|
||||
default:
|
||||
return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
// Create collections for UI based on known drive speeds
|
||||
public static List<double> SpeedsForCDAsCollection { get; } = GetDoubleCollectionFromIntList(cd);
|
||||
public static List<double> SpeedsForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(dvd);
|
||||
public static List<double> SpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(bd);
|
||||
private static List<double> GetDoubleCollectionFromIntList(IReadOnlyList<int> list)
|
||||
=> new List<double>(list.Select(i => Convert.ToDouble(i)).ToList());
|
||||
}
|
||||
}
|
||||
36
DICUI.Avalonia/DICUI.Avalonia.csproj
Normal file
36
DICUI.Avalonia/DICUI.Avalonia.csproj
Normal file
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||
<Version>1.16.1</Version>
|
||||
<Copyright>Copyright © 2020</Copyright>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.9.12" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.9.12" />
|
||||
<PackageReference Include="BurnOutSharp" Version="1.3.9.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="DiscInformationWindow.axaml.cs">
|
||||
<DependentUpon>DiscInformationWindow.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="LogWindow.axaml.cs">
|
||||
<DependentUpon>LogWindow.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="MainWindow.axaml.cs">
|
||||
<DependentUpon>MainWindow.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="OptionsWindow.axaml.cs">
|
||||
<DependentUpon>OptionsWindow.axaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Icon.ico" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
120
DICUI.Avalonia/DiscInformationWindow.axaml
Normal file
120
DICUI.Avalonia/DiscInformationWindow.axaml
Normal file
@@ -0,0 +1,120 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="515.132" d:DesignHeight="705" Width="515.132" Height="705"
|
||||
x:Class="DICUI.Avalonia.DiscInformationWindow" Icon="Icon.ico" CanResize="False"
|
||||
Title="Disc Information" Closed="OnClosed">
|
||||
|
||||
<Grid RowDefinitions="585,80,25">
|
||||
|
||||
<!-- Common Disc Information -->
|
||||
<Border Grid.Row="0" Margin="5" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="Common Disc Information" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="0" Margin="10,15,10,10" ColumnDefinitions="1*,1*" RowDefinitions="1*,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25">
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Title" />
|
||||
<TextBox Name="TitleTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Foreign Title (Non-Latin)" />
|
||||
<TextBox Name="ForeignTitleTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Disc Number / Letter" />
|
||||
<TextBox Name="DiscNumberLetterTextBox" Grid.Row="3" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Disc Title" />
|
||||
<TextBox Name="DiscTitleTextBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Category" />
|
||||
<ComboBox Name="CategoryComboBox" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=Name}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Region" />
|
||||
<ComboBox Name="RegionComboBox" Grid.Row="6" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=Name}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Languages" />
|
||||
<ComboBox Name="LanguagesComboBox" Grid.Row="7" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Name}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Serial" />
|
||||
<TextBox Name="SerialTextBox" Grid.Row="8" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<!-- Layer 0 / Data Side -->
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Data/L0 Mastering Ring" />
|
||||
<TextBox Name="L0MasteringRingTextBox" Grid.Row="9" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" AcceptsTab="True" />
|
||||
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Data/L0 Mastering SID" />
|
||||
<TextBox Name="L0MasteringSIDTextBox" Grid.Row="10" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Data/L0 Toolstamp/Mastering Code" />
|
||||
<TextBox Name="L0ToolstampTextBox" Grid.Row="11" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Data/L0 Mould SID" />
|
||||
<TextBox Name="L0MouldSIDTextBox" Grid.Row="12" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="13" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Data/L0 Additional Mould" />
|
||||
<TextBox Name="L0AdditionalMouldTextBox" Grid.Row="13" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<!-- Layer 1 / Label Side -->
|
||||
<TextBlock Grid.Row="14" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Label/L1 Mastering Ring" />
|
||||
<TextBox Name="L1MasteringRingTextBox" Grid.Row="14" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" AcceptsTab="True" />
|
||||
|
||||
<TextBlock Grid.Row="15" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Label/L1 Mastering SID" />
|
||||
<TextBox Name="L1MasteringSIDTextBox" Grid.Row="15" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="16" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Label/L1 Toolstamp/Mastering Code" />
|
||||
<TextBox Name="L1ToolstampTextBox" Grid.Row="16" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="17" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Label/L1 Mould SID" />
|
||||
<TextBox Name="L1MouldSIDTextBox" Grid.Row="17" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="18" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Label/L1 Additional Mould" />
|
||||
<TextBox Name="L1AdditionalMouldTextBox" Grid.Row="18" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="19" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Barcode" />
|
||||
<TextBox Name="BarcodeTextBox" Grid.Row="19" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<!-- This needs to be a multiline textbox -->
|
||||
<TextBlock Grid.Row="20" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Comments" />
|
||||
<TextBox Name="CommentsTextBox" Grid.Row="20" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True" />
|
||||
|
||||
<!-- This needs to be a multiline textbox -->
|
||||
<TextBlock Grid.Row="21" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Contents" />
|
||||
<TextBox Name="ContentsTextBox" Grid.Row="21" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Version and Editions -->
|
||||
<Border Grid.Row="1" Margin="5" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="Version and Editions" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="1" Margin="10,15,10,10" ColumnDefinitions="1*,1*" RowDefinitions="25,25">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Version" />
|
||||
<TextBox Name="VersionTextBox" Grid.Row="0" Grid.Column="1" Height="25" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Edition" />
|
||||
<TextBox Name="EditionTextBox" Grid.Row="1" Grid.Column="1" Height="25" HorizontalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
</Grid>
|
||||
|
||||
<!-- Accept / Cancel -->
|
||||
<Grid Height="25" Grid.Row="2" Grid.Column="0" ColumnDefinitions="2*,1*,1*">
|
||||
<Button Name="AcceptButton" Grid.Row="0" Grid.Column="1" Height="25" Width="80" Content="Accept" Click="OnAcceptClick" />
|
||||
<Button Name="CancelButton" Grid.Row="0" Grid.Column="2" Height="25" Width="80" Content="Cancel" Click="OnCancelClick" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
264
DICUI.Avalonia/DiscInformationWindow.axaml.cs
Normal file
264
DICUI.Avalonia/DiscInformationWindow.axaml.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
using DICUI.Web;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public class DiscInformationWindow : Window
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// List of available disc categories
|
||||
/// </summary>
|
||||
public List<CategoryComboBoxItem> Categories { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// SubmissionInfo object to fill and save
|
||||
/// </summary>
|
||||
public SubmissionInfo SubmissionInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of available regions
|
||||
/// </summary>
|
||||
public List<RegionComboBoxItem> Regions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of available languages
|
||||
/// </summary>
|
||||
public List<LanguageComboBoxItem> Languages { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
public DiscInformationWindow()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
PopulateCategories();
|
||||
PopulateRegions();
|
||||
PopulateLanguages();
|
||||
DisableFieldsIfNeeded();
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Disable fields that aren't applicable to the current disc
|
||||
/// </summary>
|
||||
private void DisableFieldsIfNeeded()
|
||||
{
|
||||
// Only disable for single-layer discs
|
||||
if (SubmissionInfo.SizeAndChecksums?.Layerbreak == default(long))
|
||||
{
|
||||
this.Find<TextBox>("L1MasteringRingTextBox").IsEnabled = false;
|
||||
this.Find<TextBox>("L1MasteringRingTextBox").Background = Brushes.Gray;
|
||||
|
||||
this.Find<TextBox>("L1MasteringSIDTextBox").IsEnabled = false;
|
||||
this.Find<TextBox>("L1MasteringSIDTextBox").Background = Brushes.Gray;
|
||||
|
||||
this.Find<TextBox>("L1ToolstampTextBox").IsEnabled = false;
|
||||
this.Find<TextBox>("L1ToolstampTextBox").Background = Brushes.Gray;
|
||||
|
||||
this.Find<TextBox>("L1MouldSIDTextBox").IsEnabled = false;
|
||||
this.Find<TextBox>("L1MouldSIDTextBox").Background = Brushes.Gray;
|
||||
|
||||
this.Find<TextBox>("L1AdditionalMouldTextBox").IsEnabled = false;
|
||||
this.Find<TextBox>("L1AdditionalMouldTextBox").Background = Brushes.Gray;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the current contents of the base SubmissionInfo to the UI
|
||||
/// </summary>
|
||||
public void Load()
|
||||
{
|
||||
// Common Disc Info
|
||||
if (SubmissionInfo.CommonDiscInfo == null)
|
||||
SubmissionInfo.CommonDiscInfo = new CommonDiscInfoSection();
|
||||
|
||||
this.Find<TextBox>("TitleTextBox").Text = SubmissionInfo.CommonDiscInfo.Title ?? "";
|
||||
this.Find<TextBox>("ForeignTitleTextBox").Text = SubmissionInfo.CommonDiscInfo.ForeignTitleNonLatin ?? "";
|
||||
this.Find<TextBox>("DiscNumberLetterTextBox").Text = SubmissionInfo.CommonDiscInfo.DiscNumberLetter ?? "";
|
||||
this.Find<TextBox>("DiscTitleTextBox").Text = SubmissionInfo.CommonDiscInfo.DiscTitle ?? "";
|
||||
this.Find<ComboBox>("CategoryComboBox").SelectedIndex = Categories.FindIndex(r => r == SubmissionInfo.CommonDiscInfo.Category);
|
||||
this.Find<ComboBox>("RegionComboBox").SelectedIndex = Regions.FindIndex(r => r == SubmissionInfo.CommonDiscInfo.Region);
|
||||
if (SubmissionInfo.CommonDiscInfo.Languages != null)
|
||||
{
|
||||
foreach (var language in SubmissionInfo.CommonDiscInfo.Languages)
|
||||
Languages.Find(l => l == language).IsChecked = true;
|
||||
}
|
||||
|
||||
this.Find<TextBox>("SerialTextBox").Text = SubmissionInfo.CommonDiscInfo.Serial ?? "";
|
||||
this.Find<TextBox>("L0MasteringRingTextBox").Text = SubmissionInfo.CommonDiscInfo.MasteringRingFirstLayerDataSide ?? "";
|
||||
this.Find<TextBox>("L0MasteringSIDTextBox").Text = SubmissionInfo.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide ?? "";
|
||||
this.Find<TextBox>("L0ToolstampTextBox").Text = SubmissionInfo.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide ?? "";
|
||||
this.Find<TextBox>("L0MouldSIDTextBox").Text = SubmissionInfo.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide ?? "";
|
||||
this.Find<TextBox>("L0AdditionalMouldTextBox").Text = SubmissionInfo.CommonDiscInfo.AdditionalMouldFirstLayerDataSide ?? "";
|
||||
this.Find<TextBox>("L1MasteringRingTextBox").Text = SubmissionInfo.CommonDiscInfo.MasteringRingSecondLayerLabelSide ?? "";
|
||||
this.Find<TextBox>("L1MasteringSIDTextBox").Text = SubmissionInfo.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide ?? "";
|
||||
this.Find<TextBox>("L1ToolstampTextBox").Text = SubmissionInfo.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide ?? "";
|
||||
this.Find<TextBox>("L1MouldSIDTextBox").Text = SubmissionInfo.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide ?? "";
|
||||
this.Find<TextBox>("L1AdditionalMouldTextBox").Text = SubmissionInfo.CommonDiscInfo.AdditionalMouldSecondLayerLabelSide ?? "";
|
||||
this.Find<TextBox>("BarcodeTextBox").Text = SubmissionInfo.CommonDiscInfo.Barcode ?? "";
|
||||
this.Find<TextBox>("CommentsTextBox").Text = SubmissionInfo.CommonDiscInfo.Comments ?? "";
|
||||
this.Find<TextBox>("ContentsTextBox").Text = SubmissionInfo.CommonDiscInfo.Contents ?? "";
|
||||
|
||||
// Version and Editions
|
||||
if (SubmissionInfo.VersionAndEditions == null)
|
||||
SubmissionInfo.VersionAndEditions = new VersionAndEditionsSection();
|
||||
|
||||
this.Find<TextBox>("VersionTextBox").Text = SubmissionInfo.VersionAndEditions.Version ?? "";
|
||||
this.Find<TextBox>("EditionTextBox").Text = SubmissionInfo.VersionAndEditions.OtherEditions ?? "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a complete list of categories and fill the combo box
|
||||
/// </summary>
|
||||
private void PopulateCategories()
|
||||
{
|
||||
var categories = Enum.GetValues(typeof(DiscCategory)).OfType<DiscCategory?>().ToList();
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Populating categories, {0} categories found.", categories.Count);
|
||||
|
||||
Categories = new List<CategoryComboBoxItem>();
|
||||
foreach (var category in categories)
|
||||
{
|
||||
Categories.Add(new CategoryComboBoxItem(category));
|
||||
}
|
||||
|
||||
this.Find<ComboBox>("CategoryComboBox").Items = Categories;
|
||||
this.Find<ComboBox>("CategoryComboBox").SelectedIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a complete list of languages and fill the combo box
|
||||
/// </summary>
|
||||
private void PopulateLanguages()
|
||||
{
|
||||
var languages = Enum.GetValues(typeof(Language)).OfType<Language?>().ToList();
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Populating languages, {0} languages found.", languages.Count);
|
||||
|
||||
Languages = new List<LanguageComboBoxItem>();
|
||||
foreach (var language in languages)
|
||||
{
|
||||
Languages.Add(new LanguageComboBoxItem(language));
|
||||
}
|
||||
|
||||
this.Find<ComboBox>("LanguagesComboBox").Items = Languages;
|
||||
this.Find<ComboBox>("LanguagesComboBox").SelectedIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a complete list of regions and fill the combo box
|
||||
/// </summary>
|
||||
private void PopulateRegions()
|
||||
{
|
||||
var regions = Enum.GetValues(typeof(Region)).OfType<Region?>().ToList();
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Populating regions, {0} regions found.", regions.Count);
|
||||
|
||||
Regions = new List<RegionComboBoxItem>();
|
||||
foreach (var region in regions)
|
||||
{
|
||||
Regions.Add(new RegionComboBoxItem(region));
|
||||
}
|
||||
|
||||
this.Find<ComboBox>("RegionComboBox").Items = Regions;
|
||||
this.Find<ComboBox>("RegionComboBox").SelectedIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the current contents of the UI to the base SubmissionInfo
|
||||
/// </summary>
|
||||
private void Save()
|
||||
{
|
||||
// Common Disc Info
|
||||
if (SubmissionInfo.CommonDiscInfo == null)
|
||||
SubmissionInfo.CommonDiscInfo = new CommonDiscInfoSection();
|
||||
|
||||
SubmissionInfo.CommonDiscInfo.Title = this.Find<TextBox>("TitleTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.ForeignTitleNonLatin = this.Find<TextBox>("ForeignTitleTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.DiscNumberLetter = this.Find<TextBox>(" DiscNumberLetterTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.DiscTitle = this.Find<TextBox>("DiscTitleTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.Category = (this.Find<ComboBox>("CategoryComboBox").SelectedItem as CategoryComboBoxItem)?.Value ?? DiscCategory.Games;
|
||||
SubmissionInfo.CommonDiscInfo.Region = (this.Find<ComboBox>("RegionComboBox").SelectedItem as RegionComboBoxItem)?.Value ?? Region.World;
|
||||
var languages = new List<Language?>();
|
||||
foreach (var language in Languages)
|
||||
{
|
||||
if (language.IsChecked)
|
||||
languages.Add(language.Value);
|
||||
}
|
||||
if (languages.Count == 0)
|
||||
languages.Add(null);
|
||||
|
||||
SubmissionInfo.CommonDiscInfo.Languages = languages.ToArray();
|
||||
SubmissionInfo.CommonDiscInfo.Serial = this.Find<TextBox>("SerialTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.MasteringRingFirstLayerDataSide = this.Find<TextBox>("L0MasteringRingTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide = this.Find<TextBox>("L0MasteringSIDTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide = this.Find<TextBox>("L0ToolstampTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide = this.Find<TextBox>("L0MouldSIDTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.AdditionalMouldFirstLayerDataSide = this.Find<TextBox>("L0AdditionalMouldTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.MasteringRingSecondLayerLabelSide = this.Find<TextBox>("L1MasteringRingTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide = this.Find<TextBox>("L1MasteringSIDTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide = this.Find<TextBox>("L1ToolstampTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide = this.Find<TextBox>("L1MouldSIDTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.AdditionalMouldSecondLayerLabelSide = this.Find<TextBox>("L1AdditionalMouldTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.Barcode = this.Find<TextBox>("BarcodeTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.Comments = this.Find<TextBox>("CommentsTextBox").Text ?? "";
|
||||
SubmissionInfo.CommonDiscInfo.Contents = this.Find<TextBox>("ContentsTextBox").Text ?? "";
|
||||
|
||||
// Version and Editions
|
||||
if (SubmissionInfo.VersionAndEditions == null)
|
||||
SubmissionInfo.VersionAndEditions = new VersionAndEditionsSection();
|
||||
|
||||
SubmissionInfo.VersionAndEditions.Version = this.Find<TextBox>("VersionTextBox").Text ?? "";
|
||||
SubmissionInfo.VersionAndEditions.OtherEditions = this.Find<TextBox>("EditionTextBox").Text ?? "";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AcceptButton Click event
|
||||
/// </summary>
|
||||
private void OnAcceptClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Save();
|
||||
Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CancelButton Click event
|
||||
/// </summary>
|
||||
private void OnCancelClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for DiscInformationWindow Closed event
|
||||
/// </summary>
|
||||
private void OnClosed(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
32
DICUI.Avalonia/EnumDescriptionConverter.cs
Normal file
32
DICUI.Avalonia/EnumDescriptionConverter.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
using DICUI.Data;
|
||||
using DICUI.Utilities;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to provide a converter to XAML files to render comboboxes with enum values
|
||||
/// </summary>
|
||||
public class EnumDescriptionConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
// Common
|
||||
if (value is MediaType?)
|
||||
return ((MediaType?)value).LongName();
|
||||
else if (value is KnownSystem?)
|
||||
return ((KnownSystem?)value).LongName();
|
||||
|
||||
// Default
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
DICUI.Avalonia/Icon.ico
Normal file
BIN
DICUI.Avalonia/Icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
40
DICUI.Avalonia/LogWindow.axaml
Normal file
40
DICUI.Avalonia/LogWindow.axaml
Normal file
@@ -0,0 +1,40 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:DICUI.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="350" Width="600" Height="350"
|
||||
x:Class="DICUI.Avalonia.LogWindow" Icon="Icon.ico" CanResize="False"
|
||||
Title="Log Window">
|
||||
|
||||
<Grid RowDefinitions="40,250,40">
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<Grid Grid.Row="0" Height="25" Margin="10 10 10 0">
|
||||
<ProgressBar Name="ProgressBar" />
|
||||
<TextBlock Name="ProgressLabel" Grid.Row="0" Height="25" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
<!-- Log Area -->
|
||||
<Border Grid.Row="1" Background="White" BorderBrush="Gainsboro" BorderThickness="1" Margin="10">
|
||||
<ScrollViewer Name="OutputViewer">
|
||||
<TextBox Name="Output" FontFamily="Consolas" Background="Gray" IsReadOnly="True" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<!-- Options -->
|
||||
<Grid Grid.Row="2" RowDefinitions="Auto" ColumnDefinitions="Auto,Auto,3*,Auto,Auto,Auto">
|
||||
<CheckBox Name="VerboseCheckBox" Grid.Column="0" Height="25" VerticalAlignment="Center" Margin="10 0 0 10"
|
||||
Content="Verbose" DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=VerboseLogging}"
|
||||
ToolTip.Tip="Enable verbose logging of tasks" />
|
||||
<CheckBox Name="OpenAtStartupCheckBox" Grid.Column="1" Grid.ColumnSpan="2" Height="25" VerticalAlignment="Center" Margin="10 0 0 10"
|
||||
Content="Open at startup" DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=OpenLogWindowAtStartup}"
|
||||
ToolTip.Tip="Open this window at startup" />
|
||||
<Button Margin="0 0 10 10" Grid.Column="3" Height="25" Width="60" Content="Clear" HorizontalAlignment="Right" Click="OnClearButton" />
|
||||
<Button Margin="0 0 10 10" Grid.Column="4" Height="25" Width="60" Content="Hide" HorizontalAlignment="Right" Click="OnHideButton" />
|
||||
<Button Margin="0 0 10 10" Grid.Column="5" Height="25" Width="60" Content="Save" HorizontalAlignment="Right" Click="OnSaveButton" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
82
DICUI.Avalonia/LogWindow.axaml.cs
Normal file
82
DICUI.Avalonia/LogWindow.axaml.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System.IO;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public class LogWindow : Window
|
||||
{
|
||||
public LogWindow()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjust the position of the log window if the main window is moved
|
||||
/// </summary>
|
||||
public void AdjustPositionToMainWindow()
|
||||
{
|
||||
var owner = Owner as Window;
|
||||
Position = new PixelPoint(
|
||||
owner.Position.X,
|
||||
owner.Position.Y + (int)owner.Height + Constants.LogWindowMarginFromMainWindow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Append rich text to the scrolling element
|
||||
/// </summary>
|
||||
/// <param name="text">Text to add, including newlines</param>
|
||||
/// <param name="color">Color to format the text</param>
|
||||
public void AppendToTextBox(string text, ISolidColorBrush color)
|
||||
{
|
||||
// TODO: Use brush color
|
||||
this.Find<TextBox>("Output").Text += $"{text}\n";
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handler for ClearButton Click event
|
||||
/// </summary>
|
||||
private void OnClearButton(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.Find<TextBox>("Output").Text = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for HideButton Click event
|
||||
/// </summary>
|
||||
private void OnHideButton(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModels.LoggerViewModel.WindowVisible = false;
|
||||
|
||||
//TODO: this should be bound directly to WindowVisible property in two way fashion
|
||||
// we need to study how to properly do it in XAML
|
||||
(Owner as MainWindow).Find<CheckBox>("ShowLogCheckBox").IsChecked = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for SaveButton Click event
|
||||
/// </summary>
|
||||
private void OnSaveButton(object sender, RoutedEventArgs e)
|
||||
{
|
||||
using (StreamWriter tw = new StreamWriter(File.OpenWrite("console.log")))
|
||||
{
|
||||
tw.Write(this.Find<TextBox>("Output").Text);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
109
DICUI.Avalonia/MainWindow.axaml
Normal file
109
DICUI.Avalonia/MainWindow.axaml
Normal file
@@ -0,0 +1,109 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:DICUI.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="450" Width="600" Height="450"
|
||||
x:Class="DICUI.Avalonia.MainWindow" Icon="Icon.ico" CanResize="False"
|
||||
Title="DICUI" WindowStartupLocation="CenterScreen"
|
||||
PositionChanged="MainWindowLocationChanged" Activated="MainWindowActivated" Closing="MainWindowClosing">
|
||||
|
||||
<Window.Resources>
|
||||
<local:EnumDescriptionConverter x:Key="enumConverter" />
|
||||
</Window.Resources>
|
||||
|
||||
<Grid ColumnDefinitions="4*,13*" RowDefinitions="30,4*,1*,1*">
|
||||
|
||||
<!-- Menu Bar -->
|
||||
<StackPanel VerticalAlignment="Top" Grid.ColumnSpan="4">
|
||||
<Menu Height="20" >
|
||||
<MenuItem Header="_File">
|
||||
<MenuItem Name="AppExitMenuItem" Header="E_xit" HorizontalAlignment="Left" Width="185" Click="AppExitMenuItemClick" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Tools">
|
||||
<MenuItem Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="185" Click="OptionsMenuItemClick" />
|
||||
<MenuItem Name="ShowLogMenuItem" Header="Show _Log Window" HorizontalAlignment="Left" Width="185">
|
||||
<MenuItem.Icon>
|
||||
<CheckBox Name="ShowLogCheckBox" BorderThickness="0" DataContext="{Binding Source={x:Static local:ViewModels.LoggerViewModel}}" IsChecked="{Binding Path=WindowVisible}" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Help">
|
||||
<MenuItem Name="AboutMenuItem" Header="_About" HorizontalAlignment="Left" Width="185" Click="AboutMenuItemClick" />
|
||||
<MenuItem Name="CheckForUpdatesMenuItem" Header="_Check for Updates" HorizontalAlignment="Left" Width="185" Click="CheckForUpdatesMenuItemClick" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Settings -->
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5.2,5.4" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="Settings" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="1" Grid.Column="0" Margin="15,25,15.2,10.4" Grid.ColumnSpan="2" ColumnDefinitions="1*,2.5*" RowDefinitions="1*,1*,1*,1*,1*,1*">
|
||||
|
||||
<!-- System / Media Type Selection -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Text="System/Media Type" />
|
||||
<ComboBox Name="SystemTypeComboBox" Grid.Row="0" Grid.Column="1" Height="25" Width="250" HorizontalAlignment="Left" AutoScrollToSelectedItem="True" SelectionChanged="SystemTypeComboBoxSelectionChanged">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=Name}" Foreground="{Binding Path=Foreground}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<ComboBox Name="MediaTypeComboBox" Grid.Row="0" Grid.Column="1" Height="25" Width="140" HorizontalAlignment="Right" AutoScrollToSelectedItem="True" SelectionChanged="MediaTypeComboBoxSelectionChanged">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={StaticResource enumConverter}}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<!-- Output Filename -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Text="Output Filename" />
|
||||
<TextBox Name="OutputFilenameTextBox" Grid.Row="1" Grid.Column="1" Height="25" ScrollViewer.VerticalScrollBarVisibility="Disabled" TextInput="OutputFilenameTextBoxTextChanged" />
|
||||
|
||||
<!-- Output Directory -->
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Text="Output Directory" />
|
||||
<TextBox Name="OutputDirectoryTextBox" Grid.Row="2" Grid.Column="1" Height="25" Width="345" HorizontalAlignment="Left" ScrollViewer.VerticalScrollBarVisibility="Disabled" TextInput="OutputDirectoryTextBoxTextChanged" />
|
||||
<Button Name="OutputDirectoryBrowseButton" Grid.Row="2" Grid.Column="1" Height="25" Width="50" HorizontalAlignment="Right" Content="Browse" Click="OutputDirectoryBrowseButtonClick" />
|
||||
|
||||
<!-- Drive Letter -->
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Text="Drive Letter" />
|
||||
<ComboBox Name="DriveLetterComboBox" Grid.Row="3" Grid.Column="1" Height="25" Width="60" HorizontalAlignment="Left" SelectionChanged="DriveLetterComboBoxSelectionChanged">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=Letter}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<!-- Drive Speed -->
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Text="Drive Speed" />
|
||||
<ComboBox Name="DriveSpeedComboBox" Grid.Row="4" Grid.Column="1" Height="25" Width="60" HorizontalAlignment="Left" SelectionChanged="DriveSpeedComboBoxSelectionChanged" />
|
||||
|
||||
<!-- Parameters -->
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" Text="Parameters" />
|
||||
<TextBox Name="ParametersTextBox" Grid.Row="5" Grid.Column="1" Height="25" Width="370" HorizontalAlignment="Left" ScrollViewer.VerticalScrollBarVisibility="Disabled" IsEnabled="False" />
|
||||
<CheckBox Name="EnableParametersCheckBox" Grid.Row="5" Grid.Column="1" Height="25" HorizontalAlignment="Right" IsChecked="False" Click="EnableParametersCheckBoxClick" />
|
||||
</Grid>
|
||||
|
||||
<!-- Controls -->
|
||||
<Border Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,4.6,5.2,4.8" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="Controls" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="2" Grid.Column="0" Margin="15,19.6,15.2,9.8" Grid.ColumnSpan="2" ColumnDefinitions="1*,1*,1*,1*" RowDefinitions="1*">
|
||||
<Button Name="StartStopButton" Grid.Row="0" Grid.Column="0" Height="25" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Start Dumping" Click="StartStopButtonClick" IsEnabled="False" />
|
||||
<Button Name="MediaScanButton" Grid.Row="0" Grid.Column="1" Height="25" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan For Media" Click="MediaScanButtonClick" />
|
||||
<Button Name="CopyProtectScanButton" Grid.Row="0" Grid.Column="2" Height="25" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan For Protection" Click="CopyProtectScanButtonClick" />
|
||||
<CheckBox Name="EjectWhenDoneCheckBox" Grid.Row="0" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Eject When Done" IsChecked="False" />
|
||||
</Grid>
|
||||
|
||||
<!-- Status -->
|
||||
<Border Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5.2,5.2,4.8" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="Status" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="3" Grid.Column="0" Margin="15,20.2,15.2,9.8" Grid.ColumnSpan="2" ColumnDefinitions="1*" RowDefinitions="1*">
|
||||
<TextBlock Name="StatusLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Text="Waiting for media..." />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
843
DICUI.Avalonia/MainWindow.axaml.cs
Normal file
843
DICUI.Avalonia/MainWindow.axaml.cs
Normal file
@@ -0,0 +1,843 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using BurnOutSharp;
|
||||
using DICUI.Data;
|
||||
using DICUI.Utilities;
|
||||
using DICUI.Web;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public class MainWindow : Window
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Currently selected or detected media type
|
||||
/// </summary>
|
||||
public MediaType? CurrentMediaType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current list of drives
|
||||
/// </summary>
|
||||
public List<Drive> Drives { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current dumping environment
|
||||
/// </summary>
|
||||
public DumpEnvironment Env { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current list of supported media types
|
||||
/// </summary>
|
||||
public List<MediaType?> MediaTypes { get; private set; } = new List<MediaType?>();
|
||||
|
||||
/// <summary>
|
||||
/// Current list of supported system profiles
|
||||
/// </summary>
|
||||
public List<KnownSystemComboBoxItem> Systems { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current UI options
|
||||
/// </summary>
|
||||
public UIOptions UIOptions { get; private set; } = new UIOptions();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Instance Variables
|
||||
|
||||
/// <summary>
|
||||
/// Current attached LogWindow
|
||||
/// </summary>
|
||||
private LogWindow logWindow;
|
||||
|
||||
#endregion
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
// Load the options
|
||||
ViewModels.OptionsViewModel = new OptionsViewModel(UIOptions);
|
||||
|
||||
// Load the log window
|
||||
logWindow = new LogWindow();
|
||||
logWindow.Owner = this;
|
||||
ViewModels.LoggerViewModel.SetWindow(logWindow);
|
||||
|
||||
// Disable buttons until we load
|
||||
this.Find<Button>("StartStopButton").IsEnabled = false;
|
||||
this.Find<Button>("MediaScanButton").IsEnabled = false;
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = false;
|
||||
|
||||
// TODO: If log window open, "dock" it to the current Window
|
||||
|
||||
if (UIOptions.OpenLogWindowAtStartup)
|
||||
{
|
||||
//TODO: this should be bound directly to WindowVisible property in two way fashion
|
||||
// we need to study how to properly do it in XAML
|
||||
this.Find<CheckBox>("ShowLogCheckBox").IsChecked = true;
|
||||
ViewModels.LoggerViewModel.WindowVisible = true;
|
||||
}
|
||||
|
||||
// Populate the list of systems
|
||||
this.Find<TextBlock>("StatusLabel").Text = "Creating system list, please wait!";
|
||||
PopulateSystems();
|
||||
|
||||
// Populate the list of drives
|
||||
this.Find<TextBlock>("StatusLabel").Text = "Creating drive list, please wait!";
|
||||
PopulateDrives();
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Browse for an output folder
|
||||
/// </summary>
|
||||
private async void BrowseFolder()
|
||||
{
|
||||
OpenFolderDialog folderDialog = new OpenFolderDialog { Directory = AppDomain.CurrentDomain.BaseDirectory };
|
||||
string directory = await folderDialog.ShowAsync(this);
|
||||
if (!string.IsNullOrWhiteSpace(directory))
|
||||
this.Find<TextBox>("OutputDirectoryTextBox").Text = directory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cache the current disc type to internal variable
|
||||
/// </summary>
|
||||
private void CacheCurrentDiscType()
|
||||
{
|
||||
// Get the drive letter from the selected item
|
||||
var drive = this.Find<ComboBox>("DriveLetterComboBox").SelectedItem as Drive;
|
||||
if (drive == null)
|
||||
return;
|
||||
|
||||
// Get the current media type
|
||||
if (!UIOptions.SkipMediaTypeDetection)
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter);
|
||||
CurrentMediaType = Validators.GetMediaType(drive);
|
||||
ViewModels.LoggerViewModel.VerboseLogLn(CurrentMediaType == null ? "unable to detect." : ("detected " + CurrentMediaType.LongName() + "."));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a DumpEnvironment with all current settings
|
||||
/// </summary>
|
||||
/// <returns>Filled DumpEnvironment instance</returns>
|
||||
private DumpEnvironment DetermineEnvironment()
|
||||
{
|
||||
// Populate the new environment
|
||||
var env = new DumpEnvironment(UIOptions.Options,
|
||||
this.Find<TextBox>("OutputDirectoryTextBox").Text,
|
||||
this.Find<TextBox>("OutputFilenameTextBox").Text,
|
||||
this.Find<ComboBox>("DriveLetterComboBox").SelectedItem as Drive,
|
||||
this.Find<ComboBox>("SystemTypeComboBox").SelectedItem as KnownSystemComboBoxItem,
|
||||
this.Find<ComboBox>("MediaTypeComboBox").SelectedItem as MediaType?,
|
||||
this.Find<TextBox>("ParametersTextBox").Text);
|
||||
|
||||
// Disable automatic reprocessing of the textboxes until we're done
|
||||
this.Find<TextBox>("OutputDirectoryTextBox").TextInput -= OutputDirectoryTextBoxTextChanged;
|
||||
this.Find<TextBox>("OutputFilenameTextBox").TextInput -= OutputFilenameTextBoxTextChanged;
|
||||
|
||||
this.Find<TextBox>("OutputDirectoryTextBox").Text = env.OutputDirectory;
|
||||
this.Find<TextBox>("OutputFilenameTextBox").Text = env.OutputFilename;
|
||||
|
||||
this.Find<TextBox>("OutputDirectoryTextBox").TextInput += OutputDirectoryTextBoxTextChanged;
|
||||
this.Find<TextBox>("OutputFilenameTextBox").TextInput += OutputFilenameTextBoxTextChanged;
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure information is consistent with the currently selected disc type
|
||||
/// </summary>
|
||||
private void EnsureDiscInformation()
|
||||
{
|
||||
// Get the current environment information
|
||||
Env = DetermineEnvironment();
|
||||
|
||||
// Take care of null cases
|
||||
if (Env.System == null)
|
||||
Env.System = KnownSystem.NONE;
|
||||
if (Env.Type == null)
|
||||
Env.Type = MediaType.NONE;
|
||||
|
||||
// Get the status to write out
|
||||
Result result = Validators.GetSupportStatus(Env.System, Env.Type);
|
||||
this.Find<TextBlock>("StatusLabel").Text = result.Message;
|
||||
|
||||
// Set the index for the current disc type
|
||||
SetCurrentDiscType();
|
||||
|
||||
this.Find<Button>("StartStopButton").IsEnabled = result && (Drives != null && Drives.Count > 0 ? true : false);
|
||||
|
||||
// If we're in a type that doesn't support drive speeds
|
||||
this.Find<ComboBox>("DriveSpeedComboBox").IsEnabled = Env.Type.DoesSupportDriveSpeed();
|
||||
|
||||
// If input params are not enabled, generate the full parameters from the environment
|
||||
if (!this.Find<TextBox>("ParametersTextBox").IsEnabled)
|
||||
{
|
||||
string generated = Env.GetFullParameters((int?)this.Find<ComboBox>("DriveSpeedComboBox").SelectedItem);
|
||||
if (generated != null)
|
||||
this.Find<TextBox>("ParametersTextBox").Text = generated;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the default output directory name from the currently selected drive
|
||||
/// </summary>
|
||||
/// <param name="driveChanged">Force an updated name if the drive letter changes</param>
|
||||
private void GetOutputNames(bool driveChanged)
|
||||
{
|
||||
Drive drive = this.Find<ComboBox>("DriveLetterComboBox").SelectedItem as Drive;
|
||||
KnownSystem? systemType = this.Find<ComboBox>("SystemTypeComboBox").SelectedItem as KnownSystemComboBoxItem;
|
||||
MediaType? mediaType = this.Find<ComboBox>("MediaTypeComboBox").SelectedItem as MediaType?;
|
||||
|
||||
// Set the output directory, if we changed drives or it's not already
|
||||
if (driveChanged || string.IsNullOrEmpty(this.Find<TextBox>("OutputDirectoryTextBox").Text))
|
||||
this.Find<TextBox>("OutputDirectoryTextBox").Text = Path.Combine(UIOptions.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
|
||||
|
||||
// Get the extension for the file for the next two statements
|
||||
string extension = Env?.GetExtension(mediaType);
|
||||
|
||||
// Set the output filename, if we changed drives or it's not already
|
||||
if (driveChanged || string.IsNullOrEmpty(this.Find<TextBox>("OutputFilenameTextBox").Text))
|
||||
this.Find<TextBox>("OutputFilenameTextBox").Text = (drive?.VolumeLabel ?? systemType.LongName()) + (extension ?? ".bin");
|
||||
|
||||
// If the extension for the file changed, update that automatically
|
||||
else if (Path.GetExtension(this.Find<TextBox>("OutputFilenameTextBox").Text) != extension)
|
||||
this.Find<TextBox>("OutputFilenameTextBox").Text = Path.GetFileNameWithoutExtension(this.Find<TextBox>("OutputFilenameTextBox").Text) + (extension ?? ".bin");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a complete list of active disc drives and fill the combo box
|
||||
/// </summary>
|
||||
/// <remarks>TODO: Find a way for this to periodically run, or have it hook to a "drive change" event</remarks>
|
||||
private void PopulateDrives()
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Scanning for drives..");
|
||||
|
||||
// Always enable the disk scan
|
||||
this.Find<Button>("MediaScanButton").IsEnabled = true;
|
||||
|
||||
// Populate the list of drives and add it to the combo box
|
||||
Drives = Validators.CreateListOfDrives(UIOptions.IgnoreFixedDrives);
|
||||
this.Find<ComboBox>("DriveLetterComboBox").Items = Drives;
|
||||
|
||||
if (Drives.Any())
|
||||
{
|
||||
// Check for active optical drives first
|
||||
int index = Drives.FindIndex(d => d.MarkedActive && d.InternalDriveType == InternalDriveType.Optical);
|
||||
|
||||
// Then we check for floppy drives
|
||||
if (index == -1)
|
||||
index = Drives.FindIndex(d => d.MarkedActive && d.InternalDriveType == InternalDriveType.Floppy);
|
||||
|
||||
// Then we try all other drive types
|
||||
if (index == -1)
|
||||
index = Drives.FindIndex(d => d.MarkedActive);
|
||||
|
||||
// Set the selected index
|
||||
this.Find<ComboBox>("DriveLetterComboBox").SelectedIndex = (index != -1 ? index : 0);
|
||||
this.Find<TextBlock>("StatusLabel").Text = "Valid drive found! Choose your Media Type";
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = true;
|
||||
|
||||
// Get the current media type
|
||||
if (!UIOptions.SkipSystemDetection && index != -1)
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLog("Trying to detect system for drive {0}.. ", Drives[index].Letter);
|
||||
var currentSystem = Validators.GetKnownSystem(Drives[index]);
|
||||
ViewModels.LoggerViewModel.VerboseLogLn(currentSystem == null || currentSystem == KnownSystem.NONE ? "unable to detect." : ("detected " + currentSystem.LongName() + "."));
|
||||
|
||||
if (currentSystem != null && currentSystem != KnownSystem.NONE)
|
||||
{
|
||||
int sysIndex = Systems.FindIndex(s => s == currentSystem);
|
||||
this.Find<ComboBox>("SystemTypeComboBox").SelectedIndex = sysIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Only enable the start/stop if we don't have the default selected
|
||||
this.Find<Button>("StartStopButton").IsEnabled = (this.Find<ComboBox>("SystemTypeComboBox").SelectedItem as KnownSystemComboBoxItem) != KnownSystem.NONE;
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", Drives.Count, string.Join(", ", Drives.Select(d => d.Letter)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Find<ComboBox>("DriveLetterComboBox").SelectedIndex = -1;
|
||||
this.Find<TextBlock>("StatusLabel").Text = "No valid drive found!";
|
||||
this.Find<Button>("StartStopButton").IsEnabled = false;
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = false;
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Found no drives");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populate media type according to system type
|
||||
/// </summary>
|
||||
private void PopulateMediaType()
|
||||
{
|
||||
KnownSystem? currentSystem = this.Find<ComboBox>("SystemTypeComboBox").SelectedItem as KnownSystemComboBoxItem;
|
||||
|
||||
if (currentSystem != null)
|
||||
{
|
||||
MediaTypes = Validators.GetValidMediaTypes(currentSystem);
|
||||
this.Find<ComboBox>("MediaTypeComboBox").Items = MediaTypes;
|
||||
this.Find<ComboBox>("MediaTypeComboBox").IsEnabled = MediaTypes.Count > 1;
|
||||
this.Find<ComboBox>("MediaTypeComboBox").SelectedIndex = (MediaTypes.IndexOf(CurrentMediaType) >= 0 ? MediaTypes.IndexOf(CurrentMediaType) : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Find<ComboBox>("MediaTypeComboBox").Items = null;
|
||||
this.Find<ComboBox>("MediaTypeComboBox").IsEnabled = false;
|
||||
this.Find<ComboBox>("MediaTypeComboBox").SelectedIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a complete list of supported systems and fill the combo box
|
||||
/// </summary>
|
||||
private void PopulateSystems()
|
||||
{
|
||||
var knownSystems = Validators.CreateListOfSystems();
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", knownSystems.Count);
|
||||
|
||||
Dictionary<KnownSystemCategory, List<KnownSystem?>> mapping = knownSystems
|
||||
.GroupBy(s => s.Category())
|
||||
.ToDictionary(
|
||||
k => k.Key,
|
||||
v => v
|
||||
.OrderBy(s => s.LongName())
|
||||
.ToList()
|
||||
);
|
||||
|
||||
Systems = new List<KnownSystemComboBoxItem>();
|
||||
Systems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE));
|
||||
foreach (var group in mapping)
|
||||
{
|
||||
Systems.Add(new KnownSystemComboBoxItem(group.Key));
|
||||
group.Value.ForEach(system => Systems.Add(new KnownSystemComboBoxItem(system)));
|
||||
}
|
||||
|
||||
this.Find<ComboBox>("SystemTypeComboBox").Items = Systems;
|
||||
this.Find<ComboBox>("SystemTypeComboBox").SelectedIndex = 0;
|
||||
|
||||
this.Find<Button>("StartStopButton").IsEnabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the current custom parameters back into UI values
|
||||
/// </summary>
|
||||
private void ProcessCustomParameters()
|
||||
{
|
||||
Env.SetParameters(this.Find<TextBox>("ParametersTextBox").Text);
|
||||
if (Env.Parameters == null)
|
||||
return;
|
||||
|
||||
int driveIndex = Drives.Select(d => d.Letter).ToList().IndexOf(Env.Parameters.InputPath()[0]);
|
||||
if (driveIndex > -1)
|
||||
this.Find<ComboBox>("DriveLetterComboBox").SelectedIndex = driveIndex;
|
||||
|
||||
int driveSpeed = Env.Parameters.GetSpeed() ?? -1;
|
||||
if (driveSpeed > 0)
|
||||
this.Find<ComboBox>("DriveSpeedComboBox").SelectedItem = driveSpeed;
|
||||
else
|
||||
Env.Parameters.SetSpeed((int?)this.Find<ComboBox>("DriveSpeedComboBox").SelectedItem);
|
||||
|
||||
string trimmedPath = Env.Parameters.OutputPath()?.Trim('"') ?? string.Empty;
|
||||
string outputDirectory = Path.GetDirectoryName(trimmedPath);
|
||||
string outputFilename = Path.GetFileName(trimmedPath);
|
||||
if (!string.IsNullOrWhiteSpace(outputDirectory))
|
||||
this.Find<TextBox>("OutputDirectoryTextBox").Text = outputDirectory;
|
||||
else
|
||||
outputDirectory = this.Find<TextBox>("OutputDirectoryTextBox").Text;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(outputFilename))
|
||||
this.Find<TextBox>("OutputFilenameTextBox").Text = outputFilename;
|
||||
else
|
||||
outputFilename = this.Find<TextBox>("OutputFilenameTextBox").Text;
|
||||
|
||||
MediaType? mediaType = Env.Parameters.GetMediaType();
|
||||
int mediaTypeIndex = MediaTypes.IndexOf(mediaType);
|
||||
if (mediaTypeIndex > -1)
|
||||
this.Find<ComboBox>("MediaTypeComboBox").SelectedIndex = mediaTypeIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan and show copy protection for the current disc
|
||||
/// </summary>
|
||||
private async void ScanAndShowProtection()
|
||||
{
|
||||
if (Env == null)
|
||||
Env = DetermineEnvironment();
|
||||
|
||||
if (Env.Drive.Letter != default(char))
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Scanning for copy protection in {0}", Env.Drive.Letter);
|
||||
|
||||
var tempContent = this.Find<TextBlock>("StatusLabel").Text;
|
||||
this.Find<TextBlock>("StatusLabel").Text = "Scanning for copy protection... this might take a while!";
|
||||
this.Find<Button>("StartStopButton").IsEnabled = false;
|
||||
this.Find<Button>("MediaScanButton").IsEnabled = false;
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = false;
|
||||
|
||||
var progress = new Progress<FileProtection>();
|
||||
progress.ProgressChanged += ProgressUpdated;
|
||||
string protections = await Validators.RunProtectionScanOnPath(Env.Drive.Letter + ":\\");
|
||||
|
||||
// If SmartE is detected on the current disc, remove `/sf` from the flags for DIC only
|
||||
if (Env.InternalProgram == InternalProgram.DiscImageCreator && protections.Contains("SmartE"))
|
||||
{
|
||||
((DiscImageCreator.Parameters)Env.Parameters)[DiscImageCreator.Flag.ScanFileProtect] = false;
|
||||
ViewModels.LoggerViewModel.VerboseLogLn($"SmartE detected, removing {DiscImageCreator.FlagStrings.ScanFileProtect} from parameters");
|
||||
}
|
||||
|
||||
if (!ViewModels.LoggerViewModel.WindowVisible)
|
||||
{
|
||||
new Window()
|
||||
{
|
||||
Title = "Detected Protection",
|
||||
Content = protections,
|
||||
SizeToContent = SizeToContent.WidthAndHeight,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner,
|
||||
}.ShowDialog(this);
|
||||
}
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLog("Detected the following protections in {0}:\r\n\r\n{1}", Env.Drive.Letter, protections);
|
||||
|
||||
this.Find<TextBlock>("StatusLabel").Text = tempContent;
|
||||
this.Find<Button>("StartStopButton").IsEnabled = true;
|
||||
this.Find<Button>("MediaScanButton").IsEnabled = true;
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the current disc type in the combo box
|
||||
/// </summary>
|
||||
private void SetCurrentDiscType()
|
||||
{
|
||||
// If we have an invalid current type, we don't care and return
|
||||
if (CurrentMediaType == null || CurrentMediaType == MediaType.NONE)
|
||||
return;
|
||||
|
||||
// Now set the selected item, if possible
|
||||
int index = MediaTypes.FindIndex(kvp => kvp.Value == CurrentMediaType);
|
||||
if (index != -1)
|
||||
this.Find<ComboBox>("MediaTypeComboBox").SelectedIndex = index;
|
||||
else
|
||||
this.Find<TextBlock>("StatusLabel").Text = $"Disc of type '{Converters.LongName(CurrentMediaType)}' found, but the current system does not support it!";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the drive speed based on reported maximum and user-defined option
|
||||
/// </summary>
|
||||
private void SetSupportedDriveSpeed()
|
||||
{
|
||||
// Set the drive speed list that's appropriate
|
||||
var values = Constants.GetSpeedsForMediaType(CurrentMediaType);
|
||||
this.Find<ComboBox>("DriveSpeedComboBox").Items = values;
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Supported media speeds: {0}", string.Join(",", values));
|
||||
|
||||
// Set the selected speed
|
||||
int speed = UIOptions.GetPreferredDumpSpeedForMediaType(CurrentMediaType);
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Setting drive speed to: {0}", speed);
|
||||
this.Find<ComboBox>("DriveSpeedComboBox").SelectedItem = speed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begin the dumping process using the given inputs
|
||||
/// </summary>
|
||||
private async void StartDumping()
|
||||
{
|
||||
// One last check to determine environment, just in case
|
||||
Env = DetermineEnvironment();
|
||||
|
||||
// If still in custom parameter mode, check that users meant to continue or not
|
||||
if (this.Find<CheckBox>("EnableParametersCheckBox").IsChecked == true)
|
||||
{
|
||||
MessageBoxResult result = await MessageBox.Show(this, "It looks like you have custom parameters that have not been saved. Would you like to apply those changes before starting to dump?", "Custom Changes", MessageBoxButtons.YesNoCancel);
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
this.Find<CheckBox>("EnableParametersCheckBox").IsChecked = false;
|
||||
this.Find<TextBox>("ParametersTextBox").IsEnabled = false;
|
||||
ProcessCustomParameters();
|
||||
}
|
||||
else if (result == MessageBoxResult.Cancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If "No", then we continue with the current known environment
|
||||
}
|
||||
|
||||
// Fix the output paths
|
||||
Env.FixOutputPaths();
|
||||
|
||||
try
|
||||
{
|
||||
// Validate that the user explicitly wants an inactive drive to be considered for dumping
|
||||
if (!Env.Drive.MarkedActive)
|
||||
{
|
||||
MessageBoxResult mbresult = await MessageBox.Show(this, "The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButtons.YesNo);
|
||||
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel)
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If a complete dump already exists
|
||||
if (Env.FoundAllFiles())
|
||||
{
|
||||
MessageBoxResult mbresult = await MessageBox.Show(this, "A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButtons.YesNo);
|
||||
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel)
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.Find<Button>("StartStopButton").Content = Constants.StopDumping;
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = false;
|
||||
this.Find<TextBlock>("StatusLabel").Text = "Beginning dumping process";
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Starting dumping process..");
|
||||
|
||||
// Get progress indicators
|
||||
var resultProgress = new Progress<Result>();
|
||||
resultProgress.ProgressChanged += ProgressUpdated;
|
||||
var protectionProgress = new Progress<FileProtection>();
|
||||
protectionProgress.ProgressChanged += ProgressUpdated;
|
||||
|
||||
// Run the program with the parameters
|
||||
Result result = await Env.Run(resultProgress);
|
||||
|
||||
// If we didn't execute a dumping command we cannot get submission output
|
||||
if (!Env.Parameters.IsDumpingCommand())
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("No dumping command was run, submission information will not be gathered.");
|
||||
this.Find<TextBlock>("StatusLabel").Text = "Execution complete!";
|
||||
this.Find<Button>("StartStopButton").Content = Constants.StartDumping;
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
// Verify dump output and save it
|
||||
result = await Env.VerifyAndSaveDumpOutput(resultProgress,
|
||||
protectionProgress,
|
||||
this.Find<CheckBox>("EjectWhenDoneCheckBox").IsChecked,
|
||||
UIOptions.ResetDriveAfterDump,
|
||||
(si) =>
|
||||
{
|
||||
var discInformationWindow = new DiscInformationWindow();
|
||||
discInformationWindow.SubmissionInfo = si;
|
||||
discInformationWindow.Load();
|
||||
discInformationWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
discInformationWindow.ShowDialog(this).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// No-op, we don't care what it was
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.Find<Button>("StartStopButton").Content = Constants.StartDumping;
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AboutMenuItem Click event
|
||||
/// </summary>
|
||||
private void AboutMenuItemClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MessageBox.Show(this, $"darksabre76 - Project Lead / Backend Design"
|
||||
+ $"{Environment.NewLine}ReignStumble - Former Project Lead / UI Design"
|
||||
+ $"{Environment.NewLine}Jakz - Primary Feature Contributor"
|
||||
+ $"{Environment.NewLine}NHellFire - Feature Contributor", "About", MessageBoxButtons.Ok);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AppExitMenuItem Click event
|
||||
/// </summary>
|
||||
private void AppExitMenuItemClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
logWindow?.Close();
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CheckForUpdatesMenuItem Click event
|
||||
/// </summary>
|
||||
private void CheckForUpdatesMenuItemClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Get the current internal version
|
||||
var assemblyVersion = Assembly.GetEntryAssembly().GetName().Version;
|
||||
string version = $"{assemblyVersion.Major}.{assemblyVersion.Minor}" + (assemblyVersion.Build != 0 ? $".{assemblyVersion.Build}" : string.Empty);
|
||||
|
||||
// Get the latest tag from GitHub
|
||||
using (var client = new RedumpWebClient())
|
||||
{
|
||||
client.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0";
|
||||
|
||||
// TODO: Figure out a better way than having this hardcoded...
|
||||
string url = "https://api.github.com/repos/SabreTools/DICUI/releases/latest";
|
||||
string latestReleaseJsonString = client.DownloadString(url);
|
||||
var latestReleaseJson = JObject.Parse(latestReleaseJsonString);
|
||||
string latestTag = latestReleaseJson["tag_name"].ToString();
|
||||
string releaseUrl = latestReleaseJson["html_url"].ToString();
|
||||
|
||||
bool different = version != latestTag;
|
||||
|
||||
string message = $"Local version: {version}"
|
||||
+ $"{Environment.NewLine}Remote version: {latestTag}"
|
||||
+ (different
|
||||
? $"{Environment.NewLine}The update URL has been added copied to your clipboard"
|
||||
: $"{Environment.NewLine}You have the newest version!");
|
||||
|
||||
// If we have a new version, put it in the clipboard
|
||||
if (different)
|
||||
Application.Current.Clipboard.SetTextAsync(releaseUrl);
|
||||
|
||||
MessageBox.Show(this, message, "Version Update Check", MessageBoxButtons.Ok);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CopyProtectScanButton Click event
|
||||
/// </summary>
|
||||
private void CopyProtectScanButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ScanAndShowProtection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for DriveLetterComboBox SelectionChanged event
|
||||
/// </summary>
|
||||
private void DriveLetterComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
CacheCurrentDiscType();
|
||||
SetCurrentDiscType();
|
||||
GetOutputNames(true);
|
||||
SetSupportedDriveSpeed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for DriveSpeedComboBox SelectionChanged event
|
||||
/// </summary>
|
||||
private void DriveSpeedComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for EnableParametersCheckBox Click event
|
||||
/// </summary>
|
||||
private void EnableParametersCheckBoxClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (this.Find<CheckBox>("EnableParametersCheckBox").IsChecked == true)
|
||||
this.Find<TextBox>("ParametersTextBox").IsEnabled = true;
|
||||
else
|
||||
{
|
||||
this.Find<TextBox>("ParametersTextBox").IsEnabled = false;
|
||||
ProcessCustomParameters();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MediaTypeComboBox SelectionChanged event
|
||||
/// </summary>
|
||||
private void MediaTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
// Only change the media type if the selection and not the list has changed
|
||||
if (e.RemovedItems.Count == 1 && e.AddedItems.Count == 1)
|
||||
{
|
||||
CurrentMediaType = this.Find<ComboBox>("MediaTypeComboBox").SelectedItem as MediaType?;
|
||||
SetSupportedDriveSpeed();
|
||||
}
|
||||
|
||||
GetOutputNames(false);
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MediaScanButton Click event
|
||||
/// </summary>
|
||||
private void MediaScanButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PopulateDrives();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MainWindow Activated event
|
||||
/// </summary>
|
||||
private void MainWindowActivated(object sender, EventArgs e)
|
||||
{
|
||||
if (logWindow.IsVisible && !this.Topmost)
|
||||
{
|
||||
logWindow.Topmost = true;
|
||||
logWindow.Topmost = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MainWindow Closing event
|
||||
/// </summary>
|
||||
private void MainWindowClosing(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (logWindow.IsVisible)
|
||||
logWindow?.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MainWindow PositionChanged event
|
||||
/// </summary>
|
||||
private void MainWindowLocationChanged(object sender, PixelPointEventArgs e)
|
||||
{
|
||||
if (logWindow.IsVisible)
|
||||
logWindow.AdjustPositionToMainWindow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for OptionsMenuItem Click event
|
||||
/// </summary>
|
||||
private async void OptionsMenuItemClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Show the window and wait for the response
|
||||
var optionsWindow = new OptionsWindow();
|
||||
optionsWindow.UIOptions = UIOptions;
|
||||
optionsWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
await optionsWindow.ShowDialog(this);
|
||||
|
||||
// Set any new options
|
||||
PopulateDrives();
|
||||
GetOutputNames(false);
|
||||
SetSupportedDriveSpeed();
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for OutputDirectoryBrowseButton Click event
|
||||
/// </summary>
|
||||
private void OutputDirectoryBrowseButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
BrowseFolder();
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for OutputFilenameTextBox TextInput event
|
||||
/// </summary>
|
||||
// TODO: Not triggered properly
|
||||
private void OutputDirectoryTextBoxTextChanged(object sender, TextInputEventArgs e)
|
||||
{
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for OutputFilenameTextBox TextInput event
|
||||
/// </summary>
|
||||
// TODO: Not triggered properly
|
||||
private void OutputFilenameTextBoxTextChanged(object sender, TextInputEventArgs e)
|
||||
{
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for Result ProgressChanged event
|
||||
/// </summary>
|
||||
private void ProgressUpdated(object sender, Result value)
|
||||
{
|
||||
this.Find<TextBlock>("StatusLabel").Text = value.Message;
|
||||
ViewModels.LoggerViewModel.VerboseLogLn(value.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for FileProtection ProgressChanged event
|
||||
/// </summary>
|
||||
private void ProgressUpdated(object sender, FileProtection value)
|
||||
{
|
||||
string message = $"{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}";
|
||||
this.Find<TextBlock>("StatusLabel").Text = message;
|
||||
ViewModels.LoggerViewModel.VerboseLogLn(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for StartStopButton Click event
|
||||
/// </summary>
|
||||
private void StartStopButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Dump or stop the dump
|
||||
if ((string)this.Find<Button>("StartStopButton").Content == Constants.StartDumping)
|
||||
{
|
||||
StartDumping();
|
||||
}
|
||||
else if ((string)this.Find<Button>("StartStopButton").Content == Constants.StopDumping)
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
|
||||
Env.CancelDumping();
|
||||
this.Find<Button>("CopyProtectScanButton").IsEnabled = true;
|
||||
|
||||
if (this.Find<CheckBox>("EjectWhenDoneCheckBox").IsChecked == true)
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {Env.Drive.Letter}");
|
||||
Env.EjectDisc();
|
||||
}
|
||||
|
||||
if (UIOptions.ResetDriveAfterDump)
|
||||
{
|
||||
ViewModels.LoggerViewModel.VerboseLogLn($"Resetting drive {Env.Drive.Letter}");
|
||||
Env.ResetDrive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for SystemTypeComboBox SelectionChanged event
|
||||
/// </summary>
|
||||
private void SystemTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
// If we're on a separator, go to the next item and return
|
||||
if ((this.Find<ComboBox>("SystemTypeComboBox").SelectedItem as KnownSystemComboBoxItem).IsHeader())
|
||||
{
|
||||
this.Find<ComboBox>("SystemTypeComboBox").SelectedIndex++;
|
||||
return;
|
||||
}
|
||||
|
||||
ViewModels.LoggerViewModel.VerboseLogLn("Changed system to: {0}", (this.Find<ComboBox>("SystemTypeComboBox").SelectedItem as KnownSystemComboBoxItem).Name);
|
||||
PopulateMediaType();
|
||||
GetOutputNames(false);
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
17
DICUI.Avalonia/MessageBox.axaml
Normal file
17
DICUI.Avalonia/MessageBox.axaml
Normal file
@@ -0,0 +1,17 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
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" Icon="Icon.ico"
|
||||
x:Class="DICUI.Avalonia.MessageBox" SizeToContent="WidthAndHeight" CanResize="False">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBlock HorizontalAlignment="Center" Name="Text"/>
|
||||
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal" Name="Buttons">
|
||||
<StackPanel.Styles>
|
||||
<Style Selector="Button">
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
83
DICUI.Avalonia/MessageBox.axaml.cs
Normal file
83
DICUI.Avalonia/MessageBox.axaml.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
// https://stackoverflow.com/questions/55706291/how-to-show-a-message-box-in-avaloniaui-beta
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public enum MessageBoxButtons
|
||||
{
|
||||
Ok,
|
||||
OkCancel,
|
||||
YesNo,
|
||||
YesNoCancel
|
||||
}
|
||||
|
||||
public enum MessageBoxResult
|
||||
{
|
||||
Ok,
|
||||
Cancel,
|
||||
Yes,
|
||||
No
|
||||
}
|
||||
|
||||
public class MessageBox : Window
|
||||
{
|
||||
public MessageBox()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Task<MessageBoxResult> Show(Window parent, string text, string title, MessageBoxButtons buttons)
|
||||
{
|
||||
var msgbox = new MessageBox()
|
||||
{
|
||||
Title = title
|
||||
};
|
||||
msgbox.FindControl<TextBlock>("Text").Text = text;
|
||||
var buttonPanel = msgbox.FindControl<StackPanel>("Buttons");
|
||||
|
||||
var res = MessageBoxResult.Ok;
|
||||
|
||||
void AddButton(string caption, MessageBoxResult r, bool def = false)
|
||||
{
|
||||
var btn = new Button { Content = caption };
|
||||
btn.Click += (_, __) => {
|
||||
res = r;
|
||||
msgbox.Close();
|
||||
};
|
||||
buttonPanel.Children.Add(btn);
|
||||
if (def)
|
||||
res = r;
|
||||
}
|
||||
|
||||
if (buttons == MessageBoxButtons.Ok || buttons == MessageBoxButtons.OkCancel)
|
||||
AddButton("Ok", MessageBoxResult.Ok, true);
|
||||
if (buttons == MessageBoxButtons.YesNo || buttons == MessageBoxButtons.YesNoCancel)
|
||||
{
|
||||
AddButton("Yes", MessageBoxResult.Yes);
|
||||
AddButton("No", MessageBoxResult.No, true);
|
||||
}
|
||||
|
||||
if (buttons == MessageBoxButtons.OkCancel || buttons == MessageBoxButtons.YesNoCancel)
|
||||
AddButton("Cancel", MessageBoxResult.Cancel, true);
|
||||
|
||||
|
||||
var tcs = new TaskCompletionSource<MessageBoxResult>();
|
||||
msgbox.Closed += delegate { tcs.TrySetResult(res); };
|
||||
if (parent != null)
|
||||
msgbox.ShowDialog(parent);
|
||||
else msgbox.Show();
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
162
DICUI.Avalonia/OptionsWindow.axaml
Normal file
162
DICUI.Avalonia/OptionsWindow.axaml
Normal file
@@ -0,0 +1,162 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:DICUI.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="515.132" d:DesignHeight="600" Width="515.132" Height="600"
|
||||
x:Class="DICUI.Avalonia.OptionsWindow" Icon="Icon.ico" CanResize="False"
|
||||
Title="Options">
|
||||
|
||||
<Grid RowDefinitions="150,150,150,80,40">
|
||||
|
||||
<!-- Paths -->
|
||||
<Border Grid.Row="0" Grid.ColumnSpan="2" Margin="5" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="Paths" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="0" Grid.ColumnSpan="2" Margin="10,15,10,10" ColumnDefinitions="1*,2*,0.2*" RowDefinitions="Auto,Auto,Auto,Auto">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Aaru Path" />
|
||||
<TextBox Name="AaruPathTextBox" Grid.Row="0" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=AaruPath}" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
<Button Name="AaruPathButton" Grid.Row="0" Grid.Column="2" Height="25" Width="25" Content="..." Click="BrowseForPathClick" />
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="DiscImageCreator Path" />
|
||||
<TextBox Name="CreatorPathTextBox" Grid.Row="1" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=CreatorPath}" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
<Button Name="CreatorPathButton" Grid.Row="1" Grid.Column="2" Height="25" Width="25" Content="..." Click="BrowseForPathClick" />
|
||||
|
||||
<!--
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="dd Path" />
|
||||
<TextBox Name="DDPathTextBox" Grid.Row="0" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=DDPath}" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
<Button Name="DDPathButton" Grid.Row="0" Grid.Column="2" Height="25" Width="25" Content="..." Click="BrowseForPathClick" />
|
||||
-->
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Subdump Path" />
|
||||
<TextBox Name="SubDumpPathTextBox" Grid.Row="2" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=SubDumpPath}" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
<Button Name="SubDumpPathButton" Grid.Row="2" Grid.Column="2" Height="25" Width="25" Content="..." Click="BrowseForPathClick" />
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Default Output Path" />
|
||||
<TextBox Name="DefaultOutputPathTextBox" Grid.Row="3" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=DefaultOutputPath}" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
<Button Name="DefaultOutputPathButton" Grid.Row="3" Grid.Column="2" Height="25" Width="25" Content="..." Click="BrowseForPathClick" />
|
||||
</Grid>
|
||||
|
||||
<!-- Dumping Speeds -->
|
||||
<Border Grid.Row="1" Grid.ColumnSpan="2" Margin="5" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="Preferred Dump Speed" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="1" Grid.ColumnSpan="2" Margin="10,15,10,10" ColumnDefinitions="80,2*,40" RowDefinitions="1*,Auto,Auto,Auto">
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="CD-ROM" Margin="5" />
|
||||
<Slider Name="DumpSpeedCDSlider" Grid.Row="1" Grid.Column="1" Minimum="0" Maximum="72" Margin="5"
|
||||
IsSnapToTickEnabled="True" TickFrequency="4"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Value="{Binding Path=PreferredDumpSpeedCD}" />
|
||||
<!-- Ticks="{Binding Source={x:Static local:Constants.SpeedsForCDAsCollection}}" -->
|
||||
<TextBox Name="DumpSpeedCDTextBox" Grid.Row="1" Grid.Column="2" Width="25" Height="25" TextAlignment="Center" VerticalAlignment="Center"
|
||||
IsReadOnly="True" Text="{Binding ElementName=DumpSpeedCDSlider, Path=Value}"
|
||||
Background="LightGray" Foreground="Gray" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="DVD-ROM" Margin="5" />
|
||||
<Slider Name="DumpSpeedDVDSlider" Grid.Row="2" Grid.Column="1" Minimum="0" Maximum="24" Margin="5"
|
||||
IsSnapToTickEnabled="True" TickFrequency="2"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Value="{Binding Path=PreferredDumpSpeedDVD}" />
|
||||
<!-- Ticks="{Binding Source={x:Static local:Constants.SpeedsForDVDAsCollection}}" -->
|
||||
<TextBox Name="DumpSpeedDVDTextBox" Grid.Row="2" Grid.Column="2" Width="25" Height="25" TextAlignment="Center" VerticalAlignment="Center"
|
||||
IsReadOnly="True" Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value}"
|
||||
Background="LightGray" Foreground="Gray" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="BD-ROM" Margin="5" />
|
||||
<Slider Name="DumpSpeedBDSlider" Grid.Row="3" Grid.Column="1" Minimum="0" Maximum="16" Margin="5"
|
||||
IsSnapToTickEnabled="True" TickFrequency="2"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Value="{Binding Path=PreferredDumpSpeedBD}" />
|
||||
<!-- Ticks="{Binding Source={x:Static local:Constants.SpeedsForBDAsCollection}}" -->
|
||||
<TextBox Name="DumpSpeedBDTextBox" Grid.Row="3" Grid.Column="2" Width="25" Height="25" TextAlignment="Center" VerticalAlignment="Center"
|
||||
IsReadOnly="True" Text="{Binding ElementName=DumpSpeedBDSlider, Path=Value}"
|
||||
Background="LightGray" Foreground="Gray" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
</Grid>
|
||||
|
||||
<!-- Misc. Options -->
|
||||
<Border Grid.Row="2" Grid.ColumnSpan="2" Margin="5" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="Options" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="2" Grid.ColumnSpan="2" Margin="10,15,10,10" ColumnDefinitions="1*,1*,1*,1*" RowDefinitions="1*,Auto,Auto,Auto">
|
||||
<CheckBox Grid.Row="1" Grid.Column="0" Margin="0,4" VerticalAlignment="Center" Content="Quiet Mode"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=QuietMode}"
|
||||
ToolTip.Tip="Disable DiscImageCreator sounds" />
|
||||
|
||||
<CheckBox Grid.Row="1" Grid.Column="1" Margin="0,4" VerticalAlignment="Center" Content="Paranoid Mode"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=ParanoidMode}"
|
||||
ToolTip.Tip="Enable pedantic and super-safe flags" />
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" Margin="5" Text="Reread Tries:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="3" Margin="0,4" VerticalAlignment="Center"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=RereadAmountForC2}"
|
||||
ToolTip.Tip="Specifies how many rereads are attempted on C2 error" />
|
||||
|
||||
<CheckBox Grid.Row="2" Grid.Column="0" Margin="0,4" VerticalAlignment="Center" Content="Protection Scan"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=ScanForProtection}"
|
||||
ToolTip.Tip="Enable automatic checking for copy protection on dumped media" />
|
||||
|
||||
<CheckBox Grid.Row="2" Grid.Column="1" Margin="0,4" VerticalAlignment="Center" Content="Skip Type Detect"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=SkipMediaTypeDetection}"
|
||||
ToolTip.Tip="Disable trying to guess media type inserted (may improve performance at startup)" />
|
||||
|
||||
<CheckBox Grid.Row="2" Grid.Column="2" Margin="0,4" VerticalAlignment="Center" Content="Add Placeholders"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=AddPlaceholders}"
|
||||
ToolTip.Tip="Enable adding placeholder text in the submissioninfo output for required and optional fields" />
|
||||
|
||||
<CheckBox Grid.Row="3" Grid.Column="0" Margin="0,4" VerticalAlignment="Center" Content="Show Disc Info"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=PromptForDiscInformation}"
|
||||
ToolTip.Tip="Enable showing the disc information output after dumping" />
|
||||
|
||||
<CheckBox Grid.Row="3" Grid.Column="1" Margin="0,4" VerticalAlignment="Center" Content="No Fixed Drives"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=IgnoreFixedDrives}"
|
||||
ToolTip.Tip="Ignore hard drives and other fixed drives" />
|
||||
|
||||
<CheckBox Grid.Row="3" Grid.Column="2" Margin="0,4" VerticalAlignment="Center" Content="Reset After Dump"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
IsChecked="{Binding Path=ResetDriveAfterDump}"
|
||||
ToolTip.Tip="Reset disc drives after dumping; useful for some older machines" />
|
||||
</Grid>
|
||||
|
||||
<!-- Redump -->
|
||||
<Border Grid.Row="3" Grid.ColumnSpan="2" Margin="5" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="Redump Login" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontSize="14" Foreground="Gray" />
|
||||
</Border>
|
||||
<Grid Grid.Row="3" Grid.ColumnSpan="2" Margin="10,15,10,10" ColumnDefinitions="1*,1*,1*,1*,1.2*" RowDefinitions="1*,Auto">
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Username" />
|
||||
<TextBox Name="RedumpUsernameTextBox" Grid.Row="1" Grid.Column="1" Height="25" HorizontalAlignment="Stretch"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=Username}" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5" Text="Username" />
|
||||
<TextBox Name="RedumpPasswordTextBox" Grid.Row="1" Grid.Column="3" Height="25" HorizontalAlignment="Stretch" PasswordChar="*"
|
||||
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
|
||||
Text="{Binding Path=Password}" ScrollViewer.VerticalScrollBarVisibility="Disabled" />
|
||||
|
||||
<Button Name="RedumpLoginTestButton" Grid.Row="1" Grid.Column="5" Height="25" Width="80" Content="Test Login" Click="OnRedumpTestClick" />
|
||||
</Grid>
|
||||
|
||||
<!-- Accept / Cancel -->
|
||||
<Grid Height="25" Grid.Row="4" Grid.Column="0" ColumnDefinitions="2*,1*,1*">
|
||||
<Button Name="AcceptButton" Grid.Row="0" Grid.Column="1" Height="25" Width="80" Content="Accept" Click="OnAcceptClick" />
|
||||
<Button Name="CancelButton" Grid.Row="0" Grid.Column="2" Height="25" Width="80" Content="Cancel" Click="OnCancelClick" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
142
DICUI.Avalonia/OptionsWindow.axaml.cs
Normal file
142
DICUI.Avalonia/OptionsWindow.axaml.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using DICUI.Web;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public class OptionsWindow : Window
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Current UI options
|
||||
/// </summary>
|
||||
public UIOptions UIOptions { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
public OptionsWindow()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Find a TextBox by setting name
|
||||
/// </summary>
|
||||
/// <param name="name">Setting name to find</param>
|
||||
/// <returns>TextBox for that setting</returns>
|
||||
private TextBox TextBoxForPathSetting(string name)
|
||||
{
|
||||
return this.Find<TextBox>(name + "TextBox");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handler for generic Click event
|
||||
/// </summary>
|
||||
private async void BrowseForPathClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Button button = sender as Button;
|
||||
|
||||
// strips button prefix to obtain the setting name
|
||||
string pathSettingName = button.Name.Substring(0, button.Name.IndexOf("Button"));
|
||||
|
||||
// TODO: hack for now, then we'll see
|
||||
bool shouldBrowseForPath = pathSettingName == "DefaultOutputPath";
|
||||
|
||||
// Directory
|
||||
if (shouldBrowseForPath)
|
||||
{
|
||||
OpenFolderDialog dialog = new OpenFolderDialog();
|
||||
string result = await dialog.ShowAsync(this);
|
||||
if (!string.IsNullOrWhiteSpace(result))
|
||||
{
|
||||
if (Directory.Exists(result))
|
||||
TextBoxForPathSetting(pathSettingName).Text = result;
|
||||
else
|
||||
Console.WriteLine($"Path '{result}' cannot be found!");
|
||||
}
|
||||
}
|
||||
|
||||
// File
|
||||
else
|
||||
{
|
||||
OpenFileDialog dialog = new OpenFileDialog();
|
||||
string[] result = await dialog.ShowAsync(this);
|
||||
if (result != null && result.Length > 0 && !string.IsNullOrWhiteSpace(result[0]))
|
||||
{
|
||||
if (File.Exists(result[0]))
|
||||
TextBoxForPathSetting(pathSettingName).Text = result[0];
|
||||
else
|
||||
Console.WriteLine($"Path '{result[0]}' cannot be found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AcceptButton Click event
|
||||
/// </summary>
|
||||
private void OnAcceptClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
UIOptions.Save();
|
||||
Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CancelButton Click event
|
||||
/// </summary>
|
||||
private void OnCancelClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for RedumpLoginTestButton Click event
|
||||
/// </summary>
|
||||
private void OnRedumpTestClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
using (RedumpWebClient wc = new RedumpWebClient())
|
||||
{
|
||||
if (wc.Login(this.Find<TextBox>("RedumpUsernameTextBox").Text, this.Find<TextBox>("RedumpPasswordTextBox").Text))
|
||||
{
|
||||
new Window()
|
||||
{
|
||||
Title = "Success",
|
||||
Content = "Redump login credentials accepted!",
|
||||
SizeToContent = SizeToContent.WidthAndHeight,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
||||
}.ShowDialog(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
new Window()
|
||||
{
|
||||
Title = "Failure",
|
||||
Content = "Redump login credentials denied!",
|
||||
SizeToContent = SizeToContent.WidthAndHeight,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
||||
}.ShowDialog(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
22
DICUI.Avalonia/Program.cs
Normal file
22
DICUI.Avalonia/Program.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Logging.Serilog;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
class Program
|
||||
{
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.LogToDebug();
|
||||
}
|
||||
}
|
||||
122
DICUI.Avalonia/UIOptions.cs
Normal file
122
DICUI.Avalonia/UIOptions.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using DICUI.Data;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public class UIOptions
|
||||
{
|
||||
// TODO: Is there any way that this can be made private?
|
||||
public Options Options { get; set; }
|
||||
|
||||
#region Passthrough readonly values
|
||||
|
||||
// TODO: Can any of these be removed?
|
||||
public string DefaultOutputPath { get { return Options.DefaultOutputPath; } }
|
||||
public bool IgnoreFixedDrives { get { return Options.IgnoreFixedDrives; } }
|
||||
public bool ResetDriveAfterDump { get { return Options.ResetDriveAfterDump; } }
|
||||
public bool SkipMediaTypeDetection { get { return Options.SkipMediaTypeDetection; } }
|
||||
public bool SkipSystemDetection { get { return Options.SkipSystemDetection; } }
|
||||
public bool OpenLogWindowAtStartup { get { return Options.OpenLogWindowAtStartup; } }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public UIOptions()
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save a configuration from internal Options
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
|
||||
// Loop through all settings in Options and save them, overwriting existing settings
|
||||
foreach (var kvp in Options)
|
||||
{
|
||||
configFile.AppSettings.Settings.Remove(kvp.Key);
|
||||
configFile.AppSettings.Settings.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
configFile.Save(ConfigurationSaveMode.Modified);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a configuration into internal Options
|
||||
/// </summary>
|
||||
private void Load()
|
||||
{
|
||||
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
|
||||
var settings = ConvertToDictionary(configFile);
|
||||
Options = new Options(settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a setting value from the base Options
|
||||
/// </summary>
|
||||
/// <param name="key">Key to retrieve the value for</param>
|
||||
/// <returns>String value if possible, null otherwise</returns>
|
||||
public string Get(string key)
|
||||
{
|
||||
return Options[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a setting value in the base Options
|
||||
/// </summary>
|
||||
/// <param name="key">Key to set the value for</param>
|
||||
/// <param name="value">Value to set</param>
|
||||
public void Set(string key, string value)
|
||||
{
|
||||
Options[key] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the preferred dumping speed given a media type
|
||||
/// </summary>
|
||||
/// <param name="type">MediaType representing the current selection</param>
|
||||
/// <returns>Int value representing the dump speed</returns>
|
||||
public int GetPreferredDumpSpeedForMediaType(MediaType? type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MediaType.CDROM:
|
||||
case MediaType.GDROM:
|
||||
return this.Options.PreferredDumpSpeedCD;
|
||||
case MediaType.DVD:
|
||||
case MediaType.HDDVD:
|
||||
case MediaType.NintendoGameCubeGameDisc:
|
||||
case MediaType.NintendoWiiOpticalDisc:
|
||||
return this.Options.PreferredDumpSpeedDVD;
|
||||
case MediaType.BluRay:
|
||||
return this.Options.PreferredDumpSpeedBD;
|
||||
default:
|
||||
return this.Options.PreferredDumpSpeedCD;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert the configuration app settings to a dictionary
|
||||
/// </summary>
|
||||
/// <param name="configFile">Configuration to load from</param>
|
||||
/// <returns>Dictionary with all values from app settings</returns>
|
||||
private Dictionary<string, string> ConvertToDictionary(Configuration configFile)
|
||||
{
|
||||
var settings = configFile.AppSettings.Settings;
|
||||
var dict = new Dictionary<string, string>();
|
||||
|
||||
foreach (string key in settings.AllKeys)
|
||||
{
|
||||
dict[key] = settings[key]?.Value ?? string.Empty;
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
233
DICUI.Avalonia/ViewModels.cs
Normal file
233
DICUI.Avalonia/ViewModels.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace DICUI.Avalonia
|
||||
{
|
||||
public class OptionsViewModel
|
||||
{
|
||||
private UIOptions _uiOptions;
|
||||
|
||||
#region Internal Program
|
||||
|
||||
public string AaruPath
|
||||
{
|
||||
get { return _uiOptions.Options.AaruPath; }
|
||||
set { _uiOptions.Options.AaruPath = value; }
|
||||
}
|
||||
|
||||
public string CreatorPath
|
||||
{
|
||||
get { return _uiOptions.Options.CreatorPath; }
|
||||
set { _uiOptions.Options.CreatorPath = value; }
|
||||
}
|
||||
|
||||
public string DDPath
|
||||
{
|
||||
get { return _uiOptions.Options.DDPath; }
|
||||
set { _uiOptions.Options.DDPath = value; }
|
||||
}
|
||||
|
||||
public string InternalProgram
|
||||
{
|
||||
get { return _uiOptions.Options.InternalProgram; }
|
||||
set { _uiOptions.Options.InternalProgram = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Extra Paths
|
||||
|
||||
public string DefaultOutputPath
|
||||
{
|
||||
get { return _uiOptions.Options.DefaultOutputPath; }
|
||||
set { _uiOptions.Options.DefaultOutputPath = value; }
|
||||
}
|
||||
|
||||
public string SubDumpPath
|
||||
{
|
||||
get { return _uiOptions.Options.SubDumpPath; }
|
||||
set { _uiOptions.Options.SubDumpPath = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dumping Speeds
|
||||
|
||||
public int PreferredDumpSpeedCD
|
||||
{
|
||||
get { return _uiOptions.Options.PreferredDumpSpeedCD; }
|
||||
set { _uiOptions.Options.PreferredDumpSpeedCD = value; }
|
||||
}
|
||||
|
||||
public int PreferredDumpSpeedDVD
|
||||
{
|
||||
get { return _uiOptions.Options.PreferredDumpSpeedDVD; }
|
||||
set { _uiOptions.Options.PreferredDumpSpeedDVD = value; }
|
||||
}
|
||||
|
||||
public int PreferredDumpSpeedBD
|
||||
{
|
||||
get { return _uiOptions.Options.PreferredDumpSpeedBD; }
|
||||
set { _uiOptions.Options.PreferredDumpSpeedBD = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Extra Dumping Options
|
||||
|
||||
public bool QuietMode
|
||||
{
|
||||
get { return _uiOptions.Options.QuietMode; }
|
||||
set { _uiOptions.Options.QuietMode = value; }
|
||||
}
|
||||
|
||||
public bool ParanoidMode
|
||||
{
|
||||
get { return _uiOptions.Options.ParanoidMode; }
|
||||
set { _uiOptions.Options.ParanoidMode = value; }
|
||||
}
|
||||
|
||||
public bool ScanForProtection
|
||||
{
|
||||
get { return _uiOptions.Options.ScanForProtection; }
|
||||
set { _uiOptions.Options.ScanForProtection = value; }
|
||||
}
|
||||
|
||||
public string RereadAmountForC2
|
||||
{
|
||||
get { return Convert.ToString(_uiOptions.Options.RereadAmountForC2); }
|
||||
set
|
||||
{
|
||||
if (Int32.TryParse(value, out int result))
|
||||
_uiOptions.Options.RereadAmountForC2 = result;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddPlaceholders
|
||||
{
|
||||
get { return _uiOptions.Options.AddPlaceholders; }
|
||||
set { _uiOptions.Options.AddPlaceholders = value; }
|
||||
}
|
||||
|
||||
public bool PromptForDiscInformation
|
||||
{
|
||||
get { return _uiOptions.Options.PromptForDiscInformation; }
|
||||
set { _uiOptions.Options.PromptForDiscInformation = value; }
|
||||
}
|
||||
|
||||
public bool IgnoreFixedDrives
|
||||
{
|
||||
get { return _uiOptions.Options.IgnoreFixedDrives; }
|
||||
set { _uiOptions.Options.IgnoreFixedDrives = value; }
|
||||
}
|
||||
|
||||
public bool ResetDriveAfterDump
|
||||
{
|
||||
get { return _uiOptions.Options.ResetDriveAfterDump; }
|
||||
set { _uiOptions.Options.ResetDriveAfterDump = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Skip Options
|
||||
|
||||
public bool SkipMediaTypeDetection
|
||||
{
|
||||
get { return _uiOptions.Options.SkipMediaTypeDetection; }
|
||||
set { _uiOptions.Options.SkipMediaTypeDetection = value; }
|
||||
}
|
||||
|
||||
public bool SkipSystemDetection
|
||||
{
|
||||
get { return _uiOptions.Options.SkipSystemDetection; }
|
||||
set { _uiOptions.Options.SkipSystemDetection = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Logging Options
|
||||
|
||||
public bool VerboseLogging
|
||||
{
|
||||
get { return _uiOptions.Options.VerboseLogging; }
|
||||
set
|
||||
{
|
||||
_uiOptions.Options.VerboseLogging = value;
|
||||
_uiOptions.Save(); // TODO: Why does this save here?
|
||||
}
|
||||
}
|
||||
|
||||
public bool OpenLogWindowAtStartup
|
||||
{
|
||||
get { return _uiOptions.Options.OpenLogWindowAtStartup; }
|
||||
set
|
||||
{
|
||||
_uiOptions.Options.OpenLogWindowAtStartup = value;
|
||||
_uiOptions.Save(); // TODO: Why does this save here?
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Redump Login Information
|
||||
|
||||
public string Username
|
||||
{
|
||||
get { return _uiOptions.Options.Username; }
|
||||
set { _uiOptions.Options.Username = value; }
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get { return _uiOptions.Options.Password; }
|
||||
set { _uiOptions.Options.Password = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public OptionsViewModel(UIOptions uiOptions)
|
||||
{
|
||||
this._uiOptions = uiOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public class LoggerViewModel
|
||||
{
|
||||
private LogWindow _logWindow;
|
||||
|
||||
public void SetWindow(LogWindow logWindow) => _logWindow = logWindow;
|
||||
|
||||
public bool WindowVisible
|
||||
{
|
||||
get => _logWindow != null ? _logWindow.IsVisible : false;
|
||||
set
|
||||
{
|
||||
if (_logWindow == null)
|
||||
_logWindow = new LogWindow();
|
||||
|
||||
if (value)
|
||||
{
|
||||
_logWindow.AdjustPositionToMainWindow();
|
||||
_logWindow.Show();
|
||||
}
|
||||
else
|
||||
_logWindow.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public void VerboseLog(string text)
|
||||
{
|
||||
if (ViewModels.OptionsViewModel.VerboseLogging)
|
||||
_logWindow.AppendToTextBox(text, Brushes.Yellow);
|
||||
}
|
||||
|
||||
public void VerboseLog(string format, params object[] args) => VerboseLog(string.Format(format, args));
|
||||
public void VerboseLogLn(string format, params object[] args) => VerboseLog(string.Format(format, args) + "\n");
|
||||
}
|
||||
|
||||
public static class ViewModels
|
||||
{
|
||||
public static OptionsViewModel OptionsViewModel { get; set; }
|
||||
public static LoggerViewModel LoggerViewModel { get; set; } = new LoggerViewModel();
|
||||
}
|
||||
}
|
||||
11
DICUI.Avalonia/nuget.config
Normal file
11
DICUI.Avalonia/nuget.config
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
To use the Avalonia CI feed to get unstable packages, move this file to the root of your solution.
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="AvaloniaCI" value="https://www.myget.org/F/avalonia-ci/api/v2" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFrameworks>net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFrameworks>net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -804,31 +804,31 @@ namespace DICUI.Utilities
|
||||
|
||||
#region Possibly useful fields
|
||||
|
||||
foreach (var property in queryObj.Properties)
|
||||
{
|
||||
Console.WriteLine(property);
|
||||
}
|
||||
//foreach (var property in queryObj.Properties)
|
||||
//{
|
||||
// Console.WriteLine(property);
|
||||
//}
|
||||
|
||||
// Capabilities list
|
||||
ushort[] capabilities = (ushort[])queryObj["Capabilities"];
|
||||
//// Capabilities list
|
||||
//ushort?[] capabilities = (ushort?[])queryObj["Capabilities"];
|
||||
|
||||
// Internal name of the device
|
||||
string caption = (string)queryObj["Caption"];
|
||||
//// Internal name of the device
|
||||
//string caption = (string)queryObj["Caption"];
|
||||
|
||||
// Flags for the file system, see FileSystemFlags
|
||||
uint fileSystemFlagsEx = (uint)queryObj["FileSystemFlagsEx"];
|
||||
//// Flags for the file system, see FileSystemFlags
|
||||
//uint? fileSystemFlagsEx = (uint?)queryObj["FileSystemFlagsEx"];
|
||||
|
||||
// "CD Writer" doesn't fit https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-cdromdrive
|
||||
string mediaTypeString = (string)queryObj["MediaType"];
|
||||
//// "CD Writer" doesn't fit https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-cdromdrive
|
||||
//string mediaTypeString = (string)queryObj["MediaType"];
|
||||
|
||||
// Internal name of the device (Seems like a duplicate of Caption)
|
||||
string name = (string)queryObj["Name"];
|
||||
//// Internal name of the device (Seems like a duplicate of Caption)
|
||||
//string name = (string)queryObj["Name"];
|
||||
|
||||
// Full device ID for the drive (Seems like duplicate of DeviceID)
|
||||
string pnpDeviceId = (string)queryObj["PNPDeviceId"];
|
||||
//// Full device ID for the drive (Seems like duplicate of DeviceID)
|
||||
//string pnpDeviceId = (string)queryObj["PNPDeviceId"];
|
||||
|
||||
// Size of the loaded media (extrapolate disc type from this?)
|
||||
ulong size = (ulong)queryObj["Size"];
|
||||
//// Size of the loaded media (extrapolate disc type from this?)
|
||||
//ulong? size = (ulong?)queryObj["Size"];
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFrameworks>net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
14
DICUI.sln
14
DICUI.sln
@@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28803.156
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI", "DICUI\DICUI.csproj", "{7B1B75EB-8940-466F-BD51-76471A57F9BE}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DICUI", "DICUI\DICUI.csproj", "{7B1B75EB-8940-466F-BD51-76471A57F9BE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Test", "DICUI.Test\DICUI.Test.csproj", "{7CC064D2-38AB-4A05-8519-28660DE4562A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DICUI.Test", "DICUI.Test\DICUI.Test.csproj", "{7CC064D2-38AB-4A05-8519-28660DE4562A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Library", "DICUI.Library\DICUI.Library.csproj", "{51AB0928-13F9-44BF-A407-B6957A43A056}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DICUI.Library", "DICUI.Library\DICUI.Library.csproj", "{51AB0928-13F9-44BF-A407-B6957A43A056}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Check", "DICUI.Check\DICUI.Check.csproj", "{8CFDE289-E171-4D49-A40D-5293265C1253}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DICUI.Check", "DICUI.Check\DICUI.Check.csproj", "{8CFDE289-E171-4D49-A40D-5293265C1253}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4D1DCF5A-F0B0-4E81-A05B-F1A7D37C9D9D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Avalonia", "DICUI.Avalonia\DICUI.Avalonia.csproj", "{2D09902F-D93E-42D9-84C7-E0246A2EF1CD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -40,6 +42,10 @@ Global
|
||||
{8CFDE289-E171-4D49-A40D-5293265C1253}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8CFDE289-E171-4D49-A40D-5293265C1253}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8CFDE289-E171-4D49-A40D-5293265C1253}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2D09902F-D93E-42D9-84C7-E0246A2EF1CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2D09902F-D93E-42D9-84C7-E0246A2EF1CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2D09902F-D93E-42D9-84C7-E0246A2EF1CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2D09902F-D93E-42D9-84C7-E0246A2EF1CD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<TargetFrameworks>net472;net48;netcoreapp3.1</TargetFrameworks>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
|
||||
36
appveyor.yml
36
appveyor.yml
@@ -36,36 +36,56 @@ after_build:
|
||||
- ps: appveyor DownloadFile http://www.chrysocome.net/downloads/8ab730cd2a29e76ddd89be1f99357942/dd-0.6beta3.zip
|
||||
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/4931645/DiscImageCreator_20200716.zip
|
||||
- ps: appveyor DownloadFile https://archive.org/download/subdump_fua_0x28/subdump_fua_0x28.zip
|
||||
- 7z e aaru-5.1.0.3214-1_windows_x64.zip -oDICUI\bin\Debug\net462\Programs\Aaru *
|
||||
|
||||
- 7z e aaru-5.1.0.3214-1_windows_x64.zip -oDICUI\bin\Debug\net472\Programs\Aaru *
|
||||
- 7z e aaru-5.1.0.3214-1_windows_x64.zip -oDICUI\bin\Debug\net48\Programs\Aaru *
|
||||
- 7z e aaru-5.1.0.3214-1_windows_x64.zip -oDICUI\bin\Debug\netcoreapp3.1\Programs\Aaru *
|
||||
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\net462\Programs\DD *
|
||||
- 7z e aaru-5.1.0.3214-1_windows_x64.zip -oDICUI.Avalonia\bin\Debug\net472\Programs\Aaru *
|
||||
- 7z e aaru-5.1.0.3214-1_windows_x64.zip -oDICUI.Avalonia\bin\Debug\net48\Programs\Aaru *
|
||||
- 7z e aaru-5.1.0.3214-1_windows_x64.zip -oDICUI.Avalonia\bin\Debug\netcoreapp3.1\Programs\Aaru *
|
||||
|
||||
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\net472\Programs\DD *
|
||||
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\net48\Programs\DD *
|
||||
- 7z e dd-0.6beta3.zip -oDICUI\bin\Debug\netcoreapp3.1\Programs\DD *
|
||||
- 7z e DiscImageCreator_20200716.zip -oDICUI\bin\Debug\net462\Programs\Creator Release_ANSI\*
|
||||
- 7z e dd-0.6beta3.zip -oDICUI.Avalonia\bin\Debug\net472\Programs\DD *
|
||||
- 7z e dd-0.6beta3.zip -oDICUI.Avalonia\bin\Debug\net48\Programs\DD *
|
||||
- 7z e dd-0.6beta3.zip -oDICUI.Avalonia\bin\Debug\netcoreapp3.1\Programs\DD *
|
||||
|
||||
- 7z e DiscImageCreator_20200716.zip -oDICUI\bin\Debug\net472\Programs\Creator Release_ANSI\*
|
||||
- 7z e DiscImageCreator_20200716.zip -oDICUI\bin\Debug\net48\Programs\Creator Release_ANSI\*
|
||||
- 7z e DiscImageCreator_20200716.zip -oDICUI\bin\Debug\netcoreapp3.1\Programs\Creator Release_ANSI\*
|
||||
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net462 *
|
||||
- mkdir DICUI\bin\Debug\net462\Programs\Subdump
|
||||
- mv DICUI\bin\Debug\net462\subdump_fua_0x28.exe DICUI\bin\Debug\net462\Programs\Subdump\subdump.exe
|
||||
- 7z e DiscImageCreator_20200716.zip -oDICUI.Avalonia\bin\Debug\net472\Programs\Creator Release_ANSI\*
|
||||
- 7z e DiscImageCreator_20200716.zip -oDICUI.Avalonia\bin\Debug\net48\Programs\Creator Release_ANSI\*
|
||||
- 7z e DiscImageCreator_20200716.zip -oDICUI.Avalonia\bin\Debug\netcoreapp3.1\Programs\Creator Release_ANSI\*
|
||||
|
||||
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net472 *
|
||||
- mkdir DICUI\bin\Debug\net472\Programs\Subdump
|
||||
- mv DICUI\bin\Debug\net472\subdump_fua_0x28.exe DICUI\bin\Debug\net472\Programs\Subdump\subdump.exe
|
||||
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net48 *
|
||||
- mkdir DICUI\bin\Debug\net48\Programs\Subdump
|
||||
- mv DICUI\bin\Debug\net48\subdump_fua_0x28.exe DICUI\bin\Debug\net462\Programs\Subdump\subdump.exe
|
||||
- mv DICUI\bin\Debug\net48\subdump_fua_0x28.exe DICUI\bin\Debug\net48\Programs\Subdump\subdump.exe
|
||||
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\netcoreapp3.1 *
|
||||
- mkdir DICUI\bin\Debug\netcoreapp3.1\Programs\Subdump
|
||||
- mv DICUI\bin\Debug\netcoreapp3.1\subdump_fua_0x28.exe DICUI\bin\Debug\netcoreapp3.1\Programs\Subdump\subdump.exe
|
||||
- 7z e subdump_fua_0x28.zip -oDICUI.Avalonia\bin\Debug\net472 *
|
||||
- mkdir DICUI.Avalonia\bin\Debug\net472\Programs\Subdump
|
||||
- mv DICUI.Avalonia\bin\Debug\net472\subdump_fua_0x28.exe DICUI.Avalonia\bin\Debug\net472\Programs\Subdump\subdump.exe
|
||||
- 7z e subdump_fua_0x28.zip -oDICUI.Avalonia\bin\Debug\net48 *
|
||||
- mkdir DICUI.Avalonia\bin\Debug\net48\Programs\Subdump
|
||||
- mv DICUI.Avalonia\bin\Debug\net48\subdump_fua_0x28.exe DICUI.Avalonia\bin\Debug\net48\Programs\Subdump\subdump.exe
|
||||
- 7z e subdump_fua_0x28.zip -oDICUI.Avalonia\bin\Debug\netcoreapp3.1 *
|
||||
- mkdir DICUI.Avalonia\bin\Debug\netcoreapp3.1\Programs\Subdump
|
||||
- mv DICUI.Avalonia\bin\Debug\netcoreapp3.1\subdump_fua_0x28.exe DICUI.Avalonia\bin\Debug\netcoreapp3.1\Programs\Subdump\subdump.exe
|
||||
|
||||
- 7z a DICUI.zip DICUI\bin\Debug\*
|
||||
- 7z a DICUI-Avalonia.zip DICUI.Avalonia\bin\Debug\*
|
||||
- 7z a DICUI-Check.zip DICUI.Check\bin\Debug\*
|
||||
|
||||
# artifact linking
|
||||
artifacts:
|
||||
- path: DICUI.zip
|
||||
name: DICUI
|
||||
name: DICUI (WPF UI)
|
||||
- path: DICUI-Avalonia.zip
|
||||
name: DICUI (Avalonia UI)
|
||||
- path: DICUI-Check.zip
|
||||
name: DICUI Check
|
||||
|
||||
Reference in New Issue
Block a user