mirror of
https://github.com/SabreTools/MPF.git
synced 2026-02-04 21:30:11 +00:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f4921a47c | ||
|
|
07359d2a63 | ||
|
|
e5ba670c04 | ||
|
|
3096c369d3 | ||
|
|
333368675a | ||
|
|
d78d744ae2 | ||
|
|
a8efe056c1 | ||
|
|
9b2475a854 | ||
|
|
33e2b27e6d | ||
|
|
91fe9d9bec | ||
|
|
b1b9b3134f | ||
|
|
ca5386b529 | ||
|
|
347beca874 | ||
|
|
27ca4fd1af | ||
|
|
6d57a05f8c | ||
|
|
4d81449cfa | ||
|
|
76fcb3ae10 | ||
|
|
b913f5f9ae | ||
|
|
68fa1eecfb | ||
|
|
dc84f17ac5 | ||
|
|
c91137130b | ||
|
|
972b07551f | ||
|
|
61562fe995 | ||
|
|
01b6c3cc98 | ||
|
|
b461dc76b9 | ||
|
|
03eeed4113 | ||
|
|
07615cb336 | ||
|
|
9a9a977cc4 | ||
|
|
ab5869331b | ||
|
|
1c9ebfd703 | ||
|
|
a9bc3587a6 | ||
|
|
b1af2b6061 | ||
|
|
2fccd53098 | ||
|
|
a7ad3e41d9 | ||
|
|
1fc6476f71 | ||
|
|
53e5a1b1b1 | ||
|
|
119e9dc4cc | ||
|
|
9263769906 | ||
|
|
ebaf9539b2 | ||
|
|
818fb5ab34 | ||
|
|
2f514082a9 | ||
|
|
5c5379e972 | ||
|
|
c39894d9fc | ||
|
|
2c6cf0e736 | ||
|
|
7e96bbee27 | ||
|
|
f7019546d1 | ||
|
|
086f54abf0 | ||
|
|
143a4149bd | ||
|
|
20aed68d58 |
@@ -1,3 +1,32 @@
|
||||
### 2.1 (2021-07-22)
|
||||
- Enum, no more
|
||||
- Sony works backward
|
||||
- Add experimental dark mode
|
||||
- Allow users to customize protection scanning
|
||||
- Fix negative offsets for `/a` flag
|
||||
- Always check for all DIC log files, just in case
|
||||
- Check for the zipped logs for dealing with overwrites
|
||||
- Be smarter about checking for zipped logs
|
||||
- Change offset value for HVN discs
|
||||
- Update to DIC 20210601
|
||||
- Fix Aaru command normalization
|
||||
- Handle carriage returns better
|
||||
- Add logging helper class
|
||||
- Set matcher on carriage return for log formatting
|
||||
- Replace dumping program output processing
|
||||
- Fix volume name detection for XBOX discs
|
||||
- Add new setting for including artifacts in serialzied JSON
|
||||
- Fix logging in to Redump for verifications
|
||||
- Gracefully handle timeouts during login
|
||||
- Update to DIC 20210701
|
||||
- Support `/mr` value parameter
|
||||
- Support new mainInfo header
|
||||
- Add BD to IBM-PC supported discs
|
||||
- Fix launching MPF on Windows 7
|
||||
- Fix log window background turning white
|
||||
- Add DMI/PFI/SS to log zipfile
|
||||
- Update to BurnOutSharp 1.7.0
|
||||
|
||||
### 2.0 (2021-04-23)
|
||||
- Rename DICUI to Media Preservation Frontend (MPF)
|
||||
- Add handling for BEh drive _mainInfo.txt changes
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net48;netcoreapp3.1</TargetFrameworks>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<Title>MPF Check</Title>
|
||||
<AssemblyName>MPF.Check</AssemblyName>
|
||||
<Description>Validator for various dumping programs</Description>
|
||||
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
|
||||
<Copyright>Copyright (c)2019-2021</Copyright>
|
||||
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
|
||||
<Version>2.0</Version>
|
||||
<Version>2.1</Version>
|
||||
<AssemblyVersion>$(Version)</AssemblyVersion>
|
||||
<FileVersion>$(Version)</FileVersion>
|
||||
<IncludeSource>true</IncludeSource>
|
||||
@@ -28,10 +28,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="1.6.1" GeneratePathProperty="true">
|
||||
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="1.7.0" GeneratePathProperty="true">
|
||||
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.0" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace MPF.Aaru
|
||||
/// </summary>
|
||||
public static class CommandStrings
|
||||
{
|
||||
public const string NONE = "";
|
||||
|
||||
// Database Family
|
||||
public const string DatabasePrefixShort = "db";
|
||||
public const string DatabasePrefixLong = "database";
|
||||
|
||||
@@ -18,407 +18,5 @@ namespace MPF.Aaru
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convert to Long Name
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the Command enum values
|
||||
/// </summary>
|
||||
/// <param name="command">Command value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string LongName(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
// Database Family
|
||||
case Command.DatabaseStats:
|
||||
return $"{CommandStrings.DatabasePrefixLong} {CommandStrings.DatabaseStats}";
|
||||
case Command.DatabaseUpdate:
|
||||
return $"{CommandStrings.DatabasePrefixLong} {CommandStrings.DatabaseUpdate}";
|
||||
|
||||
// Device Family
|
||||
case Command.DeviceInfo:
|
||||
return $"{CommandStrings.DevicePrefixLong} {CommandStrings.DeviceInfo}";
|
||||
case Command.DeviceList:
|
||||
return $"{CommandStrings.DevicePrefixLong} {CommandStrings.DeviceList}";
|
||||
case Command.DeviceReport:
|
||||
return $"{CommandStrings.DevicePrefixLong} {CommandStrings.DeviceReport}";
|
||||
|
||||
// Filesystem Family
|
||||
case Command.FilesystemExtract:
|
||||
return $"{CommandStrings.FilesystemPrefixLong} {CommandStrings.FilesystemExtract}";
|
||||
case Command.FilesystemList:
|
||||
return $"{CommandStrings.FilesystemPrefixLong} {CommandStrings.FilesystemListLong}";
|
||||
case Command.FilesystemOptions:
|
||||
return $"{CommandStrings.FilesystemPrefixLong} {CommandStrings.FilesystemOptions}";
|
||||
|
||||
// Image Family
|
||||
case Command.ImageAnalyze:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageAnalyze}";
|
||||
case Command.ImageChecksum:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageChecksumLong}";
|
||||
case Command.ImageCompare:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageCompareLong}";
|
||||
case Command.ImageConvert:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageConvert}";
|
||||
case Command.ImageCreateSidecar:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageCreateSidecar}";
|
||||
case Command.ImageDecode:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageDecode}";
|
||||
case Command.ImageEntropy:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageEntropy}";
|
||||
case Command.ImageInfo:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageInfo}";
|
||||
case Command.ImageOptions:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageOptions}";
|
||||
case Command.ImagePrint:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImagePrint}";
|
||||
case Command.ImageVerify:
|
||||
return $"{CommandStrings.ImagePrefixLong} {CommandStrings.ImageVerify}";
|
||||
|
||||
// Media Family
|
||||
case Command.MediaDump:
|
||||
return $"{CommandStrings.MediaPrefixLong} {CommandStrings.MediaDump}";
|
||||
case Command.MediaInfo:
|
||||
return $"{CommandStrings.MediaPrefixLong} {CommandStrings.MediaInfo}";
|
||||
case Command.MediaScan:
|
||||
return $"{CommandStrings.MediaPrefixLong} {CommandStrings.MediaScan}";
|
||||
|
||||
// Standalone Commands
|
||||
case Command.Configure:
|
||||
return CommandStrings.Configure;
|
||||
case Command.Formats:
|
||||
return CommandStrings.Formats;
|
||||
case Command.ListEncodings:
|
||||
return CommandStrings.ListEncodings;
|
||||
case Command.ListNamespaces:
|
||||
return CommandStrings.ListNamespaces;
|
||||
case Command.Remote:
|
||||
return CommandStrings.Remote;
|
||||
|
||||
case Command.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the Flag enum values
|
||||
/// </summary>
|
||||
/// <param name="command">Flag value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string LongName(Flag flag)
|
||||
{
|
||||
switch (flag)
|
||||
{
|
||||
// Boolean flags
|
||||
case Flag.Adler32:
|
||||
return FlagStrings.Adler32Long;
|
||||
case Flag.Clear:
|
||||
return FlagStrings.ClearLong;
|
||||
case Flag.ClearAll:
|
||||
return FlagStrings.ClearAllLong;
|
||||
case Flag.CRC16:
|
||||
return FlagStrings.CRC16Long;
|
||||
case Flag.CRC32:
|
||||
return FlagStrings.CRC32Long;
|
||||
case Flag.CRC64:
|
||||
return FlagStrings.CRC64Long;
|
||||
case Flag.Debug:
|
||||
return FlagStrings.DebugLong;
|
||||
case Flag.DiskTags:
|
||||
return FlagStrings.DiskTagsLong;
|
||||
case Flag.DuplicatedSectors:
|
||||
return FlagStrings.DuplicatedSectorsLong;
|
||||
case Flag.Eject:
|
||||
return FlagStrings.EjectLong;
|
||||
case Flag.ExtendedAttributes:
|
||||
return FlagStrings.ExtendedAttributesLong;
|
||||
case Flag.Filesystems:
|
||||
return FlagStrings.FilesystemsLong;
|
||||
case Flag.FirstPregap:
|
||||
return FlagStrings.FirstPregapLong;
|
||||
case Flag.FixOffset:
|
||||
return FlagStrings.FixOffsetLong;
|
||||
case Flag.FixSubchannel:
|
||||
return FlagStrings.FixSubchannelLong;
|
||||
case Flag.FixSubchannelCrc:
|
||||
return FlagStrings.FixSubchannelCrcLong;
|
||||
case Flag.FixSubchannelPosition:
|
||||
return FlagStrings.FixSubchannelPositionLong;
|
||||
case Flag.Fletcher16:
|
||||
return FlagStrings.Fletcher16Long;
|
||||
case Flag.Fletcher32:
|
||||
return FlagStrings.Fletcher32Long;
|
||||
case Flag.Force:
|
||||
return FlagStrings.ForceLong;
|
||||
case Flag.GenerateSubchannels:
|
||||
return FlagStrings.GenerateSubchannelsLong;
|
||||
case Flag.Help:
|
||||
return FlagStrings.HelpLong;
|
||||
case Flag.LongFormat:
|
||||
return FlagStrings.LongFormatLong;
|
||||
case Flag.LongSectors:
|
||||
return FlagStrings.LongSectorsLong;
|
||||
case Flag.MD5:
|
||||
return FlagStrings.MD5Long;
|
||||
case Flag.Metadata:
|
||||
return FlagStrings.MetadataLong;
|
||||
case Flag.Partitions:
|
||||
return FlagStrings.PartitionsLong;
|
||||
case Flag.Persistent:
|
||||
return FlagStrings.PersistentLong;
|
||||
case Flag.Private:
|
||||
return FlagStrings.PrivateLong;
|
||||
case Flag.Resume:
|
||||
return FlagStrings.ResumeLong;
|
||||
case Flag.RetrySubchannel:
|
||||
return FlagStrings.RetrySubchannelLong;
|
||||
case Flag.SectorTags:
|
||||
return FlagStrings.SectorTagsLong;
|
||||
case Flag.SeparatedTracks:
|
||||
return FlagStrings.SeparatedTracksLong;
|
||||
case Flag.SHA1:
|
||||
return FlagStrings.SHA1Long;
|
||||
case Flag.SHA256:
|
||||
return FlagStrings.SHA256Long;
|
||||
case Flag.SHA384:
|
||||
return FlagStrings.SHA384Long;
|
||||
case Flag.SHA512:
|
||||
return FlagStrings.SHA512Long;
|
||||
case Flag.SkipCdiReadyHole:
|
||||
return FlagStrings.SkipCdiReadyHoleLong;
|
||||
case Flag.SpamSum:
|
||||
return FlagStrings.SpamSumLong;
|
||||
case Flag.StopOnError:
|
||||
return FlagStrings.StopOnErrorLong;
|
||||
case Flag.Tape:
|
||||
return FlagStrings.TapeLong;
|
||||
case Flag.Trim:
|
||||
return FlagStrings.TrimLong;
|
||||
case Flag.Verbose:
|
||||
return FlagStrings.VerboseLong;
|
||||
case Flag.VerifyDisc:
|
||||
return FlagStrings.VerifyDiscLong;
|
||||
case Flag.VerifySectors:
|
||||
return FlagStrings.VerifySectorsLong;
|
||||
case Flag.Version:
|
||||
return FlagStrings.VersionLong;
|
||||
case Flag.WholeDisc:
|
||||
return FlagStrings.WholeDiscLong;
|
||||
|
||||
// Int8 flags
|
||||
case Flag.Speed:
|
||||
return FlagStrings.SpeedLong;
|
||||
|
||||
// Int16 flags
|
||||
case Flag.RetryPasses:
|
||||
return FlagStrings.RetryPassesLong;
|
||||
case Flag.Width:
|
||||
return FlagStrings.WidthLong;
|
||||
|
||||
// Int32 flags
|
||||
case Flag.BlockSize:
|
||||
return FlagStrings.BlockSizeLong;
|
||||
case Flag.Count:
|
||||
return FlagStrings.CountLong;
|
||||
case Flag.MediaLastSequence:
|
||||
return FlagStrings.MediaLastSequenceLong;
|
||||
case Flag.MediaSequence:
|
||||
return FlagStrings.MediaSequenceLong;
|
||||
case Flag.Skip:
|
||||
return FlagStrings.SkipLong;
|
||||
|
||||
// Int64 flags
|
||||
case Flag.Length:
|
||||
return FlagStrings.LengthLong;
|
||||
case Flag.Start:
|
||||
return FlagStrings.StartLong;
|
||||
|
||||
// String flags
|
||||
case Flag.Comments:
|
||||
return FlagStrings.CommentsLong;
|
||||
case Flag.Creator:
|
||||
return FlagStrings.CreatorLong;
|
||||
case Flag.DriveManufacturer:
|
||||
return FlagStrings.DriveManufacturerLong;
|
||||
case Flag.DriveModel:
|
||||
return FlagStrings.DriveModelLong;
|
||||
case Flag.DriveRevision:
|
||||
return FlagStrings.DriveRevisionLong;
|
||||
case Flag.DriveSerial:
|
||||
return FlagStrings.DriveSerialLong;
|
||||
case Flag.Encoding:
|
||||
return FlagStrings.EncodingLong;
|
||||
case Flag.FormatConvert:
|
||||
return FlagStrings.FormatConvertLong;
|
||||
case Flag.FormatDump:
|
||||
return FlagStrings.FormatDumpLong;
|
||||
case Flag.ImgBurnLog:
|
||||
return FlagStrings.ImgBurnLogLong;
|
||||
case Flag.MediaBarcode:
|
||||
return FlagStrings.MediaBarcodeLong;
|
||||
case Flag.MediaManufacturer:
|
||||
return FlagStrings.MediaManufacturerLong;
|
||||
case Flag.MediaModel:
|
||||
return FlagStrings.MediaModelLong;
|
||||
case Flag.MediaPartNumber:
|
||||
return FlagStrings.MediaPartNumberLong;
|
||||
case Flag.MediaSerial:
|
||||
return FlagStrings.MediaSerialLong;
|
||||
case Flag.MediaTitle:
|
||||
return FlagStrings.MediaTitleLong;
|
||||
case Flag.MHDDLog:
|
||||
return FlagStrings.MHDDLogLong;
|
||||
case Flag.Namespace:
|
||||
return FlagStrings.NamespaceLong;
|
||||
case Flag.Options:
|
||||
return FlagStrings.OptionsLong;
|
||||
case Flag.OutputPrefix:
|
||||
return FlagStrings.OutputPrefixLong;
|
||||
case Flag.ResumeFile:
|
||||
return FlagStrings.ResumeFileLong;
|
||||
case Flag.Subchannel:
|
||||
return FlagStrings.SubchannelLong;
|
||||
case Flag.XMLSidecar:
|
||||
return FlagStrings.XMLSidecarLong;
|
||||
|
||||
case Flag.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convert From String
|
||||
|
||||
/// <summary>
|
||||
/// Get the Command enum value for a given string
|
||||
/// </summary>
|
||||
/// <param name="commandOne">First part of String value to convert</param>
|
||||
/// <param name="commandTwo">Second part of String value to convert</param>
|
||||
/// <param name="useSecond">Output bool if the second command was used</param>
|
||||
/// <returns>Command represented by the string(s), if possible</returns>
|
||||
public static Command StringToCommand(string commandOne, string commandTwo, out bool useSecond)
|
||||
{
|
||||
useSecond = false;
|
||||
switch (commandOne)
|
||||
{
|
||||
// Database Family
|
||||
case CommandStrings.DatabasePrefixShort:
|
||||
case CommandStrings.DatabasePrefixLong:
|
||||
useSecond = true;
|
||||
switch (commandTwo)
|
||||
{
|
||||
case CommandStrings.DatabaseStats:
|
||||
return Command.DatabaseStats;
|
||||
case CommandStrings.DatabaseUpdate:
|
||||
return Command.DatabaseUpdate;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Device Family
|
||||
case CommandStrings.DevicePrefixShort:
|
||||
case CommandStrings.DevicePrefixLong:
|
||||
useSecond = true;
|
||||
switch (commandTwo)
|
||||
{
|
||||
case CommandStrings.DeviceInfo:
|
||||
return Command.DeviceInfo;
|
||||
case CommandStrings.DeviceList:
|
||||
return Command.DeviceList;
|
||||
case CommandStrings.DeviceReport:
|
||||
return Command.DeviceReport;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Filesystem Family
|
||||
case CommandStrings.FilesystemPrefixShort:
|
||||
case CommandStrings.FilesystemPrefixShortAlt:
|
||||
case CommandStrings.FilesystemPrefixLong:
|
||||
useSecond = true;
|
||||
switch (commandTwo)
|
||||
{
|
||||
case CommandStrings.FilesystemExtract:
|
||||
return Command.FilesystemExtract;
|
||||
case CommandStrings.FilesystemListShort:
|
||||
case CommandStrings.FilesystemListLong:
|
||||
return Command.FilesystemList;
|
||||
case CommandStrings.DatabaseStats:
|
||||
return Command.FilesystemOptions;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Image Family
|
||||
case CommandStrings.ImagePrefixShort:
|
||||
case CommandStrings.ImagePrefixLong:
|
||||
useSecond = true;
|
||||
switch (commandTwo)
|
||||
{
|
||||
case CommandStrings.ImageAnalyze:
|
||||
return Command.ImageAnalyze;
|
||||
case CommandStrings.ImageChecksumShort:
|
||||
case CommandStrings.ImageChecksumLong:
|
||||
return Command.ImageChecksum;
|
||||
case CommandStrings.ImageCompareShort:
|
||||
case CommandStrings.ImageCompareLong:
|
||||
return Command.ImageCompare;
|
||||
case CommandStrings.ImageConvert:
|
||||
return Command.ImageConvert;
|
||||
case CommandStrings.ImageCreateSidecar:
|
||||
return Command.ImageCreateSidecar;
|
||||
case CommandStrings.ImageDecode:
|
||||
return Command.ImageDecode;
|
||||
case CommandStrings.ImageEntropy:
|
||||
return Command.ImageEntropy;
|
||||
case CommandStrings.ImageInfo:
|
||||
return Command.ImageInfo;
|
||||
case CommandStrings.ImageOptions:
|
||||
return Command.ImageOptions;
|
||||
case CommandStrings.ImagePrint:
|
||||
return Command.ImagePrint;
|
||||
case CommandStrings.ImageVerify:
|
||||
return Command.ImageVerify;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Media Family
|
||||
case CommandStrings.MediaPrefixShort:
|
||||
case CommandStrings.MediaPrefixLong:
|
||||
useSecond = true;
|
||||
switch (commandTwo)
|
||||
{
|
||||
case CommandStrings.MediaDump:
|
||||
return Command.MediaDump;
|
||||
case CommandStrings.MediaInfo:
|
||||
return Command.MediaInfo;
|
||||
case CommandStrings.MediaScan:
|
||||
return Command.MediaScan;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Standalone Commands
|
||||
case CommandStrings.Configure:
|
||||
return Command.Configure;
|
||||
case CommandStrings.Formats:
|
||||
return Command.Formats;
|
||||
case CommandStrings.ListEncodings:
|
||||
return Command.ListEncodings;
|
||||
case CommandStrings.ListNamespaces:
|
||||
return Command.ListNamespaces;
|
||||
case CommandStrings.Remote:
|
||||
return Command.Remote;
|
||||
}
|
||||
|
||||
return Command.NONE;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
namespace MPF.Aaru
|
||||
{
|
||||
/// <summary>
|
||||
/// Supported Aaru commands
|
||||
/// </summary>
|
||||
public enum Command : int
|
||||
{
|
||||
NONE = 0,
|
||||
|
||||
// Database Family
|
||||
DatabaseStats,
|
||||
DatabaseUpdate,
|
||||
|
||||
// Device Family
|
||||
DeviceInfo,
|
||||
DeviceList,
|
||||
DeviceReport,
|
||||
|
||||
// Filesystem Family
|
||||
FilesystemExtract,
|
||||
FilesystemList,
|
||||
FilesystemOptions,
|
||||
|
||||
// Image Family
|
||||
ImageAnalyze,
|
||||
ImageChecksum,
|
||||
ImageCompare,
|
||||
ImageConvert,
|
||||
ImageCreateSidecar,
|
||||
ImageDecode,
|
||||
ImageEntropy,
|
||||
ImageInfo,
|
||||
ImageOptions,
|
||||
ImagePrint,
|
||||
ImageVerify,
|
||||
|
||||
// Media Family
|
||||
MediaDump,
|
||||
MediaInfo,
|
||||
MediaScan,
|
||||
|
||||
// Standalone Commands
|
||||
Configure,
|
||||
Formats,
|
||||
ListEncodings,
|
||||
ListNamespaces,
|
||||
Remote,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supported Aaru flags
|
||||
/// </summary>
|
||||
public enum Flag : int
|
||||
{
|
||||
NONE = 0,
|
||||
|
||||
// Boolean flags
|
||||
Adler32,
|
||||
Clear,
|
||||
ClearAll,
|
||||
CRC16,
|
||||
CRC32,
|
||||
CRC64,
|
||||
Debug,
|
||||
DiskTags,
|
||||
DuplicatedSectors,
|
||||
Eject,
|
||||
ExtendedAttributes,
|
||||
Filesystems,
|
||||
FirstPregap,
|
||||
FixOffset,
|
||||
FixSubchannel,
|
||||
FixSubchannelCrc,
|
||||
FixSubchannelPosition,
|
||||
Fletcher16,
|
||||
Fletcher32,
|
||||
Force,
|
||||
GenerateSubchannels,
|
||||
Help,
|
||||
LongFormat,
|
||||
LongSectors,
|
||||
MD5,
|
||||
Metadata,
|
||||
Partitions,
|
||||
Persistent,
|
||||
Private,
|
||||
Resume,
|
||||
RetrySubchannel,
|
||||
SectorTags,
|
||||
SeparatedTracks,
|
||||
SHA1,
|
||||
SHA256,
|
||||
SHA384,
|
||||
SHA512,
|
||||
SkipCdiReadyHole,
|
||||
SpamSum,
|
||||
StopOnError,
|
||||
Tape,
|
||||
Trim,
|
||||
Verbose,
|
||||
VerifyDisc,
|
||||
VerifySectors,
|
||||
Version,
|
||||
WholeDisc,
|
||||
|
||||
// Int8 flags
|
||||
Speed,
|
||||
|
||||
// Int16 flags
|
||||
RetryPasses,
|
||||
Width,
|
||||
|
||||
// Int32 flags
|
||||
BlockSize,
|
||||
Count,
|
||||
MediaLastSequence,
|
||||
MediaSequence,
|
||||
Skip,
|
||||
|
||||
// Int64 flags
|
||||
Length,
|
||||
Start,
|
||||
|
||||
// String flags
|
||||
Comments,
|
||||
Creator,
|
||||
DriveManufacturer,
|
||||
DriveModel,
|
||||
DriveRevision,
|
||||
DriveSerial,
|
||||
Encoding,
|
||||
FormatConvert,
|
||||
FormatDump,
|
||||
ImgBurnLog,
|
||||
MediaBarcode,
|
||||
MediaManufacturer,
|
||||
MediaModel,
|
||||
MediaPartNumber,
|
||||
MediaSerial,
|
||||
MediaTitle,
|
||||
MHDDLog,
|
||||
Namespace,
|
||||
Options,
|
||||
OutputPrefix,
|
||||
ResumeFile,
|
||||
Subchannel,
|
||||
XMLSidecar,
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using MPF.Data;
|
||||
using MPF.Utilities;
|
||||
|
||||
namespace MPF.CleanRip
|
||||
{
|
||||
@@ -31,7 +30,7 @@ namespace MPF.CleanRip
|
||||
#region BaseParameters Implementations
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
|
||||
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath, bool preCheck)
|
||||
{
|
||||
List<string> missingFiles = new List<string>();
|
||||
switch (this.Type)
|
||||
@@ -39,10 +38,13 @@ namespace MPF.CleanRip
|
||||
case MediaType.DVD: // Only added here to help users; not strictly correct
|
||||
case MediaType.NintendoGameCubeGameDisc:
|
||||
case MediaType.NintendoWiiOpticalDisc:
|
||||
if (!File.Exists($"{basePath}-dumpinfo.txt"))
|
||||
missingFiles.Add($"{basePath}-dumpinfo.txt");
|
||||
if (!File.Exists($"{basePath}.bca"))
|
||||
missingFiles.Add($"{basePath}.bca");
|
||||
if (!File.Exists($"{basePath}_logs.zip") || !preCheck)
|
||||
{
|
||||
if (!File.Exists($"{basePath}-dumpinfo.txt"))
|
||||
missingFiles.Add($"{basePath}-dumpinfo.txt");
|
||||
if (!File.Exists($"{basePath}.bca"))
|
||||
missingFiles.Add($"{basePath}.bca");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
/// <remarks>
|
||||
@@ -71,10 +72,23 @@ namespace MPF.CueSheets
|
||||
/// <param name="fileType">File type to set</param>
|
||||
/// <param name="cueLines">Lines array to pull from</param>
|
||||
/// <param name="i">Reference to index in array</param>
|
||||
public CueFile(string fileName, string fileType, string[] cueLines, ref int i)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public CueFile(string fileName, string fileType, string[] cueLines, ref int i, bool throwOnError = false)
|
||||
{
|
||||
if (cueLines == null || i < 0 || i > cueLines.Length)
|
||||
return; // TODO: Make this throw an exception
|
||||
if (cueLines == null)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentNullException(nameof(cueLines));
|
||||
|
||||
return;
|
||||
}
|
||||
else if (i < 0 || i > cueLines.Length)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the current fields
|
||||
this.FileName = fileName.Trim('"');
|
||||
@@ -102,14 +116,24 @@ namespace MPF.CueSheets
|
||||
// Read track information
|
||||
case "TRACK":
|
||||
if (splitLine.Length < 3)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"TRACK line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.Tracks == null)
|
||||
this.Tracks = new List<CueTrack>();
|
||||
|
||||
var track = new CueTrack(splitLine[1], splitLine[2], cueLines, ref i);
|
||||
if (track == default)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"TRACK line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Tracks.Add(track);
|
||||
break;
|
||||
@@ -126,11 +150,24 @@ namespace MPF.CueSheets
|
||||
/// Write the FILE out to a stream
|
||||
/// </summary>
|
||||
/// <param name="sw">StreamWriter to write to</param>
|
||||
public void Write(StreamWriter sw)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public void Write(StreamWriter sw, bool throwOnError = false)
|
||||
{
|
||||
// If we don't have any tracks, it's invalid
|
||||
if (this.Tracks == null || this.Tracks.Count == 0)
|
||||
return; // TODO: Make this throw an exception
|
||||
if (this.Tracks == null)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentNullException(nameof(this.Tracks));
|
||||
|
||||
return;
|
||||
}
|
||||
else if (this.Tracks.Count == 0)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException("No tracks provided to write");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sw.WriteLine($"FILE \"{this.FileName}\" {FromFileType(this.FileType)}");
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
/// <remarks>
|
||||
@@ -45,47 +46,103 @@ namespace MPF.CueSheets
|
||||
/// </summary>
|
||||
/// <param name="index">Index to set</param>
|
||||
/// <param name="startTime">Start time to set</param>
|
||||
public CueIndex(string index, string startTime)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public CueIndex(string index, string startTime, bool throwOnError = false)
|
||||
{
|
||||
// Set the current fields
|
||||
if (!int.TryParse(index, out int parsedIndex))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException($"Index was not a number: {index}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (parsedIndex < 0 || parsedIndex > 99)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Index must be between 0 and 99: {parsedIndex}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore empty lines
|
||||
if (string.IsNullOrWhiteSpace(startTime))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException("Start time was null or whitespace");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore lines that don't contain the correct information
|
||||
if (startTime.Length != 8 || startTime.Count(c => c == ':') != 2)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Start time was not in a recognized format: {startTime}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Split the line
|
||||
string[] splitTime = startTime.Split(':');
|
||||
if (splitTime.Length != 3)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Start time was not in a recognized format: {startTime}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the lengths
|
||||
int[] lengthSegments = new int[3];
|
||||
|
||||
// Minutes
|
||||
if (!int.TryParse(splitTime[0], out lengthSegments[0]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Minutes segment was not a number: {splitTime[0]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[0] < 0)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Minutes segment must be 0 or greater: {lengthSegments[0]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Seconds
|
||||
if (!int.TryParse(splitTime[1], out lengthSegments[1]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Seconds segment was not a number: {splitTime[1]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[1] < 0 || lengthSegments[1] > 60)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Seconds segment must be between 0 and 60: {lengthSegments[1]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Frames
|
||||
if (!int.TryParse(splitTime[2], out lengthSegments[2]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Frames segment was not a number: {splitTime[2]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[2] < 0 || lengthSegments[2] > 75)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Frames segment must be between 0 and 75: {lengthSegments[2]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the values
|
||||
this.Index = parsedIndex;
|
||||
|
||||
@@ -56,7 +56,8 @@ namespace MPF.CueSheets
|
||||
/// Create a cuesheet from a file, if possible
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
public CueSheet(string filename)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public CueSheet(string filename, bool throwOnError = false)
|
||||
{
|
||||
// Check that the file exists
|
||||
if (!File.Exists(filename))
|
||||
@@ -97,7 +98,12 @@ namespace MPF.CueSheets
|
||||
// Read MCN
|
||||
case "CATALOG":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"CATALOG line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Catalog = splitLine[1];
|
||||
break;
|
||||
@@ -105,7 +111,12 @@ namespace MPF.CueSheets
|
||||
// Read external CD-Text file path
|
||||
case "CDTEXTFILE":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"CDTEXTFILE line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.CdTextFile = splitLine[1];
|
||||
break;
|
||||
@@ -113,7 +124,12 @@ namespace MPF.CueSheets
|
||||
// Read CD-Text enhanced performer
|
||||
case "PERFORMER":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"PERFORMER line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Performer = splitLine[1];
|
||||
break;
|
||||
@@ -121,7 +137,12 @@ namespace MPF.CueSheets
|
||||
// Read CD-Text enhanced songwriter
|
||||
case "SONGWRITER":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"SONGWRITER line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Songwriter = splitLine[1];
|
||||
break;
|
||||
@@ -129,7 +150,12 @@ namespace MPF.CueSheets
|
||||
// Read CD-Text enhanced title
|
||||
case "TITLE":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"TITLE line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Title = splitLine[1];
|
||||
break;
|
||||
@@ -137,14 +163,24 @@ namespace MPF.CueSheets
|
||||
// Read file information
|
||||
case "FILE":
|
||||
if (splitLine.Length < 3)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"FILE line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.Files == null)
|
||||
this.Files = new List<CueFile>();
|
||||
|
||||
var file = new CueFile(splitLine[1], splitLine[2], cueLines, ref i);
|
||||
if (file == default)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"FILE line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Files.Add(file);
|
||||
break;
|
||||
@@ -168,11 +204,24 @@ namespace MPF.CueSheets
|
||||
/// Write the cuesheet out to a stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to write to</param>
|
||||
public void Write(Stream stream)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public void Write(Stream stream, bool throwOnError = false)
|
||||
{
|
||||
// If we don't have any files, it's invalid
|
||||
if (this.Files == null || this.Files.Count == 0)
|
||||
return; // TODO: Make this throw an exception
|
||||
if (this.Files == null)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentNullException(nameof(this.Files));
|
||||
|
||||
return;
|
||||
}
|
||||
else if (this.Files.Count == 0)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException("No files provided to write");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
using (var sw = new StreamWriter(stream, Encoding.ASCII, 1024, true))
|
||||
{
|
||||
|
||||
@@ -156,16 +156,39 @@ namespace MPF.CueSheets
|
||||
/// <param name="dataType">Data type to set</param>
|
||||
/// <param name="cueLines">Lines array to pull from</param>
|
||||
/// <param name="i">Reference to index in array</param>
|
||||
public CueTrack(string number, string dataType, string[] cueLines, ref int i)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public CueTrack(string number, string dataType, string[] cueLines, ref int i, bool throwOnError = false)
|
||||
{
|
||||
if (cueLines == null || i < 0 || i > cueLines.Length)
|
||||
return; // TODO: Make this throw an exception
|
||||
if (cueLines == null)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentNullException(nameof(cueLines));
|
||||
|
||||
return;
|
||||
}
|
||||
else if (i < 0 || i > cueLines.Length)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the current fields
|
||||
if (!int.TryParse(number, out int parsedNumber))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException($"Number was not a number: {number}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (parsedNumber < 1 || parsedNumber > 99)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Index must be between 1 and 99: {parsedNumber}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.Number = parsedNumber;
|
||||
this.DataType = GetDataType(dataType);
|
||||
@@ -192,7 +215,12 @@ namespace MPF.CueSheets
|
||||
// Read flag information
|
||||
case "FLAGS":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"FLAGS line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Flags = GetFlags(splitLine);
|
||||
break;
|
||||
@@ -200,7 +228,12 @@ namespace MPF.CueSheets
|
||||
// Read International Standard Recording Code
|
||||
case "ISRC":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"ISRC line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.ISRC = splitLine[1];
|
||||
break;
|
||||
@@ -208,7 +241,12 @@ namespace MPF.CueSheets
|
||||
// Read CD-Text enhanced performer
|
||||
case "PERFORMER":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"PERFORMER line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Performer = splitLine[1];
|
||||
break;
|
||||
@@ -216,7 +254,12 @@ namespace MPF.CueSheets
|
||||
// Read CD-Text enhanced songwriter
|
||||
case "SONGWRITER":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"SONGWRITER line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Songwriter = splitLine[1];
|
||||
break;
|
||||
@@ -224,7 +267,12 @@ namespace MPF.CueSheets
|
||||
// Read CD-Text enhanced title
|
||||
case "TITLE":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"TITLE line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Title = splitLine[1];
|
||||
break;
|
||||
@@ -232,11 +280,21 @@ namespace MPF.CueSheets
|
||||
// Read pregap information
|
||||
case "PREGAP":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"PREGAP line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var pregap = new PreGap(splitLine[1]);
|
||||
if (pregap == default)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"PREGAP line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.PreGap = pregap;
|
||||
break;
|
||||
@@ -244,14 +302,24 @@ namespace MPF.CueSheets
|
||||
// Read index information
|
||||
case "INDEX":
|
||||
if (splitLine.Length < 3)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"INDEX line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.Indices == null)
|
||||
this.Indices = new List<CueIndex>();
|
||||
|
||||
var index = new CueIndex(splitLine[1], splitLine[2]);
|
||||
if (index == default)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"INDEX line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.Indices.Add(index);
|
||||
break;
|
||||
@@ -259,11 +327,21 @@ namespace MPF.CueSheets
|
||||
// Read postgap information
|
||||
case "POSTGAP":
|
||||
if (splitLine.Length < 2)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"POSTGAP line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var postgap = new PostGap(splitLine[1]);
|
||||
if (postgap == default)
|
||||
continue; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"POSTGAP line malformed: {line}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.PostGap = postgap;
|
||||
break;
|
||||
@@ -279,12 +357,25 @@ namespace MPF.CueSheets
|
||||
/// <summary>
|
||||
/// Write the TRACK out to a stream
|
||||
/// </summary>
|
||||
/// <param name="sw">StreamWriter to write to</param>
|
||||
public void Write(StreamWriter sw)
|
||||
/// <param name="sw">StreamWriter to write to</param
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public void Write(StreamWriter sw, bool throwOnError = false)
|
||||
{
|
||||
// If we don't have any indices, it's invalid
|
||||
if (this.Indices == null || this.Indices.Count == 0)
|
||||
return; // TODO: Make this throw an exception
|
||||
if (this.Indices == null)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentNullException(nameof(this.Indices));
|
||||
|
||||
return;
|
||||
}
|
||||
else if (this.Indices.Count == 0)
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException("No indices provided to write");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sw.WriteLine($" TRACK {this.Number:D2} {FromDataType(this.DataType)}");
|
||||
|
||||
@@ -402,7 +493,6 @@ namespace MPF.CueSheets
|
||||
|
||||
foreach (string flagString in flagStrings)
|
||||
{
|
||||
// TODO: Make default throw an exception
|
||||
switch (flagString.ToLowerInvariant())
|
||||
{
|
||||
case "flags":
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
/// <remarks>
|
||||
@@ -38,41 +39,87 @@ namespace MPF.CueSheets
|
||||
/// Create a POSTGAP from a mm:ss:ff length
|
||||
/// </summary>
|
||||
/// <param name="length">String to get length information from</param>
|
||||
public PostGap(string length)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public PostGap(string length, bool throwOnError = false)
|
||||
{
|
||||
// Ignore empty lines
|
||||
if (string.IsNullOrWhiteSpace(length))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException("Length was null or whitespace");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore lines that don't contain the correct information
|
||||
if (length.Length != 8 || length.Count(c => c == ':') != 2)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Length was not in a recognized format: {length}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Split the line
|
||||
string[] splitLength = length.Split(':');
|
||||
if (splitLength.Length != 3)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Length was not in a recognized format: {length}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the lengths
|
||||
int[] lengthSegments = new int[3];
|
||||
|
||||
// Minutes
|
||||
if (!int.TryParse(splitLength[0], out lengthSegments[0]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Minutes segment was not a number: {splitLength[0]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[0] < 0)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Minutes segment must be 0 or greater: {lengthSegments[0]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Seconds
|
||||
if (!int.TryParse(splitLength[1], out lengthSegments[1]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Seconds segment was not a number: {splitLength[1]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[1] < 0 || lengthSegments[1] > 60)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Seconds segment must be between 0 and 60: {lengthSegments[1]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Frames
|
||||
if (!int.TryParse(splitLength[2], out lengthSegments[2]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Frames segment was not a number: {splitLength[2]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[2] < 0 || lengthSegments[2] > 75)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Frames segment must be between 0 and 75: {lengthSegments[2]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the values
|
||||
this.Minutes = lengthSegments[0];
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
/// <remarks>
|
||||
@@ -39,41 +40,87 @@ namespace MPF.CueSheets
|
||||
/// Create a PREGAP from a mm:ss:ff length
|
||||
/// </summary>
|
||||
/// <param name="length">String to get length information from</param>
|
||||
public PreGap(string length)
|
||||
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
|
||||
public PreGap(string length, bool throwOnError = false)
|
||||
{
|
||||
// Ignore empty lines
|
||||
if (string.IsNullOrWhiteSpace(length))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new ArgumentException("Length was null or whitespace");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore lines that don't contain the correct information
|
||||
if (length.Length != 8 || length.Count(c => c == ':') != 2)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Length was not in a recognized format: {length}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Split the line
|
||||
string[] splitLength = length.Split(':');
|
||||
if (splitLength.Length != 3)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Length was not in a recognized format: {length}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the lengths
|
||||
int[] lengthSegments = new int[3];
|
||||
|
||||
// Minutes
|
||||
if (!int.TryParse(splitLength[0], out lengthSegments[0]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Minutes segment was not a number: {splitLength[0]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[0] < 0)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Minutes segment must be 0 or greater: {lengthSegments[0]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Seconds
|
||||
if (!int.TryParse(splitLength[1], out lengthSegments[1]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Seconds segment was not a number: {splitLength[1]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[1] < 0 || lengthSegments[1] > 60)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Seconds segment must be between 0 and 60: {lengthSegments[1]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Frames
|
||||
if (!int.TryParse(splitLength[2], out lengthSegments[2]))
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new FormatException($"Frames segment was not a number: {splitLength[2]}");
|
||||
|
||||
return;
|
||||
}
|
||||
else if (lengthSegments[2] < 0 || lengthSegments[2] > 75)
|
||||
return; // TODO: Make this throw an exception
|
||||
{
|
||||
if (throwOnError)
|
||||
throw new IndexOutOfRangeException($"Frames segment must be between 0 and 75: {lengthSegments[2]}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the values
|
||||
this.Minutes = lengthSegments[0];
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace MPF.DD
|
||||
/// </summary>
|
||||
public static class CommandStrings
|
||||
{
|
||||
public const string NONE = "";
|
||||
public const string List = "--list";
|
||||
}
|
||||
|
||||
|
||||
@@ -18,87 +18,5 @@ namespace MPF.DD
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convert to Long Name
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the Command enum values
|
||||
/// </summary>
|
||||
/// <param name="command">Command value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string LongName(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case Command.List:
|
||||
return CommandStrings.List;
|
||||
|
||||
case Command.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the Flag enum values
|
||||
/// </summary>
|
||||
/// <param name="command">Flag value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string LongName(Flag flag)
|
||||
{
|
||||
switch (flag)
|
||||
{
|
||||
// Boolean flags
|
||||
case Flag.Progress:
|
||||
return FlagStrings.Progress;
|
||||
case Flag.Size:
|
||||
return FlagStrings.Size;
|
||||
|
||||
// Int64 flags
|
||||
case Flag.BlockSize:
|
||||
return FlagStrings.BlockSize;
|
||||
case Flag.Count:
|
||||
return FlagStrings.Count;
|
||||
case Flag.Seek:
|
||||
return FlagStrings.Seek;
|
||||
case Flag.Skip:
|
||||
return FlagStrings.Skip;
|
||||
|
||||
// String flags
|
||||
case Flag.Filter:
|
||||
return FlagStrings.Filter;
|
||||
case Flag.InputFile:
|
||||
return FlagStrings.InputFile;
|
||||
case Flag.OutputFile:
|
||||
return FlagStrings.OutputFile;
|
||||
|
||||
case Flag.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convert From String
|
||||
|
||||
/// <summary>
|
||||
/// Get the Command enum value for a given string
|
||||
/// </summary>
|
||||
/// <param name="command">String value to convert</param>
|
||||
/// <returns>Command represented by the string(s), if possible</returns>
|
||||
public static Command StringToCommand(string command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case CommandStrings.List:
|
||||
return Command.List;
|
||||
|
||||
default:
|
||||
return Command.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
namespace MPF.DD
|
||||
{
|
||||
/// <summary>
|
||||
/// Supported DD commands
|
||||
/// </summary>
|
||||
public enum Command: int
|
||||
{
|
||||
NONE = 0, // For DD, this represents a normal dump
|
||||
List,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supported DD flags
|
||||
/// </summary>
|
||||
public enum Flag : int
|
||||
{
|
||||
NONE = 0,
|
||||
|
||||
// Boolean flags
|
||||
Progress,
|
||||
Size,
|
||||
|
||||
// Int64 flags
|
||||
BlockSize,
|
||||
Count,
|
||||
Seek,
|
||||
Skip,
|
||||
|
||||
// String flags
|
||||
Filter,
|
||||
InputFile,
|
||||
OutputFile,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using MPF.Data;
|
||||
using MPF.Utilities;
|
||||
|
||||
namespace MPF.DD
|
||||
{
|
||||
@@ -16,7 +14,7 @@ namespace MPF.DD
|
||||
#region Generic Dumping Information
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string InputPath => InputFileValue;
|
||||
public override string InputPath => InputFileValue?.TrimStart('\\', '?');
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string OutputPath => OutputFileValue;
|
||||
@@ -33,36 +31,11 @@ namespace MPF.DD
|
||||
|
||||
#region Metadata
|
||||
|
||||
/// <summary>
|
||||
/// Base command to run
|
||||
/// </summary>
|
||||
public Command BaseCommand { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override InternalProgram InternalProgram => InternalProgram.DD;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Set of flags to pass to the executable
|
||||
/// </summary>
|
||||
protected Dictionary<Flag, bool?> _flags = new Dictionary<Flag, bool?>();
|
||||
public bool? this[Flag key]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_flags.ContainsKey(key))
|
||||
return _flags[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
_flags[key] = value;
|
||||
}
|
||||
}
|
||||
protected internal IEnumerable<Flag> Keys => _flags.Keys;
|
||||
|
||||
#region Flag Values
|
||||
|
||||
public long? BlockSizeValue { get; set; }
|
||||
@@ -94,7 +67,7 @@ namespace MPF.DD
|
||||
#region BaseParameters Implementations
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
|
||||
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath, bool preCheck)
|
||||
{
|
||||
// TODO: Figure out what sort of output files are expected... just `.bin`?
|
||||
return (true, new List<string>());
|
||||
@@ -161,23 +134,26 @@ namespace MPF.DD
|
||||
{
|
||||
List<string> parameters = new List<string>();
|
||||
|
||||
if (BaseCommand != Command.NONE)
|
||||
parameters.Add(Converters.LongName(BaseCommand));
|
||||
if (BaseCommand == null)
|
||||
BaseCommand = CommandStrings.NONE;
|
||||
|
||||
if (!string.IsNullOrEmpty(BaseCommand))
|
||||
parameters.Add(BaseCommand);
|
||||
|
||||
#region Boolean flags
|
||||
|
||||
// Progress
|
||||
if (GetSupportedCommands(Flag.Progress).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.Progress))
|
||||
{
|
||||
if (this[Flag.Progress] == true)
|
||||
parameters.Add($"{this[Flag.Progress]}");
|
||||
if (this[FlagStrings.Progress] == true)
|
||||
parameters.Add($"{FlagStrings.Progress}");
|
||||
}
|
||||
|
||||
// Size
|
||||
if (GetSupportedCommands(Flag.Size).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.Size))
|
||||
{
|
||||
if (this[Flag.Size] == true)
|
||||
parameters.Add($"{this[Flag.Size]}");
|
||||
if (this[FlagStrings.Size] == true)
|
||||
parameters.Add($"{FlagStrings.Size}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -185,31 +161,31 @@ namespace MPF.DD
|
||||
#region Int64 flags
|
||||
|
||||
// Block Size
|
||||
if (GetSupportedCommands(Flag.BlockSize).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.BlockSize))
|
||||
{
|
||||
if (this[Flag.BlockSize] == true && BlockSizeValue != null)
|
||||
parameters.Add($"{Converters.LongName(Flag.BlockSize)}={BlockSizeValue}");
|
||||
if (this[FlagStrings.BlockSize] == true && BlockSizeValue != null)
|
||||
parameters.Add($"{FlagStrings.BlockSize}={BlockSizeValue}");
|
||||
}
|
||||
|
||||
// Count
|
||||
if (GetSupportedCommands(Flag.Count).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.Count))
|
||||
{
|
||||
if (this[Flag.Count] == true && CountValue != null)
|
||||
parameters.Add($"{Converters.LongName(Flag.Count)}={CountValue}");
|
||||
if (this[FlagStrings.Count] == true && CountValue != null)
|
||||
parameters.Add($"{FlagStrings.Count}={CountValue}");
|
||||
}
|
||||
|
||||
// Seek
|
||||
if (GetSupportedCommands(Flag.Seek).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.Seek))
|
||||
{
|
||||
if (this[Flag.Seek] == true && SeekValue != null)
|
||||
parameters.Add($"{Converters.LongName(Flag.Seek)}={SeekValue}");
|
||||
if (this[FlagStrings.Seek] == true && SeekValue != null)
|
||||
parameters.Add($"{FlagStrings.Seek}={SeekValue}");
|
||||
}
|
||||
|
||||
// Skip
|
||||
if (GetSupportedCommands(Flag.Skip).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.Skip))
|
||||
{
|
||||
if (this[Flag.Skip] == true && SkipValue != null)
|
||||
parameters.Add($"{Converters.LongName(Flag.Skip)}={SkipValue}");
|
||||
if (this[FlagStrings.Skip] == true && SkipValue != null)
|
||||
parameters.Add($"{FlagStrings.Skip}={SkipValue}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -217,33 +193,57 @@ namespace MPF.DD
|
||||
#region String flags
|
||||
|
||||
// Filter
|
||||
if (GetSupportedCommands(Flag.Filter).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.Filter))
|
||||
{
|
||||
if (this[Flag.Filter] == true && FilterValue != null)
|
||||
parameters.Add($"{Converters.LongName(Flag.Filter)}={FilterValue}");
|
||||
if (this[FlagStrings.Filter] == true && FilterValue != null)
|
||||
parameters.Add($"{FlagStrings.Filter}={FilterValue}");
|
||||
}
|
||||
|
||||
// Input File
|
||||
if (GetSupportedCommands(Flag.InputFile).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.InputFile))
|
||||
{
|
||||
if (this[Flag.InputFile] == true && InputFileValue != null)
|
||||
parameters.Add($"{Converters.LongName(Flag.InputFile)}={InputFileValue}");
|
||||
if (this[FlagStrings.InputFile] == true && InputFileValue != null)
|
||||
parameters.Add($"{FlagStrings.InputFile}=\"{InputFileValue}\"");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
// Output File
|
||||
if (GetSupportedCommands(Flag.OutputFile).Contains(BaseCommand))
|
||||
if (IsFlagSupported(FlagStrings.OutputFile))
|
||||
{
|
||||
if (this[Flag.OutputFile] == true && OutputFileValue != null)
|
||||
parameters.Add($"{Converters.LongName(Flag.OutputFile)}={OutputFileValue}");
|
||||
if (this[FlagStrings.OutputFile] == true && OutputFileValue != null)
|
||||
parameters.Add($"{FlagStrings.OutputFile}=\"{OutputFileValue}\"");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return string.Empty;
|
||||
return string.Join(" ", parameters);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Dictionary<string, List<string>> GetCommandSupport()
|
||||
{
|
||||
return new Dictionary<string, List<string>>()
|
||||
{
|
||||
[CommandStrings.NONE] = new List<string>()
|
||||
{
|
||||
FlagStrings.BlockSize,
|
||||
FlagStrings.Count,
|
||||
FlagStrings.Filter,
|
||||
FlagStrings.InputFile,
|
||||
FlagStrings.OutputFile,
|
||||
FlagStrings.Progress,
|
||||
FlagStrings.Seek,
|
||||
FlagStrings.Size,
|
||||
FlagStrings.Skip,
|
||||
},
|
||||
|
||||
[CommandStrings.List] = new List<string>()
|
||||
{
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -254,7 +254,7 @@ namespace MPF.DD
|
||||
{
|
||||
switch (this.BaseCommand)
|
||||
{
|
||||
case Command.List:
|
||||
case CommandStrings.List:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
@@ -264,9 +264,9 @@ namespace MPF.DD
|
||||
/// <inheritdoc/>
|
||||
protected override void ResetValues()
|
||||
{
|
||||
BaseCommand = Command.NONE;
|
||||
BaseCommand = CommandStrings.NONE;
|
||||
|
||||
_flags = new Dictionary<Flag, bool?>();
|
||||
flags = new Dictionary<string, bool?>();
|
||||
|
||||
BlockSizeValue = null;
|
||||
CountValue = null;
|
||||
@@ -279,16 +279,16 @@ namespace MPF.DD
|
||||
/// <inheritdoc/>
|
||||
protected override void SetDefaultParameters(char driveLetter, string filename, int? driveSpeed, Options options)
|
||||
{
|
||||
BaseCommand = Command.NONE;
|
||||
BaseCommand = CommandStrings.NONE;
|
||||
|
||||
this[Flag.InputFile] = true;
|
||||
this[FlagStrings.InputFile] = true;
|
||||
InputFileValue = $"\\\\?\\{driveLetter}:";
|
||||
|
||||
this[Flag.OutputFile] = true;
|
||||
this[FlagStrings.OutputFile] = true;
|
||||
OutputFileValue = filename;
|
||||
|
||||
// TODO: Add more common block sizes
|
||||
this[Flag.BlockSize] = true;
|
||||
this[FlagStrings.BlockSize] = true;
|
||||
switch (this.Type)
|
||||
{
|
||||
case MediaType.FloppyDisk:
|
||||
@@ -300,13 +300,15 @@ namespace MPF.DD
|
||||
break;
|
||||
}
|
||||
|
||||
this[Flag.Progress] = true;
|
||||
this[Flag.Size] = true;
|
||||
this[FlagStrings.Progress] = true;
|
||||
this[FlagStrings.Size] = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool ValidateAndSetParameters(string parameters)
|
||||
{
|
||||
BaseCommand = CommandStrings.NONE;
|
||||
|
||||
// The string has to be valid by itself first
|
||||
if (string.IsNullOrWhiteSpace(parameters))
|
||||
return false;
|
||||
@@ -321,13 +323,14 @@ namespace MPF.DD
|
||||
|
||||
// Determine what the commandline should look like given the first item
|
||||
int start = 0;
|
||||
BaseCommand = Converters.StringToCommand(parts[0]);
|
||||
if (BaseCommand != Command.NONE)
|
||||
if (parts[0] == CommandStrings.List)
|
||||
{
|
||||
BaseCommand = parts[0];
|
||||
start = 1;
|
||||
}
|
||||
|
||||
// Loop through all auxilary flags, if necessary
|
||||
int i = 0;
|
||||
for (i = start; i < parts.Count; i++)
|
||||
for (int i = start; i < parts.Count; i++)
|
||||
{
|
||||
// Flag read-out values
|
||||
long? longValue = null;
|
||||
@@ -339,41 +342,33 @@ namespace MPF.DD
|
||||
#region Boolean flags
|
||||
|
||||
// Progress
|
||||
ProcessBooleanParameter(parts, FlagStrings.Progress, Flag.Progress, ref i);
|
||||
ProcessFlagParameter(parts, FlagStrings.Progress, ref i);
|
||||
|
||||
// Size
|
||||
ProcessBooleanParameter(parts, FlagStrings.Size, Flag.Size, ref i);
|
||||
ProcessFlagParameter(parts, FlagStrings.Size, ref i);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Int64 flags
|
||||
|
||||
// Block Size
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.BlockSize, Flag.BlockSize, ref i);
|
||||
if (longValue == Int64.MinValue)
|
||||
return false;
|
||||
else if (longValue != null)
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.BlockSize, ref i);
|
||||
if (longValue != null)
|
||||
BlockSizeValue = longValue;
|
||||
|
||||
// Count
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.Count, Flag.Count, ref i);
|
||||
if (longValue == Int64.MinValue)
|
||||
return false;
|
||||
else if (longValue != null)
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.Count, ref i);
|
||||
if (longValue != null)
|
||||
CountValue = longValue;
|
||||
|
||||
// Seek
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.Seek, Flag.Seek, ref i);
|
||||
if (longValue == Int64.MinValue)
|
||||
return false;
|
||||
else if (longValue != null)
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.Seek, ref i);
|
||||
if (longValue != null)
|
||||
SeekValue = longValue;
|
||||
|
||||
// Skip
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.Skip, Flag.Skip, ref i);
|
||||
if (longValue == Int64.MinValue)
|
||||
return false;
|
||||
else if (longValue != null)
|
||||
longValue = ProcessInt64Parameter(parts, FlagStrings.Skip, ref i);
|
||||
if (longValue != null)
|
||||
SkipValue = longValue;
|
||||
|
||||
#endregion
|
||||
@@ -381,22 +376,18 @@ namespace MPF.DD
|
||||
#region String flags
|
||||
|
||||
// Filter (fixed, removable, disk, partition)
|
||||
stringValue = ProcessStringParameter(parts, FlagStrings.Filter, Flag.Filter, ref i);
|
||||
stringValue = ProcessStringParameter(parts, FlagStrings.Filter, ref i);
|
||||
if (!string.IsNullOrEmpty(stringValue))
|
||||
FilterValue = stringValue;
|
||||
|
||||
// Input File
|
||||
stringValue = ProcessStringParameter(parts, FlagStrings.InputFile, Flag.InputFile, ref i);
|
||||
if (string.Equals(stringValue, string.Empty))
|
||||
return false;
|
||||
else if (stringValue != null)
|
||||
stringValue = ProcessStringParameter(parts, FlagStrings.InputFile, ref i);
|
||||
if (!string.IsNullOrEmpty(stringValue))
|
||||
InputFileValue = stringValue;
|
||||
|
||||
// Output File
|
||||
stringValue = ProcessStringParameter(parts, FlagStrings.OutputFile, Flag.OutputFile, ref i);
|
||||
if (string.Equals(stringValue, string.Empty))
|
||||
return false;
|
||||
else if (stringValue != null)
|
||||
stringValue = ProcessStringParameter(parts, FlagStrings.OutputFile, ref i);
|
||||
if (!string.IsNullOrEmpty(stringValue))
|
||||
OutputFileValue = stringValue;
|
||||
|
||||
#endregion
|
||||
@@ -406,212 +397,5 @@ namespace MPF.DD
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Extra Methods
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of commands that use a given flag
|
||||
/// </summary>
|
||||
/// <param name="flag">Flag value to get commands for</param>
|
||||
/// <returns>List of Commands, if possible</returns>
|
||||
private static List<Command> GetSupportedCommands(Flag flag)
|
||||
{
|
||||
var commands = new List<Command>();
|
||||
switch (flag)
|
||||
{
|
||||
#region Boolean flags
|
||||
|
||||
case Flag.Progress:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
case Flag.Size:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Int64 flags
|
||||
|
||||
case Flag.BlockSize:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
case Flag.Count:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
case Flag.Seek:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
case Flag.Skip:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
|
||||
#endregion
|
||||
|
||||
#region String flags
|
||||
|
||||
case Flag.Filter:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
case Flag.InputFile:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
case Flag.OutputFile:
|
||||
commands.Add(Command.NONE);
|
||||
break;
|
||||
|
||||
#endregion
|
||||
|
||||
case Flag.NONE:
|
||||
default:
|
||||
return commands;
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Process Parameter Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Process a boolean parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string to check</param>
|
||||
/// <param name="flag">Flag value corresponding to the flag</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
|
||||
private bool ProcessBooleanParameter(List<string> parts, string flagString, Flag flag, ref int i)
|
||||
{
|
||||
if (parts == null)
|
||||
return false;
|
||||
|
||||
if (parts[i] == flagString)
|
||||
{
|
||||
if (!GetSupportedCommands(flag).Contains(BaseCommand))
|
||||
return false;
|
||||
|
||||
this[flag] = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int64 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string to check</param>
|
||||
/// <param name="flag">Flag value corresponding to the flag</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <returns>Int64 value if success, Int64.MinValue if skipped, null on error/returns>
|
||||
private long? ProcessInt64Parameter(List<string> parts, string flagString, Flag flag, ref int i)
|
||||
{
|
||||
if (parts == null)
|
||||
return null;
|
||||
|
||||
if (parts[i].StartsWith(flagString))
|
||||
{
|
||||
if (!GetSupportedCommands(flag).Contains(BaseCommand))
|
||||
return null;
|
||||
|
||||
string[] commandParts = parts[i].Split('=');
|
||||
if (commandParts.Length != 2)
|
||||
return null;
|
||||
|
||||
string valuePart = commandParts[1];
|
||||
long factor = 1;
|
||||
|
||||
// Characters
|
||||
if (valuePart.EndsWith("c", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1;
|
||||
valuePart.TrimEnd('c');
|
||||
}
|
||||
|
||||
// Words
|
||||
else if (valuePart.EndsWith("w", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 2;
|
||||
valuePart.TrimEnd('w');
|
||||
}
|
||||
|
||||
// Double Words
|
||||
else if (valuePart.EndsWith("d", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 4;
|
||||
valuePart.TrimEnd('d');
|
||||
}
|
||||
|
||||
// Quad Words
|
||||
else if (valuePart.EndsWith("q", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 8;
|
||||
valuePart.TrimEnd('q');
|
||||
}
|
||||
|
||||
// Kilobytes
|
||||
else if (valuePart.EndsWith("k", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1024;
|
||||
valuePart.TrimEnd('k');
|
||||
}
|
||||
|
||||
// Megabytes
|
||||
else if (valuePart.EndsWith("M", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1024 * 1024;
|
||||
valuePart.TrimEnd('M');
|
||||
}
|
||||
|
||||
// Gigabytes
|
||||
else if (valuePart.EndsWith("G", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1024 * 1024 * 1024;
|
||||
valuePart.TrimEnd('G');
|
||||
}
|
||||
|
||||
if (!IsValidInt64(valuePart))
|
||||
return null;
|
||||
|
||||
this[flag] = true;
|
||||
return long.Parse(valuePart) * factor;
|
||||
}
|
||||
|
||||
return Int64.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a string parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string to check</param>
|
||||
/// <param name="flag">Flag value corresponding to the flag</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <returns>String value if possible, string.Empty on missing, null on error</returns>
|
||||
private string ProcessStringParameter(List<string> parts, string flagString, Flag flag, ref int i)
|
||||
{
|
||||
if (parts == null)
|
||||
return null;
|
||||
|
||||
if (parts[i] == flagString)
|
||||
{
|
||||
if (!GetSupportedCommands(flag).Contains(BaseCommand))
|
||||
return null;
|
||||
|
||||
string[] commandParts = parts[i].Split('=');
|
||||
if (commandParts.Length != 2)
|
||||
return null;
|
||||
|
||||
string valuePart = commandParts[1];
|
||||
|
||||
this[flag] = true;
|
||||
return valuePart.Trim('"');
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
||||
using BurnOutSharp.ProtectionType;
|
||||
using Compress.ThreadReaders;
|
||||
using MPF.Hashing;
|
||||
using MPF.Utilities;
|
||||
|
||||
namespace MPF.Data
|
||||
{
|
||||
@@ -22,18 +23,53 @@ namespace MPF.Data
|
||||
/// <param name="message">String value to report</param>
|
||||
public EventHandler<string> ReportStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for data returned from a process
|
||||
/// </summary>
|
||||
private void OutputToLog(object proc, DataReceivedEventArgs args)
|
||||
{
|
||||
ReportStatus.Invoke(this, args.Data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Generic Dumping Information
|
||||
|
||||
/// <summary>
|
||||
/// Base command to run
|
||||
/// </summary>
|
||||
public string BaseCommand { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set of flags to pass to the executable
|
||||
/// </summary>
|
||||
protected Dictionary<string, bool?> flags = new Dictionary<string, bool?>();
|
||||
protected internal IEnumerable<string> Keys => flags.Keys;
|
||||
|
||||
/// <summary>
|
||||
/// Safe access to currently set flags
|
||||
/// </summary>
|
||||
public bool? this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (flags.ContainsKey(key))
|
||||
return flags[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
flags[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process to track external program
|
||||
/// </summary>
|
||||
private Process process;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Virtual Dumping Information
|
||||
|
||||
/// <summary>
|
||||
/// Command to flag support mappings
|
||||
/// </summary>
|
||||
public Dictionary<string, List<string>> CommandSupport => GetCommandSupport();
|
||||
|
||||
/// <summary>
|
||||
/// Input path for operations
|
||||
/// </summary>
|
||||
@@ -50,11 +86,6 @@ namespace MPF.Data
|
||||
/// </summary>
|
||||
public virtual int? Speed { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Process to track external program
|
||||
/// </summary>
|
||||
private Process process;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Metadata
|
||||
@@ -114,8 +145,9 @@ namespace MPF.Data
|
||||
/// Validate if all required output files exist
|
||||
/// </summary>
|
||||
/// <param name="basePath">Base filename and path to use for checking</param>
|
||||
/// <param name="preCheck">True if this is a check done before a dump, false if done after</param>
|
||||
/// <returns>Tuple of true if all required files exist, false otherwise and a list representing missing files</returns>
|
||||
public abstract (bool, List<string>) CheckAllOutputFilesExist(string basePath);
|
||||
public abstract (bool, List<string>) CheckAllOutputFilesExist(string basePath, bool preCheck);
|
||||
|
||||
/// <summary>
|
||||
/// Generate a SubmissionInfo for the output files
|
||||
@@ -130,6 +162,12 @@ namespace MPF.Data
|
||||
|
||||
#region Virtual Methods
|
||||
|
||||
/// <summary>
|
||||
/// Get all commands mapped to the supported flags
|
||||
/// </summary>
|
||||
/// <returns>Mappings from command to supported flags</returns>
|
||||
public virtual Dictionary<string, List<string>> GetCommandSupport() => null;
|
||||
|
||||
/// <summary>
|
||||
/// Blindly generate a parameter string based on the inputs
|
||||
/// </summary>
|
||||
@@ -162,6 +200,22 @@ namespace MPF.Data
|
||||
/// <returns>True if it's a dumping command, false otherwise</returns>
|
||||
public virtual bool IsDumpingCommand() => true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the flag is supported by the current command
|
||||
/// </summary>
|
||||
/// <param name="flag">Flag value to check</param>
|
||||
/// <returns>True if the flag value is supported, false otherwise</returns>
|
||||
public virtual bool IsFlagSupported(string flag)
|
||||
{
|
||||
if (CommandSupport == null)
|
||||
return false;
|
||||
if (this.BaseCommand == null)
|
||||
return false;
|
||||
if (!CommandSupport.ContainsKey(this.BaseCommand))
|
||||
return false;
|
||||
return CommandSupport[this.BaseCommand].Contains(flag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if the current Parameter object is valid
|
||||
/// </summary>
|
||||
@@ -212,22 +266,15 @@ namespace MPF.Data
|
||||
|
||||
// Create the new process
|
||||
process = new Process() { StartInfo = startInfo };
|
||||
|
||||
// Add event handlers, if necessary
|
||||
if (!separateWindow)
|
||||
{
|
||||
process.OutputDataReceived += OutputToLog;
|
||||
process.ErrorDataReceived += OutputToLog;
|
||||
}
|
||||
|
||||
// Start the process
|
||||
process.Start();
|
||||
|
||||
// Begin reading the outputs, if necessary
|
||||
// Start processing tasks, if necessary
|
||||
if (!separateWindow)
|
||||
{
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
Logging.OutputToLog(process.StandardOutput, this, ReportStatus);
|
||||
Logging.OutputToLog(process.StandardError, this, ReportStatus);
|
||||
}
|
||||
|
||||
process.WaitForExit();
|
||||
@@ -304,19 +351,6 @@ namespace MPF.Data
|
||||
return string.Join("\n", File.ReadAllLines(filename));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a string is a flag (starts with '/')
|
||||
/// </summary>
|
||||
/// <param name="parameter">String value to check</param>
|
||||
/// <returns>True if it's a flag, false otherwise</returns>
|
||||
protected static bool IsFlag(string parameter)
|
||||
{
|
||||
if (parameter.Trim('\"').StartsWith("/"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a string is a valid drive letter
|
||||
/// </summary>
|
||||
@@ -349,7 +383,8 @@ namespace MPF.Data
|
||||
/// <returns>True if it's a valid byte, false otherwise</returns>
|
||||
protected static bool IsValidInt8(string parameter, sbyte lowerBound = -1, sbyte upperBound = -1)
|
||||
{
|
||||
if (!sbyte.TryParse(parameter, out sbyte temp))
|
||||
(string value, long _) = ExtractFactorFromValue(parameter);
|
||||
if (!sbyte.TryParse(value, out sbyte temp))
|
||||
return false;
|
||||
else if (lowerBound != -1 && temp < lowerBound)
|
||||
return false;
|
||||
@@ -368,7 +403,8 @@ namespace MPF.Data
|
||||
/// <returns>True if it's a valid Int16, false otherwise</returns>
|
||||
protected static bool IsValidInt16(string parameter, short lowerBound = -1, short upperBound = -1)
|
||||
{
|
||||
if (!short.TryParse(parameter, out short temp))
|
||||
(string value, long _) = ExtractFactorFromValue(parameter);
|
||||
if (!short.TryParse(value, out short temp))
|
||||
return false;
|
||||
else if (lowerBound != -1 && temp < lowerBound)
|
||||
return false;
|
||||
@@ -387,7 +423,8 @@ namespace MPF.Data
|
||||
/// <returns>True if it's a valid Int32, false otherwise</returns>
|
||||
protected static bool IsValidInt32(string parameter, int lowerBound = -1, int upperBound = -1)
|
||||
{
|
||||
if (!int.TryParse(parameter, out int temp))
|
||||
(string value, long _) = ExtractFactorFromValue(parameter);
|
||||
if (!int.TryParse(value, out int temp))
|
||||
return false;
|
||||
else if (lowerBound != -1 && temp < lowerBound)
|
||||
return false;
|
||||
@@ -406,7 +443,8 @@ namespace MPF.Data
|
||||
/// <returns>True if it's a valid Int64, false otherwise</returns>
|
||||
protected static bool IsValidInt64(string parameter, long lowerBound = -1, long upperBound = -1)
|
||||
{
|
||||
if (!long.TryParse(parameter, out long temp))
|
||||
(string value, long _) = ExtractFactorFromValue(parameter);
|
||||
if (!long.TryParse(value, out long temp))
|
||||
return false;
|
||||
else if (lowerBound != -1 && temp < lowerBound)
|
||||
return false;
|
||||
@@ -416,6 +454,571 @@ namespace MPF.Data
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a flag parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
|
||||
protected bool ProcessFlagParameter(List<string> parts, string flagString, ref int i)
|
||||
{
|
||||
return ProcessFlagParameter(parts, null, flagString, ref i);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a flag parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="shortFlagString">Short flag string, if available</param>
|
||||
/// <param name="longFlagString">Long flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
|
||||
protected bool ProcessFlagParameter(List<string> parts, string shortFlagString, string longFlagString, ref int i)
|
||||
{
|
||||
if (parts == null)
|
||||
return false;
|
||||
|
||||
if (parts[i] == shortFlagString || parts[i] == longFlagString)
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
return false;
|
||||
|
||||
this[longFlagString] = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a boolean parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
|
||||
protected bool ProcessBooleanParameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
return ProcessBooleanParameter(parts, null, flagString, ref i, missingAllowed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a boolean parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="shortFlagString">Short flag string, if available</param>
|
||||
/// <param name="longFlagString">Long flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>True if the parameter was processed successfully or skipped, false otherwise</returns>
|
||||
protected bool ProcessBooleanParameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
if (parts == null)
|
||||
return false;
|
||||
|
||||
if (parts[i] == shortFlagString || parts[i] == longFlagString)
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!DoesExist(parts, i + 1))
|
||||
{
|
||||
if (missingAllowed)
|
||||
{
|
||||
this[longFlagString] = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (IsFlagSupported(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
{
|
||||
this[longFlagString] = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!IsValidBool(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
{
|
||||
this[longFlagString] = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this[longFlagString] = bool.Parse(parts[i + 1]);
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a sbyte parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>SByte value if success, SByte.MinValue if skipped, null on error/returns>
|
||||
protected sbyte? ProcessInt8Parameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
return ProcessInt8Parameter(parts, null, flagString, ref i, missingAllowed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an sbyte parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="shortFlagString">Short flag string, if available</param>
|
||||
/// <param name="longFlagString">Long flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>SByte value if success, SByte.MinValue if skipped, null on error/returns>
|
||||
protected sbyte? ProcessInt8Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
if (parts == null)
|
||||
return null;
|
||||
|
||||
if (parts[i] == shortFlagString || parts[i] == longFlagString)
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (!DoesExist(parts, i + 1))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (IsFlagSupported(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (!IsValidInt8(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
this[longFlagString] = true;
|
||||
i++;
|
||||
|
||||
(string value, long factor) = ExtractFactorFromValue(parts[i]);
|
||||
return (sbyte)(sbyte.Parse(value) * factor);
|
||||
}
|
||||
else if (parts[i].StartsWith(shortFlagString + "=") || parts[i].StartsWith(longFlagString + "="))
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
return null;
|
||||
|
||||
string[] commandParts = parts[i].Split('=');
|
||||
if (commandParts.Length != 2)
|
||||
return null;
|
||||
|
||||
string valuePart = commandParts[1];
|
||||
|
||||
(string value, long factor) = ExtractFactorFromValue(valuePart);
|
||||
return (sbyte)(sbyte.Parse(value) * factor);
|
||||
}
|
||||
|
||||
return SByte.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int16 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>Int16 value if success, Int16.MinValue if skipped, null on error/returns>
|
||||
protected short? ProcessInt16Parameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
return ProcessInt16Parameter(parts, null, flagString, ref i, missingAllowed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int16 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="shortFlagString">Short flag string, if available</param>
|
||||
/// <param name="longFlagString">Long flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>Int16 value if success, Int16.MinValue if skipped, null on error/returns>
|
||||
protected short? ProcessInt16Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
if (parts == null)
|
||||
return null;
|
||||
|
||||
if (parts[i] == shortFlagString || parts[i] == longFlagString)
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (!DoesExist(parts, i + 1))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (IsFlagSupported(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (!IsValidInt16(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
this[longFlagString] = true;
|
||||
i++;
|
||||
(string value, long factor) = ExtractFactorFromValue(parts[i]);
|
||||
return (short)(short.Parse(value) * factor);
|
||||
}
|
||||
else if (parts[i].StartsWith(shortFlagString + "=") || parts[i].StartsWith(longFlagString + "="))
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
return null;
|
||||
|
||||
string[] commandParts = parts[i].Split('=');
|
||||
if (commandParts.Length != 2)
|
||||
return null;
|
||||
|
||||
string valuePart = commandParts[1];
|
||||
|
||||
(string value, long factor) = ExtractFactorFromValue(valuePart);
|
||||
return (short)(short.Parse(value) * factor);
|
||||
}
|
||||
|
||||
return Int16.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int32 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>Int32 value if success, Int32.MinValue if skipped, null on error/returns>
|
||||
protected int? ProcessInt32Parameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
return ProcessInt32Parameter(parts, null, flagString, ref i, missingAllowed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int32 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="shortFlagString">Short flag string, if available</param>
|
||||
/// <param name="longFlagString">Long flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>Int32 value if success, Int32.MinValue if skipped, null on error/returns>
|
||||
protected int? ProcessInt32Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
if (parts == null)
|
||||
return null;
|
||||
|
||||
if (parts[i] == shortFlagString || parts[i] == longFlagString)
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (!DoesExist(parts, i + 1))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (IsFlagSupported(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (!IsValidInt32(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
this[longFlagString] = true;
|
||||
i++;
|
||||
(string value, long factor) = ExtractFactorFromValue(parts[i]);
|
||||
return (int)(int.Parse(value) * factor);
|
||||
}
|
||||
else if (parts[i].StartsWith(shortFlagString + "=") || parts[i].StartsWith(longFlagString + "="))
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
return null;
|
||||
|
||||
string[] commandParts = parts[i].Split('=');
|
||||
if (commandParts.Length != 2)
|
||||
return null;
|
||||
|
||||
string valuePart = commandParts[1];
|
||||
|
||||
(string value, long factor) = ExtractFactorFromValue(valuePart);
|
||||
return (int)(int.Parse(value) * factor);
|
||||
}
|
||||
|
||||
return Int32.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int64 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>Int64 value if success, Int64.MinValue if skipped, null on error/returns>
|
||||
protected long? ProcessInt64Parameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
return ProcessInt64Parameter(parts, null, flagString, ref i, missingAllowed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int64 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="shortFlagString">Short flag string, if available</param>
|
||||
/// <param name="longFlagString">Long flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>Int64 value if success, Int64.MinValue if skipped, null on error/returns>
|
||||
protected long? ProcessInt64Parameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
if (parts == null)
|
||||
return null;
|
||||
|
||||
if (parts[i] == shortFlagString || parts[i] == longFlagString)
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (!DoesExist(parts, i + 1))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (IsFlagSupported(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (!IsValidInt64(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
this[longFlagString] = true;
|
||||
i++;
|
||||
(string value, long factor) = ExtractFactorFromValue(parts[i]);
|
||||
return long.Parse(value) * factor;
|
||||
}
|
||||
else if (parts[i].StartsWith(shortFlagString + "=") || parts[i].StartsWith(longFlagString + "="))
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
return null;
|
||||
|
||||
string[] commandParts = parts[i].Split('=');
|
||||
if (commandParts.Length != 2)
|
||||
return null;
|
||||
|
||||
string valuePart = commandParts[1];
|
||||
|
||||
(string value, long factor) = ExtractFactorFromValue(valuePart);
|
||||
return long.Parse(value) * factor;
|
||||
}
|
||||
|
||||
return Int64.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process an Int64 parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="flagString">Flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>String value if possible, string.Empty on missing, null on error</returns>
|
||||
protected string ProcessStringParameter(List<string> parts, string flagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
return ProcessStringParameter(parts, null, flagString, ref i, missingAllowed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a string parameter
|
||||
/// </summary>
|
||||
/// <param name="parts">List of parts to be referenced</param>
|
||||
/// <param name="shortFlagString">Short flag string, if available</param>
|
||||
/// <param name="longFlagString">Long flag string, if available</param>
|
||||
/// <param name="i">Reference to the position in the parts</param>
|
||||
/// <param name="missingAllowed">True if missing values are allowed, false otherwise</param>
|
||||
/// <returns>String value if possible, string.Empty on missing, null on error</returns>
|
||||
protected string ProcessStringParameter(List<string> parts, string shortFlagString, string longFlagString, ref int i, bool missingAllowed = false)
|
||||
{
|
||||
if (parts == null)
|
||||
return null;
|
||||
|
||||
if (parts[i] == shortFlagString || parts[i] == longFlagString)
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (!DoesExist(parts, i + 1))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (IsFlagSupported(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(parts[i + 1]))
|
||||
{
|
||||
if (missingAllowed)
|
||||
this[longFlagString] = true;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
this[longFlagString] = true;
|
||||
i++;
|
||||
return parts[i].Trim('"');
|
||||
}
|
||||
else if (parts[i].StartsWith(shortFlagString + "=") || parts[i].StartsWith(longFlagString + "="))
|
||||
{
|
||||
if (!IsFlagSupported(longFlagString))
|
||||
return null;
|
||||
|
||||
string[] commandParts = parts[i].Split('=');
|
||||
if (commandParts.Length != 2)
|
||||
return null;
|
||||
|
||||
string valuePart = commandParts[1];
|
||||
|
||||
this[longFlagString] = true;
|
||||
return valuePart.Trim('"');
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get yhe trimmed value and multiplication factor from a value
|
||||
/// </summary>
|
||||
/// <param name="value">String value to treat as suffixed number</param>
|
||||
/// <returns>Trimmed value and multiplication factor</returns>
|
||||
private static (string trimmed, long factor) ExtractFactorFromValue(string value)
|
||||
{
|
||||
value = value.Trim('"');
|
||||
long factor = 1;
|
||||
|
||||
// Characters
|
||||
if (value.EndsWith("c", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1;
|
||||
value = value.TrimEnd('c');
|
||||
}
|
||||
|
||||
// Words
|
||||
else if (value.EndsWith("w", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 2;
|
||||
value = value.TrimEnd('w');
|
||||
}
|
||||
|
||||
// Double Words
|
||||
else if (value.EndsWith("d", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 4;
|
||||
value = value.TrimEnd('d');
|
||||
}
|
||||
|
||||
// Quad Words
|
||||
else if (value.EndsWith("q", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 8;
|
||||
value = value.TrimEnd('q');
|
||||
}
|
||||
|
||||
// Kilobytes
|
||||
else if (value.EndsWith("k", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1024;
|
||||
value = value.TrimEnd('k');
|
||||
}
|
||||
|
||||
// Megabytes
|
||||
else if (value.EndsWith("M", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1024 * 1024;
|
||||
value = value.TrimEnd('M');
|
||||
}
|
||||
|
||||
// Gigabytes
|
||||
else if (value.EndsWith("G", StringComparison.Ordinal))
|
||||
{
|
||||
factor = 1024 * 1024 * 1024;
|
||||
value = value.TrimEnd('G');
|
||||
}
|
||||
|
||||
return (value, factor);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common Information Extraction
|
||||
@@ -691,7 +1294,7 @@ namespace MPF.Data
|
||||
var systemCnf = new IniFile(systemCnfPath);
|
||||
if (systemCnf.ContainsKey("VER"))
|
||||
return systemCnf["VER"];
|
||||
|
||||
|
||||
// If "VER" can't be found, we can't do much
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -176,9 +176,9 @@ namespace MPF.Data
|
||||
/// <summary>
|
||||
/// Ensures that all required output files have been created
|
||||
/// </summary>
|
||||
/// <param name="progress">Optional result progress callback</param>
|
||||
/// <param name="preCheck">True if this is a check done before a dump, false if done after</param>
|
||||
/// <returns>Tuple of true if all required files exist, false otherwise and a list representing missing files</returns>
|
||||
public (bool, List<string>) FoundAllFiles()
|
||||
public (bool, List<string>) FoundAllFiles(bool preCheck)
|
||||
{
|
||||
// First, sanitized the output filename to strip off any potential extension
|
||||
string outputFilename = Path.GetFileNameWithoutExtension(OutputFilename);
|
||||
@@ -187,7 +187,7 @@ namespace MPF.Data
|
||||
string basePath = Path.Combine(OutputDirectory, outputFilename);
|
||||
|
||||
// Finally, let the parameters say if all files exist
|
||||
return Parameters.CheckAllOutputFilesExist(basePath);
|
||||
return Parameters.CheckAllOutputFilesExist(basePath, preCheck);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -320,7 +320,7 @@ namespace MPF.Data
|
||||
|
||||
var parameters = new DiscImageCreator.Parameters(string.Empty)
|
||||
{
|
||||
BaseCommand = DiscImageCreator.Command.Eject,
|
||||
BaseCommand = DiscImageCreator.CommandStrings.Eject,
|
||||
DriveLetter = Drive.Letter.ToString(),
|
||||
ExecutablePath = Options.DiscImageCreatorPath,
|
||||
};
|
||||
@@ -350,7 +350,7 @@ namespace MPF.Data
|
||||
|
||||
DiscImageCreator.Parameters parameters = new DiscImageCreator.Parameters(string.Empty)
|
||||
{
|
||||
BaseCommand = DiscImageCreator.Command.Reset,
|
||||
BaseCommand = DiscImageCreator.CommandStrings.Reset,
|
||||
DriveLetter = Drive.Letter.ToString(),
|
||||
ExecutablePath = Options.DiscImageCreatorPath,
|
||||
};
|
||||
@@ -412,7 +412,7 @@ namespace MPF.Data
|
||||
resultProgress?.Report(Result.Success("Gathering submission information... please wait!"));
|
||||
|
||||
// Check to make sure that the output had all the correct files
|
||||
(bool foundFiles, List<string> missingFiles) = FoundAllFiles();
|
||||
(bool foundFiles, List<string> missingFiles) = FoundAllFiles(false);
|
||||
if (!foundFiles)
|
||||
{
|
||||
resultProgress.Report(Result.Failure($"There were files missing from the output:\n{string.Join("\n", missingFiles)}"));
|
||||
@@ -568,7 +568,7 @@ namespace MPF.Data
|
||||
string outputFilename = Path.GetFileNameWithoutExtension(OutputFilename);
|
||||
|
||||
// Check that all of the relevant files are there
|
||||
(bool foundFiles, List<string> missingFiles) = FoundAllFiles();
|
||||
(bool foundFiles, List<string> missingFiles) = FoundAllFiles(false);
|
||||
if (!foundFiles)
|
||||
{
|
||||
resultProgress.Report(Result.Failure($"There were files missing from the output:\n{string.Join("\n", missingFiles)}"));
|
||||
@@ -603,7 +603,7 @@ namespace MPF.Data
|
||||
};
|
||||
|
||||
// Get specific tool output handling
|
||||
Parameters.GenerateSubmissionInfo(info, combinedBase, this.Drive, Options.OutputSubmissionJSON);
|
||||
Parameters.GenerateSubmissionInfo(info, combinedBase, this.Drive, Options.IncludeArtifacts);
|
||||
|
||||
// Get a list of matching IDs for each line in the DAT
|
||||
if (!string.IsNullOrEmpty(info.TracksAndWriteOffsets.ClrMameProData) && Options.HasRedumpLogin)
|
||||
@@ -968,6 +968,13 @@ namespace MPF.Data
|
||||
|
||||
try
|
||||
{
|
||||
// Sony-printed discs have layers in the opposite order
|
||||
var system = info.CommonDiscInfo.System;
|
||||
bool reverseOrder = (system == KnownSystem.SonyPlayStation2
|
||||
|| system == KnownSystem.SonyPlayStation3
|
||||
|| system == KnownSystem.SonyPlayStation4
|
||||
|| system == KnownSystem.SonyPlayStation5);
|
||||
|
||||
// Common Disc Info section
|
||||
List<string> output = new List<string> { "Common Disc Info:" };
|
||||
AddIfExists(output, Template.TitleField, info.CommonDiscInfo.Title, 1);
|
||||
@@ -995,9 +1002,9 @@ namespace MPF.Data
|
||||
// If we have a triple-layer disc
|
||||
if (info.SizeAndChecksums.Layerbreak3 != default)
|
||||
{
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 2);
|
||||
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 2);
|
||||
|
||||
@@ -1011,16 +1018,16 @@ namespace MPF.Data
|
||||
AddIfExists(output, "Layer 2 " + Template.MasteringSIDField, info.CommonDiscInfo.Layer2MasteringSID, 2);
|
||||
AddIfExists(output, "Layer 2 " + Template.ToolstampField, info.CommonDiscInfo.Layer2ToolstampMasteringCode, 2);
|
||||
|
||||
AddIfExists(output, "Layer 3 (Outer) " + Template.MasteringRingField, info.CommonDiscInfo.Layer3MasteringRing, 2);
|
||||
AddIfExists(output, "Layer 3 (Outer) " + Template.MasteringSIDField, info.CommonDiscInfo.Layer3MasteringSID, 2);
|
||||
AddIfExists(output, "Layer 3 (Outer) " + Template.ToolstampField, info.CommonDiscInfo.Layer3ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer3MasteringRing, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer3MasteringSID, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 3 (Inner) " : "Layer 3 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer3ToolstampMasteringCode, 2);
|
||||
}
|
||||
// If we have a triple-layer disc
|
||||
else if (info.SizeAndChecksums.Layerbreak2 != default)
|
||||
{
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 2);
|
||||
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 2);
|
||||
|
||||
@@ -1030,22 +1037,22 @@ namespace MPF.Data
|
||||
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 2);
|
||||
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 2);
|
||||
|
||||
AddIfExists(output, "Layer 2 (Outer) " + Template.MasteringRingField, info.CommonDiscInfo.Layer2MasteringRing, 2);
|
||||
AddIfExists(output, "Layer 2 (Outer) " + Template.MasteringSIDField, info.CommonDiscInfo.Layer2MasteringSID, 2);
|
||||
AddIfExists(output, "Layer 2 (Outer) " + Template.ToolstampField, info.CommonDiscInfo.Layer2ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer2MasteringRing, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer2MasteringSID, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 2 (Inner) " : "Layer 2 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer2ToolstampMasteringCode, 2);
|
||||
}
|
||||
// If we have a dual-layer disc
|
||||
else if (info.SizeAndChecksums.Layerbreak != default)
|
||||
{
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
|
||||
AddIfExists(output, "Layer 0 (Inner) " + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer0MasteringRing, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer0MasteringSID, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 0 (Outer) " : "Layer 0 (Inner) ") + Template.ToolstampField, info.CommonDiscInfo.Layer0ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, "Data Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer0MouldSID, 2);
|
||||
AddIfExists(output, "Data Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer0AdditionalMould, 2);
|
||||
|
||||
AddIfExists(output, "Layer 1 (Outer) " + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 2);
|
||||
AddIfExists(output, "Layer 1 (Outer) " + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 2);
|
||||
AddIfExists(output, "Layer 1 (Outer) " + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.MasteringRingField, info.CommonDiscInfo.Layer1MasteringRing, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.MasteringSIDField, info.CommonDiscInfo.Layer1MasteringSID, 2);
|
||||
AddIfExists(output, (reverseOrder ? "Layer 1 (Inner) " : "Layer 1 (Outer) ") + Template.ToolstampField, info.CommonDiscInfo.Layer1ToolstampMasteringCode, 2);
|
||||
AddIfExists(output, "Label Side " + Template.MouldSIDField, info.CommonDiscInfo.Layer1MouldSID, 2);
|
||||
AddIfExists(output, "Label Side " + Template.AdditionalMouldField, info.CommonDiscInfo.Layer1AdditionalMould, 2);
|
||||
}
|
||||
@@ -1356,7 +1363,7 @@ namespace MPF.Data
|
||||
{
|
||||
if (Options.ScanForProtection)
|
||||
{
|
||||
(bool success, string output) = await Validators.RunProtectionScanOnPath($"{Drive.Letter}:\\", progress);
|
||||
(bool success, string output) = await Validators.RunProtectionScanOnPath($"{Drive.Letter}:\\", this.Options, progress);
|
||||
if (success)
|
||||
return output;
|
||||
else
|
||||
|
||||
@@ -60,6 +60,15 @@ namespace MPF.Data
|
||||
|
||||
#region UI Defaults
|
||||
|
||||
/// <summary>
|
||||
/// Enable dark mode for UI elements
|
||||
/// </summary>
|
||||
public bool EnableDarkMode
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "EnableDarkMode", false); }
|
||||
set { _settings["EnableDarkMode"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default output path for dumps
|
||||
/// </summary>
|
||||
@@ -287,6 +296,15 @@ namespace MPF.Data
|
||||
set { _settings["OutputSubmissionJSON"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Include log files in serialized JSON data
|
||||
/// </summary>
|
||||
public bool IncludeArtifacts
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "IncludeArtifacts", false); }
|
||||
set { _settings["IncludeArtifacts"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compress output log files to reduce space
|
||||
/// </summary>
|
||||
@@ -320,6 +338,46 @@ namespace MPF.Data
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protection Scanning Options
|
||||
|
||||
/// <summary>
|
||||
/// Scan archive contents during protection scanning
|
||||
/// </summary>
|
||||
public bool ScanArchivesForProtection
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "ScanArchivesForProtection", true); }
|
||||
set { _settings["ScanArchivesForProtection"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan for executable packers during protection scanning
|
||||
/// </summary>
|
||||
public bool ScanPackersForProtection
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "ScanPackersForProtection", false); }
|
||||
set { _settings["ScanPackersForProtection"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Force scanning all files for protection
|
||||
/// </summary>
|
||||
public bool ForceScanningForProtection
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "ForceScanningForProtection", false); }
|
||||
set { _settings["ForceScanningForProtection"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Include debug information with scan results
|
||||
/// </summary>
|
||||
public bool IncludeDebugProtectionInformation
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "IncludeDebugProtectionInformation", false); }
|
||||
set { _settings["IncludeDebugProtectionInformation"] = value.ToString(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Logging Options
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace MPF.Data
|
||||
if (this.TokenSource.IsCancellationRequested)
|
||||
break;
|
||||
|
||||
Thread.Sleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace MPF.DiscImageCreator
|
||||
/// </summary>
|
||||
public static class CommandStrings
|
||||
{
|
||||
public const string NONE = "";
|
||||
public const string Audio = "audio";
|
||||
public const string BluRay = "bd";
|
||||
public const string Close = "close";
|
||||
|
||||
@@ -11,31 +11,31 @@ namespace MPF.DiscImageCreator
|
||||
/// </summary>
|
||||
/// <param name="baseCommand">Command value to check</param>
|
||||
/// <returns>KnownSystem if possible, null on error</returns>
|
||||
public static KnownSystem? ToKnownSystem(Command baseCommand)
|
||||
public static KnownSystem? ToKnownSystem(string baseCommand)
|
||||
{
|
||||
switch (baseCommand)
|
||||
{
|
||||
case Command.Audio:
|
||||
case CommandStrings.Audio:
|
||||
return KnownSystem.AudioCD;
|
||||
case Command.CompactDisc:
|
||||
case Command.Data:
|
||||
case Command.DigitalVideoDisc:
|
||||
case Command.Disk:
|
||||
case Command.Floppy:
|
||||
case Command.Tape:
|
||||
case CommandStrings.CompactDisc:
|
||||
case CommandStrings.Data:
|
||||
case CommandStrings.DigitalVideoDisc:
|
||||
case CommandStrings.Disk:
|
||||
case CommandStrings.Floppy:
|
||||
case CommandStrings.Tape:
|
||||
return KnownSystem.IBMPCCompatible;
|
||||
case Command.GDROM:
|
||||
case Command.Swap:
|
||||
case CommandStrings.GDROM:
|
||||
case CommandStrings.Swap:
|
||||
return KnownSystem.SegaDreamcast;
|
||||
case Command.BluRay:
|
||||
case CommandStrings.BluRay:
|
||||
return KnownSystem.SonyPlayStation3;
|
||||
case Command.SACD:
|
||||
case CommandStrings.SACD:
|
||||
return KnownSystem.SuperAudioCD;
|
||||
case Command.XBOX:
|
||||
case Command.XBOXSwap:
|
||||
case CommandStrings.XBOX:
|
||||
case CommandStrings.XBOXSwap:
|
||||
return KnownSystem.MicrosoftXBOX;
|
||||
case Command.XGD2Swap:
|
||||
case Command.XGD3Swap:
|
||||
case CommandStrings.XGD2Swap:
|
||||
case CommandStrings.XGD3Swap:
|
||||
return KnownSystem.MicrosoftXBOX360;
|
||||
default:
|
||||
return null;
|
||||
@@ -48,33 +48,33 @@ namespace MPF.DiscImageCreator
|
||||
/// <param name="baseCommand">Command value to check</param>
|
||||
/// <returns>MediaType if possible, null on error</returns>
|
||||
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
|
||||
public static MediaType? ToMediaType(Command baseCommand)
|
||||
public static MediaType? ToMediaType(string baseCommand)
|
||||
{
|
||||
switch (baseCommand)
|
||||
{
|
||||
case Command.Audio:
|
||||
case Command.CompactDisc:
|
||||
case Command.Data:
|
||||
case Command.SACD:
|
||||
case CommandStrings.Audio:
|
||||
case CommandStrings.CompactDisc:
|
||||
case CommandStrings.Data:
|
||||
case CommandStrings.SACD:
|
||||
return MediaType.CDROM;
|
||||
case Command.GDROM:
|
||||
case Command.Swap:
|
||||
case CommandStrings.GDROM:
|
||||
case CommandStrings.Swap:
|
||||
return MediaType.GDROM;
|
||||
case Command.DigitalVideoDisc:
|
||||
case Command.XBOX:
|
||||
case Command.XBOXSwap:
|
||||
case Command.XGD2Swap:
|
||||
case Command.XGD3Swap:
|
||||
case CommandStrings.DigitalVideoDisc:
|
||||
case CommandStrings.XBOX:
|
||||
case CommandStrings.XBOXSwap:
|
||||
case CommandStrings.XGD2Swap:
|
||||
case CommandStrings.XGD3Swap:
|
||||
return MediaType.DVD;
|
||||
case Command.BluRay:
|
||||
case CommandStrings.BluRay:
|
||||
return MediaType.BluRay;
|
||||
|
||||
// Non-optical
|
||||
case Command.Floppy:
|
||||
case CommandStrings.Floppy:
|
||||
return MediaType.FloppyDisk;
|
||||
case Command.Disk:
|
||||
case CommandStrings.Disk:
|
||||
return MediaType.HardDisk;
|
||||
case Command.Tape:
|
||||
case CommandStrings.Tape:
|
||||
return MediaType.DataCartridge;
|
||||
default:
|
||||
return null;
|
||||
@@ -120,222 +120,5 @@ namespace MPF.DiscImageCreator
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convert to Long Name
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the Command enum values
|
||||
/// </summary>
|
||||
/// <param name="command">Command value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string LongName(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case Command.Audio:
|
||||
return CommandStrings.Audio;
|
||||
case Command.BluRay:
|
||||
return CommandStrings.BluRay;
|
||||
case Command.Close:
|
||||
return CommandStrings.Close;
|
||||
case Command.CompactDisc:
|
||||
return CommandStrings.CompactDisc;
|
||||
case Command.Data:
|
||||
return CommandStrings.Data;
|
||||
case Command.DigitalVideoDisc:
|
||||
return CommandStrings.DigitalVideoDisc;
|
||||
case Command.Disk:
|
||||
return CommandStrings.Disk;
|
||||
case Command.DriveSpeed:
|
||||
return CommandStrings.DriveSpeed;
|
||||
case Command.Eject:
|
||||
return CommandStrings.Eject;
|
||||
case Command.Floppy:
|
||||
return CommandStrings.Floppy;
|
||||
case Command.GDROM:
|
||||
return CommandStrings.GDROM;
|
||||
case Command.MDS:
|
||||
return CommandStrings.MDS;
|
||||
case Command.Merge:
|
||||
return CommandStrings.Merge;
|
||||
case Command.Reset:
|
||||
return CommandStrings.Reset;
|
||||
case Command.SACD:
|
||||
return CommandStrings.SACD;
|
||||
case Command.Start:
|
||||
return CommandStrings.Start;
|
||||
case Command.Stop:
|
||||
return CommandStrings.Stop;
|
||||
case Command.Sub:
|
||||
return CommandStrings.Sub;
|
||||
case Command.Swap:
|
||||
return CommandStrings.Swap;
|
||||
case Command.Tape:
|
||||
return CommandStrings.Tape;
|
||||
case Command.XBOX:
|
||||
return CommandStrings.XBOX;
|
||||
case Command.XBOXSwap:
|
||||
return CommandStrings.XBOXSwap;
|
||||
case Command.XGD2Swap:
|
||||
return CommandStrings.XGD2Swap;
|
||||
case Command.XGD3Swap:
|
||||
return CommandStrings.XGD3Swap;
|
||||
|
||||
case Command.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the Flag enum values
|
||||
/// </summary>
|
||||
/// <param name="command">Flag value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string LongName(Flag flag)
|
||||
{
|
||||
switch (flag)
|
||||
{
|
||||
case Flag.AddOffset:
|
||||
return FlagStrings.AddOffset;
|
||||
case Flag.AMSF:
|
||||
return FlagStrings.AMSF;
|
||||
case Flag.AtariJaguar:
|
||||
return FlagStrings.AtariJaguar;
|
||||
case Flag.BEOpcode:
|
||||
return FlagStrings.BEOpcode;
|
||||
case Flag.C2Opcode:
|
||||
return FlagStrings.C2Opcode;
|
||||
case Flag.CopyrightManagementInformation:
|
||||
return FlagStrings.CopyrightManagementInformation;
|
||||
case Flag.D8Opcode:
|
||||
return FlagStrings.D8Opcode;
|
||||
case Flag.DisableBeep:
|
||||
return FlagStrings.DisableBeep;
|
||||
case Flag.ExtractMicroSoftCabFile:
|
||||
return FlagStrings.ExtractMicroSoftCabFile;
|
||||
case Flag.Fix:
|
||||
return FlagStrings.Fix;
|
||||
case Flag.ForceUnitAccess:
|
||||
return FlagStrings.ForceUnitAccess;
|
||||
case Flag.MultiSectorRead:
|
||||
return FlagStrings.MultiSectorRead;
|
||||
case Flag.MultiSession:
|
||||
return FlagStrings.MultiSession;
|
||||
case Flag.NoFixSubP:
|
||||
return FlagStrings.NoFixSubP;
|
||||
case Flag.NoFixSubQ:
|
||||
return FlagStrings.NoFixSubQ;
|
||||
case Flag.NoFixSubQLibCrypt:
|
||||
return FlagStrings.NoFixSubQLibCrypt;
|
||||
case Flag.NoFixSubRtoW:
|
||||
return FlagStrings.NoFixSubRtoW;
|
||||
case Flag.NoFixSubQSecuROM:
|
||||
return FlagStrings.NoFixSubQSecuROM;
|
||||
case Flag.NoSkipSS:
|
||||
return FlagStrings.NoSkipSS;
|
||||
case Flag.PadSector:
|
||||
return FlagStrings.PadSector;
|
||||
case Flag.Raw:
|
||||
return FlagStrings.Raw;
|
||||
case Flag.Resume:
|
||||
return FlagStrings.Resume;
|
||||
case Flag.Reverse:
|
||||
return FlagStrings.Reverse;
|
||||
case Flag.ScanAntiMod:
|
||||
return FlagStrings.ScanAntiMod;
|
||||
case Flag.ScanFileProtect:
|
||||
return FlagStrings.ScanFileProtect;
|
||||
case Flag.ScanSectorProtect:
|
||||
return FlagStrings.ScanSectorProtect;
|
||||
case Flag.SeventyFour:
|
||||
return FlagStrings.SeventyFour;
|
||||
case Flag.SkipSector:
|
||||
return FlagStrings.SkipSector;
|
||||
case Flag.SubchannelReadLevel:
|
||||
return FlagStrings.SubchannelReadLevel;
|
||||
case Flag.UseAnchorVolumeDescriptorPointer:
|
||||
return FlagStrings.UseAnchorVolumeDescriptorPointer;
|
||||
case Flag.VideoNow:
|
||||
return FlagStrings.VideoNow;
|
||||
case Flag.VideoNowColor:
|
||||
return FlagStrings.VideoNowColor;
|
||||
case Flag.VideoNowXP:
|
||||
return FlagStrings.VideoNowXP;
|
||||
|
||||
case Flag.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convert From String
|
||||
|
||||
/// <summary>
|
||||
/// Get the Command enum value for a given string
|
||||
/// </summary>
|
||||
/// <param name="command">String value to convert</param>
|
||||
/// <returns>Command represented by the string(s), if possible</returns>
|
||||
public static Command StringToCommand(string command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case CommandStrings.Audio:
|
||||
return Command.Audio;
|
||||
case CommandStrings.BluRay:
|
||||
return Command.BluRay;
|
||||
case CommandStrings.Close:
|
||||
return Command.Close;
|
||||
case CommandStrings.CompactDisc:
|
||||
return Command.CompactDisc;
|
||||
case CommandStrings.Data:
|
||||
return Command.Data;
|
||||
case CommandStrings.DigitalVideoDisc:
|
||||
return Command.DigitalVideoDisc;
|
||||
case CommandStrings.Disk:
|
||||
return Command.Disk;
|
||||
case CommandStrings.DriveSpeed:
|
||||
return Command.DriveSpeed;
|
||||
case CommandStrings.Eject:
|
||||
return Command.Eject;
|
||||
case CommandStrings.Floppy:
|
||||
return Command.Floppy;
|
||||
case CommandStrings.GDROM:
|
||||
return Command.GDROM;
|
||||
case CommandStrings.MDS:
|
||||
return Command.MDS;
|
||||
case CommandStrings.Merge:
|
||||
return Command.Merge;
|
||||
case CommandStrings.Reset:
|
||||
return Command.Reset;
|
||||
case CommandStrings.SACD:
|
||||
return Command.SACD;
|
||||
case CommandStrings.Start:
|
||||
return Command.Start;
|
||||
case CommandStrings.Stop:
|
||||
return Command.Stop;
|
||||
case CommandStrings.Sub:
|
||||
return Command.Sub;
|
||||
case CommandStrings.Swap:
|
||||
return Command.Swap;
|
||||
case CommandStrings.Tape:
|
||||
return Command.Tape;
|
||||
case CommandStrings.XBOX:
|
||||
return Command.XBOX;
|
||||
case CommandStrings.XBOXSwap:
|
||||
return Command.XBOXSwap;
|
||||
case CommandStrings.XGD2Swap:
|
||||
return Command.XGD2Swap;
|
||||
case CommandStrings.XGD3Swap:
|
||||
return Command.XGD3Swap;
|
||||
|
||||
default:
|
||||
return Command.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
namespace MPF.DiscImageCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// Supported DiscImageCreator commands
|
||||
/// </summary>
|
||||
public enum Command : int
|
||||
{
|
||||
NONE = 0,
|
||||
Audio,
|
||||
BluRay,
|
||||
Close,
|
||||
CompactDisc,
|
||||
Data,
|
||||
DigitalVideoDisc,
|
||||
Disk,
|
||||
DriveSpeed,
|
||||
Eject,
|
||||
Floppy,
|
||||
GDROM,
|
||||
MDS,
|
||||
Merge,
|
||||
Reset,
|
||||
SACD,
|
||||
Start,
|
||||
Stop,
|
||||
Sub,
|
||||
Swap,
|
||||
Tape,
|
||||
XBOX,
|
||||
XBOXSwap,
|
||||
XGD2Swap,
|
||||
XGD3Swap,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supported DiscImageCreator flags
|
||||
/// </summary>
|
||||
public enum Flag : int
|
||||
{
|
||||
NONE = 0,
|
||||
AddOffset,
|
||||
AMSF,
|
||||
AtariJaguar,
|
||||
BEOpcode,
|
||||
C2Opcode,
|
||||
CopyrightManagementInformation,
|
||||
D8Opcode,
|
||||
DisableBeep,
|
||||
ExtractMicroSoftCabFile,
|
||||
Fix,
|
||||
ForceUnitAccess,
|
||||
MultiSectorRead,
|
||||
MultiSession,
|
||||
NoFixSubP,
|
||||
NoFixSubQ,
|
||||
NoFixSubQLibCrypt,
|
||||
NoFixSubRtoW,
|
||||
NoFixSubQSecuROM,
|
||||
NoSkipSS,
|
||||
PadSector,
|
||||
Raw,
|
||||
Resume,
|
||||
Reverse,
|
||||
ScanAntiMod,
|
||||
ScanFileProtect,
|
||||
ScanSectorProtect,
|
||||
SeventyFour,
|
||||
SkipSector,
|
||||
SubchannelReadLevel,
|
||||
UseAnchorVolumeDescriptorPointer,
|
||||
VideoNow,
|
||||
VideoNowColor,
|
||||
VideoNowXP,
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,13 +2,14 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net48;netcoreapp3.1</TargetFrameworks>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<Title>MPF Library</Title>
|
||||
<AssemblyName>MPF.Library</AssemblyName>
|
||||
<Description>Library code for MPF and MPF.Check</Description>
|
||||
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
|
||||
<Copyright>Copyright (c)2019-2021</Copyright>
|
||||
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
|
||||
<Version>2.0</Version>
|
||||
<Version>2.1</Version>
|
||||
<AssemblyVersion>$(Version)</AssemblyVersion>
|
||||
<FileVersion>$(Version)</FileVersion>
|
||||
<IncludeSource>true</IncludeSource>
|
||||
@@ -73,13 +74,16 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="1.6.1" GeneratePathProperty="true">
|
||||
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="1.7.0" GeneratePathProperty="true">
|
||||
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
|
||||
<PackageReference Include="System.Management" Version="6.0.0-preview.3.21201.4" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.0" />
|
||||
<PackageReference Include="System.Management" Version="6.0.0-preview.6.21352.12" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -299,6 +299,7 @@ namespace MPF.Redump
|
||||
if (request is HttpWebRequest webRequest)
|
||||
{
|
||||
webRequest.CookieContainer = m_container;
|
||||
webRequest.Timeout = 5 * 1000;
|
||||
}
|
||||
|
||||
return request;
|
||||
@@ -336,16 +337,26 @@ namespace MPF.Redump
|
||||
var loginPage = DownloadString(loginUrl);
|
||||
string token = this.tokenRegex.Match(loginPage).Groups[1].Value;
|
||||
|
||||
// Encode the values
|
||||
token = WebUtility.UrlEncode(token);
|
||||
username = WebUtility.UrlEncode(username);
|
||||
password = WebUtility.UrlEncode(password);
|
||||
|
||||
// Construct the login request
|
||||
Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
|
||||
Encoding = Encoding.UTF8;
|
||||
var response = UploadString(loginUrl, $"form_sent=1&redirect_url=&csrf_token={token}&req_username={username}&req_password={password}&save_pass=0");
|
||||
var response = UploadString(loginUrl, $"form_sent=1&redirect_url=&csrf_token={token}&req_username={username}&req_password={password}&save_pass=0&login=Login");
|
||||
|
||||
if (response.Contains("Incorrect username and/or password."))
|
||||
if (response.Contains("Incorrect username and/or password"))
|
||||
{
|
||||
Console.WriteLine("Invalid credentials entered, continuing without logging in...");
|
||||
return false;
|
||||
}
|
||||
else if (response.Contains("503 Service Unavailable"))
|
||||
{
|
||||
Console.WriteLine("Redump is not currently responding, continuing without logging in...");
|
||||
return null;
|
||||
}
|
||||
|
||||
// The user was able to be logged in
|
||||
Console.WriteLine("Credentials accepted! Logged into Redump...");
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MPF.Data;
|
||||
using MPF.Utilities;
|
||||
|
||||
namespace MPF.UmdImageCreator
|
||||
{
|
||||
@@ -31,20 +30,23 @@ namespace MPF.UmdImageCreator
|
||||
#region BaseParameters Implementations
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath)
|
||||
public override (bool, List<string>) CheckAllOutputFilesExist(string basePath, bool preCheck)
|
||||
{
|
||||
List<string> missingFiles = new List<string>();
|
||||
switch (this.Type)
|
||||
{
|
||||
case MediaType.UMD:
|
||||
if (!File.Exists($"{basePath}_disc.txt"))
|
||||
missingFiles.Add($"{basePath}_disc.txt");
|
||||
if (!File.Exists($"{basePath}_mainError.txt"))
|
||||
missingFiles.Add($"{basePath}_mainError.txt");
|
||||
if (!File.Exists($"{basePath}_mainInfo.txt"))
|
||||
missingFiles.Add($"{basePath}_mainInfo.txt");
|
||||
if (!File.Exists($"{basePath}_volDesc.txt"))
|
||||
missingFiles.Add($"{basePath}_volDesc.txt");
|
||||
if (!File.Exists($"{basePath}_logs.zip") || !preCheck)
|
||||
{
|
||||
if (!File.Exists($"{basePath}_disc.txt"))
|
||||
missingFiles.Add($"{basePath}_disc.txt");
|
||||
if (!File.Exists($"{basePath}_mainError.txt"))
|
||||
missingFiles.Add($"{basePath}_mainError.txt");
|
||||
if (!File.Exists($"{basePath}_mainInfo.txt"))
|
||||
missingFiles.Add($"{basePath}_mainInfo.txt");
|
||||
if (!File.Exists($"{basePath}_volDesc.txt"))
|
||||
missingFiles.Add($"{basePath}_volDesc.txt");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
122
MPF.Library/Utilities/Logging.cs
Normal file
122
MPF.Library/Utilities/Logging.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MPF.Utilities
|
||||
{
|
||||
internal static class Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Process a chunk of text and send it to a handler
|
||||
/// </summary>
|
||||
/// <param name="reader">TextReader representing the input</param>
|
||||
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
|
||||
/// <param name="handler">Event handler to be invoked to write to log</param>
|
||||
public static async Task OutputToLog(TextReader reader, object baseClass, EventHandler<string> handler)
|
||||
{
|
||||
// Initialize the required variables
|
||||
char[] buffer = new char[256];
|
||||
int read = 0;
|
||||
var sb = new StringBuilder();
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// Try to read the next chunk of characters
|
||||
read = await reader.ReadAsync(buffer, 0, buffer.Length);
|
||||
if (read == 0)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert the characters into a string
|
||||
string line = new string(buffer, 0, read);
|
||||
|
||||
// If we have no newline characters, store in the string builder
|
||||
if (!line.Contains('\r') && !line.Contains('\n'))
|
||||
sb.Append(line);
|
||||
|
||||
// If we have a newline, append and log
|
||||
else if (line.Contains('\n') || line.Contains("\r\n"))
|
||||
ProcessNewLines(sb, line, baseClass, handler);
|
||||
|
||||
// If we have a carriage return only, append and log first and last instances
|
||||
else if (line.Contains('\r'))
|
||||
ProcessCarriageReturns(sb, line, baseClass, handler);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
handler?.Invoke(baseClass, sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a chunk that contains newlines
|
||||
/// </summary>
|
||||
/// <param name="sb">StringBuilder to write from and append to</param>
|
||||
/// <param name="line">Current line to process</param>
|
||||
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
|
||||
/// <param name="handler">Event handler to be invoked to write to log</param>
|
||||
private static void ProcessNewLines(StringBuilder sb, string line, object baseClass, EventHandler<string> handler)
|
||||
{
|
||||
line = line.Replace("\r\n", "\n");
|
||||
var split = line.Split('\n');
|
||||
for (int i = 0; i < split.Length; i++)
|
||||
{
|
||||
// If the chunk contains a carriage return, handle it like a separate line
|
||||
if (split[i].Contains('\r'))
|
||||
{
|
||||
ProcessCarriageReturns(sb, split[i], baseClass, handler);
|
||||
continue;
|
||||
}
|
||||
|
||||
// For the first item, append to anything existing and then write out
|
||||
if (i == 0)
|
||||
{
|
||||
sb.Append(split[i]);
|
||||
handler?.Invoke(baseClass, sb.ToString());
|
||||
sb.Clear();
|
||||
}
|
||||
|
||||
// For the last item, just append so it's dealt with the next time
|
||||
else if (i == split.Length - 1)
|
||||
{
|
||||
sb.Append(split[i]);
|
||||
}
|
||||
|
||||
// For everything else, directly write out
|
||||
else
|
||||
{
|
||||
handler?.Invoke(baseClass, split[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a chunk that contains carriage returns
|
||||
/// </summary>
|
||||
/// <param name="sb">StringBuilder to write from and append to</param>
|
||||
/// <param name="line">Current line to process</param>
|
||||
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
|
||||
/// <param name="handler">Event handler to be invoked to write to log</param>
|
||||
private static void ProcessCarriageReturns(StringBuilder sb, string line, object baseClass, EventHandler<string> handler)
|
||||
{
|
||||
var split = line.Split('\r');
|
||||
|
||||
// Append and log the first
|
||||
sb.Append(split[0]);
|
||||
handler?.Invoke(baseClass, sb.ToString());
|
||||
|
||||
// Append the last
|
||||
sb.Clear();
|
||||
sb.Append($"\r{split[split.Length - 1]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,6 +272,7 @@ namespace MPF.Utilities
|
||||
case KnownSystem.IBMPCCompatible:
|
||||
types.Add(MediaType.CDROM);
|
||||
types.Add(MediaType.DVD);
|
||||
types.Add(MediaType.BluRay);
|
||||
types.Add(MediaType.FloppyDisk);
|
||||
types.Add(MediaType.HardDisk);
|
||||
types.Add(MediaType.DataCartridge);
|
||||
@@ -889,7 +890,7 @@ namespace MPF.Utilities
|
||||
&& Directory.EnumerateFiles(Path.Combine(drivePath, "VIDEO_TS")).Count() > 0)
|
||||
{
|
||||
// TODO: Maybe add video track hashes to compare for Xbox and X360?
|
||||
if (string.Equals(drive.VolumeLabel, "SEP13011042072", StringComparison.OrdinalIgnoreCase))
|
||||
if (drive.VolumeLabel.StartsWith("SEP13011042", StringComparison.OrdinalIgnoreCase))
|
||||
return KnownSystem.MicrosoftXBOX;
|
||||
|
||||
return KnownSystem.DVDVideo;
|
||||
@@ -1023,9 +1024,10 @@ namespace MPF.Utilities
|
||||
/// Run protection scan on a given dump environment
|
||||
/// </summary>
|
||||
/// <param name="path">Path to scan for protection</param>
|
||||
/// <param name="options">Options object that determines what to scan</param>
|
||||
/// <param name="progress">Optional progress callback</param>
|
||||
/// <returns>TCopy protection detected in the envirionment, if any</returns>
|
||||
public static async Task<(bool, string)> RunProtectionScanOnPath(string path, IProgress<ProtectionProgress> progress = null)
|
||||
public static async Task<(bool, string)> RunProtectionScanOnPath(string path, Options options, IProgress<ProtectionProgress> progress = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1033,10 +1035,10 @@ namespace MPF.Utilities
|
||||
{
|
||||
var scanner = new Scanner(progress)
|
||||
{
|
||||
IncludePosition = false, // Debug flag to include protection position in file
|
||||
ScanAllFiles = false, // Forces all files to be scanned as executables
|
||||
ScanArchives = true, // Allows archives to have internals extracted and scanned
|
||||
ScanPackers = false, // Allows executable packers to be detected
|
||||
IncludePosition = options.IncludeDebugProtectionInformation,
|
||||
ScanAllFiles = options.ForceScanningForProtection,
|
||||
ScanArchives = options.ScanArchivesForProtection,
|
||||
ScanPackers = options.ScanPackersForProtection,
|
||||
};
|
||||
return scanner.GetProtections(path);
|
||||
});
|
||||
@@ -1048,7 +1050,8 @@ namespace MPF.Utilities
|
||||
string protections = string.Join(", ", found
|
||||
.Where(kvp => kvp.Value != null && kvp.Value.Any())
|
||||
.SelectMany(kvp => kvp.Value)
|
||||
.Distinct());
|
||||
.Distinct()
|
||||
.OrderBy(p => p));
|
||||
return (true, protections);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net48;netcoreapp3.1</TargetFrameworks>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -17,8 +18,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeCoverage" Version="16.9.0-preview-20210106-01" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.0-preview-20210106-01" />
|
||||
<PackageReference Include="Microsoft.CodeCoverage" Version="16.11.0-release-20210626-04" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0-release-20210626-04" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageReference Include="xunit.analyzers" Version="0.10.0" />
|
||||
|
||||
@@ -15,48 +15,48 @@ namespace MPF.Test.Utilities
|
||||
public static IEnumerable<object[]> KnownSystems = KnownSystemComboBoxItem.GenerateElements().Select(e => new object[] { e });
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscImageCreator.Command.Audio, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.Command.BluRay, MediaType.BluRay)]
|
||||
[InlineData(DiscImageCreator.Command.Close, null)]
|
||||
[InlineData(DiscImageCreator.Command.CompactDisc, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.Command.Data, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.Command.DigitalVideoDisc, MediaType.DVD)]
|
||||
[InlineData(DiscImageCreator.Command.Eject, null)]
|
||||
[InlineData(DiscImageCreator.Command.Floppy, MediaType.FloppyDisk)]
|
||||
[InlineData(DiscImageCreator.Command.GDROM, MediaType.GDROM)]
|
||||
[InlineData(DiscImageCreator.Command.MDS, null)]
|
||||
[InlineData(DiscImageCreator.Command.Reset, null)]
|
||||
[InlineData(DiscImageCreator.Command.SACD, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.Command.Start, null)]
|
||||
[InlineData(DiscImageCreator.Command.Stop, null)]
|
||||
[InlineData(DiscImageCreator.Command.Sub, null)]
|
||||
[InlineData(DiscImageCreator.Command.Swap, MediaType.GDROM)]
|
||||
[InlineData(DiscImageCreator.Command.XBOX, MediaType.DVD)]
|
||||
public void BaseCommandToMediaTypeTest(DiscImageCreator.Command command, MediaType? expected)
|
||||
[InlineData(DiscImageCreator.CommandStrings.Audio, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.BluRay, MediaType.BluRay)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Close, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.CompactDisc, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Data, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.DigitalVideoDisc, MediaType.DVD)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Eject, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Floppy, MediaType.FloppyDisk)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.GDROM, MediaType.GDROM)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.MDS, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Reset, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.SACD, MediaType.CDROM)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Start, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Stop, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Sub, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Swap, MediaType.GDROM)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.XBOX, MediaType.DVD)]
|
||||
public void BaseCommandToMediaTypeTest(string command, MediaType? expected)
|
||||
{
|
||||
MediaType? actual = DiscImageCreator.Converters.ToMediaType(command);
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(DiscImageCreator.Command.Audio, KnownSystem.AudioCD)]
|
||||
[InlineData(DiscImageCreator.Command.BluRay, KnownSystem.SonyPlayStation3)]
|
||||
[InlineData(DiscImageCreator.Command.Close, null)]
|
||||
[InlineData(DiscImageCreator.Command.CompactDisc, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.Command.Data, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.Command.DigitalVideoDisc, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.Command.Eject, null)]
|
||||
[InlineData(DiscImageCreator.Command.Floppy, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.Command.GDROM, KnownSystem.SegaDreamcast)]
|
||||
[InlineData(DiscImageCreator.Command.MDS, null)]
|
||||
[InlineData(DiscImageCreator.Command.Reset, null)]
|
||||
[InlineData(DiscImageCreator.Command.SACD, KnownSystem.SuperAudioCD)]
|
||||
[InlineData(DiscImageCreator.Command.Start, null)]
|
||||
[InlineData(DiscImageCreator.Command.Stop, null)]
|
||||
[InlineData(DiscImageCreator.Command.Sub, null)]
|
||||
[InlineData(DiscImageCreator.Command.Swap, KnownSystem.SegaDreamcast)]
|
||||
[InlineData(DiscImageCreator.Command.XBOX, KnownSystem.MicrosoftXBOX)]
|
||||
public void BaseCommandToKnownSystemTest(DiscImageCreator.Command command, KnownSystem? expected)
|
||||
[InlineData(DiscImageCreator.CommandStrings.Audio, KnownSystem.AudioCD)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.BluRay, KnownSystem.SonyPlayStation3)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Close, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.CompactDisc, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Data, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.DigitalVideoDisc, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Eject, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Floppy, KnownSystem.IBMPCCompatible)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.GDROM, KnownSystem.SegaDreamcast)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.MDS, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Reset, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.SACD, KnownSystem.SuperAudioCD)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Start, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Stop, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Sub, null)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.Swap, KnownSystem.SegaDreamcast)]
|
||||
[InlineData(DiscImageCreator.CommandStrings.XBOX, KnownSystem.MicrosoftXBOX)]
|
||||
public void BaseCommandToKnownSystemTest(string command, KnownSystem? expected)
|
||||
{
|
||||
KnownSystem? actual = DiscImageCreator.Converters.ToKnownSystem(command);
|
||||
Assert.Equal(expected, actual);
|
||||
|
||||
@@ -10,13 +10,13 @@ namespace MPF.Test.Utilities
|
||||
public class ParametersTest
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.CDROM, Command.CompactDisc)]
|
||||
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD, Command.XBOX)]
|
||||
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.LaserDisc, Command.NONE)]
|
||||
[InlineData(KnownSystem.SegaNu, MediaType.BluRay, Command.BluRay)]
|
||||
[InlineData(KnownSystem.AppleMacintosh, MediaType.FloppyDisk, Command.Floppy)]
|
||||
[InlineData(KnownSystem.RawThrillsVarious, MediaType.GDROM, Command.NONE)]
|
||||
public void ParametersFromSystemAndTypeTest(KnownSystem? knownSystem, MediaType? mediaType, Command expected)
|
||||
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.CDROM, CommandStrings.CompactDisc)]
|
||||
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD, CommandStrings.XBOX)]
|
||||
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.LaserDisc, null)]
|
||||
[InlineData(KnownSystem.SegaNu, MediaType.BluRay, CommandStrings.BluRay)]
|
||||
[InlineData(KnownSystem.AppleMacintosh, MediaType.FloppyDisk, CommandStrings.Floppy)]
|
||||
[InlineData(KnownSystem.RawThrillsVarious, MediaType.GDROM, null)]
|
||||
public void ParametersFromSystemAndTypeTest(KnownSystem? knownSystem, MediaType? mediaType, string expected)
|
||||
{
|
||||
var options = new Options { };
|
||||
var actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, options);
|
||||
@@ -25,26 +25,26 @@ namespace MPF.Test.Utilities
|
||||
|
||||
[Theory]
|
||||
[InlineData(KnownSystem.AppleMacintosh, MediaType.LaserDisc, true, 20, null, null)]
|
||||
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, false, 20, null, new Flag[] { Flag.Raw })]
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 20, null, new Flag[] { Flag.CopyrightManagementInformation, Flag.ScanFileProtect })]
|
||||
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, false, 20, null, new string[] { FlagStrings.Raw })]
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 20, null, new string[] { FlagStrings.CopyrightManagementInformation, FlagStrings.ScanFileProtect })]
|
||||
/* paranoid mode tests */
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.CDROM, true, 1000, 2, new Flag[] { Flag.C2Opcode, Flag.NoFixSubQSecuROM, Flag.ScanFileProtect, Flag.ScanSectorProtect, Flag.SubchannelReadLevel })]
|
||||
[InlineData(KnownSystem.AppleMacintosh, MediaType.CDROM, false, 20, null, new Flag[] { Flag.C2Opcode, Flag.NoFixSubQSecuROM, Flag.ScanFileProtect, Flag.ScanSectorProtect, Flag.SubchannelReadLevel })]
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, true, 500, null, new Flag[] { Flag.CopyrightManagementInformation, Flag.ScanFileProtect })]
|
||||
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, true, 500, null, new Flag[] { Flag.CopyrightManagementInformation })]
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 500, null, new Flag[] { Flag.CopyrightManagementInformation, Flag.ScanFileProtect })]
|
||||
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, false, 500, null, new Flag[] { Flag.CopyrightManagementInformation })]
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.CDROM, true, 1000, 2, new string[] { FlagStrings.C2Opcode, FlagStrings.NoFixSubQSecuROM, FlagStrings.ScanFileProtect, FlagStrings.ScanSectorProtect, FlagStrings.SubchannelReadLevel })]
|
||||
[InlineData(KnownSystem.AppleMacintosh, MediaType.CDROM, false, 20, null, new string[] { FlagStrings.C2Opcode, FlagStrings.NoFixSubQSecuROM, FlagStrings.ScanFileProtect, FlagStrings.ScanSectorProtect, FlagStrings.SubchannelReadLevel })]
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, true, 500, null, new string[] { FlagStrings.CopyrightManagementInformation, FlagStrings.ScanFileProtect })]
|
||||
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, true, 500, null, new string[] { FlagStrings.CopyrightManagementInformation })]
|
||||
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 500, null, new string[] { FlagStrings.CopyrightManagementInformation, FlagStrings.ScanFileProtect })]
|
||||
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, false, 500, null, new string[] { FlagStrings.CopyrightManagementInformation })]
|
||||
/* reread c2 */
|
||||
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, 1000, null, new Flag[] { Flag.C2Opcode })]
|
||||
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, -1, null, new Flag[] { Flag.C2Opcode })]
|
||||
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, 1000, null, new string[] { FlagStrings.C2Opcode })]
|
||||
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, -1, null, new string[] { FlagStrings.C2Opcode })]
|
||||
|
||||
public void ParametersFromOptionsTest(KnownSystem? knownSystem, MediaType? mediaType, bool paranoid, int rereadC2, int? subchannelLevel, Flag[] expected)
|
||||
public void ParametersFromOptionsTest(KnownSystem? knownSystem, MediaType? mediaType, bool paranoid, int rereadC2, int? subchannelLevel, string[] expected)
|
||||
{
|
||||
var options = new Options { DICParanoidMode = paranoid, DICRereadCount = rereadC2 };
|
||||
var actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, options);
|
||||
|
||||
HashSet<Flag> expectedSet = new HashSet<Flag>(expected ?? new Flag[0]);
|
||||
HashSet<Flag> actualSet = new HashSet<Flag>(actual.Keys.Cast<Flag>() ?? new Flag[0]);
|
||||
HashSet<string> expectedSet = new HashSet<string>(expected ?? new string[0]);
|
||||
HashSet<string> actualSet = new HashSet<string>(actual.Keys.Cast<string>() ?? new string[0]);
|
||||
Assert.Equal(expectedSet, actualSet);
|
||||
if (rereadC2 == -1 || !Validators.GetValidMediaTypes(knownSystem).Contains(mediaType))
|
||||
Assert.Null(actual.C2OpcodeValue[0]);
|
||||
|
||||
767
MPF/App.xaml
767
MPF/App.xaml
@@ -1,9 +1,772 @@
|
||||
<Application x:Class="MPF.App"
|
||||
<Application
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:MPF"
|
||||
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="MPF.App"
|
||||
StartupUri="Windows\MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
|
||||
<!-- Button -->
|
||||
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
|
||||
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
|
||||
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
|
||||
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
|
||||
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
|
||||
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
|
||||
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
|
||||
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
|
||||
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
|
||||
<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
|
||||
<Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisual}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource Button.Static.Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource Button.Static.Border}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="1"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
|
||||
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsDefaulted" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="Background" TargetName="border" Value="{DynamicResource Button.MouseOver.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Button.MouseOver.Border}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter Property="Background" TargetName="border" Value="{DynamicResource Button.Pressed.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Button.Pressed.Border}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Background" TargetName="border" Value="{DynamicResource Button.Disabled.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Button.Disabled.Border}"/>
|
||||
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{DynamicResource Button.Disabled.Foreground}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- ComboBox -->
|
||||
<Style x:Key="FocusVisual">
|
||||
<Setter Property="Control.Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<LinearGradientBrush x:Key="ComboBox.Static.Background" EndPoint="0,1" StartPoint="0,0">
|
||||
<GradientStop Color="#FFF0F0F0" Offset="0.0"/>
|
||||
<GradientStop Color="#FFE5E5E5" Offset="1.0"/>
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="ComboBox.Static.Border" Color="#FFACACAC"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Static.Editable.Background" Color="#FFFFFFFF"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Static.Editable.Border" Color="#FFABADB3"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Background" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Border" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ComboBox.MouseOver.Glyph" Color="#FF000000"/>
|
||||
<LinearGradientBrush x:Key="ComboBox.MouseOver.Background" EndPoint="0,1" StartPoint="0,0">
|
||||
<GradientStop Color="#FFECF4FC" Offset="0.0"/>
|
||||
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="ComboBox.MouseOver.Border" Color="#FF7EB4EA"/>
|
||||
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Background" Color="#FFFFFFFF"/>
|
||||
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Border" Color="#FF7EB4EA"/>
|
||||
<LinearGradientBrush x:Key="ComboBox.MouseOver.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
|
||||
<GradientStop Color="#FFEBF4FC" Offset="0.0"/>
|
||||
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Button.Border" Color="#FF7EB4EA"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Pressed.Glyph" Color="#FF000000"/>
|
||||
<LinearGradientBrush x:Key="ComboBox.Pressed.Background" EndPoint="0,1" StartPoint="0,0">
|
||||
<GradientStop Color="#FFDAECFC" Offset="0.0"/>
|
||||
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="ComboBox.Pressed.Border" Color="#FF569DE5"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Background" Color="#FFFFFFFF"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Border" Color="#FF569DE5"/>
|
||||
<LinearGradientBrush x:Key="ComboBox.Pressed.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
|
||||
<GradientStop Color="#FFDAEBFC" Offset="0.0"/>
|
||||
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Button.Border" Color="#FF569DE5"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Disabled.Glyph" Color="#FFBFBFBF"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Disabled.Background" Color="#FFF0F0F0"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Disabled.Border" Color="#FFD9D9D9"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Background" Color="#FFFFFFFF"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Border" Color="#FFBFBFBF"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Background" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Border" Color="Transparent"/>
|
||||
<SolidColorBrush x:Key="ComboBox.Static.Glyph" Color="#FF606060"/>
|
||||
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="IsTabStop" Value="false"/>
|
||||
<Setter Property="Focusable" Value="false"/>
|
||||
<Setter Property="ClickMode" Value="Press"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ToggleButton}">
|
||||
<Border x:Name="templateRoot" BorderBrush="{DynamicResource ComboBox.Static.Border}" BorderThickness="{TemplateBinding BorderThickness}" Background="{DynamicResource ComboBox.Static.Background}" SnapsToDevicePixels="true">
|
||||
<Border x:Name="splitBorder" BorderBrush="Transparent" BorderThickness="1" HorizontalAlignment="Right" Margin="0" SnapsToDevicePixels="true" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
|
||||
<Path x:Name="arrow" Data="F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z" Fill="{DynamicResource ComboBox.Static.Glyph}" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="{DynamicResource ComboBox.Static.Editable.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{DynamicResource ComboBox.Static.Editable.Border}"/>
|
||||
<Setter Property="Background" TargetName="splitBorder" Value="{DynamicResource ComboBox.Static.Editable.Button.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{DynamicResource ComboBox.Static.Editable.Button.Border}"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="Fill" TargetName="arrow" Value="{DynamicResource ComboBox.MouseOver.Glyph}"/>
|
||||
</Trigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="{DynamicResource ComboBox.MouseOver.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{DynamicResource ComboBox.MouseOver.Border}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="{DynamicResource ComboBox.MouseOver.Editable.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{DynamicResource ComboBox.MouseOver.Editable.Border}"/>
|
||||
<Setter Property="Background" TargetName="splitBorder" Value="{DynamicResource ComboBox.MouseOver.Editable.Button.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{DynamicResource ComboBox.MouseOver.Editable.Button.Border}"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter Property="Fill" TargetName="arrow" Value="{DynamicResource ComboBox.Pressed.Glyph}"/>
|
||||
</Trigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="{DynamicResource ComboBox.Pressed.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{DynamicResource ComboBox.Pressed.Border}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="{DynamicResource ComboBox.Pressed.Editable.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{DynamicResource ComboBox.Pressed.Editable.Border}"/>
|
||||
<Setter Property="Background" TargetName="splitBorder" Value="{DynamicResource ComboBox.Pressed.Editable.Button.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{DynamicResource ComboBox.Pressed.Editable.Button.Border}"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Fill" TargetName="arrow" Value="{DynamicResource ComboBox.Disabled.Glyph}"/>
|
||||
</Trigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="{DynamicResource ComboBox.Disabled.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{DynamicResource ComboBox.Disabled.Border}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="{DynamicResource ComboBox.Disabled.Editable.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{DynamicResource ComboBox.Disabled.Editable.Border}"/>
|
||||
<Setter Property="Background" TargetName="splitBorder" Value="{DynamicResource ComboBox.Disabled.Editable.Button.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{DynamicResource ComboBox.Disabled.Editable.Button.Border}"/>
|
||||
</MultiDataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
|
||||
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
|
||||
<Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
|
||||
<Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
|
||||
<ScrollViewer x:Name="DropDownScrollViewer">
|
||||
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
|
||||
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
|
||||
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
|
||||
</Canvas>
|
||||
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Themes:SystemDropShadowChrome>
|
||||
</Popup>
|
||||
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{DynamicResource ComboBoxToggleButton}"/>
|
||||
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="false" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
|
||||
<Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/>
|
||||
<Setter Property="Color" TargetName="shadow" Value="#71000000"/>
|
||||
</Trigger>
|
||||
<Trigger Property="HasItems" Value="false">
|
||||
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsGrouping" Value="true"/>
|
||||
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
|
||||
</MultiTrigger>
|
||||
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
|
||||
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
|
||||
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
<SolidColorBrush x:Key="TextBox.Static.Background" Color="#FFFFFFFF"/>
|
||||
<Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="AllowDrop" Value="true"/>
|
||||
<Setter Property="MinWidth" Value="0"/>
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<ScrollViewer x:Name="PART_ContentHost" Background="Transparent" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
|
||||
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
|
||||
<Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
|
||||
<Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
|
||||
<ScrollViewer x:Name="DropDownScrollViewer">
|
||||
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
|
||||
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
|
||||
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
|
||||
</Canvas>
|
||||
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Themes:SystemDropShadowChrome>
|
||||
</Popup>
|
||||
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{DynamicResource ComboBoxToggleButton}"/>
|
||||
<Border x:Name="border" Background="{DynamicResource TextBox.Static.Background}" Margin="{TemplateBinding BorderThickness}">
|
||||
<TextBox x:Name="PART_EditableTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" Style="{DynamicResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsKeyboardFocusWithin" Value="true">
|
||||
<Setter Property="Foreground" Value="Black"/>
|
||||
</Trigger>
|
||||
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
|
||||
<Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/>
|
||||
<Setter Property="Color" TargetName="shadow" Value="#71000000"/>
|
||||
</Trigger>
|
||||
<Trigger Property="HasItems" Value="false">
|
||||
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
|
||||
</Trigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsGrouping" Value="true"/>
|
||||
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
|
||||
</MultiTrigger.Conditions>
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
|
||||
</MultiTrigger>
|
||||
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
|
||||
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
|
||||
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
<Style x:Key="CustomComboBoxStyle" TargetType="{x:Type ComboBox}">
|
||||
<Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisual}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource ComboBox.Static.Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource ComboBox.Static.Border}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
|
||||
<Setter Property="Padding" Value="6,3,5,3"/>
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
|
||||
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
|
||||
<Setter Property="Template" Value="{DynamicResource ComboBoxTemplate}"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsEditable" Value="true">
|
||||
<Setter Property="IsTabStop" Value="false"/>
|
||||
<Setter Property="Padding" Value="2"/>
|
||||
<Setter Property="Template" Value="{DynamicResource ComboBoxEditableTemplate}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- ContextMenu -->
|
||||
<SolidColorBrush x:Key="ContextMenu.Static.Border" Color="#FF888888"/>
|
||||
<Style x:Key="CustomContextMenuStyle" TargetType="{x:Type ContextMenu}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||
<Setter Property="Grid.IsSharedSizeScope" Value="true" />
|
||||
<Setter Property="HasDropShadow" Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ContextMenu}">
|
||||
<Border x:Name="Border" Background="{Binding Background}" BorderBrush="{DynamicResource ContextMenu.Static.Border}" BorderThickness="1">
|
||||
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="HasDropShadow" Value="true">
|
||||
<Setter TargetName="Border" Property="Padding" Value="0,3,0,3" />
|
||||
<Setter TargetName="Border" Property="CornerRadius" Value="4" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- CustomMessageBox -->
|
||||
<SolidColorBrush x:Key="CustomMessageBox.Static.Background" Color="#FFE5E5E5"/>
|
||||
|
||||
<!-- MenuItem -->
|
||||
<SolidColorBrush x:Key="MenuItem.SubMenu.Background" Color="#FFF0F0F0"/>
|
||||
<SolidColorBrush x:Key="MenuItem.SubMenu.Border" Color="#FF999999"/>
|
||||
<SolidColorBrush x:Key="MenuItem.SubMenu.HoverRectangle" Color="Transparent"/>
|
||||
<ControlTemplate x:Key="CustomMenuItemTemplate" TargetType="{x:Type MenuItem}">
|
||||
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
|
||||
<Grid VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
|
||||
<Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/>
|
||||
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom">
|
||||
<Border x:Name="SubMenuBorder" BorderBrush="{DynamicResource MenuItem.SubMenu.Border}" BorderThickness="1" Background="{DynamicResource MenuItem.SubMenu.Background}" Padding="2">
|
||||
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
|
||||
<Grid RenderOptions.ClearTypeHint="Enabled">
|
||||
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
|
||||
<Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
|
||||
</Canvas>
|
||||
<Rectangle Fill="{DynamicResource MenuItem.SubMenu.HoverRectangle}" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/>
|
||||
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Popup>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsSuspendingPopupAnimation" Value="True">
|
||||
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Icon" Value="{x:Null}">
|
||||
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
|
||||
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsHighlighted" Value="True">
|
||||
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
|
||||
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
|
||||
<Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/>
|
||||
</Trigger>
|
||||
<Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
|
||||
<Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
|
||||
<Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<!-- ProgressBar -->
|
||||
<SolidColorBrush x:Key="ProgressBar.Progress" Color="#FF06B025"/>
|
||||
<SolidColorBrush x:Key="ProgressBar.Background" Color="#FFE6E6E6"/>
|
||||
<SolidColorBrush x:Key="ProgressBar.Border" Color="#FFBCBCBC"/>
|
||||
<Style x:Key="CustomProgressBarStyle" TargetType="{x:Type ProgressBar}">
|
||||
<Setter Property="Foreground" Value="{DynamicResource ProgressBar.Progress}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource ProgressBar.Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource ProgressBar.Border}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ProgressBar}">
|
||||
<Grid x:Name="TemplateRoot">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Determinate"/>
|
||||
<VisualState x:Name="Indeterminate">
|
||||
<Storyboard RepeatBehavior="Forever">
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="Animation">
|
||||
<EasingDoubleKeyFrame KeyTime="0" Value="0.25"/>
|
||||
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.25"/>
|
||||
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0.25"/>
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="Animation">
|
||||
<EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5"/>
|
||||
<EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5"/>
|
||||
<EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5"/>
|
||||
</PointAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
|
||||
<Rectangle x:Name="PART_Track"/>
|
||||
<Grid x:Name="PART_Indicator" ClipToBounds="true" HorizontalAlignment="Left">
|
||||
<Rectangle x:Name="Indicator" Fill="{TemplateBinding Foreground}"/>
|
||||
<Rectangle x:Name="Animation" Fill="{TemplateBinding Foreground}" RenderTransformOrigin="0.5,0.5">
|
||||
<Rectangle.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform/>
|
||||
<SkewTransform/>
|
||||
<RotateTransform/>
|
||||
<TranslateTransform/>
|
||||
</TransformGroup>
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Orientation" Value="Vertical">
|
||||
<Setter Property="LayoutTransform" TargetName="TemplateRoot">
|
||||
<Setter.Value>
|
||||
<RotateTransform Angle="-90"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Trigger>
|
||||
<Trigger Property="IsIndeterminate" Value="true">
|
||||
<Setter Property="Visibility" TargetName="Indicator" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- ScrollViewer -->
|
||||
<SolidColorBrush x:Key="ScrollViewer.ScrollBar.Background" Color="LightGray"/>
|
||||
<SolidColorBrush x:Key="ScrollViewer.ScrollBar.Foreground" Color="DarkGray"/>
|
||||
<ControlTemplate x:Key="CustomScrollViewerControlStyle" TargetType="{x:Type ScrollViewer}">
|
||||
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
|
||||
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
|
||||
<ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Background="{DynamicResource ScrollViewer.ScrollBar.Background}" Foreground="{DynamicResource ScrollViewer.ScrollBar.Foreground}"/>
|
||||
<ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}" Background="{DynamicResource ScrollViewer.ScrollBar.Background}" Foreground="{DynamicResource ScrollViewer.ScrollBar.Foreground}"/>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
<!-- TabControl -->
|
||||
<SolidColorBrush x:Key="TabItem.Selected.Background" Color="#FFFFFF"/>
|
||||
<SolidColorBrush x:Key="TabItem.Selected.Border" Color="#ACACAC"/>
|
||||
<Style x:Key="CustomTabControlStyle" TargetType="{x:Type TabControl}">
|
||||
<Setter Property="Padding" Value="2"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Background" Value="{DynamicResource TabItem.Selected.Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource TabItem.Selected.Border}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TabControl}">
|
||||
<Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition x:Name="ColumnDefinition0"/>
|
||||
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
|
||||
<RowDefinition x:Name="RowDefinition1" Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TabPanel x:Name="headerPanel" Background="Transparent" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
|
||||
<Border x:Name="contentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
|
||||
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="TabStripPlacement" Value="Bottom">
|
||||
<Setter Property="Grid.Row" TargetName="headerPanel" Value="1"/>
|
||||
<Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
|
||||
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
|
||||
<Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
|
||||
<Setter Property="Margin" TargetName="headerPanel" Value="2,0,2,2"/>
|
||||
</Trigger>
|
||||
<Trigger Property="TabStripPlacement" Value="Left">
|
||||
<Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
|
||||
<Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
|
||||
<Setter Property="Grid.Column" TargetName="headerPanel" Value="0"/>
|
||||
<Setter Property="Grid.Column" TargetName="contentPanel" Value="1"/>
|
||||
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
|
||||
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
|
||||
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
|
||||
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
|
||||
<Setter Property="Margin" TargetName="headerPanel" Value="2,2,0,2"/>
|
||||
</Trigger>
|
||||
<Trigger Property="TabStripPlacement" Value="Right">
|
||||
<Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
|
||||
<Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
|
||||
<Setter Property="Grid.Column" TargetName="headerPanel" Value="1"/>
|
||||
<Setter Property="Grid.Column" TargetName="contentPanel" Value="0"/>
|
||||
<Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
|
||||
<Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
|
||||
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
|
||||
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
|
||||
<Setter Property="Margin" TargetName="headerPanel" Value="0,2,2,2"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- TabItem -->
|
||||
<LinearGradientBrush x:Key="TabItem.Static.Background" EndPoint="0,1" StartPoint="0,0">
|
||||
<GradientStop Color="#F0F0F0" Offset="0.0"/>
|
||||
<GradientStop Color="#E5E5E5" Offset="1.0"/>
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="TabItem.Static.Border" Color="#ACACAC"/>
|
||||
<LinearGradientBrush x:Key="TabItem.MouseOver.Background" EndPoint="0,1" StartPoint="0,0">
|
||||
<GradientStop Color="#ECF4FC" Offset="0.0"/>
|
||||
<GradientStop Color="#DCECFC" Offset="1.0"/>
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="TabItem.MouseOver.Border" Color="#7EB4EA"/>
|
||||
<SolidColorBrush x:Key="TabItem.Disabled.Background" Color="#F0F0F0"/>
|
||||
<SolidColorBrush x:Key="TabItem.Disabled.Border" Color="#D9D9D9"/>
|
||||
<Style x:Key="CustomTabItemStyle" TargetType="{x:Type TabItem}">
|
||||
<Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisual}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource TabItem.Static.Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource TabItem.Static.Border}"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="6,2,6,2"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TabItem}">
|
||||
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
|
||||
<Border x:Name="mainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" Background="{TemplateBinding Background}" Margin="0">
|
||||
<Border x:Name="innerBorder" BorderBrush="{DynamicResource TabItem.Selected.Border}" BorderThickness="1,1,1,0" Background="{DynamicResource TabItem.Selected.Background}" Margin="-1" Opacity="0"/>
|
||||
</Border>
|
||||
<ContentPresenter x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Left"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,0,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,0,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Bottom"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,0,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,0,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Right"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="0,1,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="0,1,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Top"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.MouseOver.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,1,0"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,1,0"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Left"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.56"/>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,0,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,0,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Bottom"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.56"/>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,0,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,0,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Right"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.56"/>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="0,1,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="0,1,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Top"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.56"/>
|
||||
<Setter Property="Background" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="mainBorder" Value="{DynamicResource TabItem.Disabled.Border}"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,1,0"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,1,0"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Left"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,0,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,0,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Left"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
<Setter Property="Margin" Value="-2,-2,0,-2"/>
|
||||
<Setter Property="Opacity" TargetName="innerBorder" Value="1"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,0,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,0,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Bottom"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,0,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,0,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Bottom"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
<Setter Property="Margin" Value="-2,0,-2,-2"/>
|
||||
<Setter Property="Opacity" TargetName="innerBorder" Value="1"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,0,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,0,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Right"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="0,1,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="0,1,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Right"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
<Setter Property="Margin" Value="0,-2,-2,-2"/>
|
||||
<Setter Property="Opacity" TargetName="innerBorder" Value="1"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="0,1,1,1"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="0,1,1,1"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="false"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Top"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,1,0"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,1,0"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true"/>
|
||||
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Top"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
<Setter Property="Margin" Value="-2,-2,-2,0"/>
|
||||
<Setter Property="Opacity" TargetName="innerBorder" Value="1"/>
|
||||
<Setter Property="BorderThickness" TargetName="innerBorder" Value="1,1,1,0"/>
|
||||
<Setter Property="BorderThickness" TargetName="mainBorder" Value="1,1,1,0"/>
|
||||
</MultiDataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
596
MPF/External/WPFCustomMessageBox/CustomMessageBox.cs
vendored
Normal file
596
MPF/External/WPFCustomMessageBox/CustomMessageBox.cs
vendored
Normal file
@@ -0,0 +1,596 @@
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="MessageBox.cs">
|
||||
// TODO: Update copyright text.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace WPFCustomMessageBox
|
||||
{
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box.
|
||||
/// </summary>
|
||||
public static class CustomMessageBox
|
||||
{
|
||||
/// <summary>
|
||||
/// Global parameter to enable (true) or disable (false) the removal of the title bar icon.
|
||||
/// If you are using a custom window style, the icon removal may cause issues like displaying two title bar (the default windows one and the custom one).
|
||||
/// </summary>
|
||||
public static bool RemoveTitleBarIcon = true;
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message and returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(string messageBoxText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(null, messageBoxText, string.Empty, null, null, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message and a title bar caption; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(null, messageBoxText, caption, null, null, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box in front of the specified window. The message box displays a message and returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(owner, messageBoxText, string.Empty, null, null, null, timeout, timeoutResult);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box in front of the specified window. The message box displays a message and title bar caption; and it returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(owner, messageBoxText, caption, null, null, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, and button; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="button">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.YesNo:
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
return ShowYesNoMessage(null, messageBoxText, caption, null, null, null, null, timeout, timeoutResult);
|
||||
default:
|
||||
return ShowOKMessage(null, messageBoxText, caption, null, null, null, timeout, timeoutResult);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, and button; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="button">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.YesNo:
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
return ShowYesNoMessage(owner, messageBoxText, caption, null, null, null, null, timeout, timeoutResult);
|
||||
default:
|
||||
return ShowOKMessage(owner, messageBoxText, caption, null, null, null, timeout, timeoutResult);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="button">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.YesNo:
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
return ShowYesNoMessage(null, messageBoxText, caption, null, null, null, icon, timeout, timeoutResult);
|
||||
default:
|
||||
return ShowOKMessage(null, messageBoxText, caption, null, null, icon, timeout, timeoutResult);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="button">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.YesNo:
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
return ShowYesNoMessage(owner, messageBoxText, caption, null, null, null, icon, timeout, timeoutResult);
|
||||
default:
|
||||
return ShowOKMessage(owner, messageBoxText, caption, null, null, icon, timeout, timeoutResult);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, and OK button with a custom System.String value for the button's text; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOK(string messageBoxText, string caption, string okButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(null, messageBoxText, caption, okButtonText, null, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, and OK button with a custom System.String value for the button's text; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOK(Window owner, string messageBoxText, string caption, string okButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(owner, messageBoxText, caption, okButtonText, null, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, OK button with a custom System.String value for the button's text, and icon; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOK(string messageBoxText, string caption, string okButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(null, messageBoxText, caption, okButtonText, null, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, title bar caption, OK button with a custom System.String value for the button's text, and icon; and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOK(Window owner, string messageBoxText, string caption, string okButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(owner, messageBoxText, caption, okButtonText, null, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, and OK/Cancel buttons with custom System.String values for the buttons' text;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOKCancel(string messageBoxText, string caption, string okButtonText, string cancelButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(null, messageBoxText, caption, okButtonText, cancelButtonText, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, and OK/Cancel buttons with custom System.String values for the buttons' text;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOKCancel(Window owner, string messageBoxText, string caption, string okButtonText, string cancelButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(owner, messageBoxText, caption, okButtonText, cancelButtonText, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, OK/Cancel buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOKCancel(string messageBoxText, string caption, string okButtonText, string cancelButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(null, messageBoxText, caption, okButtonText, cancelButtonText, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, OK/Cancel buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowOKCancel(Window owner, string messageBoxText, string caption, string okButtonText, string cancelButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowOKMessage(owner, messageBoxText, caption, okButtonText, cancelButtonText, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, and Yes/No buttons with custom System.String values for the buttons' text;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNo(string messageBoxText, string caption, string yesButtonText, string noButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(null, messageBoxText, caption, yesButtonText, noButtonText, null, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, and Yes/No buttons with custom System.String values for the buttons' text;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNo(Window owner, string messageBoxText, string caption, string yesButtonText, string noButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(owner, messageBoxText, caption, yesButtonText, noButtonText, null, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, Yes/No buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNo(string messageBoxText, string caption, string yesButtonText, string noButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(null, messageBoxText, caption, yesButtonText, noButtonText, null, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, Yes/No buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNo(Window owner, string messageBoxText, string caption, string yesButtonText, string noButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(owner, messageBoxText, caption, yesButtonText, noButtonText, null, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, and Yes/No/Cancel buttons with custom System.String values for the buttons' text;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNoCancel(string messageBoxText, string caption, string yesButtonText, string noButtonText, string cancelButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(null, messageBoxText, caption, yesButtonText, noButtonText, cancelButtonText, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, and Yes/No/Cancel buttons with custom System.String values for the buttons' text;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNoCancel(Window owner, string messageBoxText, string caption, string yesButtonText, string noButtonText, string cancelButtonText, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(owner, messageBoxText, caption, yesButtonText, noButtonText, cancelButtonText, null, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, Yes/No/Cancel buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNoCancel(string messageBoxText, string caption, string yesButtonText, string noButtonText, string cancelButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(null, messageBoxText, caption, yesButtonText, noButtonText, cancelButtonText, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, Yes/No/Cancel buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">
|
||||
/// The message box will close automatically after <paramref name="timeout"/> milliseconds.
|
||||
/// If null, the message box will act like default message box and not close automatically.
|
||||
/// </param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to the <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
public static MessageBoxResult ShowYesNoCancel(Window owner, string messageBoxText, string caption, string yesButtonText, string noButtonText, string cancelButtonText, MessageBoxImage icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
return ShowYesNoMessage(owner, messageBoxText, caption, yesButtonText, noButtonText, cancelButtonText, icon, timeout, timeoutResult);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, OK/Cancel buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="okButtonText">A System.String that specifies the text to display within the OK button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">The message box will close automatically after given milliseconds</param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
private static MessageBoxResult ShowOKMessage(Window owner, string messageBoxText, string caption, string okButtonText, string cancelButtonText, MessageBoxImage? icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
MessageBoxButton buttonLayout = string.IsNullOrEmpty(cancelButtonText) ? MessageBoxButton.OK : MessageBoxButton.OKCancel;
|
||||
|
||||
CustomMessageBoxWindow msg = new CustomMessageBoxWindow(owner, messageBoxText, caption, buttonLayout, icon, RemoveTitleBarIcon);
|
||||
if (!string.IsNullOrEmpty(okButtonText))
|
||||
msg.OkButtonText = okButtonText;
|
||||
if (!string.IsNullOrEmpty(cancelButtonText))
|
||||
msg.CancelButtonText = cancelButtonText;
|
||||
|
||||
ShowDialog(msg, timeout, timeoutResult);
|
||||
|
||||
return msg.Result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Displays a message box that has a message, caption, Yes/No/Cancel buttons with custom System.String values for the buttons' text, and icon;
|
||||
/// and that returns a result.
|
||||
/// </summary>
|
||||
/// <param name="owner">A System.Windows.Window that represents the owner window of the message box.</param>
|
||||
/// <param name="messageBoxText">A System.String that specifies the text to display.</param>
|
||||
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
/// <param name="yesButtonText">A System.String that specifies the text to display within the Yes button.</param>
|
||||
/// <param name="noButtonText">A System.String that specifies the text to display within the No button.</param>
|
||||
/// <param name="cancelButtonText">A System.String that specifies the text to display within the Cancel button.</param>
|
||||
/// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
/// <param name="timeout">The message box will close automatically after given milliseconds</param>
|
||||
/// <param name="timeoutResult">If the message box closes automatically due to <paramref name="timeout"/> being exceeded, this result is returned.</param>
|
||||
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
private static MessageBoxResult ShowYesNoMessage(Window owner, string messageBoxText, string caption, string yesButtonText, string noButtonText, string cancelButtonText, MessageBoxImage? icon, int? timeout = null, MessageBoxResult timeoutResult = MessageBoxResult.None)
|
||||
{
|
||||
MessageBoxButton buttonLayout = string.IsNullOrEmpty(cancelButtonText) ? MessageBoxButton.YesNo : MessageBoxButton.YesNoCancel;
|
||||
|
||||
CustomMessageBoxWindow msg = new CustomMessageBoxWindow(owner, messageBoxText, caption, buttonLayout, icon, RemoveTitleBarIcon);
|
||||
if (!string.IsNullOrEmpty(yesButtonText))
|
||||
msg.YesButtonText = yesButtonText;
|
||||
if (!string.IsNullOrEmpty(noButtonText))
|
||||
msg.NoButtonText = noButtonText;
|
||||
if (!string.IsNullOrEmpty(cancelButtonText))
|
||||
msg.CancelButtonText = cancelButtonText;
|
||||
|
||||
ShowDialog(msg, timeout, timeoutResult);
|
||||
|
||||
return msg.Result;
|
||||
}
|
||||
|
||||
private static void ShowDialog(CustomMessageBoxWindow dialog, int? timeout, MessageBoxResult timeoutResult)
|
||||
{
|
||||
if (timeout.HasValue && timeout.Value <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("timeout", string.Format("Timeout must be greater than 0."));
|
||||
}
|
||||
|
||||
if (timeout.HasValue)
|
||||
{
|
||||
//System.Threading.Timer timer = null;
|
||||
//timer = new System.Threading.Timer(s => { msg.Close(); timer.Dispose(); }, null, timeout.Value, System.Threading.Timeout.Infinite);
|
||||
System.Timers.Timer timer = new System.Timers.Timer(timeout.Value) { AutoReset = false };
|
||||
timer.Elapsed += delegate {
|
||||
Application.Current.Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
dialog.Result = timeoutResult;
|
||||
dialog.Close();
|
||||
//timer.Stop();
|
||||
//timer.Dispose();
|
||||
//timer = null;
|
||||
}));
|
||||
};
|
||||
timer.Start();
|
||||
dialog.ShowDialog();
|
||||
timer.Stop();
|
||||
timer.Dispose();
|
||||
}
|
||||
else
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
84
MPF/External/WPFCustomMessageBox/CustomMessageBoxWindow.xaml
vendored
Normal file
84
MPF/External/WPFCustomMessageBox/CustomMessageBoxWindow.xaml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<Window x:Class="WPFCustomMessageBox.CustomMessageBoxWindow"
|
||||
x:ClassModifier="internal"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
WindowStyle="None"
|
||||
ShowInTaskbar="False"
|
||||
ResizeMode="NoResize" SizeToContent="WidthAndHeight"
|
||||
TextOptions.TextFormattingMode="Display" TextOptions.TextRenderingMode="ClearType" UseLayoutRounding="True"
|
||||
Title="" MinHeight="155" MaxWidth="470" MinWidth="154"
|
||||
BorderBrush="DarkGray" BorderThickness="2">
|
||||
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
|
||||
</WindowChrome.WindowChrome>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="25"/>
|
||||
<ColumnDefinition Width="115"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="50"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" />
|
||||
<Label Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown" Content="{Binding Path=Title,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Make the window width fit the title by embedding the title invisibly -->
|
||||
<TextBlock Text="{Binding Path=Title,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
|
||||
Visibility="Hidden" Height="0" Margin="50 0 0 0" />
|
||||
|
||||
<Grid Grid.Row="1" Background="{DynamicResource CustomMessageBox.Static.Background}" MinHeight="69">
|
||||
<DockPanel>
|
||||
<Image Name="Image_MessageBox" Width="32" Height="32" HorizontalAlignment="Left" DockPanel.Dock="Left" Margin="30,0,0,0" Visibility="Collapsed"/>
|
||||
<TextBlock Name="TextBlock_Message" TextWrapping="Wrap" MaxWidth="500" Width="Auto"
|
||||
VerticalAlignment="Center" Margin="12,20,41,15" />
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2" Background="{DynamicResource CustomMessageBox.Static.Background}" MinHeight="49">
|
||||
<DockPanel Margin="5,0">
|
||||
|
||||
<!-- Cancel Button -->
|
||||
<Button Name="Button_Cancel" MinWidth="88" MaxWidth="160" Height="26" Margin="5,0" HorizontalAlignment="Right" Visibility="Collapsed" IsCancel="True"
|
||||
DockPanel.Dock="Right" Click="Button_Cancel_Click" Style="{DynamicResource CustomButtonStyle}">
|
||||
<Label Name="Label_Cancel" Padding="0" Margin="10,0">_Cancel</Label>
|
||||
</Button>
|
||||
<!-- End Cancel Button -->
|
||||
|
||||
<!-- No Button -->
|
||||
<Button Name="Button_No" MinWidth="88" MaxWidth="160" Height="26" Margin="5,0" HorizontalAlignment="Right" Visibility="Collapsed"
|
||||
DockPanel.Dock="Right" Click="Button_No_Click" Style="{DynamicResource CustomButtonStyle}">
|
||||
<Label Name="Label_No" Padding="0" Margin="10,0">_No</Label>
|
||||
</Button>
|
||||
<!-- End No Button -->
|
||||
|
||||
<!-- Yes Button -->
|
||||
<Button Name="Button_Yes" MinWidth="88" MaxWidth="160" Height="26" Margin="35,0,5,0" HorizontalAlignment="Right" Visibility="Collapsed"
|
||||
DockPanel.Dock="Right" Click="Button_Yes_Click" Style="{DynamicResource CustomButtonStyle}">
|
||||
<Label Name="Label_Yes" Padding="0" Margin="10,0">_Yes</Label>
|
||||
</Button>
|
||||
<!-- End Yes Button -->
|
||||
|
||||
<!-- OK Button -->
|
||||
<Button Name="Button_OK" MinWidth="88" MaxWidth="160" Margin="35,0,5,0" HorizontalAlignment="Right" Height="26"
|
||||
Click="Button_OK_Click" Style="{DynamicResource CustomButtonStyle}">
|
||||
<Label Name="Label_Ok" Padding="0" Margin="10,0">_OK</Label>
|
||||
</Button>
|
||||
<!-- End OK Button -->
|
||||
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
223
MPF/External/WPFCustomMessageBox/CustomMessageBoxWindow.xaml.cs
vendored
Normal file
223
MPF/External/WPFCustomMessageBox/CustomMessageBoxWindow.xaml.cs
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace WPFCustomMessageBox
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ModalDialog.xaml
|
||||
/// </summary>
|
||||
internal partial class CustomMessageBoxWindow : Window
|
||||
{
|
||||
private bool _removeTitleBarIcon = true;
|
||||
|
||||
public string Caption
|
||||
{
|
||||
get
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
set
|
||||
{
|
||||
Title = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return TextBlock_Message.Text;
|
||||
}
|
||||
set
|
||||
{
|
||||
TextBlock_Message.Text = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string OkButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_Ok.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_Ok.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
public string CancelButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_Cancel.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_Cancel.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
public string YesButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_Yes.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_Yes.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
public string NoButtonText
|
||||
{
|
||||
get
|
||||
{
|
||||
return Label_No.Content.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
Label_No.Content = value.TryAddKeyboardAccellerator();
|
||||
}
|
||||
}
|
||||
|
||||
public MessageBoxResult Result { get; set; }
|
||||
|
||||
internal CustomMessageBoxWindow(Window owner, string message, string caption = null, MessageBoxButton? button = null, MessageBoxImage? image = null, bool removeTitleBarIcon = true)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_removeTitleBarIcon = removeTitleBarIcon;
|
||||
|
||||
if (owner != null)
|
||||
{
|
||||
Owner = owner;
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
}
|
||||
|
||||
Message = message;
|
||||
Caption = caption;
|
||||
|
||||
DisplayButtons(button ?? MessageBoxButton.OK);
|
||||
|
||||
if (image.HasValue)
|
||||
DisplayImage(image.Value);
|
||||
else
|
||||
Image_MessageBox.Visibility = System.Windows.Visibility.Collapsed;
|
||||
}
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
if (_removeTitleBarIcon)
|
||||
Util.RemoveIcon(this);
|
||||
|
||||
base.OnSourceInitialized(e);
|
||||
}
|
||||
|
||||
private void DisplayButtons(MessageBoxButton button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.OKCancel:
|
||||
// Hide all but OK, Cancel
|
||||
Button_OK.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_OK.Focus();
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Visible;
|
||||
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_No.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
case MessageBoxButton.YesNo:
|
||||
// Hide all but Yes, No
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_Yes.Focus();
|
||||
Button_No.Visibility = System.Windows.Visibility.Visible;
|
||||
|
||||
Button_OK.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
// Hide only OK
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_Yes.Focus();
|
||||
Button_No.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Visible;
|
||||
|
||||
Button_OK.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
default:
|
||||
// Hide all but OK
|
||||
Button_OK.Visibility = System.Windows.Visibility.Visible;
|
||||
Button_OK.Focus();
|
||||
|
||||
Button_Yes.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_No.Visibility = System.Windows.Visibility.Collapsed;
|
||||
Button_Cancel.Visibility = System.Windows.Visibility.Collapsed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayImage(MessageBoxImage image)
|
||||
{
|
||||
Icon icon;
|
||||
|
||||
switch (image)
|
||||
{
|
||||
case MessageBoxImage.Exclamation: // Enumeration value 48 - also covers "Warning"
|
||||
icon = SystemIcons.Exclamation;
|
||||
break;
|
||||
case MessageBoxImage.Error: // Enumeration value 16, also covers "Hand" and "Stop"
|
||||
icon = SystemIcons.Hand;
|
||||
break;
|
||||
case MessageBoxImage.Information: // Enumeration value 64 - also covers "Asterisk"
|
||||
icon = SystemIcons.Information;
|
||||
break;
|
||||
case MessageBoxImage.Question:
|
||||
icon = SystemIcons.Question;
|
||||
break;
|
||||
default:
|
||||
icon = SystemIcons.Information;
|
||||
break;
|
||||
}
|
||||
|
||||
Image_MessageBox.Source = icon.ToImageSource();
|
||||
Image_MessageBox.Visibility = System.Windows.Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Button_OK_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Cancel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Yes_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.Yes;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_No_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Result = MessageBoxResult.No;
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for Title MouseDown event
|
||||
/// </summary>
|
||||
private void TitleMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
this.DragMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
MPF/External/WPFCustomMessageBox/LICENSE
vendored
Normal file
23
MPF/External/WPFCustomMessageBox/LICENSE
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Thomas Absenger
|
||||
|
||||
Copyright (c) 2013 Evan Wondrasek / Apricity Software LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
92
MPF/External/WPFCustomMessageBox/Util.cs
vendored
Normal file
92
MPF/External/WPFCustomMessageBox/Util.cs
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="Util.cs">
|
||||
// TODO: Update copyright text.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace WPFCustomMessageBox
|
||||
{
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
/// <summary>
|
||||
/// TODO: Update summary.
|
||||
/// </summary>
|
||||
internal static class Util
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
static extern int GetWindowLong(IntPtr hwnd, int index);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
const int GWL_EXSTYLE = -20;
|
||||
const int WS_EX_DLGMODALFRAME = 0x0001;
|
||||
const int SWP_NOSIZE = 0x0001;
|
||||
const int SWP_NOMOVE = 0x0002;
|
||||
const int SWP_NOZORDER = 0x0004;
|
||||
const int SWP_FRAMECHANGED = 0x0020;
|
||||
const uint WM_SETICON = 0x0080;
|
||||
|
||||
|
||||
internal static ImageSource ToImageSource(this Icon icon)
|
||||
{
|
||||
ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(
|
||||
icon.Handle,
|
||||
Int32Rect.Empty,
|
||||
BitmapSizeOptions.FromEmptyOptions());
|
||||
|
||||
return imageSource;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keyboard Accellerators are used in Windows to allow easy shortcuts to controls like Buttons and
|
||||
/// MenuItems. These allow users to press the Alt key, and a shortcut key will be highlighted on the
|
||||
/// control. If the user presses that key, that control will be activated.
|
||||
/// This method checks a string if it contains a keyboard accellerator. If it doesn't, it adds one to the
|
||||
/// beginning of the string. If there are two strings with the same accellerator, Windows handles it.
|
||||
/// The keyboard accellerator character for WPF is underscore (_). It will not be visible.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
internal static string TryAddKeyboardAccellerator(this string input)
|
||||
{
|
||||
if (input == null)
|
||||
return input;
|
||||
|
||||
const string accellerator = "_"; // This is the default WPF accellerator symbol - used to be & in WinForms
|
||||
|
||||
// If it already contains an accellerator, do nothing
|
||||
if (input.Contains(accellerator)) return input;
|
||||
|
||||
return accellerator + input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the icon from the given window.
|
||||
/// See https://stackoverflow.com/a/18581096
|
||||
/// </summary>
|
||||
/// <param name="window">The window to remove the icon from.</param>
|
||||
internal static void RemoveIcon(Window window)
|
||||
{
|
||||
// Get this window's handle
|
||||
IntPtr hwnd = new WindowInteropHelper(window).Handle;
|
||||
// Change the extended window style to not show a window icon
|
||||
int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
|
||||
// Update the window's non-client area to reflect the changes
|
||||
SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
@@ -2,18 +2,18 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net48;netcoreapp3.1</TargetFrameworks>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<ApplicationIcon>Images\Icon.ico</ApplicationIcon>
|
||||
<Title>MPF</Title>
|
||||
<AssemblyName>MPF</AssemblyName>
|
||||
<Description>Frontend for various dumping programs</Description>
|
||||
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
|
||||
<Copyright>Copyright (c)2019-2021</Copyright>
|
||||
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
|
||||
<Version>2.0</Version>
|
||||
<Version>2.1</Version>
|
||||
<AssemblyVersion>$(Version)</AssemblyVersion>
|
||||
<FileVersion>$(Version)</FileVersion>
|
||||
<IncludeSource>true</IncludeSource>
|
||||
@@ -27,11 +27,14 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="1.6.1" GeneratePathProperty="true">
|
||||
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="1.7.0" GeneratePathProperty="true">
|
||||
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0-preview.3.21201.4" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0-preview.6.21352.12" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -39,6 +42,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\Icon.ico" />
|
||||
<Resource Include="Images\ring-code-guide.png" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -49,4 +53,8 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="PresentationFramework.Aero" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -9,21 +9,21 @@
|
||||
<Grid>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Grid Height="22" Margin="10 10 10 0">
|
||||
<ProgressBar x:Name="ProgressBar" />
|
||||
<ProgressBar x:Name="ProgressBar" Style="{DynamicResource CustomProgressBarStyle}" />
|
||||
<TextBlock x:Name="ProgressLabel" Grid.Row="0" Height="22" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0 2 0 0" />
|
||||
</Grid>
|
||||
|
||||
<Border Height="180" Background="White" BorderBrush="Gainsboro" BorderThickness="1" Margin="10">
|
||||
<ScrollViewer Name="OutputViewer" SizeChanged="OutputViewerSizeChanged">
|
||||
<RichTextBox Name="Output" FontFamily="Consolas" Background="#202020" IsReadOnly="true" TextChanged="OnTextChanged" />
|
||||
<ScrollViewer Name="OutputViewer" SizeChanged="OutputViewerSizeChanged" Template="{DynamicResource CustomScrollViewerControlStyle}">
|
||||
<RichTextBox Name="Output" FontFamily="Consolas" Background="#FF202020" IsReadOnly="true" TextChanged="OnTextChanged" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<GroupBox Grid.Row="2" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<UniformGrid Columns="4" Margin="5,5,5,5" Height="28">
|
||||
<Label/> <!-- Empty label for padding -->
|
||||
<Button Name="ClearButton" Height="25" Width="80" Content="Clear" Click="OnClearButton" />
|
||||
<Button Name="SaveButton" Height="25" Width="80" Content="Save" Click="OnSaveButton" />
|
||||
<Button Name="ClearButton" Height="25" Width="80" Content="Clear" Click="OnClearButton" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Button Name="SaveButton" Height="25" Width="80" Content="Save" Click="OnSaveButton" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Label/> <!-- Empty label for padding -->
|
||||
</UniformGrid>
|
||||
</GroupBox>
|
||||
|
||||
@@ -48,11 +48,15 @@ namespace MPF.UserControls
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
|
||||
var document = new FlowDocument();
|
||||
var document = new FlowDocument()
|
||||
{
|
||||
Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x20, 0x20, 0x20))
|
||||
};
|
||||
_paragraph = new Paragraph();
|
||||
document.Blocks.Add(_paragraph);
|
||||
Output.Document = document;
|
||||
|
||||
// TODO: Can we dynamically add matchers *only* during dumping?
|
||||
_matchers = new List<Matcher?>();
|
||||
AddAaruMatchers();
|
||||
AddDiscImageCreatorMatchers();
|
||||
@@ -359,7 +363,7 @@ namespace MPF.UserControls
|
||||
|
||||
// If we have verbose logs but not enabled, ignore
|
||||
if (logLevel == LogLevel.VERBOSE && !ViewModels.OptionsViewModel.VerboseLogging)
|
||||
return;
|
||||
return;
|
||||
|
||||
// Enqueue the text
|
||||
logQueue.Enqueue(new LogLine(text, logLevel));
|
||||
@@ -381,7 +385,11 @@ namespace MPF.UserControls
|
||||
// If we're not processing log formatting, just append and continue
|
||||
if (!ViewModels.OptionsViewModel.EnableLogFormatting)
|
||||
{
|
||||
AppendToTextBox(nextLogLine);
|
||||
if (nextText.StartsWith("\r"))
|
||||
ReplaceLastLine(nextLogLine);
|
||||
else
|
||||
AppendToTextBox(nextLogLine);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,6 +406,7 @@ namespace MPF.UserControls
|
||||
else if (nextText.StartsWith("\r"))
|
||||
{
|
||||
ReplaceLastLine(nextLogLine);
|
||||
lastUsedMatcher = _matchers.FirstOrDefault(m => m?.Matches(nextText.TrimStart('\r')) == true);
|
||||
}
|
||||
// If we have a cached matcher and we match
|
||||
else if (lastUsedMatcher?.Matches(nextText) == true)
|
||||
@@ -499,7 +508,7 @@ namespace MPF.UserControls
|
||||
_paragraph.Inlines.Clear();
|
||||
ResetProgressBar();
|
||||
}
|
||||
|
||||
|
||||
private void OnSaveButton(object sender, EventArgs e)
|
||||
{
|
||||
using (StreamWriter tw = new StreamWriter(File.OpenWrite("console.log")))
|
||||
|
||||
@@ -6,12 +6,67 @@
|
||||
xmlns:local="clr-namespace:MPF"
|
||||
xmlns:controls="clr-namespace:MPF.UserControls"
|
||||
mc:Ignorable="d"
|
||||
Title="Disc Information" Width="515" ResizeMode="NoResize" SizeToContent="Height">
|
||||
Title="Disc Information" Width="515" WindowStyle="None"
|
||||
WindowStartupLocation="CenterOwner" ResizeMode="CanMinimize" SizeToContent="Height"
|
||||
BorderBrush="DarkGray" BorderThickness="2">
|
||||
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
|
||||
</WindowChrome.WindowChrome>
|
||||
|
||||
<Grid>
|
||||
<StackPanel Orientation="Vertical" Width="500">
|
||||
<TabControl>
|
||||
<TabItem x:Name="CommonInfo" Header="Common Info">
|
||||
<Grid Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="25"/>
|
||||
<ColumnDefinition Width="115"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="50"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" />
|
||||
<Label Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
|
||||
<Label.Content>
|
||||
<TextBlock TextAlignment="Center"><Bold>Disc Information</Bold></TextBlock>
|
||||
</Label.Content>
|
||||
<Label.ContextMenu>
|
||||
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Style="{DynamicResource CustomContextMenuStyle}">
|
||||
<MenuItem Header="Minimize" Click="MinimizeButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
BorderBrush="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
<MenuItem Header="Close" Click="CloseButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
BorderBrush="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
</ContextMenu>
|
||||
</Label.ContextMenu>
|
||||
</Label>
|
||||
<Grid Grid.Column="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="MinimizeButton" Grid.Column="0" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="MinimizeButtonClick">
|
||||
<Path Data="M 0,0 L 10,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
<Button x:Name="CloseButton" Grid.Column="1" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="CloseButtonClick">
|
||||
<Path Data="M 0,0 L 12,12 M 0,12 L 12,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<TabControl Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Style="{DynamicResource CustomTabControlStyle}">
|
||||
<TabItem x:Name="CommonInfo" Header="Common Info" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Expander Margin="5" Padding="5" BorderThickness="1" BorderBrush="LightGray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Common Disc Information" IsExpanded="True">
|
||||
<StackPanel Orientation="Vertical">
|
||||
@@ -27,7 +82,8 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label x:Name="CategoryLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Category" />
|
||||
<ComboBox x:Name="CategoryComboBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=Categories}" SelectedIndex="0" />
|
||||
<ComboBox x:Name="CategoryComboBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ItemsSource="{Binding Categories}"
|
||||
SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}" />
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
@@ -37,7 +93,8 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label x:Name="RegionLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Region" />
|
||||
<ComboBox x:Name="RegionComboBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=Regions}" SelectedIndex="0" />
|
||||
<ComboBox x:Name="RegionComboBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ItemsSource="{Binding Regions}"
|
||||
SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}" />
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
@@ -47,10 +104,11 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label x:Name="LanguagesLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Languages" />
|
||||
<ComboBox x:Name="LanguagesComboBox" Grid.Row="0" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=Languages}" SelectedIndex="0">
|
||||
<ComboBox x:Name="LanguagesComboBox" Grid.Row="0" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" ItemsSource="{Binding Languages}"
|
||||
SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox Content="{Binding Path=Name}" IsChecked="{Binding IsChecked}" />
|
||||
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
@@ -63,10 +121,11 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label x:Name="LanguageSelectionLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Language Selection Via" />
|
||||
<ComboBox x:Name="LanguageSelectionComboBox" Grid.Row="0" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=LanguageSelections}" SelectedIndex="0">
|
||||
<ComboBox x:Name="LanguageSelectionComboBox" Grid.Row="0" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" ItemsSource="{Binding LanguageSelections}"
|
||||
SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox Content="{Binding Path=Name}" IsChecked="{Binding IsChecked}" />
|
||||
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
@@ -86,8 +145,8 @@
|
||||
</Expander>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem x:Name="L0Info" Header="Data/L0 Info">
|
||||
|
||||
<TabItem x:Name="L0Info" Header="Data/L0 Info" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<controls:UserInput x:Name="L0MasteringRing" Label="Data/L0 Mastering Ring" Tab="True"/>
|
||||
<controls:UserInput x:Name="L0MasteringSID" Label="Data/L0 Mastering SID"/>
|
||||
@@ -96,8 +155,8 @@
|
||||
<controls:UserInput x:Name="L0AdditionalMould" Label="Data/L0 Additional Mould"/>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem x:Name="L1Info" Header="Label/L1 Info">
|
||||
|
||||
<TabItem x:Name="L1Info" Header="Label/L1 Info" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<controls:UserInput x:Name="L1MasteringRing" Label="Label/L1 Mastering Ring" Tab="True"/>
|
||||
<controls:UserInput x:Name="L1MasteringSID" Label="Label/L1 Mastering SID"/>
|
||||
@@ -107,7 +166,7 @@
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem x:Name="L2Info" Header="L2 Info" Visibility="Collapsed">
|
||||
<TabItem x:Name="L2Info" Header="L2 Info" Visibility="Collapsed" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<controls:UserInput x:Name="L2MasteringRing" Label="L2 Mastering Ring" Tab="True"/>
|
||||
<controls:UserInput x:Name="L2MasteringSID" Label="L2 Mastering SID"/>
|
||||
@@ -115,7 +174,7 @@
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem x:Name="L3Info" Header="L3 Info" Visibility="Collapsed">
|
||||
<TabItem x:Name="L3Info" Header="L3 Info" Visibility="Collapsed" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<controls:UserInput x:Name="L3MasteringRing" Label="L3 Mastering Ring" Tab="True"/>
|
||||
<controls:UserInput x:Name="L3MasteringSID" Label="L3 Mastering SID"/>
|
||||
@@ -127,9 +186,12 @@
|
||||
<!-- Accept / Cancel -->
|
||||
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<UniformGrid Columns="3" Margin="5,5,5,5" Height="28">
|
||||
<Button Name="AcceptButton" Grid.Column="0" Height="25" Width="120" IsDefault="True" Content="Accept" Click="OnAcceptClick" />
|
||||
<Button Name="CancelButton" Grid.Column="1" Height="25" Width="120" IsCancel="True" Content="Cancel" Click="OnCancelClick" />
|
||||
<Button Name="RingCodeGuideButton" Grid.Column="2" Height="25" Width="120" Content="Ring Code Guide" Click="OnRingCodeGuideClick" />
|
||||
<Button Name="AcceptButton" Grid.Column="0" Height="25" Width="120" IsDefault="True" Content="Accept"
|
||||
Click="OnAcceptClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Button Name="CancelButton" Grid.Column="1" Height="25" Width="120" IsCancel="True" Content="Cancel"
|
||||
Click="OnCancelClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Button Name="RingCodeGuideButton" Grid.Column="2" Height="25" Width="120" Content="Ring Code Guide"
|
||||
Click="OnRingCodeGuideClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
</UniformGrid>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using MPF.Data;
|
||||
|
||||
namespace MPF.Windows
|
||||
@@ -55,6 +56,13 @@ namespace MPF.Windows
|
||||
/// </summary>
|
||||
private void ManipulateFields()
|
||||
{
|
||||
// Sony-printed discs have layers in the opposite order
|
||||
var system = SubmissionInfo?.CommonDiscInfo?.System;
|
||||
bool reverseOrder = (system == KnownSystem.SonyPlayStation2
|
||||
|| system == KnownSystem.SonyPlayStation3
|
||||
|| system == KnownSystem.SonyPlayStation4
|
||||
|| system == KnownSystem.SonyPlayStation5);
|
||||
|
||||
// Different media types mean different fields available
|
||||
switch (SubmissionInfo?.CommonDiscInfo?.Media)
|
||||
{
|
||||
@@ -87,7 +95,7 @@ namespace MPF.Windows
|
||||
L2Info.Visibility = Visibility.Visible;
|
||||
L3Info.Visibility = Visibility.Visible;
|
||||
|
||||
L0Info.Header = "Layer 0 (Inner)";
|
||||
L0Info.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
|
||||
L0MasteringRing.Label = "Mastering Ring";
|
||||
L0MasteringSID.Label = "Mastering SID";
|
||||
L0Toolstamp.Label = "Toolstamp/Mastering Code";
|
||||
@@ -106,7 +114,7 @@ namespace MPF.Windows
|
||||
L2MasteringSID.Label = "Mastering SID";
|
||||
L2Toolstamp.Label = "Toolstamp/Mastering Code";
|
||||
|
||||
L3Info.Header = "Layer 3 (Outer)";
|
||||
L3Info.Header = reverseOrder ? "Layer 3 (Inner)" : "Layer 3 (Outer)";
|
||||
L3MasteringRing.Label = "Mastering Ring";
|
||||
L3MasteringSID.Label = "Mastering SID";
|
||||
L3Toolstamp.Label = "Toolstamp/Mastering Code";
|
||||
@@ -117,7 +125,7 @@ namespace MPF.Windows
|
||||
{
|
||||
L2Info.Visibility = Visibility.Visible;
|
||||
|
||||
L0Info.Header = "Layer 0 (Inner)";
|
||||
L0Info.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
|
||||
L0MasteringRing.Label = "Mastering Ring";
|
||||
L0MasteringSID.Label = "Mastering SID";
|
||||
L0Toolstamp.Label = "Toolstamp/Mastering Code";
|
||||
@@ -131,7 +139,7 @@ namespace MPF.Windows
|
||||
L1MouldSID.Label = "Label Side Mould SID";
|
||||
L1AdditionalMould.Label = "Label Side Additional Mould";
|
||||
|
||||
L2Info.Header = "Layer 2 (Outer)";
|
||||
L2Info.Header = reverseOrder ? "Layer 2 (Inner)" : "Layer 2 (Outer)";
|
||||
L2MasteringRing.Label = "Mastering Ring";
|
||||
L2MasteringSID.Label = "Mastering SID";
|
||||
L2Toolstamp.Label = "Toolstamp/Mastering Code";
|
||||
@@ -140,14 +148,14 @@ namespace MPF.Windows
|
||||
// Double-layer discs
|
||||
else if (SubmissionInfo?.SizeAndChecksums?.Layerbreak != default(long))
|
||||
{
|
||||
L0Info.Header = "Layer 0 (Inner)";
|
||||
L0Info.Header = reverseOrder ? "Layer 0 (Outer)" : "Layer 0 (Inner)";
|
||||
L0MasteringRing.Label = "Mastering Ring";
|
||||
L0MasteringSID.Label = "Mastering SID";
|
||||
L0Toolstamp.Label = "Toolstamp/Mastering Code";
|
||||
L0MouldSID.Label = "Data Side Mould SID";
|
||||
L0AdditionalMould.Label = "Data Side Additional Mould";
|
||||
|
||||
L1Info.Header = "Layer 1 (Outer)";
|
||||
L1Info.Header = reverseOrder ? "Layer 1 (Inner)" : "Layer 1 (Outer)";
|
||||
L1MasteringRing.Label = "Mastering Ring";
|
||||
L1MasteringSID.Label = "Mastering SID";
|
||||
L1Toolstamp.Label = "Toolstamp/Mastering Code";
|
||||
@@ -185,7 +193,7 @@ namespace MPF.Windows
|
||||
}
|
||||
|
||||
// Different systems mean different fields available
|
||||
switch (SubmissionInfo?.CommonDiscInfo?.System)
|
||||
switch (system)
|
||||
{
|
||||
case KnownSystem.SonyPlayStation2:
|
||||
LanguageSelectionGrid.Visibility = Visibility.Visible;
|
||||
@@ -284,6 +292,23 @@ namespace MPF.Windows
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CloseButton Click event
|
||||
/// </summary>
|
||||
private void CloseButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MinimizeButton Click event
|
||||
/// </summary>
|
||||
private void MinimizeButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AcceptButton Click event
|
||||
/// </summary>
|
||||
@@ -316,6 +341,15 @@ namespace MPF.Windows
|
||||
ringCodeGuideWindow.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for Title MouseDown event
|
||||
/// </summary>
|
||||
private void TitleMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
this.DragMove();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,24 +6,97 @@
|
||||
xmlns:local="clr-namespace:MPF"
|
||||
xmlns:controls="clr-namespace:MPF.UserControls"
|
||||
mc:Ignorable="d"
|
||||
Title="Media Preservation Frontend" Width="600" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize" SizeToContent="Height">
|
||||
Title="Media Preservation Frontend" Width="600" WindowStyle="None"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize" SizeToContent="Height"
|
||||
BorderBrush="DarkGray" BorderThickness="2">
|
||||
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
|
||||
</WindowChrome.WindowChrome>
|
||||
|
||||
<Grid>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel VerticalAlignment="Top" Grid.ColumnSpan="4">
|
||||
<Menu Width="Auto" Height="20" >
|
||||
<MenuItem Header="_File">
|
||||
<MenuItem x:Name="AppExit" Header="E_xit" HorizontalAlignment="Left" Width="185" Click="AppExitClick" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Tools">
|
||||
<MenuItem x:Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="185" Click="OptionsMenuItemClick" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Help">
|
||||
<MenuItem x:Name="About" Header="_About" HorizontalAlignment="Left" Width="185" Click="AboutClick" />
|
||||
<MenuItem x:Name="CheckForUpdatesMenuItem" Header="_Check for Updates" HorizontalAlignment="Left" Width="185" Click="CheckForUpdatesClick" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</StackPanel>
|
||||
<Grid Margin="0,2,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="25"/>
|
||||
<ColumnDefinition Width="115"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="50"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" />
|
||||
<StackPanel Panel.ZIndex="1" Grid.Column="1" VerticalAlignment="Center" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
|
||||
<Menu x:Name="TopMenuBar" Width="Auto" Height="20"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}">
|
||||
<MenuItem x:Name="FileMenuItem" Header="_File"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}">
|
||||
<MenuItem x:Name="AppExitMenuItem" Header="E_xit" HorizontalAlignment="Left" Width="185" Click="AppExitClick"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}" />
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="ToolsMenuItem" Header="_Tools"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}">
|
||||
<MenuItem x:Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="185" Click="OptionsMenuItemClick"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}" />
|
||||
</MenuItem>
|
||||
<MenuItem x:Name="HelpMenuItem" Header="_Help"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}">
|
||||
<MenuItem x:Name="AboutMenuItem" Header="_About" HorizontalAlignment="Left" Width="185" Click="AboutClick"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}" />
|
||||
<MenuItem x:Name="CheckForUpdatesMenuItem" Header="_Check for Updates" HorizontalAlignment="Left" Width="185" Click="CheckForUpdatesClick"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</StackPanel>
|
||||
<Label Panel.ZIndex="0" Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
|
||||
<Label.Content>
|
||||
<TextBlock TextAlignment="Center"><Bold>Media Preservation Frontend</Bold></TextBlock>
|
||||
</Label.Content>
|
||||
<Label.ContextMenu>
|
||||
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Style="{DynamicResource CustomContextMenuStyle}">
|
||||
<MenuItem Header="Minimize" Click="MinimizeButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
<MenuItem Header="Close" Click="CloseButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
</ContextMenu>
|
||||
</Label.ContextMenu>
|
||||
</Label>
|
||||
<Grid Grid.Column="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="MinimizeButton" Grid.Column="0" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="MinimizeButtonClick">
|
||||
<Path Data="M 0,0 L 10,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
<Button x:Name="CloseButton" Grid.Column="1" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="CloseButtonClick">
|
||||
<Path Data="M 0,0 L 12,12 M 0,12 L 12,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" Header="Settings">
|
||||
<Grid Margin="5,5,5,5">
|
||||
@@ -40,40 +113,41 @@
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
|
||||
<ComboBox x:Name="SystemTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="Left" ItemsSource="{Binding Path=Systems}" SelectedIndex="0">
|
||||
<Label x:Name="SystemMediaTypeLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
|
||||
<ComboBox x:Name="SystemTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="Left" ItemsSource="{Binding Systems}" SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type ComboBoxItem}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=IsHeader}" Value="True">
|
||||
<DataTrigger Binding="{Binding IsHeader}" Value="True">
|
||||
<Setter Property="IsEnabled" Value="False"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ComboBox.ItemContainerStyle>
|
||||
</ComboBox>
|
||||
<ComboBox x:Name="MediaTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="140" HorizontalAlignment="Right" />
|
||||
<ComboBox x:Name="MediaTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="140" HorizontalAlignment="Right" Style="{DynamicResource CustomComboBoxStyle}" />
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center">Output Filename</Label>
|
||||
<Label x:Name="OutputFilenameLabel" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Content="Output Filename"/>
|
||||
<TextBox x:Name="OutputFilenameTextBox" Grid.Row="1" Grid.Column="1" Height="22" VerticalContentAlignment="Center" />
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Output Directory</Label>
|
||||
<Label x:Name="OutputDirectoryLabel" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Content="Output Directory"/>
|
||||
<TextBox x:Name="OutputDirectoryTextBox" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="Left" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="OutputDirectoryBrowseButton" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse" Click="OutputDirectoryBrowseButtonClick"/>
|
||||
<Button x:Name="OutputDirectoryBrowseButton" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse"
|
||||
Click="OutputDirectoryBrowseButtonClick" Style="{DynamicResource CustomButtonStyle}"/>
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center">Drive Letter</Label>
|
||||
<ComboBox x:Name="DriveLetterComboBox" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left">
|
||||
<Label x:Name="DriveLetterLabel" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Content="Drive Letter"/>
|
||||
<ComboBox x:Name="DriveLetterComboBox" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" Style="{DynamicResource CustomComboBoxStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=Letter}" />
|
||||
<TextBlock Text="{Binding Letter}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Drive Speed</Label>
|
||||
<ComboBox x:Name="DriveSpeedComboBox" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" />
|
||||
<Label x:Name="DriveSpeedLabel" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Content="Drive Speed"/>
|
||||
<ComboBox x:Name="DriveSpeedComboBox" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" Style="{DynamicResource CustomComboBoxStyle}" />
|
||||
|
||||
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center">Parameters</Label>
|
||||
<Label x:Name="ParametersLabel" Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" Content="Parameters"/>
|
||||
<TextBox x:Name="ParametersTextBox" Grid.Row="5" Grid.Column="1" Height="22" Width="370" HorizontalAlignment="Left" IsEnabled="False" VerticalContentAlignment="Center" />
|
||||
<CheckBox x:Name="EnableParametersCheckBox" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Right" IsChecked="False" Click="EnableParametersCheckBoxClick" />
|
||||
</Grid>
|
||||
@@ -81,9 +155,12 @@
|
||||
|
||||
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" Header="Controls">
|
||||
<UniformGrid Columns="3" Margin="5,5,5,5">
|
||||
<Button x:Name="StartStopButton" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" IsDefault="True" Content="Start Dumping" Click="StartStopButtonClick" IsEnabled="False" />
|
||||
<Button x:Name="MediaScanButton" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for disks" Click="MediaScanButtonClick" />
|
||||
<Button x:Name="CopyProtectScanButton" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for protection" Click="CopyProtectScanButtonClick" />
|
||||
<Button x:Name="StartStopButton" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" IsDefault="True" Content="Start Dumping"
|
||||
Click="StartStopButtonClick" IsEnabled="False" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Button x:Name="MediaScanButton" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for disks"
|
||||
Click="MediaScanButtonClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Button x:Name="CopyProtectScanButton" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for protection"
|
||||
Click="CopyProtectScanButtonClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
</UniformGrid>
|
||||
</GroupBox>
|
||||
|
||||
|
||||
@@ -5,10 +5,13 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using WinForms = System.Windows.Forms;
|
||||
using BurnOutSharp;
|
||||
using MPF.Data;
|
||||
using MPF.Utilities;
|
||||
using WPFCustomMessageBox;
|
||||
|
||||
namespace MPF.Windows
|
||||
{
|
||||
@@ -73,6 +76,12 @@ namespace MPF.Windows
|
||||
StartStopButton.IsEnabled = false;
|
||||
MediaScanButton.IsEnabled = false;
|
||||
CopyProtectScanButton.IsEnabled = false;
|
||||
|
||||
// Set the UI color scheme according to the options
|
||||
if (Options.EnableDarkMode)
|
||||
EnableDarkMode();
|
||||
else
|
||||
DisableDarkMode();
|
||||
}
|
||||
|
||||
#region Population
|
||||
@@ -168,6 +177,12 @@ namespace MPF.Windows
|
||||
// Disable the dumping button
|
||||
StartStopButton.IsEnabled = false;
|
||||
|
||||
// Set the UI color scheme according to the options
|
||||
if (Options.EnableDarkMode)
|
||||
EnableDarkMode();
|
||||
else
|
||||
DisableDarkMode();
|
||||
|
||||
// Remove event handlers to ensure ordering
|
||||
if (removeEventHandlers)
|
||||
RemoveEventHandlers();
|
||||
@@ -281,6 +296,140 @@ namespace MPF.Windows
|
||||
CopyProtectScanButton.IsEnabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recolor all UI elements back to normal values
|
||||
/// </summary>
|
||||
private void DisableDarkMode()
|
||||
{
|
||||
// Handle application-wide resources
|
||||
Application.Current.Resources[SystemColors.ActiveBorderBrushKey] = null;
|
||||
Application.Current.Resources[SystemColors.ControlBrushKey] = null;
|
||||
Application.Current.Resources[SystemColors.ControlTextBrushKey] = null;
|
||||
Application.Current.Resources[SystemColors.GrayTextBrushKey] = null;
|
||||
Application.Current.Resources[SystemColors.WindowBrushKey] = null;
|
||||
Application.Current.Resources[SystemColors.WindowTextBrushKey] = null;
|
||||
|
||||
// Handle Button-specific resources
|
||||
Application.Current.Resources["Button.Disabled.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xF4, 0xF4, 0xF4));
|
||||
Application.Current.Resources["Button.MouseOver.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xBE, 0xE6, 0xFD));
|
||||
Application.Current.Resources["Button.Pressed.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xC4, 0xE5, 0xF6));
|
||||
Application.Current.Resources["Button.Static.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xDD, 0xDD, 0xDD));
|
||||
|
||||
// Handle ComboBox-specific resources
|
||||
Application.Current.Resources["ComboBox.Disabled.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0));
|
||||
Application.Current.Resources["ComboBox.Disabled.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
Application.Current.Resources["ComboBox.Disabled.Editable.Button.Background"] = Brushes.Transparent;
|
||||
Application.Current.Resources["ComboBox.MouseOver.Background"] = new LinearGradientBrush(
|
||||
Color.FromArgb(0xFF, 0xEC, 0xF4, 0xFC),
|
||||
Color.FromArgb(0xFF, 0xDC, 0xEC, 0xFC),
|
||||
new Point(0, 0),
|
||||
new Point(0, 1));
|
||||
Application.Current.Resources["ComboBox.MouseOver.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
Application.Current.Resources["ComboBox.MouseOver.Editable.Button.Background"] = new LinearGradientBrush(
|
||||
Color.FromArgb(0xFF, 0xEB, 0xF4, 0xFC),
|
||||
Color.FromArgb(0xFF, 0xDC, 0xEC, 0xFC),
|
||||
new Point(0, 0),
|
||||
new Point(0, 1));
|
||||
Application.Current.Resources["ComboBox.Pressed.Background"] = new LinearGradientBrush(
|
||||
Color.FromArgb(0xFF, 0xDA, 0xEC, 0xFC),
|
||||
Color.FromArgb(0xFF, 0xC4, 0xE0, 0xFC),
|
||||
new Point(0, 0),
|
||||
new Point(0, 1));
|
||||
Application.Current.Resources["ComboBox.Pressed.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
Application.Current.Resources["ComboBox.Pressed.Editable.Button.Background"] = new LinearGradientBrush(
|
||||
Color.FromArgb(0xFF, 0xDA, 0xEB, 0xFC),
|
||||
Color.FromArgb(0xFF, 0xC4, 0xE0, 0xFC),
|
||||
new Point(0, 0),
|
||||
new Point(0, 1));
|
||||
Application.Current.Resources["ComboBox.Static.Background"] = new LinearGradientBrush(
|
||||
Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0),
|
||||
Color.FromArgb(0xFF, 0xE5, 0xE5, 0xE5),
|
||||
new Point(0, 0),
|
||||
new Point(0, 1));
|
||||
Application.Current.Resources["ComboBox.Static.Editable.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
Application.Current.Resources["ComboBox.Static.Editable.Button.Background"] = Brushes.Transparent;
|
||||
Application.Current.Resources["TextBox.Static.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
|
||||
// Handle CustomMessageBox-specific resources
|
||||
Application.Current.Resources["CustomMessageBox.Static.Background"] = null;
|
||||
|
||||
// Handle MenuItem-specific resources
|
||||
Application.Current.Resources["MenuItem.SubMenu.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0));
|
||||
Application.Current.Resources["MenuItem.SubMenu.Border"] = Brushes.DarkGray;
|
||||
|
||||
// Handle ProgressBar-specific resources
|
||||
Application.Current.Resources["ProgressBar.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xE6, 0xE6, 0xE6));
|
||||
|
||||
// Handle ScrollViewer-specific resources
|
||||
Application.Current.Resources["ScrollViewer.ScrollBar.Background"] = Brushes.LightGray;
|
||||
|
||||
// Handle TabItem-specific resources
|
||||
Application.Current.Resources["TabItem.Selected.Background"] = new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
Application.Current.Resources["TabItem.Static.Background"] = new LinearGradientBrush(
|
||||
Color.FromArgb(0xFF, 0xF0, 0xF0, 0xF0),
|
||||
Color.FromArgb(0xFF, 0xE5, 0xE5, 0xE5),
|
||||
new Point(0, 0),
|
||||
new Point(0, 1));
|
||||
Application.Current.Resources["TabItem.Static.Border"] = Brushes.DarkGray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recolor all UI elements for dark mode
|
||||
/// </summary>
|
||||
private void EnableDarkMode()
|
||||
{
|
||||
// Setup needed brushes
|
||||
var darkModeBrush = new SolidColorBrush();
|
||||
darkModeBrush.Color = Color.FromArgb(0xff, 0x20, 0x20, 0x20);
|
||||
|
||||
// Handle application-wide resources
|
||||
Application.Current.Resources[SystemColors.ActiveBorderBrushKey] = Brushes.Black;
|
||||
Application.Current.Resources[SystemColors.ControlBrushKey] = darkModeBrush;
|
||||
Application.Current.Resources[SystemColors.ControlTextBrushKey] = Brushes.White;
|
||||
Application.Current.Resources[SystemColors.GrayTextBrushKey] = Brushes.DarkGray;
|
||||
Application.Current.Resources[SystemColors.WindowBrushKey] = darkModeBrush;
|
||||
Application.Current.Resources[SystemColors.WindowTextBrushKey] = Brushes.White;
|
||||
|
||||
// Handle Button-specific resources
|
||||
Application.Current.Resources["Button.Disabled.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["Button.MouseOver.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["Button.Pressed.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["Button.Static.Background"] = darkModeBrush;
|
||||
|
||||
// Handle ComboBox-specific resources
|
||||
Application.Current.Resources["ComboBox.Disabled.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Disabled.Editable.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Disabled.Editable.Button.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.MouseOver.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.MouseOver.Editable.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.MouseOver.Editable.Button.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Pressed.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Pressed.Editable.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Pressed.Editable.Button.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Static.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Static.Editable.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["ComboBox.Static.Editable.Button.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["TextBox.Static.Background"] = darkModeBrush;
|
||||
|
||||
// Handle CustomMessageBox-specific resources
|
||||
Application.Current.Resources["CustomMessageBox.Static.Background"] = darkModeBrush;
|
||||
|
||||
// Handle MenuItem-specific resources
|
||||
Application.Current.Resources["MenuItem.SubMenu.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["MenuItem.SubMenu.Border"] = Brushes.DarkGray;
|
||||
|
||||
// Handle ProgressBar-specific resources
|
||||
Application.Current.Resources["ProgressBar.Background"] = darkModeBrush;
|
||||
|
||||
// Handle ScrollViewer-specific resources
|
||||
Application.Current.Resources["ScrollViewer.ScrollBar.Background"] = darkModeBrush;
|
||||
|
||||
// Handle TabItem-specific resources
|
||||
Application.Current.Resources["TabItem.Selected.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["TabItem.Static.Background"] = darkModeBrush;
|
||||
Application.Current.Resources["TabItem.Static.Border"] = Brushes.DarkGray;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
@@ -593,21 +742,21 @@ namespace MPF.Windows
|
||||
|
||||
var progress = new Progress<ProtectionProgress>();
|
||||
progress.ProgressChanged += ProgressUpdated;
|
||||
(bool success, string output) = await Validators.RunProtectionScanOnPath(drive.Letter + ":\\", progress);
|
||||
(bool success, string output) = await Validators.RunProtectionScanOnPath(drive.Letter + ":\\", this.Options, progress);
|
||||
|
||||
// If SmartE is detected on the current disc, remove `/sf` from the flags for DIC only
|
||||
if (Env.Options.InternalProgram == InternalProgram.DiscImageCreator && output.Contains("SmartE"))
|
||||
{
|
||||
((DiscImageCreator.Parameters)Env.Parameters)[DiscImageCreator.Flag.ScanFileProtect] = false;
|
||||
((DiscImageCreator.Parameters)Env.Parameters)[DiscImageCreator.FlagStrings.ScanFileProtect] = false;
|
||||
LogOutput.VerboseLogLn($"SmartE detected, removing {DiscImageCreator.FlagStrings.ScanFileProtect} from parameters");
|
||||
}
|
||||
|
||||
if (!LogPanel.IsExpanded)
|
||||
{
|
||||
if (success)
|
||||
MessageBox.Show(output, "Detected Protection(s)", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
CustomMessageBox.Show(output, "Detected Protection(s)", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
else
|
||||
MessageBox.Show("An exception occurred, see the log for details", "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
CustomMessageBox.Show("An exception occurred, see the log for details", "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
|
||||
if (success)
|
||||
@@ -712,7 +861,7 @@ namespace MPF.Windows
|
||||
// If still in custom parameter mode, check that users meant to continue or not
|
||||
if (EnableParametersCheckBox.IsChecked == true)
|
||||
{
|
||||
MessageBoxResult result = MessageBox.Show("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", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
|
||||
MessageBoxResult result = CustomMessageBox.Show("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", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
EnableParametersCheckBox.IsChecked = false;
|
||||
@@ -729,7 +878,7 @@ namespace MPF.Windows
|
||||
// Validate that the user explicitly wants an inactive drive to be considered for dumping
|
||||
if (!Env.Drive.MarkedActive)
|
||||
{
|
||||
MessageBoxResult mbresult = MessageBox.Show("The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
|
||||
MessageBoxResult mbresult = CustomMessageBox.Show("The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
|
||||
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
|
||||
{
|
||||
LogOutput.LogLn("Dumping aborted!");
|
||||
@@ -738,10 +887,10 @@ namespace MPF.Windows
|
||||
}
|
||||
|
||||
// If a complete dump already exists
|
||||
(bool foundFiles, List<string> _) = Env.FoundAllFiles();
|
||||
(bool foundFiles, List<string> _) = Env.FoundAllFiles(true);
|
||||
if (foundFiles)
|
||||
{
|
||||
MessageBoxResult mbresult = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
|
||||
MessageBoxResult mbresult = CustomMessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
|
||||
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
|
||||
{
|
||||
LogOutput.LogLn("Dumping aborted!");
|
||||
@@ -825,7 +974,7 @@ namespace MPF.Windows
|
||||
+ $"{Environment.NewLine}Version {Tools.GetCurrentVersion()}";
|
||||
|
||||
LogOutput.SecretLogLn(aboutText);
|
||||
MessageBox.Show(aboutText, "About", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
CustomMessageBox.Show(this, aboutText, "About", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -847,7 +996,16 @@ namespace MPF.Windows
|
||||
if (different)
|
||||
Clipboard.SetText(url);
|
||||
|
||||
MessageBox.Show(message, "Version Update Check", MessageBoxButton.OK, different ? MessageBoxImage.Exclamation : MessageBoxImage.Information);
|
||||
LogOutput.SecretLogLn(message);
|
||||
CustomMessageBox.Show(this, message, "Version Update Check", MessageBoxButton.OK, different ? MessageBoxImage.Exclamation : MessageBoxImage.Information);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CloseButton Click event
|
||||
/// </summary>
|
||||
private void CloseButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -913,6 +1071,14 @@ namespace MPF.Windows
|
||||
InitializeUIValues(removeEventHandlers: true, rescanDrives: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MinimizeButton Click event
|
||||
/// </summary>
|
||||
private void MinimizeButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MainWindow OnContentRendered event
|
||||
/// </summary>
|
||||
@@ -953,11 +1119,7 @@ namespace MPF.Windows
|
||||
/// </summary>
|
||||
private void OptionsMenuItemClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var optionsWindow = new OptionsWindow(Options)
|
||||
{
|
||||
Owner = this,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner,
|
||||
};
|
||||
var optionsWindow = new OptionsWindow(Options) { Owner = this };
|
||||
optionsWindow.Closed += OnOptionsUpdated;
|
||||
optionsWindow.Show();
|
||||
}
|
||||
@@ -1074,6 +1236,15 @@ namespace MPF.Windows
|
||||
EnsureDiscInformation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for Title MouseDown event
|
||||
/// </summary>
|
||||
private void TitleMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
this.DragMove();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,75 @@
|
||||
xmlns:local="clr-namespace:MPF"
|
||||
xmlns:controls="clr-namespace:MPF.UserControls"
|
||||
mc:Ignorable="d"
|
||||
Title="Options" Width="515.132" ResizeMode="NoResize" SizeToContent="Height">
|
||||
Title="Options" Width="515.132" WindowStyle="None"
|
||||
WindowStartupLocation="CenterOwner" ResizeMode="CanMinimize" SizeToContent="Height"
|
||||
BorderBrush="DarkGray" BorderThickness="2">
|
||||
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
|
||||
</WindowChrome.WindowChrome>
|
||||
|
||||
<Grid>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TabControl Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
|
||||
<TabItem Header="Paths">
|
||||
<Grid Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="25"/>
|
||||
<ColumnDefinition Width="115"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="50"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" />
|
||||
<Label Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
|
||||
<Label.Content>
|
||||
<TextBlock TextAlignment="Center"><Bold>Options</Bold></TextBlock>
|
||||
</Label.Content>
|
||||
<Label.ContextMenu>
|
||||
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Style="{DynamicResource CustomContextMenuStyle}">
|
||||
<MenuItem Header="Minimize" Click="MinimizeButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
<MenuItem Header="Close" Click="CloseButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
</ContextMenu>
|
||||
</Label.ContextMenu>
|
||||
</Label>
|
||||
<Grid Grid.Column="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="MinimizeButton" Grid.Column="0" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="MinimizeButtonClick">
|
||||
<Path Data="M 0,0 L 10,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
<Button x:Name="CloseButton" Grid.Column="1" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="CloseButtonClick">
|
||||
<Path Data="M 0,0 L 12,12 M 0,12 L 12,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<TabControl Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Style="{DynamicResource CustomTabControlStyle}">
|
||||
<TabItem Header="User Interface" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<UniformGrid Columns="2" Rows="3">
|
||||
<CheckBox VerticalAlignment="Center" Content="Enable Dark Mode"
|
||||
IsChecked="{Binding Options.EnableDarkMode}"
|
||||
ToolTip="(Experimental) Enable dark mode across the entire application" Margin="0,4"
|
||||
/>
|
||||
</UniformGrid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Paths" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<Grid Margin="5,5,5,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*" />
|
||||
@@ -27,46 +90,51 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Aaru Path" />
|
||||
<TextBox x:Name="AaruPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Path=Options.AaruPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="AaruPathButton" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
|
||||
<TextBox x:Name="AaruPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.AaruPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="AaruPathButton" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..."
|
||||
Click="BrowseForPathClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DiscImageCreator Path" />
|
||||
<TextBox x:Name="DiscImageCreatorPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Path=Options.DiscImageCreatorPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="DiscImageCreatorPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
|
||||
<TextBox x:Name="DiscImageCreatorPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.DiscImageCreatorPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="DiscImageCreatorPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..."
|
||||
Click="BrowseForPathClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DD Path" />
|
||||
<TextBox x:Name="DDPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Path=Options.DDPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="DDPathButton" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
|
||||
<TextBox x:Name="DDPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.DDPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="DDPathButton" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..."
|
||||
Click="BrowseForPathClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Dumping Program" />
|
||||
<ComboBox x:Name="InternalProgramComboBox" Grid.Row="3" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=InternalPrograms}" />
|
||||
<ComboBox x:Name="InternalProgramComboBox" Grid.Row="3" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
|
||||
ItemsSource="{Binding InternalPrograms}" Style="{DynamicResource CustomComboBoxStyle}" />
|
||||
|
||||
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path" />
|
||||
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Path=Options.DefaultOutputPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="DefaultOutputPathButton" Grid.Row="4" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
|
||||
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.DefaultOutputPath}" VerticalContentAlignment="Center" />
|
||||
<Button x:Name="DefaultOutputPathButton" Grid.Row="4" Grid.Column="2" Height="22" Width="22" Content="..."
|
||||
Click="BrowseForPathClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Dumping">
|
||||
<TabItem Header="Dumping" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel>
|
||||
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Dumping">
|
||||
<UniformGrid Columns="2" Rows="6">
|
||||
<UniformGrid Columns="2" Rows="7">
|
||||
<CheckBox VerticalAlignment="Center" Content="Skip Type Detect"
|
||||
IsChecked="{Binding Path=Options.SkipMediaTypeDetection}"
|
||||
IsChecked="{Binding Options.SkipMediaTypeDetection}"
|
||||
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Skip System Detect"
|
||||
IsChecked="{Binding Path=Options.SkipSystemDetection}"
|
||||
IsChecked="{Binding Options.SkipSystemDetection}"
|
||||
ToolTip="Disable trying to guess system (may improve performance at startup)" Margin="0,4"
|
||||
/>
|
||||
|
||||
<Label VerticalAlignment="Center" Content="Default System:" HorizontalAlignment="Right" />
|
||||
<ComboBox x:Name="DefaultSystemComboBox" Height="22" Width="200" HorizontalAlignment="Left" ItemsSource="{Binding Path=Systems}" SelectedIndex="0">
|
||||
<ComboBox x:Name="DefaultSystemComboBox" Height="22" Width="200" HorizontalAlignment="Left" ItemsSource="{Binding Systems}" SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}">
|
||||
<ComboBox.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type ComboBoxItem}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=IsHeader}" Value="True">
|
||||
<DataTrigger Binding="{Binding IsHeader}" Value="True">
|
||||
<Setter Property="IsEnabled" Value="False"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
@@ -75,42 +143,47 @@
|
||||
</ComboBox>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="No Fixed Drives"
|
||||
IsChecked="{Binding Path=Options.IgnoreFixedDrives}"
|
||||
IsChecked="{Binding Options.IgnoreFixedDrives}"
|
||||
ToolTip="Ignore hard drives and other fixed drives" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Show Separate Window"
|
||||
IsChecked="{Binding Path=Options.ToolsInSeparateWindow}"
|
||||
IsChecked="{Binding Options.ToolsInSeparateWindow}"
|
||||
ToolTip="Show program output in separate command window instead of in the log. Enable this if you have a weaker system as there is an increased processing load otherwise." Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Protection Scan"
|
||||
IsChecked="{Binding Path=Options.ScanForProtection}"
|
||||
IsChecked="{Binding Options.ScanForProtection}"
|
||||
ToolTip="Enable automatic checking for copy protection on dumped media" Margin="0,4,0,0"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Eject After Dump"
|
||||
IsChecked="{Binding Path=Options.EjectAfterDump}"
|
||||
IsChecked="{Binding Options.EjectAfterDump}"
|
||||
ToolTip="Eject the disc from the drive after dumping has completed" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Show Disc Info"
|
||||
IsChecked="{Binding Path=Options.PromptForDiscInformation}"
|
||||
IsChecked="{Binding Options.PromptForDiscInformation}"
|
||||
ToolTip="Enable showing the disc information output after dumping" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Add Placeholders"
|
||||
IsChecked="{Binding Path=Options.AddPlaceholders}"
|
||||
IsChecked="{Binding Options.AddPlaceholders}"
|
||||
ToolTip="Enable adding placeholder text in the submissioninfo output for required and optional fields" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Output Submission JSON"
|
||||
IsChecked="{Binding Path=Options.OutputSubmissionJSON}"
|
||||
IsChecked="{Binding Options.OutputSubmissionJSON}"
|
||||
ToolTip="Enable outputting a compressed JSON version of the submission info" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Include Artifacts"
|
||||
IsChecked="{Binding Options.IncludeArtifacts}" IsEnabled="{Binding Options.OutputSubmissionJSON}"
|
||||
ToolTip="Include log files in serialized JSON data" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Compress Log Files"
|
||||
IsChecked="{Binding Path=Options.CompressLogFiles}"
|
||||
IsChecked="{Binding Options.CompressLogFiles}"
|
||||
ToolTip="Compress output log files to reduce space" Margin="0,4"
|
||||
/>
|
||||
</UniformGrid>
|
||||
@@ -133,21 +206,21 @@
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="CD-ROM" />
|
||||
<Slider x:Name="DumpSpeedCDSlider" Grid.Row="0" Grid.Column="1" Minimum="1" Maximum="72" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
|
||||
Ticks="{Binding Source={x:Static local:Constants.SpeedsForCDAsCollection}}"
|
||||
Value="{Binding Path=Options.PreferredDumpSpeedCD}" />
|
||||
Value="{Binding Options.PreferredDumpSpeedCD}" />
|
||||
<TextBox x:Name="DumpSpeedCDTextBox" Grid.Row="0" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center"
|
||||
Text="{Binding ElementName=DumpSpeedCDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="DVD-ROM" />
|
||||
<Slider x:Name="DumpSpeedDVDSlider" Grid.Row="1" Grid.Column="1" Minimum="1" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
|
||||
Ticks="{Binding Source={x:Static local:Constants.SpeedsForDVDAsCollection}}"
|
||||
Value="{Binding Path=Options.PreferredDumpSpeedDVD}" />
|
||||
Value="{Binding Options.PreferredDumpSpeedDVD}" />
|
||||
<TextBox x:Name="DumpSpeedDVDTextBox" Grid.Row="1" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center"
|
||||
Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="BD-ROM" />
|
||||
<Slider x:Name="DumpSpeedBDSlider" Grid.Row="2" Grid.Column="1" Minimum="1" Maximum="16" IsSnapToTickEnabled="True" TickPlacement="BottomRight"
|
||||
Ticks="{Binding Source={x:Static local:Constants.SpeedsForBDAsCollection}}"
|
||||
Value="{Binding Path=Options.PreferredDumpSpeedBD}" />
|
||||
Value="{Binding Options.PreferredDumpSpeedBD}" />
|
||||
<TextBox x:Name="DumpSpeedBDTextBox" Grid.Row="2" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center"
|
||||
Text="{Binding ElementName=DumpSpeedBDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
|
||||
</Grid>
|
||||
@@ -155,102 +228,129 @@
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Aaru">
|
||||
<TabItem Header="Protection Scanning" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel>
|
||||
<UniformGrid Columns="2" Rows="2">
|
||||
<CheckBox VerticalAlignment="Center" Content="Scan Archive Contents"
|
||||
IsChecked="{Binding Options.ScanArchivesForProtection}"
|
||||
ToolTip="Enable scanning archive contents during protection scanning (may drastically increase scanning time but is more accurate)" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Include Executable Packers"
|
||||
IsChecked="{Binding Options.ScanPackersForProtection}"
|
||||
ToolTip="Include executable packers in outputted protections" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Force Scanning All Files"
|
||||
IsChecked="{Binding Options.ForceScanningForProtection}"
|
||||
ToolTip="Force scanning all files even if they're not executables" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Include Debug Information"
|
||||
IsChecked="{Binding Options.IncludeDebugProtectionInformation}"
|
||||
ToolTip="Include debug information during protection scans" Margin="0,4"
|
||||
/>
|
||||
</UniformGrid>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Aaru" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<UniformGrid Columns="2" Rows="3">
|
||||
<CheckBox VerticalAlignment="Center" Content="Enable Debug Output"
|
||||
IsChecked="{Binding Path=Options.AaruEnableDebug}"
|
||||
IsChecked="{Binding Options.AaruEnableDebug}"
|
||||
ToolTip="Enable debug output in logs" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Enable Verbose Output"
|
||||
IsChecked="{Binding Path=Options.AaruEnableVerbose}"
|
||||
IsChecked="{Binding Options.AaruEnableVerbose}"
|
||||
ToolTip="Enable verbose output in logs" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Force Dumping"
|
||||
IsChecked="{Binding Path=Options.AaruForceDumping}"
|
||||
IsChecked="{Binding Options.AaruForceDumping}"
|
||||
ToolTip="Enable forcing dump even if there are issues" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Strip Personal Data"
|
||||
IsChecked="{Binding Path=Options.AaruStripPersonalData}"
|
||||
IsChecked="{Binding Options.AaruStripPersonalData}"
|
||||
ToolTip="Enable stripping of personally identifiable information from metadata" Margin="0,4,0,0"
|
||||
/>
|
||||
|
||||
<Label Content="Reread Tries:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
<TextBox VerticalAlignment="Center" VerticalContentAlignment="Center"
|
||||
Text="{Binding Path=Options.AaruRereadCount}"
|
||||
Text="{Binding Options.AaruRereadCount}"
|
||||
ToolTip="Specifies how many rereads are attempted for sector and subchannel errors"
|
||||
/>
|
||||
</UniformGrid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="DiscImageCreator">
|
||||
<TabItem Header="DiscImageCreator" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<UniformGrid Columns="2" Rows="3">
|
||||
<CheckBox VerticalAlignment="Center" Content="Quiet Mode"
|
||||
IsChecked="{Binding Path=Options.DICQuietMode}"
|
||||
IsChecked="{Binding Options.DICQuietMode}"
|
||||
ToolTip="Disable sounds (beeps) during and after operations" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Paranoid Mode"
|
||||
IsChecked="{Binding Path=Options.DICParanoidMode}"
|
||||
IsChecked="{Binding Options.DICParanoidMode}"
|
||||
ToolTip="Enable pedantic and super-safe flags" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Use CMI Flag"
|
||||
IsChecked="{Binding Path=Options.DICUseCMIFlag}"
|
||||
IsChecked="{Binding Options.DICUseCMIFlag}"
|
||||
ToolTip="Enable the CMI flag for supported disc types (DVD/HD-DVD only)" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Reset After Dump"
|
||||
IsChecked="{Binding Path=Options.DICResetDriveAfterDump}"
|
||||
IsChecked="{Binding Options.DICResetDriveAfterDump}"
|
||||
ToolTip="Reset disc drives after dumping; useful for some older machines" Margin="0,4"
|
||||
/>
|
||||
|
||||
<Label Content="Reread Tries:" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
<TextBox VerticalAlignment="Center" VerticalContentAlignment="Center"
|
||||
Text="{Binding Path=Options.DICRereadCount}"
|
||||
Text="{Binding Options.DICRereadCount}"
|
||||
ToolTip="Specifies how many rereads are attempted on C2 error"
|
||||
/>
|
||||
</UniformGrid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Logging">
|
||||
<TabItem Header="Logging" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<UniformGrid Columns="2">
|
||||
<CheckBox VerticalAlignment="Center" Content="Verbose Logging"
|
||||
IsChecked="{Binding Path=Options.VerboseLogging}"
|
||||
IsChecked="{Binding Options.VerboseLogging}"
|
||||
ToolTip="Display all logging statements" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Auto-Open Log"
|
||||
IsChecked="{Binding Path=Options.OpenLogWindowAtStartup}"
|
||||
IsChecked="{Binding Options.OpenLogWindowAtStartup}"
|
||||
ToolTip="Open the log panel when the program launches" Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Enable Log Formatting"
|
||||
IsChecked="{Binding Path=Options.EnableLogFormatting}"
|
||||
IsChecked="{Binding Options.EnableLogFormatting}"
|
||||
ToolTip="Format log lines written to the log, including overwriting previous lines on match. Disable this if you have a weaker system as there is an increased processing load otherwise." Margin="0,4"
|
||||
/>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Content="Enable Progress Processing"
|
||||
IsChecked="{Binding Path=Options.EnableProgressProcessing}" IsEnabled="{Binding Path=Options.EnableLogFormatting}"
|
||||
IsChecked="{Binding Options.EnableProgressProcessing}" IsEnabled="{Binding Options.EnableLogFormatting}"
|
||||
ToolTip="Process lines written to the log to update the progress bar. Disable this if you have a weaker system as there is an increased processing load otherwise." Margin="0,4"
|
||||
/>
|
||||
</UniformGrid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Login Info">
|
||||
<TabItem Header="Login Info" Style="{DynamicResource CustomTabItemStyle}">
|
||||
<StackPanel>
|
||||
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Redump Credentials">
|
||||
<UniformGrid Columns="5" Rows="1">
|
||||
<Label VerticalAlignment="Center" HorizontalAlignment="Right" Content="Username" />
|
||||
<TextBox x:Name="RedumpUsernameTextBox" Height="22" HorizontalAlignment="Stretch"
|
||||
Text="{Binding Path=Options.RedumpUsername}" />
|
||||
Text="{Binding Options.RedumpUsername}" />
|
||||
|
||||
<Label VerticalAlignment="Center" HorizontalAlignment="Right" Content="Password" />
|
||||
<PasswordBox x:Name="RedumpPasswordBox" Height="22" HorizontalAlignment="Stretch" PasswordChar="*" />
|
||||
|
||||
<Button x:Name="RedumpLoginTestButton" Height="22" Width="80" Content="Test Login" Click="OnRedumpTestClick" />
|
||||
<Button x:Name="RedumpLoginTestButton" Height="22" Width="80" Content="Test Login"
|
||||
Click="OnRedumpTestClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
</UniformGrid>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
@@ -261,8 +361,10 @@
|
||||
<GroupBox Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<UniformGrid Columns="4" Margin="5,5,5,5" Height="28">
|
||||
<Label/> <!-- Empty label for padding -->
|
||||
<Button Name="AcceptButton" Height="25" Width="80" IsDefault="True" Content="Accept" Click="OnAcceptClick" />
|
||||
<Button Name="CancelButton" Height="25" Width="80" IsCancel="True" Content="Cancel" Click="OnCancelClick" />
|
||||
<Button Name="AcceptButton" Height="25" Width="80" IsDefault="True" Content="Accept"
|
||||
Click="OnAcceptClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Button Name="CancelButton" Height="25" Width="80" IsCancel="True" Content="Cancel"
|
||||
Click="OnCancelClick" Style="{DynamicResource CustomButtonStyle}" />
|
||||
<Label/> <!-- Empty label for padding -->
|
||||
</UniformGrid>
|
||||
</GroupBox>
|
||||
|
||||
@@ -4,8 +4,10 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using MPF.Data;
|
||||
using MPF.Redump;
|
||||
using WPFCustomMessageBox;
|
||||
using Button = System.Windows.Controls.Button;
|
||||
using TextBox = System.Windows.Controls.TextBox;
|
||||
|
||||
@@ -155,7 +157,7 @@ namespace MPF.Windows
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Windows.MessageBox.Show(
|
||||
CustomMessageBox.Show(
|
||||
"Specified path doesn't exists!",
|
||||
"Error",
|
||||
MessageBoxButton.OK,
|
||||
@@ -166,6 +168,22 @@ namespace MPF.Windows
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CloseButton Click event
|
||||
/// </summary>
|
||||
private void CloseButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MinimizeButton Click event
|
||||
/// </summary>
|
||||
private void MinimizeButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for AcceptButton Click event
|
||||
/// </summary>
|
||||
@@ -192,14 +210,23 @@ namespace MPF.Windows
|
||||
{
|
||||
bool? loggedIn = wc.Login(RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
|
||||
if (loggedIn == true)
|
||||
System.Windows.MessageBox.Show("Redump login credentials accepted!", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
CustomMessageBox.Show(this, "Redump login credentials accepted!", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
else if (loggedIn == false)
|
||||
System.Windows.MessageBox.Show("Redump login credentials denied!", "Failure", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
CustomMessageBox.Show(this, "Redump login credentials denied!", "Failure", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
else
|
||||
System.Windows.MessageBox.Show("Error validating credentials!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
CustomMessageBox.Show(this, "Error validating credentials!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for Title MouseDown event
|
||||
/// </summary>
|
||||
private void TitleMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
this.DragMove();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,61 @@
|
||||
xmlns:local="clr-namespace:MPF"
|
||||
xmlns:controls="clr-namespace:MPF.UserControls"
|
||||
mc:Ignorable="d"
|
||||
Title="Ring Code Guide" Width="500" ResizeMode="NoResize" SizeToContent="WidthAndHeight">
|
||||
Title="Ring Code Guide" Width="500" WindowStyle="None"
|
||||
WindowStartupLocation="CenterOwner" ResizeMode="CanMinimize" SizeToContent="Height"
|
||||
BorderBrush="DarkGray" BorderThickness="2">
|
||||
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
|
||||
</WindowChrome.WindowChrome>
|
||||
|
||||
<Grid>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Grid Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="25"/>
|
||||
<ColumnDefinition Width="115"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="50"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Grid.Column="0" Source="/Images/Icon.ico" Height="20" Width="20" Margin="1" />
|
||||
<Label Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" MouseDown="TitleMouseDown">
|
||||
<Label.Content>
|
||||
<TextBlock TextAlignment="Center"><Bold>Ring Code Guide</Bold></TextBlock>
|
||||
</Label.Content>
|
||||
<Label.ContextMenu>
|
||||
<ContextMenu Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Style="{DynamicResource CustomContextMenuStyle}">
|
||||
<MenuItem Header="Minimize" Click="MinimizeButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
<MenuItem Header="Close" Click="CloseButtonClick" Width="185"
|
||||
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
|
||||
Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"
|
||||
Template="{DynamicResource CustomMenuItemTemplate}"/>
|
||||
</ContextMenu>
|
||||
</Label.ContextMenu>
|
||||
</Label>
|
||||
<Grid Grid.Column="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button x:Name="MinimizeButton" Grid.Column="0" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="MinimizeButtonClick">
|
||||
<Path Data="M 0,0 L 10,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
<Button x:Name="CloseButton" Grid.Column="1" BorderThickness="0" Background="Transparent" Style="{DynamicResource CustomButtonStyle}" Click="CloseButtonClick">
|
||||
<Path Data="M 0,0 L 12,12 M 0,12 L 12,0" Stroke="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type Button}}}" StrokeThickness="1"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="5,5,5,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
@@ -42,7 +94,7 @@
|
||||
</Label>
|
||||
<Label Grid.Row="4">
|
||||
<Label.Content>
|
||||
<TextBlock><Bold Foreground="Blue">4. Mould SID:</Bold> IFPI 94V1</TextBlock>
|
||||
<TextBlock><Bold Foreground="LightBlue">4. Mould SID:</Bold> IFPI 94V1</TextBlock>
|
||||
</Label.Content>
|
||||
</Label>
|
||||
</Grid>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MPF.Windows
|
||||
{
|
||||
@@ -11,5 +12,34 @@ namespace MPF.Windows
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CloseButton Click event
|
||||
/// </summary>
|
||||
private void CloseButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for MinimizeButton Click event
|
||||
/// </summary>
|
||||
private void MinimizeButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler for Title MouseDown event
|
||||
/// </summary>
|
||||
private void TitleMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
this.DragMove();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ A list of all changes in each stable release and current WIP builds can now be f
|
||||
MPF uses some external libraries to assist with additional information gathering after the dumping process.
|
||||
|
||||
- **BurnOutSharp** - Protection scanning - [GitHub](https://github.com/mnadareski/BurnOutSharp)
|
||||
- **WPFCustomMessageBox.thabse** - Custom message boxes in UI - [GitHub](https://github.com/thabse/WPFCustomMessageBox)
|
||||
- **UnshieldSharp** - Protection scanning - [GitHub](https://github.com/mnadareski/UnshieldSharp)
|
||||
|
||||
## Contributors
|
||||
@@ -47,7 +48,7 @@ Here are the talented people who have contributed to the project so far:
|
||||
- **ReignStumble** - Former Project Lead / UI Design
|
||||
- **Jakz** - Primary Feature Contributor
|
||||
- **NHellFire** - Feature Contributor
|
||||
- **Shadów** - UI Support
|
||||
- **Shadów** - UI Support
|
||||
|
||||
## Notable Testers
|
||||
|
||||
@@ -57,7 +58,7 @@ These are the tireless individuals who have dedicated countless hours to help te
|
||||
- **Kludge**
|
||||
- **ajshell1**
|
||||
- **Whovian**
|
||||
— **Gameboi64**
|
||||
- **Gameboi64**
|
||||
- **silasqwerty**
|
||||
|
||||
## Community Shout-Outs
|
||||
@@ -65,4 +66,4 @@ These are the tireless individuals who have dedicated countless hours to help te
|
||||
Thanks to these communities for their use, testing, and feedback. I can't even hope to be able to thank everyone individually.
|
||||
|
||||
- **VGPC Discord** - Fast feedback and a lot of testing
|
||||
- **Redump Community** - Near-daily use to assist with metadata gathering
|
||||
- **Redump Community** - Near-daily use to assist with metadata gathering
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# version format
|
||||
version: 2.0-{build}
|
||||
version: 2.1-{build}
|
||||
|
||||
# pull request template
|
||||
pull_requests:
|
||||
@@ -37,7 +37,7 @@ build:
|
||||
after_build:
|
||||
- ps: appveyor DownloadFile https://github.com/aaru-dps/Aaru/releases/download/v5.2.0.3330/aaru-5.2.0.3330-1_windows_x64.zip
|
||||
- ps: appveyor DownloadFile http://www.chrysocome.net/downloads/8ab730cd2a29e76ddd89be1f99357942/dd-0.6beta3.zip
|
||||
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/6241075/DiscImageCreator_20210401.zip
|
||||
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/6748071/DiscImageCreator_20210701.zip
|
||||
- ps: appveyor DownloadFile https://archive.org/download/subdump_fua_0x28/subdump_fua_0x28.zip
|
||||
|
||||
- 7z e aaru-5.2.0.3330-1_windows_x64.zip -oMPF\bin\Debug\net48\Programs\Aaru *
|
||||
@@ -46,8 +46,8 @@ after_build:
|
||||
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\net48\Programs\DD *
|
||||
- 7z e dd-0.6beta3.zip -oMPF\bin\Debug\netcoreapp3.1\Programs\DD *
|
||||
|
||||
- 7z e DiscImageCreator_20210401.zip -oMPF\bin\Debug\net48\Programs\Creator Release_ANSI\*
|
||||
- 7z e DiscImageCreator_20210401.zip -oMPF\bin\Debug\netcoreapp3.1\Programs\Creator Release_ANSI\*
|
||||
- 7z e DiscImageCreator_20210701.zip -oMPF\bin\Debug\net48\Programs\Creator Release_ANSI\*
|
||||
- 7z e DiscImageCreator_20210701.zip -oMPF\bin\Debug\netcoreapp3.1\Programs\Creator Release_ANSI\*
|
||||
|
||||
- 7z e subdump_fua_0x28.zip -oMPF\bin\Debug\net48 *
|
||||
- mkdir MPF\bin\Debug\net48\Programs\Subdump
|
||||
|
||||
Reference in New Issue
Block a user