mirror of
https://github.com/claunia/romrepomgr.git
synced 2025-12-16 19:24:51 +00:00
Compare commits
16 Commits
5096884f2a
...
d041e7b1b3
| Author | SHA1 | Date | |
|---|---|---|---|
|
d041e7b1b3
|
|||
|
563ffcdd32
|
|||
|
86420a4fd0
|
|||
|
01a2f916b9
|
|||
|
7e8e42d07c
|
|||
|
63a16cb19e
|
|||
|
aa1ad9fd64
|
|||
|
d75381c4eb
|
|||
|
7bc6da0780
|
|||
|
8c12694fd6
|
|||
|
ad27c2a9ab
|
|||
|
a88c9000ed
|
|||
|
44fb779034
|
|||
|
66ecf4c432
|
|||
|
9818a8c416
|
|||
|
ca1708a337
|
@@ -390,8 +390,8 @@ resharper_loop_can_be_converted_to_query_highlighting
|
||||
resharper_loop_can_be_partly_converted_to_query_highlighting = warning
|
||||
resharper_member_can_be_file_local_highlighting = warning
|
||||
resharper_member_can_be_internal_highlighting = warning
|
||||
resharper_member_can_be_made_static_global_highlighting = warning
|
||||
resharper_member_can_be_made_static_local_highlighting = warning
|
||||
resharper_member_can_be_made_static_global_highlighting = none
|
||||
resharper_member_can_be_made_static_local_highlighting = none
|
||||
resharper_member_can_be_private_global_highlighting = warning
|
||||
resharper_member_can_be_private_local_highlighting = warning
|
||||
resharper_member_can_be_protected_global_highlighting = warning
|
||||
|
||||
@@ -28,7 +28,7 @@ public sealed class Fuse : FileSystem
|
||||
_directoryCache = new ConcurrentDictionary<long, List<DirectoryEntry>>();
|
||||
_lastHandle = 0;
|
||||
_fileStatHandleCache = new ConcurrentDictionary<long, Stat>();
|
||||
Name = "romrepombgrfs";
|
||||
Name = "romrepomgrfs";
|
||||
_vfs = vfs;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
@@ -19,29 +20,17 @@ namespace RomRepoMgr.Core.Filesystem;
|
||||
// TODO: Do not show machines or romsets with no ROMs in repo
|
||||
public class Vfs : IDisposable
|
||||
{
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedDisk>> _machineDisksCache;
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>> _machineFilesCache;
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedMedia>> _machineMediasCache;
|
||||
readonly ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>> _machinesStatCache;
|
||||
readonly ConcurrentDictionary<long, RomSet> _romSetsCache;
|
||||
readonly ConcurrentDictionary<long, Stream> _streamsCache;
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedDisk>> _machineDisksCache = [];
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>> _machineFilesCache = [];
|
||||
readonly ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedMedia>> _machineMediasCache = [];
|
||||
readonly ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>> _machinesStatCache = [];
|
||||
readonly ConcurrentDictionary<long, RomSet> _romSetsCache = [];
|
||||
readonly ConcurrentDictionary<long, Stream> _streamsCache = [];
|
||||
Fuse _fuse;
|
||||
long _lastHandle;
|
||||
ConcurrentDictionary<string, long> _rootDirectoryCache;
|
||||
ConcurrentDictionary<string, long> _rootDirectoryCache = [];
|
||||
Winfsp _winfsp;
|
||||
|
||||
public Vfs()
|
||||
{
|
||||
_rootDirectoryCache = new ConcurrentDictionary<string, long>();
|
||||
_romSetsCache = new ConcurrentDictionary<long, RomSet>();
|
||||
_machinesStatCache = new ConcurrentDictionary<long, ConcurrentDictionary<string, CachedMachine>>();
|
||||
_machineFilesCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedFile>>();
|
||||
_machineDisksCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedDisk>>();
|
||||
_machineMediasCache = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, CachedMedia>>();
|
||||
_streamsCache = new ConcurrentDictionary<long, Stream>();
|
||||
_lastHandle = 0;
|
||||
}
|
||||
|
||||
public static bool IsAvailable => OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()
|
||||
? Fuse.IsAvailable
|
||||
: OperatingSystem.IsWindows() && Winfsp.IsAvailable;
|
||||
@@ -59,7 +48,7 @@ public class Vfs : IDisposable
|
||||
MountPoint = mountPoint
|
||||
};
|
||||
|
||||
Task.Run(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
_fuse.Start();
|
||||
|
||||
@@ -667,6 +656,12 @@ public class Vfs : IDisposable
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
[ContractInvariantMethod]
|
||||
void ObjectInvariant()
|
||||
{
|
||||
Contract.Invariant(_machineMediasCache.All(pair => pair.Value != null));
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class CachedMachine
|
||||
|
||||
@@ -14,13 +14,10 @@ using FileInfo = Fsp.Interop.FileInfo;
|
||||
namespace RomRepoMgr.Core.Filesystem;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class Winfsp : FileSystemBase
|
||||
public class Winfsp(Vfs vfs) : FileSystemBase
|
||||
{
|
||||
readonly Vfs _vfs;
|
||||
FileSystemHost _host;
|
||||
|
||||
public Winfsp(Vfs vfs) => _vfs = vfs;
|
||||
|
||||
public static bool IsAvailable
|
||||
{
|
||||
get
|
||||
@@ -128,7 +125,7 @@ public class Winfsp : FileSystemBase
|
||||
{
|
||||
volumeInfo = new VolumeInfo();
|
||||
|
||||
_vfs.GetInfo(out _, out ulong totalSize);
|
||||
vfs.GetInfo(out _, out ulong totalSize);
|
||||
|
||||
volumeInfo.FreeSize = 0;
|
||||
volumeInfo.TotalSize = totalSize;
|
||||
@@ -144,7 +141,7 @@ public class Winfsp : FileSystemBase
|
||||
fileInfo = default(FileInfo);
|
||||
normalizedName = default(string);
|
||||
|
||||
string[] pieces = _vfs.SplitPath(fileName);
|
||||
string[] pieces = vfs.SplitPath(fileName);
|
||||
|
||||
// Root directory
|
||||
if(pieces.Length == 0)
|
||||
@@ -169,11 +166,11 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
long romSetId = _vfs.GetRomSetId(pieces[0]);
|
||||
long romSetId = vfs.GetRomSetId(pieces[0]);
|
||||
|
||||
if(romSetId <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
RomSet romSet = _vfs.GetRomSet(romSetId);
|
||||
RomSet romSet = vfs.GetRomSet(romSetId);
|
||||
|
||||
if(romSet == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -207,7 +204,7 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
|
||||
CachedMachine machine = vfs.GetMachine(romSetId, pieces[1]);
|
||||
|
||||
if(machine == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -242,7 +239,7 @@ public class Winfsp : FileSystemBase
|
||||
}
|
||||
|
||||
long handle = 0;
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
CachedFile file = vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file != null)
|
||||
{
|
||||
@@ -250,7 +247,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(file.Sha384 == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
handle = vfs.Open(file.Sha384, (long)file.Size);
|
||||
|
||||
if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -280,7 +277,7 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
CachedDisk disk = vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk != null)
|
||||
{
|
||||
@@ -288,7 +285,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(disk.Sha1 == null && disk.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.OpenDisk(disk.Sha1, disk.Md5);
|
||||
handle = vfs.OpenDisk(disk.Sha1, disk.Md5);
|
||||
|
||||
if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -318,7 +315,7 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]);
|
||||
CachedMedia media = vfs.GetMedia(machine.Id, pieces[2]);
|
||||
|
||||
if(media == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -326,7 +323,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(media.Sha256 == null && media.Sha1 == null && media.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5);
|
||||
handle = vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5);
|
||||
|
||||
if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -362,7 +359,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(node.Handle <= 0) return;
|
||||
|
||||
_vfs.Close(node.Handle);
|
||||
vfs.Close(node.Handle);
|
||||
}
|
||||
|
||||
public override int Read(object fileNode, object fileDesc, IntPtr buffer, ulong offset, uint length,
|
||||
@@ -374,7 +371,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
var buf = new byte[length];
|
||||
|
||||
int ret = _vfs.Read(node.Handle, buf, (long)offset);
|
||||
int ret = vfs.Read(node.Handle, buf, (long)offset);
|
||||
|
||||
if(ret < 0) return STATUS_INVALID_HANDLE;
|
||||
|
||||
@@ -408,12 +405,12 @@ public class Winfsp : FileSystemBase
|
||||
{
|
||||
if(node.MachineId > 0)
|
||||
{
|
||||
ConcurrentDictionary<string, CachedFile> cachedMachineFiles = _vfs.GetFilesFromMachine(node.MachineId);
|
||||
ConcurrentDictionary<string, CachedFile> cachedMachineFiles = vfs.GetFilesFromMachine(node.MachineId);
|
||||
|
||||
ConcurrentDictionary<string, CachedDisk> cachedMachineDisks = _vfs.GetDisksFromMachine(node.MachineId);
|
||||
ConcurrentDictionary<string, CachedDisk> cachedMachineDisks = vfs.GetDisksFromMachine(node.MachineId);
|
||||
|
||||
ConcurrentDictionary<string, CachedMedia> cachedMachineMedias =
|
||||
_vfs.GetMediasFromMachine(node.MachineId);
|
||||
vfs.GetMediasFromMachine(node.MachineId);
|
||||
|
||||
node.Children =
|
||||
[
|
||||
@@ -483,7 +480,7 @@ public class Winfsp : FileSystemBase
|
||||
}
|
||||
else if(node.RomSetId > 0)
|
||||
{
|
||||
ConcurrentDictionary<string, CachedMachine> machines = _vfs.GetMachinesFromRomSet(node.RomSetId);
|
||||
ConcurrentDictionary<string, CachedMachine> machines = vfs.GetMachinesFromRomSet(node.RomSetId);
|
||||
|
||||
node.Children =
|
||||
[
|
||||
@@ -514,12 +511,12 @@ public class Winfsp : FileSystemBase
|
||||
{
|
||||
node.Children = [];
|
||||
|
||||
node.Children.AddRange(_vfs.GetRootEntries()
|
||||
.Select(e => new FileEntry
|
||||
{
|
||||
FileName = e,
|
||||
IsRomSet = true
|
||||
}));
|
||||
node.Children.AddRange(vfs.GetRootEntries()
|
||||
.Select(e => new FileEntry
|
||||
{
|
||||
FileName = e,
|
||||
IsRomSet = true
|
||||
}));
|
||||
}
|
||||
|
||||
if(marker != null)
|
||||
@@ -540,11 +537,11 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(entry.IsRomSet)
|
||||
{
|
||||
long romSetId = _vfs.GetRomSetId(entry.FileName);
|
||||
long romSetId = vfs.GetRomSetId(entry.FileName);
|
||||
|
||||
if(romSetId <= 0) continue;
|
||||
|
||||
RomSet romSet = _vfs.GetRomSet(romSetId);
|
||||
RomSet romSet = vfs.GetRomSet(romSetId);
|
||||
|
||||
if(romSet is null) continue;
|
||||
|
||||
@@ -569,7 +566,7 @@ public class Winfsp : FileSystemBase
|
||||
{
|
||||
fileAttributes = 0;
|
||||
|
||||
string[] pieces = _vfs.SplitPath(fileName);
|
||||
string[] pieces = vfs.SplitPath(fileName);
|
||||
|
||||
// Root directory
|
||||
if(pieces.Length == 0)
|
||||
@@ -588,11 +585,11 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
long romSetId = _vfs.GetRomSetId(pieces[0]);
|
||||
long romSetId = vfs.GetRomSetId(pieces[0]);
|
||||
|
||||
if(romSetId <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
RomSet romSet = _vfs.GetRomSet(romSetId);
|
||||
RomSet romSet = vfs.GetRomSet(romSetId);
|
||||
|
||||
if(romSet == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -604,7 +601,7 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedMachine machine = _vfs.GetMachine(romSetId, pieces[1]);
|
||||
CachedMachine machine = vfs.GetMachine(romSetId, pieces[1]);
|
||||
|
||||
if(machine == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -617,7 +614,7 @@ public class Winfsp : FileSystemBase
|
||||
}
|
||||
|
||||
long handle = 0;
|
||||
CachedFile file = _vfs.GetFile(machine.Id, pieces[2]);
|
||||
CachedFile file = vfs.GetFile(machine.Id, pieces[2]);
|
||||
|
||||
if(file != null)
|
||||
{
|
||||
@@ -625,7 +622,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(file.Sha384 == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.Open(file.Sha384, (long)file.Size);
|
||||
handle = vfs.Open(file.Sha384, (long)file.Size);
|
||||
|
||||
if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -634,7 +631,7 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedDisk disk = _vfs.GetDisk(machine.Id, pieces[2]);
|
||||
CachedDisk disk = vfs.GetDisk(machine.Id, pieces[2]);
|
||||
|
||||
if(disk != null)
|
||||
{
|
||||
@@ -642,7 +639,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(disk.Sha1 == null && disk.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.OpenDisk(disk.Sha1, disk.Md5);
|
||||
handle = vfs.OpenDisk(disk.Sha1, disk.Md5);
|
||||
|
||||
if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -651,7 +648,7 @@ public class Winfsp : FileSystemBase
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CachedMedia media = _vfs.GetMedia(machine.Id, pieces[2]);
|
||||
CachedMedia media = vfs.GetMedia(machine.Id, pieces[2]);
|
||||
|
||||
if(media == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
@@ -659,7 +656,7 @@ public class Winfsp : FileSystemBase
|
||||
|
||||
if(media.Sha256 == null && media.Sha1 == null && media.Md5 == null) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
handle = _vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5);
|
||||
handle = vfs.OpenMedia(media.Sha256, media.Sha1, media.Md5);
|
||||
|
||||
if(handle <= 0) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
|
||||
@@ -3,20 +3,12 @@ using System.IO;
|
||||
|
||||
namespace RomRepoMgr.Core;
|
||||
|
||||
internal sealed class StreamWithLength : Stream
|
||||
internal sealed class StreamWithLength(Stream baseStream, long length) : Stream
|
||||
{
|
||||
readonly Stream _baseStream;
|
||||
|
||||
public StreamWithLength(Stream baseStream, long length)
|
||||
{
|
||||
_baseStream = baseStream;
|
||||
Length = length;
|
||||
}
|
||||
|
||||
public override bool CanRead => _baseStream.CanRead;
|
||||
public override bool CanSeek => _baseStream.CanSeek;
|
||||
public override bool CanWrite => _baseStream.CanWrite;
|
||||
public override long Length { get; }
|
||||
public override bool CanRead => baseStream.CanRead;
|
||||
public override bool CanSeek => baseStream.CanSeek;
|
||||
public override bool CanWrite => baseStream.CanWrite;
|
||||
public override long Length { get; } = length;
|
||||
|
||||
public override long Position
|
||||
{
|
||||
@@ -24,9 +16,9 @@ internal sealed class StreamWithLength : Stream
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Flush() => _baseStream.Flush();
|
||||
public override void Flush() => baseStream.Flush();
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count) => _baseStream.Read(buffer, offset, count);
|
||||
public override int Read(byte[] buffer, int offset, int count) => baseStream.Read(buffer, offset, count);
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
|
||||
|
||||
@@ -36,7 +28,7 @@ internal sealed class StreamWithLength : Stream
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
_baseStream.Close();
|
||||
baseStream.Close();
|
||||
base.Close();
|
||||
}
|
||||
}
|
||||
@@ -90,27 +90,27 @@ internal sealed class Checksum
|
||||
_sha384Pkt = new Sha384Packet();
|
||||
_sha512Pkt = new Sha512Packet();
|
||||
|
||||
_crc32Pkt.context = _crc32Ctx;
|
||||
_md5Pkt.context = _md5Ctx;
|
||||
_sha1Pkt.context = _sha1Ctx;
|
||||
_sha256Pkt.context = _sha256Ctx;
|
||||
_sha384Pkt.context = _sha384Ctx;
|
||||
_sha512Pkt.context = _sha512Ctx;
|
||||
_crc32Pkt.Context = _crc32Ctx;
|
||||
_md5Pkt.Context = _md5Ctx;
|
||||
_sha1Pkt.Context = _sha1Ctx;
|
||||
_sha256Pkt.Context = _sha256Ctx;
|
||||
_sha384Pkt.Context = _sha384Ctx;
|
||||
_sha512Pkt.Context = _sha512Ctx;
|
||||
}
|
||||
|
||||
internal void Update(byte[] data)
|
||||
{
|
||||
_crc32Pkt.data = data;
|
||||
_crc32Pkt.Data = data;
|
||||
_crc32Thread.Start(_crc32Pkt);
|
||||
_md5Pkt.data = data;
|
||||
_md5Pkt.Data = data;
|
||||
_md5Thread.Start(_md5Pkt);
|
||||
_sha1Pkt.data = data;
|
||||
_sha1Pkt.Data = data;
|
||||
_sha1Thread.Start(_sha1Pkt);
|
||||
_sha256Pkt.data = data;
|
||||
_sha256Pkt.Data = data;
|
||||
_sha256Thread.Start(_sha256Pkt);
|
||||
_sha384Pkt.data = data;
|
||||
_sha384Pkt.Data = data;
|
||||
_sha384Thread.Start(_sha384Pkt);
|
||||
_sha512Pkt.data = data;
|
||||
_sha512Pkt.Data = data;
|
||||
_sha512Thread.Start(_sha512Pkt);
|
||||
|
||||
while(_crc32Thread.IsAlive ||
|
||||
@@ -142,51 +142,51 @@ internal sealed class Checksum
|
||||
|
||||
struct Crc32Packet
|
||||
{
|
||||
public Crc32Context context;
|
||||
public byte[] data;
|
||||
public Crc32Context Context;
|
||||
public byte[] Data;
|
||||
}
|
||||
|
||||
struct Md5Packet
|
||||
{
|
||||
public Md5Context context;
|
||||
public byte[] data;
|
||||
public Md5Context Context;
|
||||
public byte[] Data;
|
||||
}
|
||||
|
||||
struct Sha1Packet
|
||||
{
|
||||
public Sha1Context context;
|
||||
public byte[] data;
|
||||
public Sha1Context Context;
|
||||
public byte[] Data;
|
||||
}
|
||||
|
||||
struct Sha256Packet
|
||||
{
|
||||
public Sha256Context context;
|
||||
public byte[] data;
|
||||
public Sha256Context Context;
|
||||
public byte[] Data;
|
||||
}
|
||||
|
||||
struct Sha384Packet
|
||||
{
|
||||
public Sha384Context context;
|
||||
public byte[] data;
|
||||
public Sha384Context Context;
|
||||
public byte[] Data;
|
||||
}
|
||||
|
||||
struct Sha512Packet
|
||||
{
|
||||
public Sha512Context context;
|
||||
public byte[] data;
|
||||
public Sha512Context Context;
|
||||
public byte[] Data;
|
||||
}
|
||||
|
||||
static void UpdateCrc32(object packet) => ((Crc32Packet)packet).context.Update(((Crc32Packet)packet).data);
|
||||
static void UpdateCrc32(object packet) => ((Crc32Packet)packet).Context.Update(((Crc32Packet)packet).Data);
|
||||
|
||||
static void UpdateMd5(object packet) => ((Md5Packet)packet).context.Update(((Md5Packet)packet).data);
|
||||
static void UpdateMd5(object packet) => ((Md5Packet)packet).Context.Update(((Md5Packet)packet).Data);
|
||||
|
||||
static void UpdateSha1(object packet) => ((Sha1Packet)packet).context.Update(((Sha1Packet)packet).data);
|
||||
static void UpdateSha1(object packet) => ((Sha1Packet)packet).Context.Update(((Sha1Packet)packet).Data);
|
||||
|
||||
static void UpdateSha256(object packet) => ((Sha256Packet)packet).context.Update(((Sha256Packet)packet).data);
|
||||
static void UpdateSha256(object packet) => ((Sha256Packet)packet).Context.Update(((Sha256Packet)packet).Data);
|
||||
|
||||
static void UpdateSha384(object packet) => ((Sha384Packet)packet).context.Update(((Sha384Packet)packet).data);
|
||||
static void UpdateSha384(object packet) => ((Sha384Packet)packet).Context.Update(((Sha384Packet)packet).Data);
|
||||
|
||||
static void UpdateSha512(object packet) => ((Sha512Packet)packet).context.Update(((Sha512Packet)packet).data);
|
||||
static void UpdateSha512(object packet) => ((Sha512Packet)packet).Context.Update(((Sha512Packet)packet).Data);
|
||||
|
||||
#endregion Threading helpers
|
||||
}
|
||||
@@ -15,23 +15,15 @@ using CompressionMode = SharpCompress.Compressors.CompressionMode;
|
||||
|
||||
namespace RomRepoMgr.Core.Workers;
|
||||
|
||||
public class FileExporter
|
||||
public class FileExporter(long romSetId, string outPath)
|
||||
{
|
||||
const long BUFFER_SIZE = 131072;
|
||||
readonly string _outPath;
|
||||
readonly long _romSetId;
|
||||
const long BUFFER_SIZE = 131072;
|
||||
long _filePosition;
|
||||
Dictionary<string, FileByMachine> _filesByMachine;
|
||||
long _machinePosition;
|
||||
Machine[] _machines;
|
||||
string _zipCurrentEntryName;
|
||||
|
||||
public FileExporter(long romSetId, string outPath)
|
||||
{
|
||||
_romSetId = romSetId;
|
||||
_outPath = outPath;
|
||||
}
|
||||
|
||||
public event EventHandler WorkFinished;
|
||||
public event EventHandler<ProgressBoundsEventArgs> SetProgressBounds;
|
||||
public event EventHandler<ProgressEventArgs> SetProgress;
|
||||
@@ -53,7 +45,7 @@ public class FileExporter
|
||||
|
||||
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
|
||||
RomSet romSet = ctx.RomSets.Find(_romSetId);
|
||||
RomSet romSet = ctx.RomSets.Find(romSetId);
|
||||
|
||||
if(romSet == null)
|
||||
{
|
||||
@@ -74,7 +66,7 @@ public class FileExporter
|
||||
Message = Localization.ExportingRoms
|
||||
});
|
||||
|
||||
_machines = ctx.Machines.Where(m => m.RomSet.Id == _romSetId).ToArray();
|
||||
_machines = ctx.Machines.Where(m => m.RomSet.Id == romSetId).ToArray();
|
||||
|
||||
SetProgressBounds?.Invoke(this,
|
||||
new ProgressBoundsEventArgs
|
||||
@@ -135,7 +127,7 @@ public class FileExporter
|
||||
if(machineName.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
|
||||
machineName = machineName[..^4];
|
||||
|
||||
string machinePath = Path.Combine(_outPath, machineName);
|
||||
string machinePath = Path.Combine(outPath, machineName);
|
||||
|
||||
if(!Directory.Exists(machinePath)) Directory.CreateDirectory(machinePath);
|
||||
|
||||
@@ -340,7 +332,7 @@ public class FileExporter
|
||||
if(machineName.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
|
||||
machineName = machineName[..^4];
|
||||
|
||||
string machinePath = Path.Combine(_outPath, machineName);
|
||||
string machinePath = Path.Combine(outPath, machineName);
|
||||
|
||||
if(!Directory.Exists(machinePath)) Directory.CreateDirectory(machinePath);
|
||||
|
||||
@@ -498,7 +490,7 @@ public class FileExporter
|
||||
if(_filesByMachine.Count == 0)
|
||||
{
|
||||
_machinePosition++;
|
||||
Task.Run(CompressNextMachine);
|
||||
_ = Task.Run(CompressNextMachine);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -512,7 +504,7 @@ public class FileExporter
|
||||
|
||||
if(!machineName.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) machineName += ".zip";
|
||||
|
||||
var zf = new ZipFile(Path.Combine(_outPath, machineName), Encoding.UTF8)
|
||||
var zf = new ZipFile(Path.Combine(outPath, machineName), Encoding.UTF8)
|
||||
{
|
||||
CompressionLevel = CompressionLevel.BestCompression,
|
||||
CompressionMethod = CompressionMethod.Deflate,
|
||||
|
||||
@@ -18,42 +18,23 @@ using SharpCompress.Compressors.LZMA;
|
||||
|
||||
namespace RomRepoMgr.Core.Workers;
|
||||
|
||||
public class FileImporter
|
||||
public class FileImporter(bool onlyKnown, bool deleteAfterImport)
|
||||
{
|
||||
const long BUFFER_SIZE = 131072;
|
||||
readonly Context _ctx;
|
||||
readonly bool _deleteAfterImport;
|
||||
readonly List<DbDisk> _newDisks;
|
||||
readonly List<DbFile> _newFiles;
|
||||
readonly List<DbMedia> _newMedias;
|
||||
readonly bool _onlyKnown;
|
||||
readonly Dictionary<string, DbDisk> _pendingDisksByMd5;
|
||||
readonly Dictionary<string, DbDisk> _pendingDisksBySha1;
|
||||
readonly Dictionary<string, DbFile> _pendingFiles;
|
||||
readonly Dictionary<string, DbMedia> _pendingMediasByMd5;
|
||||
readonly Dictionary<string, DbMedia> _pendingMediasBySha1;
|
||||
readonly Dictionary<string, DbMedia> _pendingMediasBySha256;
|
||||
readonly Context _ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
readonly List<DbDisk> _newDisks = [];
|
||||
readonly List<DbFile> _newFiles = [];
|
||||
readonly List<DbMedia> _newMedias = [];
|
||||
readonly Dictionary<string, DbDisk> _pendingDisksByMd5 = [];
|
||||
readonly Dictionary<string, DbDisk> _pendingDisksBySha1 = [];
|
||||
readonly Dictionary<string, DbFile> _pendingFiles = [];
|
||||
readonly Dictionary<string, DbMedia> _pendingMediasByMd5 = [];
|
||||
readonly Dictionary<string, DbMedia> _pendingMediasBySha1 = [];
|
||||
readonly Dictionary<string, DbMedia> _pendingMediasBySha256 = [];
|
||||
string _lastMessage;
|
||||
long _position;
|
||||
long _totalFiles;
|
||||
|
||||
public FileImporter(bool onlyKnown, bool deleteAfterImport)
|
||||
{
|
||||
_pendingFiles = new Dictionary<string, DbFile>();
|
||||
_pendingDisksByMd5 = new Dictionary<string, DbDisk>();
|
||||
_pendingDisksBySha1 = new Dictionary<string, DbDisk>();
|
||||
_pendingMediasBySha256 = new Dictionary<string, DbMedia>();
|
||||
_pendingMediasBySha1 = new Dictionary<string, DbMedia>();
|
||||
_pendingMediasByMd5 = new Dictionary<string, DbMedia>();
|
||||
_newFiles = [];
|
||||
_newDisks = [];
|
||||
_newMedias = [];
|
||||
_onlyKnown = onlyKnown;
|
||||
_deleteAfterImport = deleteAfterImport;
|
||||
_position = 0;
|
||||
_ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
}
|
||||
|
||||
public event EventHandler SetIndeterminateProgress2;
|
||||
public event EventHandler<ProgressBoundsEventArgs> SetProgressBounds2;
|
||||
public event EventHandler<ProgressEventArgs> SetProgress2;
|
||||
@@ -77,7 +58,7 @@ public class FileImporter
|
||||
Message = Localization.EnumeratingFiles
|
||||
});
|
||||
|
||||
string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories).OrderBy(p => p).ToArray();
|
||||
string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories).Order().ToArray();
|
||||
_totalFiles += files.LongLength;
|
||||
|
||||
SetProgressBounds?.Invoke(this,
|
||||
@@ -388,7 +369,7 @@ public class FileImporter
|
||||
|
||||
if(dbFile == null)
|
||||
{
|
||||
if(_onlyKnown)
|
||||
if(onlyKnown)
|
||||
{
|
||||
_lastMessage = Localization.UnknownFile;
|
||||
|
||||
@@ -493,7 +474,7 @@ public class FileImporter
|
||||
|
||||
inFs.Close();
|
||||
|
||||
if(_deleteAfterImport) File.Delete(path);
|
||||
if(deleteAfterImport) File.Delete(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -559,7 +540,7 @@ public class FileImporter
|
||||
|
||||
if(!fileInDb) _newFiles.Add(dbFile);
|
||||
|
||||
if(_deleteAfterImport) File.Delete(path);
|
||||
if(deleteAfterImport) File.Delete(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -655,7 +636,7 @@ public class FileImporter
|
||||
|
||||
if(dbDisk == null)
|
||||
{
|
||||
if(_onlyKnown)
|
||||
if(onlyKnown)
|
||||
{
|
||||
_lastMessage = Localization.UnknownFile;
|
||||
|
||||
@@ -770,7 +751,7 @@ public class FileImporter
|
||||
|
||||
inFs.Close();
|
||||
|
||||
if(_deleteAfterImport) File.Delete(path);
|
||||
if(deleteAfterImport) File.Delete(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -833,7 +814,7 @@ public class FileImporter
|
||||
|
||||
if(!diskInDb) _newDisks.Add(dbDisk);
|
||||
|
||||
if(_deleteAfterImport) File.Delete(path);
|
||||
if(deleteAfterImport) File.Delete(path);
|
||||
|
||||
if(knownDiskWasBigger) File.Delete(repoPath + ".bak");
|
||||
|
||||
@@ -954,7 +935,7 @@ public class FileImporter
|
||||
|
||||
if(dbMedia == null)
|
||||
{
|
||||
if(_onlyKnown)
|
||||
if(onlyKnown)
|
||||
{
|
||||
_lastMessage = Localization.UnknownFile;
|
||||
|
||||
@@ -1107,7 +1088,7 @@ public class FileImporter
|
||||
|
||||
inFs.Close();
|
||||
|
||||
if(_deleteAfterImport) File.Delete(path);
|
||||
if(deleteAfterImport) File.Delete(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1170,7 +1151,7 @@ public class FileImporter
|
||||
|
||||
if(!mediaInDb) _newMedias.Add(dbMedia);
|
||||
|
||||
if(_deleteAfterImport) File.Delete(path);
|
||||
if(deleteAfterImport) File.Delete(path);
|
||||
|
||||
if(knownMediaWasBigger) File.Delete(repoPath + ".bak");
|
||||
|
||||
@@ -1341,7 +1322,7 @@ public class FileImporter
|
||||
|
||||
long counter = 0;
|
||||
|
||||
unarProcess.OutputDataReceived += (sender, e) =>
|
||||
unarProcess.OutputDataReceived += (_, e) =>
|
||||
{
|
||||
counter++;
|
||||
|
||||
|
||||
@@ -29,10 +29,8 @@ using RomRepoMgr.Database.Models;
|
||||
|
||||
namespace RomRepoMgr.Database;
|
||||
|
||||
public sealed class Context : DbContext
|
||||
public sealed class Context(DbContextOptions options) : DbContext(options)
|
||||
{
|
||||
public Context(DbContextOptions options) : base(options) {}
|
||||
|
||||
public DbSet<DbFile> Files { get; set; }
|
||||
public DbSet<RomSet> RomSets { get; set; }
|
||||
public DbSet<Machine> Machines { get; set; }
|
||||
@@ -198,6 +196,6 @@ public sealed class Context : DbContext
|
||||
entity.HasOne(e => e.Media).WithMany(e => e.Machines).OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<RomSetStat>(entity => { entity.HasOne(e => e.RomSet).WithOne(e => e.Statistics); });
|
||||
modelBuilder.Entity<RomSetStat>(entity => entity.HasOne(e => e.RomSet).WithOne(e => e.Statistics));
|
||||
}
|
||||
}
|
||||
@@ -117,6 +117,6 @@ public class App : Application
|
||||
})
|
||||
return;
|
||||
|
||||
mainWindowViewModel.ExecuteSettingsCommand();
|
||||
_ = mainWindowViewModel.ExecuteSettingsCommandAsync();
|
||||
}
|
||||
}
|
||||
494
RomRepoMgr/Resources/Localization.Designer.cs
generated
494
RomRepoMgr/Resources/Localization.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -6,15 +6,13 @@
|
||||
<Compile Update="**\*.xaml.cs">
|
||||
<DependentUpon>%(Filename)</DependentUpon>
|
||||
</Compile>
|
||||
<None Remove="**\*.xaml"/>
|
||||
<AvaloniaResource Include="**\*.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</AvaloniaResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Assets\**"/>
|
||||
<Compile Update="Resources\Localization.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Localization.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia"/>
|
||||
@@ -33,7 +31,7 @@
|
||||
<PackageReference Include="Roslynator.Analyzers"/>
|
||||
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers"/>
|
||||
<PackageReference Include="Roslynator.Formatting.Analyzers"/>
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux"/>
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer"/>
|
||||
<PackageReference Include="Text.Analyzers"/>
|
||||
</ItemGroup>
|
||||
@@ -44,7 +42,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\Localization.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Localization.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -34,7 +34,6 @@ using System.Threading.Tasks;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Resources;
|
||||
using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
@@ -58,8 +57,7 @@ public sealed class AboutViewModel : ViewModelBase
|
||||
|
||||
Assemblies = [];
|
||||
|
||||
// TODO: They do not load in time
|
||||
Task.Run(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies().OrderBy(a => a.FullName))
|
||||
{
|
||||
@@ -83,23 +81,14 @@ public sealed class AboutViewModel : ViewModelBase
|
||||
});
|
||||
}
|
||||
|
||||
public string AboutLabel => Localization.AboutLabel;
|
||||
public string LibrariesLabel => Localization.LibrariesLabel;
|
||||
public string AuthorsLabel => Localization.AuthorsLabel;
|
||||
public string Title => Localization.AboutTitle;
|
||||
public string SoftwareName => "RomRepoMgr";
|
||||
public string SuiteName => "ROM Repository Manager";
|
||||
public string Copyright => "© 2020-2024 Natalia Portillo";
|
||||
public string Website => "https://www.claunia.com";
|
||||
public string License => Localization.LicenseLabel;
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
public string AssembliesLibraryText => Localization.AssembliesLibraryText;
|
||||
public string AssembliesVersionText => Localization.AssembliesVersionText;
|
||||
public string Authors => Localization.AuthorsText;
|
||||
public ReactiveCommand<Unit, Unit> WebsiteCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> LicenseCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ObservableCollection<AssemblyModel> Assemblies { get; }
|
||||
public string SoftwareName => "RomRepoMgr";
|
||||
public string SuiteName => "ROM Repository Manager";
|
||||
public string Copyright => "© 2020-2024 Natalia Portillo";
|
||||
public string Website => "https://www.claunia.com";
|
||||
public ReactiveCommand<Unit, Unit> WebsiteCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> LicenseCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ObservableCollection<AssemblyModel> Assemblies { get; }
|
||||
|
||||
public string VersionText
|
||||
{
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Database;
|
||||
using RomRepoMgr.Database.Models;
|
||||
using RomRepoMgr.Resources;
|
||||
using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
@@ -61,30 +61,11 @@ public class EditDatViewModel : ViewModelBase
|
||||
_date = romSet.Date;
|
||||
_description = romSet.Description;
|
||||
_homepage = romSet.Homepage;
|
||||
SaveCommand = ReactiveCommand.Create(ExecuteSaveCommand);
|
||||
SaveCommand = ReactiveCommand.CreateFromTask(ExecuteSaveCommandAsync);
|
||||
CancelCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
}
|
||||
|
||||
public string NameLabel => Localization.RomSetNameLabel;
|
||||
public string VersionLabel => Localization.RomSetVersionLabel;
|
||||
public string AuthorLabel => Localization.RomSetAuthorLabel;
|
||||
public string CategoryLabel => Localization.RomSetCategoryLabel;
|
||||
public string CommentLabel => Localization.RomSetCommentLabel;
|
||||
public string DateLabel => Localization.RomSetDateLabel;
|
||||
public string DescriptionLabel => Localization.RomSetDescriptionLabel;
|
||||
public string HomepageLabel => Localization.HomepageLabel;
|
||||
public string TotalMachinesLabel => Localization.TotalMachinesLabel;
|
||||
public string CompleteMachinesLabel => Localization.CompleteMachinesLabel;
|
||||
public string IncompleteMachinesLabel => Localization.IncompleteMachinesLabel;
|
||||
public string TotalRomsLabel => Localization.TotalRomsLabel;
|
||||
public string HaveRomsLabel => Localization.HaveRomsLabel;
|
||||
public string MissRomsLabel => Localization.MissRomsLabel;
|
||||
public string Title => Localization.EditDatTitle;
|
||||
public string SaveLabel => Localization.SaveLabel;
|
||||
public string CancelLabel => Localization.CancelLabel;
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SaveCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CancelCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
@@ -193,9 +174,9 @@ public class EditDatViewModel : ViewModelBase
|
||||
|
||||
void ExecuteCloseCommand() => _view.Close();
|
||||
|
||||
async void ExecuteSaveCommand()
|
||||
async Task ExecuteSaveCommandAsync()
|
||||
{
|
||||
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
await using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
|
||||
RomSet romSetDb = await ctx.RomSets.FindAsync(_romSet.Id);
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ public sealed class ExportDatViewModel : ViewModelBase
|
||||
_worker.FailedWithText += OnWorkerOnFailedWithText;
|
||||
}
|
||||
|
||||
public string Title => Localization.ExportDatTitle;
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
@@ -94,7 +92,6 @@ public sealed class ExportDatViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
|
||||
void OnWorkerOnFinishedWithText(object sender, MessageEventArgs args) => Dispatcher.UIThread.Post(() =>
|
||||
@@ -119,24 +116,23 @@ public sealed class ExportDatViewModel : ViewModelBase
|
||||
ProgressVisible = true;
|
||||
StatusMessage = Localization.DecompressingDat;
|
||||
|
||||
var sha384Bytes = new byte[48];
|
||||
string sha384 = _datHash;
|
||||
var sha384Bytes = new byte[48];
|
||||
|
||||
for(var i = 0; i < 48; i++)
|
||||
{
|
||||
if(sha384[i * 2] >= 0x30 && sha384[i * 2] <= 0x39)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x30) * 0x10);
|
||||
else if(sha384[i * 2] >= 0x41 && sha384[i * 2] <= 0x46)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x37) * 0x10);
|
||||
else if(sha384[i * 2] >= 0x61 && sha384[i * 2] <= 0x66)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x57) * 0x10);
|
||||
if(_datHash[i * 2] >= 0x30 && _datHash[i * 2] <= 0x39)
|
||||
sha384Bytes[i] = (byte)((_datHash[i * 2] - 0x30) * 0x10);
|
||||
else if(_datHash[i * 2] >= 0x41 && _datHash[i * 2] <= 0x46)
|
||||
sha384Bytes[i] = (byte)((_datHash[i * 2] - 0x37) * 0x10);
|
||||
else if(_datHash[i * 2] >= 0x61 && _datHash[i * 2] <= 0x66)
|
||||
sha384Bytes[i] = (byte)((_datHash[i * 2] - 0x57) * 0x10);
|
||||
|
||||
if(sha384[i * 2 + 1] >= 0x30 && sha384[i * 2 + 1] <= 0x39)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x30);
|
||||
else if(sha384[i * 2 + 1] >= 0x41 && sha384[i * 2 + 1] <= 0x46)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x37);
|
||||
else if(sha384[i * 2 + 1] >= 0x61 && sha384[i * 2 + 1] <= 0x66)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x57);
|
||||
if(_datHash[i * 2 + 1] >= 0x30 && _datHash[i * 2 + 1] <= 0x39)
|
||||
sha384Bytes[i] += (byte)(_datHash[i * 2 + 1] - 0x30);
|
||||
else if(_datHash[i * 2 + 1] >= 0x41 && _datHash[i * 2 + 1] <= 0x46)
|
||||
sha384Bytes[i] += (byte)(_datHash[i * 2 + 1] - 0x37);
|
||||
else if(_datHash[i * 2 + 1] >= 0x61 && _datHash[i * 2 + 1] <= 0x66)
|
||||
sha384Bytes[i] += (byte)(_datHash[i * 2 + 1] - 0x57);
|
||||
}
|
||||
|
||||
string datHash32 = Base32.ToBase32String(sha384Bytes);
|
||||
@@ -145,6 +141,6 @@ public sealed class ExportDatViewModel : ViewModelBase
|
||||
|
||||
if(!File.Exists(compressedDatPath)) _view.Close();
|
||||
|
||||
Task.Run(() => _worker.DecompressFile(compressedDatPath, _outPath));
|
||||
_ = Task.Run(() => _worker.DecompressFile(compressedDatPath, _outPath));
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Resources;
|
||||
using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
@@ -68,7 +67,6 @@ public sealed class ExportRomsViewModel : ViewModelBase
|
||||
CanClose = false;
|
||||
}
|
||||
|
||||
public string PathLabel => Localization.PathLabel;
|
||||
public string FolderPath { get; }
|
||||
|
||||
public bool ProgressVisible
|
||||
@@ -179,9 +177,6 @@ public sealed class ExportRomsViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _progress3IsIndeterminate, value);
|
||||
}
|
||||
|
||||
public string Title => Localization.ExportRomsTitle;
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
get => _canClose;
|
||||
@@ -260,6 +255,6 @@ public sealed class ExportRomsViewModel : ViewModelBase
|
||||
|
||||
ProgressVisible = true;
|
||||
|
||||
Task.Run(worker.Export);
|
||||
_ = Task.Run(worker.Export);
|
||||
}
|
||||
}
|
||||
@@ -75,11 +75,7 @@ public sealed class ImportDatFolderViewModel : ViewModelBase
|
||||
StartCommand = ReactiveCommand.Create(ExecuteStartCommand);
|
||||
}
|
||||
|
||||
public string PathLabel => Localization.PathLabel;
|
||||
public string CategoryLabel => Localization.RomSetCategoryLabel;
|
||||
public string FolderPath { get; }
|
||||
public string AllFilesLabel => Localization.AllFilesLabel;
|
||||
public string RecursiveLabel => Localization.RecursiveLabel;
|
||||
public string FolderPath { get; }
|
||||
|
||||
public bool AllFilesChecked
|
||||
{
|
||||
@@ -191,13 +187,7 @@ public sealed class ImportDatFolderViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _category, value);
|
||||
}
|
||||
|
||||
public string Title => Localization.ImportDatFolderTitle;
|
||||
|
||||
public ObservableCollection<ImportDatFolderItem> ImportResults { get; }
|
||||
public string ResultFilenameLabel => Localization.ResultFilenameLabel;
|
||||
public string ResultStatusLabel => Localization.ResultStatusLabel;
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
public string StartLabel => Localization.StartLabel;
|
||||
public ObservableCollection<ImportDatFolderItem> ImportResults { get; }
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
@@ -216,52 +206,56 @@ public sealed class ImportDatFolderViewModel : ViewModelBase
|
||||
|
||||
internal void OnOpened() => RefreshFiles();
|
||||
|
||||
void RefreshFiles() => Task.Run(() =>
|
||||
void RefreshFiles()
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
IsReady = false;
|
||||
ProgressVisible = true;
|
||||
Progress2Visible = false;
|
||||
ProgressIsIndeterminate = true;
|
||||
StatusMessage = Localization.SearchingForFiles;
|
||||
});
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
IsReady = false;
|
||||
ProgressVisible = true;
|
||||
Progress2Visible = false;
|
||||
ProgressIsIndeterminate = true;
|
||||
StatusMessage = Localization.SearchingForFiles;
|
||||
});
|
||||
|
||||
if(_allFilesChecked)
|
||||
{
|
||||
_datFiles = Directory
|
||||
.GetFiles(FolderPath,
|
||||
"*.*",
|
||||
_recursiveChecked ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
|
||||
.OrderBy(f => f)
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] dats = Directory.GetFiles(FolderPath,
|
||||
"*.dat",
|
||||
if(_allFilesChecked)
|
||||
{
|
||||
_datFiles = Directory.GetFiles(FolderPath,
|
||||
"*.*",
|
||||
_recursiveChecked
|
||||
? SearchOption.AllDirectories
|
||||
: SearchOption.TopDirectoryOnly);
|
||||
: SearchOption.TopDirectoryOnly)
|
||||
.Order()
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] dats = Directory.GetFiles(FolderPath,
|
||||
"*.dat",
|
||||
_recursiveChecked
|
||||
? SearchOption.AllDirectories
|
||||
: SearchOption.TopDirectoryOnly);
|
||||
|
||||
string[] xmls = Directory.GetFiles(FolderPath,
|
||||
"*.xml",
|
||||
_recursiveChecked
|
||||
? SearchOption.AllDirectories
|
||||
: SearchOption.TopDirectoryOnly);
|
||||
string[] xmls = Directory.GetFiles(FolderPath,
|
||||
"*.xml",
|
||||
_recursiveChecked
|
||||
? SearchOption.AllDirectories
|
||||
: SearchOption.TopDirectoryOnly);
|
||||
|
||||
_datFiles = dats.Concat(xmls).OrderBy(f => f).ToArray();
|
||||
}
|
||||
_datFiles = dats.Concat(xmls).Order().ToArray();
|
||||
}
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
IsReady = true;
|
||||
ProgressVisible = false;
|
||||
StatusMessage = string.Format(Localization.FoundFiles, _datFiles.Length);
|
||||
CanClose = true;
|
||||
CanStart = true;
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
IsReady = true;
|
||||
ProgressVisible = false;
|
||||
StatusMessage = string.Format(Localization.FoundFiles, _datFiles.Length);
|
||||
CanClose = true;
|
||||
CanStart = true;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ExecuteCloseCommand() => _view.Close();
|
||||
|
||||
@@ -299,15 +293,15 @@ public sealed class ImportDatFolderViewModel : ViewModelBase
|
||||
StatusMessage = string.Format(Localization.ImportingItem, Path.GetFileName(_datFiles[_listPosition]));
|
||||
ProgressValue = _listPosition;
|
||||
|
||||
var _worker = new DatImporter(_datFiles[_listPosition], Category);
|
||||
_worker.ErrorOccurred += OnWorkerOnErrorOccurred;
|
||||
_worker.SetIndeterminateProgress += OnWorkerOnSetIndeterminateProgress;
|
||||
_worker.SetMessage += OnWorkerOnSetMessage;
|
||||
_worker.SetProgress += OnWorkerOnSetProgress;
|
||||
_worker.SetProgressBounds += OnWorkerOnSetProgressBounds;
|
||||
_worker.WorkFinished += OnWorkerOnWorkFinished;
|
||||
_worker.RomSetAdded += RomSetAdded;
|
||||
Task.Run(_worker.Import);
|
||||
var worker = new DatImporter(_datFiles[_listPosition], Category);
|
||||
worker.ErrorOccurred += OnWorkerOnErrorOccurred;
|
||||
worker.SetIndeterminateProgress += OnWorkerOnSetIndeterminateProgress;
|
||||
worker.SetMessage += OnWorkerOnSetMessage;
|
||||
worker.SetProgress += OnWorkerOnSetProgress;
|
||||
worker.SetProgressBounds += OnWorkerOnSetProgressBounds;
|
||||
worker.WorkFinished += OnWorkerOnWorkFinished;
|
||||
worker.RomSetAdded += RomSetAdded;
|
||||
_ = Task.Run(worker.Import);
|
||||
}
|
||||
|
||||
void OnWorkerOnWorkFinished(object sender, MessageEventArgs args) => Dispatcher.UIThread.Post(() =>
|
||||
|
||||
@@ -30,7 +30,6 @@ using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Resources;
|
||||
using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
@@ -65,8 +64,6 @@ public sealed class ImportDatViewModel : ViewModelBase
|
||||
_worker.WorkFinished += OnWorkerOnWorkFinished;
|
||||
}
|
||||
|
||||
public string Title => Localization.ImportDatTitle;
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
@@ -121,7 +118,6 @@ public sealed class ImportDatViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
|
||||
void OnWorkerOnWorkFinished(object sender, MessageEventArgs args) => Dispatcher.UIThread.Post(() =>
|
||||
@@ -161,7 +157,7 @@ public sealed class ImportDatViewModel : ViewModelBase
|
||||
{
|
||||
ProgressVisible = true;
|
||||
_worker.RomSetAdded += RomSetAdded;
|
||||
Task.Run(_worker.Import);
|
||||
_ = Task.Run(_worker.Import);
|
||||
}
|
||||
|
||||
public event EventHandler<RomSetEventArgs> RomSetAdded;
|
||||
|
||||
@@ -77,11 +77,7 @@ public sealed class ImportRomFolderViewModel : ViewModelBase
|
||||
_removeFilesEnabled = false;
|
||||
}
|
||||
|
||||
public string PathLabel => Localization.PathLabel;
|
||||
public string FolderPath { get; }
|
||||
public string RemoveFilesLabel => Localization.RemoveFilesLabel;
|
||||
public string KnownOnlyLabel => Localization.KnownOnlyLabel;
|
||||
public string RecurseArchivesLabel => Localization.RecurseArchivesLabel;
|
||||
public bool RecurseArchivesEnabled => Settings.Settings.UnArUsable;
|
||||
|
||||
public bool RemoveFilesChecked
|
||||
@@ -198,13 +194,7 @@ public sealed class ImportRomFolderViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _isImporting, value);
|
||||
}
|
||||
|
||||
public string Title => Localization.ImportRomFolderTitle;
|
||||
|
||||
public ObservableCollection<ImportRomItem> ImportResults { get; }
|
||||
public string ResultFilenameLabel => Localization.ResultFilenameLabel;
|
||||
public string ResultStatusLabel => Localization.ResultStatusLabel;
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
public string StartLabel => Localization.StartLabel;
|
||||
public ObservableCollection<ImportRomItem> ImportResults { get; }
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
@@ -244,7 +234,7 @@ public sealed class ImportRomFolderViewModel : ViewModelBase
|
||||
worker.Finished += OnWorkerOnFinished;
|
||||
worker.ImportedRom += OnWorkerOnImportedRom;
|
||||
|
||||
Task.Run(() => worker.ProcessPath(FolderPath, true, RecurseArchivesChecked));
|
||||
_ = Task.Run(() => worker.ProcessPath(FolderPath, true, RecurseArchivesChecked));
|
||||
}
|
||||
|
||||
void OnWorkerOnImportedRom(object sender, ImportedRomItemEventArgs args) =>
|
||||
|
||||
@@ -29,9 +29,11 @@ using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using MsBox.Avalonia;
|
||||
using MsBox.Avalonia.Enums;
|
||||
@@ -54,56 +56,23 @@ public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
_view = view;
|
||||
ExitCommand = ReactiveCommand.Create(ExecuteExitCommand);
|
||||
SettingsCommand = ReactiveCommand.Create(ExecuteSettingsCommand);
|
||||
SettingsCommand = ReactiveCommand.CreateFromTask(ExecuteSettingsCommandAsync);
|
||||
AboutCommand = ReactiveCommand.Create(ExecuteAboutCommand);
|
||||
ImportDatCommand = ReactiveCommand.Create(ExecuteImportDatCommand);
|
||||
ImportDatFolderCommand = ReactiveCommand.Create(ExecuteImportDatFolderCommand);
|
||||
ImportRomFolderCommand = ReactiveCommand.Create(ExecuteImportRomFolderCommand);
|
||||
DeleteRomSetCommand = ReactiveCommand.Create(ExecuteDeleteRomSetCommand);
|
||||
ImportDatCommand = ReactiveCommand.CreateFromTask(ExecuteImportDatCommandAsync);
|
||||
ImportDatFolderCommand = ReactiveCommand.CreateFromTask(ExecuteImportDatFolderCommandAsync);
|
||||
ImportRomFolderCommand = ReactiveCommand.CreateFromTask(ExecuteImportRomFolderCommandAsync);
|
||||
DeleteRomSetCommand = ReactiveCommand.CreateFromTask(ExecuteDeleteRomSetCommandAsync);
|
||||
EditRomSetCommand = ReactiveCommand.Create(ExecuteEditRomSetCommand);
|
||||
ExportDatCommand = ReactiveCommand.Create(ExecuteExportDatCommand);
|
||||
ExportRomsCommand = ReactiveCommand.Create(ExecuteExportRomsCommand);
|
||||
MountCommand = ReactiveCommand.Create(ExecuteMountCommand);
|
||||
ExportDatCommand = ReactiveCommand.CreateFromTask(ExecuteExportDatCommandAsync);
|
||||
ExportRomsCommand = ReactiveCommand.CreateFromTask(ExecuteExportRomsCommandAsync);
|
||||
MountCommand = ReactiveCommand.CreateFromTask(ExecuteMountCommandAsync);
|
||||
UmountCommand = ReactiveCommand.Create(ExecuteUmountCommand);
|
||||
UpdateStatsCommand = ReactiveCommand.Create(ExecuteUpdateStatsCommand);
|
||||
UpdateStatsCommand = ReactiveCommand.CreateFromTask(ExecuteUpdateStatsCommandAsync);
|
||||
RomSets = new ObservableCollection<RomSetModel>(romSets);
|
||||
}
|
||||
|
||||
public ObservableCollection<RomSetModel> RomSets { get; }
|
||||
public string RomSetLabel => Localization.RomSets;
|
||||
public string RomSetNameLabel => Localization.RomSetNameLabel;
|
||||
public string RomSetVersionLabel => Localization.RomSetVersionLabel;
|
||||
public string RomSetAuthorLabel => Localization.RomSetAuthorLabel;
|
||||
public string RomSetCategoryLabel => Localization.RomSetCategoryLabel;
|
||||
public string RomSetDateLabel => Localization.RomSetDateLabel;
|
||||
public string RomSetDescriptionLabel => Localization.RomSetDescriptionLabel;
|
||||
public string RomSetCommentLabel => Localization.RomSetCommentLabel;
|
||||
public string RomSetTotalMachinesLabel => Localization.RomSetTotalMachinesLabel;
|
||||
public string RomSetCompleteMachinesLabel => Localization.RomSetCompleteMachinesLabel;
|
||||
public string RomSetIncompleteMachinesLabel => Localization.RomSetIncompleteMachinesLabel;
|
||||
public string RomSetTotalRomsLabel => Localization.RomSetTotalRomsLabel;
|
||||
public string RomSetHaveRomsLabel => Localization.RomSetHaveRomsLabel;
|
||||
public string RomSetMissRomsLabel => Localization.RomSetMissRomsLabel;
|
||||
public bool IsVfsAvailable => Vfs.IsAvailable;
|
||||
public string FileMenuText => Localization.FileMenuText;
|
||||
public string FileMenuImportDatFileText => Localization.FileMenuImportDatFileText;
|
||||
public string FileMenuImportDatFolderText => Localization.FileMenuImportDatFolderText;
|
||||
public string FileMenuSettingsText => Localization.FileMenuSettingsText;
|
||||
public string FileMenuExitText => Localization.FileMenuExitText;
|
||||
public string FilesystemMenuText => Localization.FilesystemMenuText;
|
||||
public string FilesystemMenuMountText => Localization.FilesystemMenuMountText;
|
||||
public string RomsMenuText => Localization.RomsMenuText;
|
||||
public string RomsMenuImportText => Localization.RomsMenuImportText;
|
||||
public string RomSetsMenuText => Localization.RomSetsMenuText;
|
||||
public string RomSetsMenuSaveRomsText => Localization.RomSetsMenuSaveRomsText;
|
||||
public string RomSetsMenuSaveDatText => Localization.RomSetsMenuSaveDatText;
|
||||
public string RomSetsMenuEditText => Localization.RomSetsMenuEditText;
|
||||
public string RomSetsMenuDeleteText => Localization.RomSetsMenuDeleteText;
|
||||
public string HelpMenuText => Localization.HelpMenuText;
|
||||
public string HelpMenuAboutText => Localization.HelpMenuAboutText;
|
||||
public string FilesystemMenuUmountText => Localization.FilesystemMenuUmountText;
|
||||
public string DatabaseMenuText => Localization.DatabaseMenuText;
|
||||
public string DatabaseMenuUpdateStatsText => Localization.DatabaseMenuUpdateStatsText;
|
||||
public ObservableCollection<RomSetModel> RomSets { get; }
|
||||
public bool IsVfsAvailable => Vfs.IsAvailable;
|
||||
|
||||
public bool NativeMenuSupported =>
|
||||
NativeMenu.GetIsNativeMenuExported((Application.Current.ApplicationLifetime as
|
||||
@@ -135,11 +104,12 @@ public class MainWindowViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _selectedRomSet, value);
|
||||
}
|
||||
|
||||
internal async void ExecuteSettingsCommand()
|
||||
internal Task ExecuteSettingsCommandAsync()
|
||||
{
|
||||
var dialog = new SettingsDialog();
|
||||
dialog.DataContext = new SettingsViewModel(dialog);
|
||||
await dialog.ShowDialog(_view);
|
||||
|
||||
return dialog.ShowDialog(_view);
|
||||
}
|
||||
|
||||
internal void ExecuteExitCommand() =>
|
||||
@@ -149,79 +119,72 @@ public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
var dialog = new About();
|
||||
dialog.DataContext = new AboutViewModel(dialog);
|
||||
dialog.ShowDialog(_view);
|
||||
_ = dialog.ShowDialog(_view);
|
||||
}
|
||||
|
||||
async void ExecuteImportDatCommand()
|
||||
async Task ExecuteImportDatCommandAsync()
|
||||
{
|
||||
var dlgOpen = new OpenFileDialog
|
||||
var datFileType = new FilePickerFileType(Localization.DatFilesDialogLabel)
|
||||
{
|
||||
AllowMultiple = false,
|
||||
Title = Localization.ImportDatFileDialogTitle
|
||||
Patterns = ["*.dat", "*.xml"],
|
||||
AppleUniformTypeIdentifiers = ["public.xml", "public.json"],
|
||||
MimeTypes = ["application/xml", "text/*"]
|
||||
};
|
||||
|
||||
dlgOpen.Filters.Add(new FileDialogFilter
|
||||
IReadOnlyList<IStorageFile> result = await _view.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Extensions = ["dat", "xml"],
|
||||
Name = Localization.DatFilesDialogLabel
|
||||
Title = Localization.ImportDatFileDialogTitle,
|
||||
AllowMultiple = false,
|
||||
SuggestedStartLocation = await _view.StorageProvider.TryGetWellKnownFolderAsync(WellKnownFolder.Documents),
|
||||
FileTypeFilter = [datFileType, FilePickerFileTypes.All]
|
||||
});
|
||||
|
||||
dlgOpen.Filters.Add(new FileDialogFilter
|
||||
{
|
||||
Extensions = ["*"],
|
||||
Name = Localization.AllFilesDialogLabel
|
||||
});
|
||||
|
||||
string[] result = await dlgOpen.ShowAsync(_view);
|
||||
|
||||
if(result?.Length != 1) return;
|
||||
if(result.Count != 1) return;
|
||||
|
||||
var dialog = new ImportDat();
|
||||
var importDatViewModel = new ImportDatViewModel(dialog, result[0]);
|
||||
var importDatViewModel = new ImportDatViewModel(dialog, result[0].Path.LocalPath);
|
||||
importDatViewModel.RomSetAdded += ImportDatViewModelOnRomSetAdded;
|
||||
dialog.DataContext = importDatViewModel;
|
||||
await dialog.ShowDialog(_view);
|
||||
_ = dialog.ShowDialog(_view);
|
||||
}
|
||||
|
||||
void ImportDatViewModelOnRomSetAdded(object sender, RomSetEventArgs e) =>
|
||||
Dispatcher.UIThread.Post(() => RomSets.Add(e.RomSet));
|
||||
|
||||
async void ExecuteImportDatFolderCommand()
|
||||
async Task ExecuteImportDatFolderCommandAsync()
|
||||
{
|
||||
var dlgOpen = new OpenFolderDialog
|
||||
{
|
||||
Title = Localization.ImportDatFolderDialogTitle
|
||||
};
|
||||
IReadOnlyList<IStorageFolder> result =
|
||||
await _view.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = Localization.ImportDatFolderDialogTitle
|
||||
});
|
||||
|
||||
string result = await dlgOpen.ShowAsync(_view);
|
||||
|
||||
if(result == null) return;
|
||||
if(result.Count < 1) return;
|
||||
|
||||
var dialog = new ImportDatFolder();
|
||||
var importDatFolderViewModel = new ImportDatFolderViewModel(dialog, result);
|
||||
var importDatFolderViewModel = new ImportDatFolderViewModel(dialog, result[0].Path.LocalPath);
|
||||
importDatFolderViewModel.RomSetAdded += ImportDatViewModelOnRomSetAdded;
|
||||
dialog.DataContext = importDatFolderViewModel;
|
||||
await dialog.ShowDialog(_view);
|
||||
_ = dialog.ShowDialog(_view);
|
||||
}
|
||||
|
||||
async void ExecuteImportRomFolderCommand()
|
||||
async Task ExecuteImportRomFolderCommandAsync()
|
||||
{
|
||||
var dlgOpen = new OpenFolderDialog
|
||||
{
|
||||
Title = Localization.ImportRomsFolderDialogTitle
|
||||
};
|
||||
IReadOnlyList<IStorageFolder> result =
|
||||
await _view.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = Localization.ImportRomsFolderDialogTitle
|
||||
});
|
||||
|
||||
string result = await dlgOpen.ShowAsync(_view);
|
||||
|
||||
if(result == null) return;
|
||||
if(result.Count < 1) return;
|
||||
|
||||
var dialog = new ImportRomFolder();
|
||||
var importRomFolderViewModel = new ImportRomFolderViewModel(dialog, result);
|
||||
var importRomFolderViewModel = new ImportRomFolderViewModel(dialog, result[0].Path.LocalPath);
|
||||
dialog.DataContext = importRomFolderViewModel;
|
||||
await dialog.ShowDialog(_view);
|
||||
_ = dialog.ShowDialog(_view);
|
||||
}
|
||||
|
||||
async void ExecuteDeleteRomSetCommand()
|
||||
async Task ExecuteDeleteRomSetCommandAsync()
|
||||
{
|
||||
if(SelectedRomSet == null) return;
|
||||
|
||||
@@ -251,7 +214,7 @@ public class MainWindowViewModel : ViewModelBase
|
||||
var window = new EditDat();
|
||||
var viewModel = new EditDatViewModel(window, SelectedRomSet);
|
||||
|
||||
viewModel.RomSetModified += (sender, args) =>
|
||||
viewModel.RomSetModified += (_, args) =>
|
||||
{
|
||||
RomSetModel old = RomSets.FirstOrDefault(r => r.Id == args.RomSet.Id);
|
||||
|
||||
@@ -266,60 +229,57 @@ public class MainWindowViewModel : ViewModelBase
|
||||
window.Show();
|
||||
}
|
||||
|
||||
async void ExecuteExportDatCommand()
|
||||
async Task ExecuteExportDatCommandAsync()
|
||||
{
|
||||
if(SelectedRomSet == null) return;
|
||||
|
||||
var dlgSave = new SaveFileDialog
|
||||
IStorageFile result = await _view.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||
{
|
||||
InitialFileName = SelectedRomSet.Filename
|
||||
};
|
||||
|
||||
string result = await dlgSave.ShowAsync(_view);
|
||||
SuggestedFileName = SelectedRomSet.Filename,
|
||||
SuggestedStartLocation = await _view.StorageProvider.TryGetWellKnownFolderAsync(WellKnownFolder.Documents)
|
||||
});
|
||||
|
||||
if(result == null) return;
|
||||
|
||||
var dialog = new ExportDat();
|
||||
var viewModel = new ExportDatViewModel(dialog, SelectedRomSet.Sha384, result);
|
||||
var viewModel = new ExportDatViewModel(dialog, SelectedRomSet.Sha384, result.Path.LocalPath);
|
||||
dialog.DataContext = viewModel;
|
||||
await dialog.ShowDialog(_view);
|
||||
_ = dialog.ShowDialog(_view);
|
||||
}
|
||||
|
||||
async void ExecuteExportRomsCommand()
|
||||
async Task ExecuteExportRomsCommandAsync()
|
||||
{
|
||||
var dlgOpen = new OpenFolderDialog
|
||||
{
|
||||
Title = Localization.ExportRomsDialogTitle
|
||||
};
|
||||
IReadOnlyList<IStorageFolder> result =
|
||||
await _view.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = Localization.ExportRomsDialogTitle
|
||||
});
|
||||
|
||||
string result = await dlgOpen.ShowAsync(_view);
|
||||
|
||||
if(result == null) return;
|
||||
if(result.Count < 1) return;
|
||||
|
||||
var dialog = new ExportRoms();
|
||||
var viewModel = new ExportRomsViewModel(dialog, result, SelectedRomSet.Id);
|
||||
var viewModel = new ExportRomsViewModel(dialog, result[0].Path.LocalPath, SelectedRomSet.Id);
|
||||
dialog.DataContext = viewModel;
|
||||
await dialog.ShowDialog(_view);
|
||||
_ = dialog.ShowDialog(_view);
|
||||
}
|
||||
|
||||
async void ExecuteMountCommand()
|
||||
async Task ExecuteMountCommandAsync()
|
||||
{
|
||||
if(Vfs != null) return;
|
||||
|
||||
var dlgOpen = new OpenFolderDialog
|
||||
{
|
||||
Title = Localization.SelectMountPointDialogTitle
|
||||
};
|
||||
IReadOnlyList<IStorageFolder> result =
|
||||
await _view.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = Localization.SelectMountPointDialogTitle
|
||||
});
|
||||
|
||||
string result = await dlgOpen.ShowAsync(_view);
|
||||
|
||||
if(result == null) return;
|
||||
if(result.Count < 1) return;
|
||||
|
||||
try
|
||||
{
|
||||
Vfs = new Vfs();
|
||||
Vfs.Umounted += VfsOnUmounted;
|
||||
Vfs.MountTo(result);
|
||||
Vfs.MountTo(result[0].Path.LocalPath);
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
@@ -333,7 +293,7 @@ public class MainWindowViewModel : ViewModelBase
|
||||
|
||||
void ExecuteUmountCommand() => Vfs?.Umount();
|
||||
|
||||
async void ExecuteUpdateStatsCommand()
|
||||
async Task ExecuteUpdateStatsCommandAsync()
|
||||
{
|
||||
ButtonResult result = await MessageBoxManager
|
||||
.GetMessageBoxStandard(Localization.DatabaseMenuUpdateStatsText,
|
||||
@@ -347,6 +307,6 @@ public class MainWindowViewModel : ViewModelBase
|
||||
var view = new UpdateStats();
|
||||
var viewModel = new UpdateStatsViewModel(view);
|
||||
view.DataContext = viewModel;
|
||||
await view.ShowDialog(_view);
|
||||
_ = view.ShowDialog(_view);
|
||||
}
|
||||
}
|
||||
@@ -35,19 +35,9 @@ using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class RemoveDatViewModel : ViewModelBase
|
||||
public sealed class RemoveDatViewModel(RemoveDat view, long romSetId) : ViewModelBase
|
||||
{
|
||||
readonly long _romSetId;
|
||||
readonly RemoveDat _view;
|
||||
string _statusMessage;
|
||||
|
||||
public RemoveDatViewModel(RemoveDat view, long romSetId)
|
||||
{
|
||||
_view = view;
|
||||
_romSetId = romSetId;
|
||||
}
|
||||
|
||||
public string Title => Localization.RemoveDatTitle;
|
||||
string _statusMessage;
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
@@ -55,52 +45,55 @@ public sealed class RemoveDatViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
internal void OnOpened() => Task.Run(() =>
|
||||
internal void OnOpened()
|
||||
{
|
||||
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.RetrievingRomSetFromDatabase);
|
||||
|
||||
RomSet romSet = ctx.RomSets.Find(_romSetId);
|
||||
|
||||
if(romSet == null) return;
|
||||
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.RemovingRomSetFromDatabase);
|
||||
|
||||
ctx.RomSets.Remove(romSet);
|
||||
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.SavingChangesToDatabase);
|
||||
|
||||
ctx.SaveChanges();
|
||||
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.RemovingDatFileFromRepo);
|
||||
|
||||
var sha384Bytes = new byte[48];
|
||||
string sha384 = romSet.Sha384;
|
||||
|
||||
for(var i = 0; i < 48; i++)
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
if(sha384[i * 2] >= 0x30 && sha384[i * 2] <= 0x39)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x30) * 0x10);
|
||||
else if(sha384[i * 2] >= 0x41 && sha384[i * 2] <= 0x46)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x37) * 0x10);
|
||||
else if(sha384[i * 2] >= 0x61 && sha384[i * 2] <= 0x66)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x57) * 0x10);
|
||||
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
|
||||
if(sha384[i * 2 + 1] >= 0x30 && sha384[i * 2 + 1] <= 0x39)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x30);
|
||||
else if(sha384[i * 2 + 1] >= 0x41 && sha384[i * 2 + 1] <= 0x46)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x37);
|
||||
else if(sha384[i * 2 + 1] >= 0x61 && sha384[i * 2 + 1] <= 0x66)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x57);
|
||||
}
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.RetrievingRomSetFromDatabase);
|
||||
|
||||
string datHash32 = Base32.ToBase32String(sha384Bytes);
|
||||
string datFilesPath = Path.Combine(Settings.Settings.Current.RepositoryPath, "datfiles");
|
||||
string compressedDatPath = Path.Combine(datFilesPath, datHash32 + ".lz");
|
||||
RomSet romSet = ctx.RomSets.Find(romSetId);
|
||||
|
||||
if(File.Exists(compressedDatPath)) File.Delete(compressedDatPath);
|
||||
if(romSet == null) return;
|
||||
|
||||
Dispatcher.UIThread.Post(_view.Close);
|
||||
});
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.RemovingRomSetFromDatabase);
|
||||
|
||||
ctx.RomSets.Remove(romSet);
|
||||
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.SavingChangesToDatabase);
|
||||
|
||||
ctx.SaveChanges();
|
||||
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.RemovingDatFileFromRepo);
|
||||
|
||||
var sha384Bytes = new byte[48];
|
||||
string sha384 = romSet.Sha384;
|
||||
|
||||
for(var i = 0; i < 48; i++)
|
||||
{
|
||||
if(sha384[i * 2] >= 0x30 && sha384[i * 2] <= 0x39)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x30) * 0x10);
|
||||
else if(sha384[i * 2] >= 0x41 && sha384[i * 2] <= 0x46)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x37) * 0x10);
|
||||
else if(sha384[i * 2] >= 0x61 && sha384[i * 2] <= 0x66)
|
||||
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x57) * 0x10);
|
||||
|
||||
if(sha384[i * 2 + 1] >= 0x30 && sha384[i * 2 + 1] <= 0x39)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x30);
|
||||
else if(sha384[i * 2 + 1] >= 0x41 && sha384[i * 2 + 1] <= 0x46)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x37);
|
||||
else if(sha384[i * 2 + 1] >= 0x61 && sha384[i * 2 + 1] <= 0x66)
|
||||
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x57);
|
||||
}
|
||||
|
||||
string datHash32 = Base32.ToBase32String(sha384Bytes);
|
||||
string datFilesPath = Path.Combine(Settings.Settings.Current.RepositoryPath, "datfiles");
|
||||
string compressedDatPath = Path.Combine(datFilesPath, datHash32 + ".lz");
|
||||
|
||||
if(File.Exists(compressedDatPath)) File.Delete(compressedDatPath);
|
||||
|
||||
Dispatcher.UIThread.Post(view.Close);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,11 @@
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MsBox.Avalonia;
|
||||
@@ -64,10 +65,10 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
_unArChanged = false;
|
||||
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
UnArCommand = ReactiveCommand.Create(ExecuteUnArCommand);
|
||||
TemporaryCommand = ReactiveCommand.Create(ExecuteTemporaryCommand);
|
||||
RepositoryCommand = ReactiveCommand.Create(ExecuteRepositoryCommand);
|
||||
DatabaseCommand = ReactiveCommand.Create(ExecuteDatabaseCommand);
|
||||
UnArCommand = ReactiveCommand.CreateFromTask(ExecuteUnArCommandAsync);
|
||||
TemporaryCommand = ReactiveCommand.CreateFromTask(ExecuteTemporaryCommandAsync);
|
||||
RepositoryCommand = ReactiveCommand.CreateFromTask(ExecuteRepositoryCommandAsync);
|
||||
DatabaseCommand = ReactiveCommand.CreateFromTask(ExecuteDatabaseCommandAsync);
|
||||
SaveCommand = ReactiveCommand.Create(ExecuteSaveCommand);
|
||||
|
||||
DatabasePath = Settings.Settings.Current.DatabasePath;
|
||||
@@ -78,14 +79,6 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
if(!string.IsNullOrWhiteSpace(UnArPath)) CheckUnAr();
|
||||
}
|
||||
|
||||
public string ChooseLabel => Localization.ChooseLabel;
|
||||
public string Title => Localization.SettingsTitle;
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
public string DatabaseLabel => Localization.DatabaseFileLabel;
|
||||
public string RepositoryLabel => Localization.RepositoryFolderLabel;
|
||||
public string TemporaryLabel => Localization.TemporaryFolderLabel;
|
||||
public string UnArPathLabel => Localization.UnArPathLabel;
|
||||
|
||||
public ReactiveCommand<Unit, Unit> UnArCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> TemporaryCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> RepositoryCommand { get; }
|
||||
@@ -137,8 +130,6 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _unArVersion, value);
|
||||
}
|
||||
|
||||
public string SaveLabel => Localization.SaveLabel;
|
||||
|
||||
void CheckUnAr()
|
||||
{
|
||||
var worker = new Compression();
|
||||
@@ -146,16 +137,16 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
worker.FinishedWithText += CheckUnArFinished;
|
||||
worker.FailedWithText += CheckUnArFailed;
|
||||
|
||||
Task.Run(() => worker.CheckUnAr(UnArPath));
|
||||
_ = Task.Run(() => worker.CheckUnAr(UnArPath));
|
||||
}
|
||||
|
||||
async void CheckUnArFailed(object sender, ErrorEventArgs args)
|
||||
void CheckUnArFailed(object sender, ErrorEventArgs args)
|
||||
{
|
||||
UnArVersion = "";
|
||||
UnArPath = "";
|
||||
|
||||
await MessageBoxManager.GetMessageBoxStandard(Localization.Error, $"{args.Message}", ButtonEnum.Ok, Icon.Error)
|
||||
.ShowWindowDialogAsync(_view);
|
||||
_ = MessageBoxManager.GetMessageBoxStandard(Localization.Error, args.Message, ButtonEnum.Ok, Icon.Error)
|
||||
.ShowWindowDialogAsync(_view);
|
||||
}
|
||||
|
||||
void CheckUnArFinished(object sender, MessageEventArgs args) => Dispatcher.UIThread.Post(() =>
|
||||
@@ -166,65 +157,65 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
|
||||
void ExecuteCloseCommand() => _view.Close();
|
||||
|
||||
async void ExecuteUnArCommand()
|
||||
async Task ExecuteUnArCommandAsync()
|
||||
{
|
||||
var dlgFile = new OpenFileDialog
|
||||
IReadOnlyList<IStorageFile> result = await _view.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = Localization.ChooseUnArExecutable,
|
||||
AllowMultiple = false
|
||||
};
|
||||
AllowMultiple = false,
|
||||
SuggestedStartLocation =
|
||||
!string.IsNullOrWhiteSpace(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles))
|
||||
? await _view.StorageProvider.TryGetFolderFromPathAsync(Environment.GetFolderPath(Environment
|
||||
.SpecialFolder.ProgramFiles))
|
||||
: await _view.StorageProvider.TryGetWellKnownFolderAsync(WellKnownFolder.Desktop)
|
||||
});
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)))
|
||||
dlgFile.Directory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
|
||||
if(result.Count != 1) return;
|
||||
|
||||
string[] result = await dlgFile.ShowAsync(_view);
|
||||
|
||||
if(result?.Length != 1) return;
|
||||
|
||||
UnArPath = result[0];
|
||||
UnArPath = result[0].Path.LocalPath;
|
||||
CheckUnAr();
|
||||
}
|
||||
|
||||
async void ExecuteTemporaryCommand()
|
||||
async Task ExecuteTemporaryCommandAsync()
|
||||
{
|
||||
var dlgFolder = new OpenFolderDialog
|
||||
{
|
||||
Title = Localization.ChooseTemporaryFolder
|
||||
};
|
||||
IReadOnlyList<IStorageFolder> result =
|
||||
await _view.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = Localization.ChooseTemporaryFolder
|
||||
});
|
||||
|
||||
string result = await dlgFolder.ShowAsync(_view);
|
||||
if(result.Count < 1) return;
|
||||
|
||||
if(result == null) return;
|
||||
|
||||
TemporaryPath = result;
|
||||
TemporaryPath = result[0].Path.LocalPath;
|
||||
}
|
||||
|
||||
async void ExecuteRepositoryCommand()
|
||||
async Task ExecuteRepositoryCommandAsync()
|
||||
{
|
||||
var dlgFolder = new OpenFolderDialog
|
||||
{
|
||||
Title = Localization.ChooseRepositoryFolder
|
||||
};
|
||||
IReadOnlyList<IStorageFolder> result =
|
||||
await _view.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = Localization.ChooseRepositoryFolder,
|
||||
AllowMultiple = false
|
||||
});
|
||||
|
||||
string result = await dlgFolder.ShowAsync(_view);
|
||||
if(result.Count < 1) return;
|
||||
|
||||
if(result == null) return;
|
||||
|
||||
RepositoryPath = result;
|
||||
RepositoryPath = result[0].Path.LocalPath;
|
||||
}
|
||||
|
||||
async void ExecuteDatabaseCommand()
|
||||
async Task ExecuteDatabaseCommandAsync()
|
||||
{
|
||||
var dlgFile = new SaveFileDialog
|
||||
IStorageFile resultFile = await _view.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||
{
|
||||
InitialFileName = "romrepo.db",
|
||||
Directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
|
||||
Title = Localization.ChooseDatabaseFile
|
||||
};
|
||||
SuggestedFileName = "romrepo.db",
|
||||
SuggestedStartLocation = await _view.StorageProvider.TryGetWellKnownFolderAsync(WellKnownFolder.Documents),
|
||||
Title = Localization.ChooseDatabaseFile,
|
||||
ShowOverwritePrompt = true
|
||||
});
|
||||
|
||||
string result = await dlgFile.ShowAsync(_view);
|
||||
if(resultFile == null) return;
|
||||
|
||||
if(result == null) return;
|
||||
string result = resultFile.Path.LocalPath;
|
||||
|
||||
if(File.Exists(result))
|
||||
{
|
||||
|
||||
@@ -37,7 +37,6 @@ using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Database;
|
||||
using RomRepoMgr.Resources;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
@@ -180,33 +179,30 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingRomSetsUnknown, value);
|
||||
}
|
||||
|
||||
public string LoadingText => "ROM Repository Manager";
|
||||
public string LoadingSettingsText => Localization.LoadingSettingsText;
|
||||
public string CheckingUnArText => Localization.CheckingUnArText;
|
||||
public string LoadingDatabaseText => Localization.LoadingDatabaseText;
|
||||
public string MigratingDatabaseText => Localization.MigratingDatabaseText;
|
||||
public string LoadingRomSetsText => Localization.LoadingRomSetsText;
|
||||
public string ExitButtonText => Localization.ExitButtonText;
|
||||
public string LoadingText => "ROM Repository Manager";
|
||||
|
||||
void ExecuteExitCommand() =>
|
||||
(Application.Current.ApplicationLifetime as ClassicDesktopStyleApplicationLifetime)?.Shutdown();
|
||||
|
||||
internal void OnOpened() => Dispatcher.UIThread.Post(LoadSettings);
|
||||
|
||||
void LoadSettings() => Task.Run(() =>
|
||||
void LoadSettings()
|
||||
{
|
||||
try
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Settings.Settings.LoadSettings();
|
||||
try
|
||||
{
|
||||
Settings.Settings.LoadSettings();
|
||||
|
||||
Dispatcher.UIThread.Post(CheckUnAr);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Dispatcher.UIThread.Post(FailedLoadingSettings);
|
||||
}
|
||||
});
|
||||
Dispatcher.UIThread.Post(CheckUnAr);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Dispatcher.UIThread.Post(FailedLoadingSettings);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FailedLoadingSettings()
|
||||
{
|
||||
@@ -215,24 +211,27 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
ExitVisible = true;
|
||||
}
|
||||
|
||||
void CheckUnAr() => Task.Run(() =>
|
||||
void CheckUnAr()
|
||||
{
|
||||
LoadingSettingsUnknown = false;
|
||||
LoadingSettingsOk = true;
|
||||
|
||||
try
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
var worker = new Compression();
|
||||
Settings.Settings.UnArUsable = worker.CheckUnAr(Settings.Settings.Current.UnArchiverPath);
|
||||
LoadingSettingsUnknown = false;
|
||||
LoadingSettingsOk = true;
|
||||
|
||||
Dispatcher.UIThread.Post(LoadDatabase);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Dispatcher.UIThread.Post(FailedCheckUnAr);
|
||||
}
|
||||
});
|
||||
try
|
||||
{
|
||||
var worker = new Compression();
|
||||
Settings.Settings.UnArUsable = worker.CheckUnAr(Settings.Settings.Current.UnArchiverPath);
|
||||
|
||||
Dispatcher.UIThread.Post(LoadDatabase);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Dispatcher.UIThread.Post(FailedCheckUnAr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FailedCheckUnAr()
|
||||
{
|
||||
@@ -246,7 +245,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
CheckingUnArUnknown = false;
|
||||
CheckingUnArOk = true;
|
||||
|
||||
Task.Run(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -278,7 +277,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
LoadingDatabaseUnknown = false;
|
||||
LoadingDatabaseOk = true;
|
||||
|
||||
Task.Run(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -308,7 +307,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
MigratingDatabaseUnknown = false;
|
||||
MigratingDatabaseOk = true;
|
||||
|
||||
Task.Run(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -60,21 +60,6 @@ public sealed class UpdateStatsViewModel : ViewModelBase
|
||||
RomSets = [];
|
||||
}
|
||||
|
||||
public string Title => Localization.UpdateStatsTitle;
|
||||
public string RomSetNameLabel => Localization.RomSetNameLabel;
|
||||
public string RomSetVersionLabel => Localization.RomSetVersionLabel;
|
||||
public string RomSetAuthorLabel => Localization.RomSetAuthorLabel;
|
||||
public string RomSetCategoryLabel => Localization.RomSetCategoryLabel;
|
||||
public string RomSetDateLabel => Localization.RomSetDateLabel;
|
||||
public string RomSetDescriptionLabel => Localization.RomSetDescriptionLabel;
|
||||
public string RomSetCommentLabel => Localization.RomSetCommentLabel;
|
||||
public string RomSetTotalMachinesLabel => Localization.RomSetTotalMachinesLabel;
|
||||
public string RomSetCompleteMachinesLabel => Localization.RomSetCompleteMachinesLabel;
|
||||
public string RomSetIncompleteMachinesLabel => Localization.RomSetIncompleteMachinesLabel;
|
||||
public string RomSetTotalRomsLabel => Localization.RomSetTotalRomsLabel;
|
||||
public string RomSetHaveRomsLabel => Localization.RomSetHaveRomsLabel;
|
||||
public string RomSetMissRomsLabel => Localization.RomSetMissRomsLabel;
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
@@ -125,142 +110,144 @@ public sealed class UpdateStatsViewModel : ViewModelBase
|
||||
|
||||
public ObservableCollection<RomSetModel> RomSets { get; }
|
||||
|
||||
public string CloseLabel => Localization.CloseLabel;
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
|
||||
internal void OnOpened() => Task.Run(() =>
|
||||
internal void OnOpened()
|
||||
{
|
||||
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
StatusMessage = Localization.RetrievingRomSetsFromDatabase;
|
||||
ProgressVisible = true;
|
||||
IndeterminateProgress = true;
|
||||
});
|
||||
|
||||
long romSetCount = ctx.RomSets.LongCount();
|
||||
|
||||
Dispatcher.UIThread.Post(() => { StatusMessage = Localization.RemovingOldStatistics; });
|
||||
|
||||
ctx.Database.ExecuteSql($"DELETE FROM \"RomSetStats\"");
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
IndeterminateProgress = false;
|
||||
MinimumValue = 0;
|
||||
MaximumValue = romSetCount;
|
||||
CurrentValue = 0;
|
||||
});
|
||||
|
||||
long pos = 0;
|
||||
|
||||
foreach(RomSet romSet in ctx.RomSets)
|
||||
{
|
||||
long currentPos = pos;
|
||||
using var ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
StatusMessage = string.Format(Localization.CalculatingStatisticsForRomSet,
|
||||
romSet.Name,
|
||||
romSet.Version,
|
||||
romSet.Description);
|
||||
|
||||
CurrentValue = currentPos;
|
||||
StatusMessage = Localization.RetrievingRomSetsFromDatabase;
|
||||
ProgressVisible = true;
|
||||
IndeterminateProgress = true;
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
RomSetStat stats = ctx.RomSets.Where(r => r.Id == romSet.Id)
|
||||
.Select(r => new RomSetStat
|
||||
{
|
||||
RomSetId = r.Id,
|
||||
TotalMachines = r.Machines.Count,
|
||||
CompleteMachines =
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count == 0 &&
|
||||
m.Files.All(f => f.File.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Disks.Count > 0 &&
|
||||
m.Files.Count == 0 &&
|
||||
m.Disks.All(f => f.Disk.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count > 0 &&
|
||||
m.Files.All(f => f.File.IsInRepo) &&
|
||||
m.Disks.All(f => f.Disk.IsInRepo)),
|
||||
IncompleteMachines =
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count == 0 &&
|
||||
m.Files.Any(f => !f.File.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Disks.Count > 0 &&
|
||||
m.Files.Count == 0 &&
|
||||
m.Disks.Any(f => !f.Disk.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count > 0 &&
|
||||
(m.Files.Any(f => !f.File.IsInRepo) ||
|
||||
m.Disks.Any(f => !f.Disk.IsInRepo))),
|
||||
TotalRoms =
|
||||
r.Machines.Sum(m => m.Files.Count) +
|
||||
r.Machines.Sum(m => m.Disks.Count) +
|
||||
r.Machines.Sum(m => m.Medias.Count),
|
||||
HaveRoms = r.Machines.Sum(m => m.Files.Count(f => f.File.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Disks.Count(f => f.Disk.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Medias.Count(f => f.Media.IsInRepo)),
|
||||
MissRoms = r.Machines.Sum(m => m.Files.Count(f => !f.File.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Disks.Count(f => !f.Disk.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Medias.Count(f => !f.Media.IsInRepo))
|
||||
})
|
||||
.FirstOrDefault();
|
||||
long romSetCount = ctx.RomSets.LongCount();
|
||||
|
||||
ctx.RomSetStats.Add(stats);
|
||||
Dispatcher.UIThread.Post(() => StatusMessage = Localization.RemovingOldStatistics);
|
||||
|
||||
ctx.Database.ExecuteSql($"DELETE FROM \"RomSetStats\"");
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
IndeterminateProgress = false;
|
||||
MinimumValue = 0;
|
||||
MaximumValue = romSetCount;
|
||||
CurrentValue = 0;
|
||||
});
|
||||
|
||||
long pos = 0;
|
||||
|
||||
foreach(RomSet romSet in ctx.RomSets)
|
||||
{
|
||||
long currentPos = pos;
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
RomSets.Add(new RomSetModel
|
||||
{
|
||||
Id = romSet.Id,
|
||||
Author = romSet.Author,
|
||||
Comment = romSet.Comment,
|
||||
Date = romSet.Date,
|
||||
Description = romSet.Description,
|
||||
Filename = romSet.Filename,
|
||||
Homepage = romSet.Homepage,
|
||||
Name = romSet.Name,
|
||||
Sha384 = romSet.Sha384,
|
||||
Version = romSet.Version,
|
||||
TotalMachines = stats.TotalMachines,
|
||||
CompleteMachines = stats.CompleteMachines,
|
||||
IncompleteMachines = stats.IncompleteMachines,
|
||||
TotalRoms = stats.TotalRoms,
|
||||
HaveRoms = stats.HaveRoms,
|
||||
MissRoms = stats.MissRoms,
|
||||
Category = romSet.Category
|
||||
});
|
||||
StatusMessage = string.Format(Localization.CalculatingStatisticsForRomSet,
|
||||
romSet.Name,
|
||||
romSet.Version,
|
||||
romSet.Description);
|
||||
|
||||
CurrentValue = currentPos;
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
RomSetStat stats = ctx.RomSets.Where(r => r.Id == romSet.Id)
|
||||
.Select(r => new RomSetStat
|
||||
{
|
||||
RomSetId = r.Id,
|
||||
TotalMachines = r.Machines.Count,
|
||||
CompleteMachines =
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count == 0 &&
|
||||
m.Files.All(f => f.File.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Disks.Count > 0 &&
|
||||
m.Files.Count == 0 &&
|
||||
m.Disks.All(f => f.Disk.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count > 0 &&
|
||||
m.Files.All(f => f.File.IsInRepo) &&
|
||||
m.Disks.All(f => f.Disk.IsInRepo)),
|
||||
IncompleteMachines =
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count == 0 &&
|
||||
m.Files.Any(f => !f.File.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Disks.Count > 0 &&
|
||||
m.Files.Count == 0 &&
|
||||
m.Disks.Any(f => !f.Disk.IsInRepo)) +
|
||||
r.Machines.Count(m => m.Files.Count > 0 &&
|
||||
m.Disks.Count > 0 &&
|
||||
(m.Files.Any(f => !f.File.IsInRepo) ||
|
||||
m.Disks.Any(f => !f.Disk.IsInRepo))),
|
||||
TotalRoms =
|
||||
r.Machines.Sum(m => m.Files.Count) +
|
||||
r.Machines.Sum(m => m.Disks.Count) +
|
||||
r.Machines.Sum(m => m.Medias.Count),
|
||||
HaveRoms = r.Machines.Sum(m => m.Files.Count(f => f.File.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Disks.Count(f => f.Disk.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Medias.Count(f => f.Media.IsInRepo)),
|
||||
MissRoms = r.Machines.Sum(m => m.Files.Count(f => !f.File.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Disks.Count(f => !f.Disk.IsInRepo)) +
|
||||
r.Machines.Sum(m => m.Medias.Count(f => !f.Media.IsInRepo))
|
||||
})
|
||||
.FirstOrDefault();
|
||||
|
||||
ctx.RomSetStats.Add(stats);
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
RomSets.Add(new RomSetModel
|
||||
{
|
||||
Id = romSet.Id,
|
||||
Author = romSet.Author,
|
||||
Comment = romSet.Comment,
|
||||
Date = romSet.Date,
|
||||
Description = romSet.Description,
|
||||
Filename = romSet.Filename,
|
||||
Homepage = romSet.Homepage,
|
||||
Name = romSet.Name,
|
||||
Sha384 = romSet.Sha384,
|
||||
Version = romSet.Version,
|
||||
TotalMachines = stats.TotalMachines,
|
||||
CompleteMachines = stats.CompleteMachines,
|
||||
IncompleteMachines = stats.IncompleteMachines,
|
||||
TotalRoms = stats.TotalRoms,
|
||||
HaveRoms = stats.HaveRoms,
|
||||
MissRoms = stats.MissRoms,
|
||||
Category = romSet.Category
|
||||
});
|
||||
});
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
// Ignored
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
catch(Exception)
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
// Ignored
|
||||
}
|
||||
StatusMessage = Localization.SavingChangesToDatabase;
|
||||
ProgressVisible = true;
|
||||
IndeterminateProgress = true;
|
||||
});
|
||||
|
||||
pos++;
|
||||
}
|
||||
ctx.SaveChanges();
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
StatusMessage = Localization.SavingChangesToDatabase;
|
||||
ProgressVisible = true;
|
||||
IndeterminateProgress = true;
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
StatusMessage = Localization.Finished;
|
||||
ProgressVisible = false;
|
||||
CanClose = true;
|
||||
});
|
||||
});
|
||||
|
||||
ctx.SaveChanges();
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
StatusMessage = Localization.Finished;
|
||||
ProgressVisible = false;
|
||||
CanClose = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ExecuteCloseCommand() => _view.Close();
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,19 +38,14 @@
|
||||
x:Class="RomRepoMgr.Views.About"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}">
|
||||
Title="{x:Static resources:Localization.AboutTitle}">
|
||||
<Design.DataContext>
|
||||
<vm:AboutViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<Grid Grid.Row="0"
|
||||
ColumnDefinitions="Auto,*">
|
||||
<Border Grid.Column="0"
|
||||
BorderThickness="5">
|
||||
<Image Source="/Assets/avalonia-logo.ico"
|
||||
@@ -58,18 +54,16 @@
|
||||
</Border>
|
||||
<Grid Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
VerticalAlignment="Center"
|
||||
RowDefinitions="Auto,Auto">
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding SoftwareName}"
|
||||
Text="{Binding SoftwareName, Mode=OneWay}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="16"
|
||||
FontWeight="Bold" />
|
||||
<TextBlock Grid.Row="1"
|
||||
Text="{Binding VersionText}"
|
||||
Text="{Binding VersionText, Mode=OneWay}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
@@ -79,28 +73,22 @@
|
||||
VerticalAlignment="Stretch">
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="{Binding AboutLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.AboutLabel}" />
|
||||
</TabItem.Header>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="12" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="12" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,12,Auto,12,Auto,Auto,*">
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding SuiteName}" />
|
||||
Text="{Binding SuiteName, Mode=OneWay}" />
|
||||
<TextBlock Grid.Row="2"
|
||||
Text="{Binding Copyright}" />
|
||||
Text="{Binding Copyright, Mode=OneWay}" />
|
||||
<Button Grid.Row="4"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Padding="0"
|
||||
Command="{Binding WebsiteCommand}">
|
||||
Command="{Binding WebsiteCommand, Mode=OneWay}">
|
||||
<!-- TODO: TextDecorations="Underline" in next Avalonia UI version -->
|
||||
<TextBlock Text="{Binding Website}"
|
||||
<TextBlock Text="{Binding Website, Mode=OneWay}"
|
||||
Foreground="Blue" />
|
||||
</Button>
|
||||
<Button Grid.Row="5"
|
||||
@@ -109,32 +97,32 @@
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Padding="0"
|
||||
Command="{Binding LicenseCommand}">
|
||||
Command="{Binding LicenseCommand, Mode=OneWay}">
|
||||
<!-- TODO: TextDecorations="Underline" in next Avalonia UI version -->
|
||||
<TextBlock Text="{Binding License}"
|
||||
<TextBlock Text="{x:Static resources:Localization.LicenseLabel}"
|
||||
Foreground="Blue" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="{Binding LibrariesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.LibrariesLabel}" />
|
||||
</TabItem.Header>
|
||||
<DataGrid ItemsSource="{Binding Assemblies}"
|
||||
<DataGrid ItemsSource="{Binding Assemblies, Mode=OneWay}"
|
||||
HorizontalScrollBarVisibility="Visible">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Name}"
|
||||
<DataGridTextColumn Binding="{Binding Name, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding AssembliesLibraryText}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.AssembliesLibraryText}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Version}"
|
||||
<DataGridTextColumn Binding="{Binding Version, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding AssembliesVersionText}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.AssembliesVersionText}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
@@ -142,17 +130,17 @@
|
||||
</TabItem>
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="{Binding AuthorsLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.AuthorsLabel}" />
|
||||
</TabItem.Header>
|
||||
<TextBox IsReadOnly="True"
|
||||
Text="{Binding Authors}" />
|
||||
Text="{x:Static resources:Localization.AuthorsText}" />
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<Button Grid.Row="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,242 +38,207 @@
|
||||
x:Class="RomRepoMgr.Views.EditDat"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.EditDatTitle}"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Design.DataContext>
|
||||
<vm:EditDatViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
<Grid Grid.Row="0"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding NameLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetNameLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Name}"
|
||||
Text="{Binding Name, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="1"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding VersionLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetVersionLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Version}"
|
||||
Text="{Binding Version, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="2"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding AuthorLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetAuthorLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Author}"
|
||||
Text="{Binding Author, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="3"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding CategoryLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetCategoryLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Category}"
|
||||
Text="{Binding Category, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="4"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding CommentLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetCommentLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Comment}"
|
||||
Text="{Binding Comment, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="5"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding DateLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetDateLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Date}"
|
||||
Text="{Binding Date, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="6"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding DescriptionLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetDescriptionLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Description}"
|
||||
Text="{Binding Description, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="7">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="7"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding HomepageLabel}"
|
||||
Text="{x:Static resources:Localization.HomepageLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Homepage}"
|
||||
Text="{Binding Homepage, Mode=TwoWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="8"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding TotalMachinesLabel}"
|
||||
Text="{x:Static resources:Localization.TotalMachinesLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBlock Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding TotalMachines}"
|
||||
Text="{Binding TotalMachines, Mode=OneWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="9">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="9"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding CompleteMachinesLabel}"
|
||||
Text="{x:Static resources:Localization.CompleteMachinesLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBlock Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding CompleteMachines}"
|
||||
Text="{Binding CompleteMachines, Mode=OneWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="10"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding IncompleteMachinesLabel}"
|
||||
Text="{x:Static resources:Localization.IncompleteMachinesLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBlock Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding IncompleteMachines}"
|
||||
Text="{Binding IncompleteMachines, Mode=OneWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="11">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="11"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding TotalRomsLabel}"
|
||||
Text="{x:Static resources:Localization.TotalRomsLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBlock Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding TotalRoms}"
|
||||
Text="{Binding TotalRoms, Mode=OneWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="12"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding HaveRomsLabel}"
|
||||
Text="{x:Static resources:Localization.HaveRomsLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBlock Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding HaveRoms}"
|
||||
Text="{Binding HaveRoms, Mode=OneWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="13">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="140" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="13"
|
||||
ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding MissRomsLabel}"
|
||||
Text="{x:Static resources:Localization.MissRomsLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBlock Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding MissRoms}"
|
||||
Text="{Binding MissRoms, Mode=OneWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<StackPanel Grid.Row="14"
|
||||
@@ -280,21 +246,21 @@
|
||||
HorizontalAlignment="Right">
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding SaveCommand}"
|
||||
IsVisible="{Binding Modified}">
|
||||
<TextBlock Text="{Binding SaveLabel}" />
|
||||
Command="{Binding SaveCommand, Mode=OneWay}"
|
||||
IsVisible="{Binding Modified, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.SaveLabel}" />
|
||||
</Button>
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding CancelCommand}"
|
||||
IsVisible="{Binding Modified}">
|
||||
<TextBlock Text="{Binding CancelLabel}" />
|
||||
Command="{Binding CancelCommand, Mode=OneWay}"
|
||||
IsVisible="{Binding Modified, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CancelLabel}" />
|
||||
</Button>
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding CloseCommand}"
|
||||
IsVisible="{Binding !Modified}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
Command="{Binding CloseCommand, Mode=OneWay}"
|
||||
IsVisible="{Binding !Modified, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,35 +38,31 @@
|
||||
x:Class="RomRepoMgr.Views.ExportDat"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.ExportDatTitle}"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Design.DataContext>
|
||||
<vm:ExportDatViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,auto,Auto,Auto">
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding StatusMessage}"
|
||||
Text="{Binding StatusMessage, Mode=OneWay}"
|
||||
HorizontalAlignment="Center" />
|
||||
<ProgressBar Grid.Row="1"
|
||||
IsIndeterminate="True"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsVisible="{Binding ProgressVisible}" />
|
||||
IsVisible="{Binding ProgressVisible, Mode=OneWay}" />
|
||||
<TextBlock Grid.Row="2"
|
||||
Text="{Binding ErrorMessage}"
|
||||
Text="{Binding ErrorMessage, Mode=OneWay}"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="Red"
|
||||
IsVisible="{Binding ErrorVisible}" />
|
||||
IsVisible="{Binding ErrorVisible, Mode=OneWay}" />
|
||||
<Button Grid.Row="3"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanClose}"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
IsEnabled="{Binding CanClose, Mode=OneWay}"
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,57 +38,52 @@
|
||||
x:Class="RomRepoMgr.Views.ExportRoms"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.ExportRomsTitle}"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Design.DataContext>
|
||||
<vm:ExportRomsViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,*,Auto">
|
||||
<StackPanel Grid.Row="0"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="{Binding PathLabel}"
|
||||
<TextBlock Text="{x:Static resources:Localization.PathLabel}"
|
||||
FontWeight="Bold" />
|
||||
<TextBlock Text="{Binding FolderPath}" />
|
||||
<TextBlock Text="{Binding FolderPath, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Row="1"
|
||||
Text="{Binding StatusMessage}"
|
||||
Text="{Binding StatusMessage, Mode=OneWay}"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center" />
|
||||
<ProgressBar Grid.Row="2"
|
||||
Minimum="{Binding ProgressMinimum}"
|
||||
Maximum="{Binding ProgressMaximum}"
|
||||
Value="{Binding ProgressValue}"
|
||||
IsIndeterminate="{Binding ProgressIsIndeterminate}"
|
||||
IsVisible="{Binding ProgressVisible}" />
|
||||
Minimum="{Binding ProgressMinimum, Mode=OneWay}"
|
||||
Maximum="{Binding ProgressMaximum, Mode=OneWay}"
|
||||
Value="{Binding ProgressValue, Mode=OneWay}"
|
||||
IsIndeterminate="{Binding ProgressIsIndeterminate, Mode=OneWay}"
|
||||
IsVisible="{Binding ProgressVisible, Mode=OneWay}" />
|
||||
<StackPanel Grid.Row="3"
|
||||
IsVisible="{Binding Progress2Visible}">
|
||||
<TextBlock Text="{Binding Status2Message}" />
|
||||
<ProgressBar Minimum="{Binding Progress2Minimum}"
|
||||
Maximum="{Binding Progress2Maximum}"
|
||||
Value="{Binding Progress2Value}"
|
||||
IsIndeterminate="{Binding Progress2IsIndeterminate}" />
|
||||
IsVisible="{Binding Progress2Visible, Mode=OneWay}">
|
||||
<TextBlock Text="{Binding Status2Message, Mode=OneWay}" />
|
||||
<ProgressBar Minimum="{Binding Progress2Minimum, Mode=OneWay}"
|
||||
Maximum="{Binding Progress2Maximum, Mode=OneWay}"
|
||||
Value="{Binding Progress2Value, Mode=OneWay}"
|
||||
IsIndeterminate="{Binding Progress2IsIndeterminate, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="4"
|
||||
IsVisible="{Binding Progress3Visible}">
|
||||
<TextBlock Text="{Binding Status3Message}" />
|
||||
<ProgressBar Minimum="{Binding Progress3Minimum}"
|
||||
Maximum="{Binding Progress3Maximum}"
|
||||
Value="{Binding Progress3Value}"
|
||||
IsIndeterminate="{Binding Progress3IsIndeterminate}" />
|
||||
IsVisible="{Binding Progress3Visible, Mode=OneWay}">
|
||||
<TextBlock Text="{Binding Status3Message, Mode=OneWay}" />
|
||||
<ProgressBar Minimum="{Binding Progress3Minimum, Mode=OneWay}"
|
||||
Maximum="{Binding Progress3Maximum, Mode=OneWay}"
|
||||
Value="{Binding Progress3Value, Mode=OneWay}"
|
||||
IsIndeterminate="{Binding Progress3IsIndeterminate, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<Button Grid.Row="5"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanClose}"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
IsEnabled="{Binding CanClose, Mode=OneWay}"
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,38 +38,34 @@
|
||||
x:Class="RomRepoMgr.Views.ImportDat"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.ImportDatTitle}"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Design.DataContext>
|
||||
<vm:ImportDatViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,auto,Auto,Auto">
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding StatusMessage}"
|
||||
Text="{Binding StatusMessage, Mode=OneWay}"
|
||||
HorizontalAlignment="Center" />
|
||||
<ProgressBar Grid.Row="1"
|
||||
IsIndeterminate="{Binding IndeterminateProgress}"
|
||||
Maximum="{Binding MaximumValue}"
|
||||
Minimum="{Binding MinimumValue}"
|
||||
Value="{Binding CurrentValue}"
|
||||
IsIndeterminate="{Binding IndeterminateProgress, Mode=OneWay}"
|
||||
Maximum="{Binding MaximumValue, Mode=OneWay}"
|
||||
Minimum="{Binding MinimumValue, Mode=OneWay}"
|
||||
Value="{Binding CurrentValue, Mode=OneWay}"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsVisible="{Binding ProgressVisible}" />
|
||||
IsVisible="{Binding ProgressVisible, Mode=OneWay}" />
|
||||
<TextBlock Grid.Row="2"
|
||||
Text="{Binding ErrorMessage}"
|
||||
Text="{Binding ErrorMessage, Mode=OneWay}"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="Red"
|
||||
IsVisible="{Binding ErrorVisible}" />
|
||||
IsVisible="{Binding ErrorVisible, Mode=OneWay}" />
|
||||
<Button Grid.Row="3"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanClose}"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
IsEnabled="{Binding CanClose, Mode=OneWay}"
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,109 +38,102 @@
|
||||
x:Class="RomRepoMgr.Views.ImportDatFolder"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.ImportDatFolderTitle}"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Design.DataContext>
|
||||
<vm:ImportDatFolderViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,*,Auto">
|
||||
<StackPanel Grid.Row="0"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="{Binding PathLabel}"
|
||||
<TextBlock Text="{x:Static resources:Localization.PathLabel}"
|
||||
FontWeight="Bold" />
|
||||
<TextBlock Text="{Binding FolderPath}" />
|
||||
<TextBlock Text="{Binding FolderPath, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="1"
|
||||
ColumnDefinitions="Auto,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding CategoryLabel}"
|
||||
Text="{x:Static resources:Localization.RomSetCategoryLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Category}"
|
||||
Text="{Binding Category, Mode=OneWay}"
|
||||
Padding="5" />
|
||||
</Grid>
|
||||
<CheckBox Grid.Row="2"
|
||||
IsChecked="{Binding AllFilesChecked}"
|
||||
IsEnabled="{Binding IsReady}">
|
||||
IsChecked="{Binding AllFilesChecked, Mode=TwoWay}"
|
||||
IsEnabled="{Binding IsReady, Mode=OneWay}">
|
||||
<CheckBox.Content>
|
||||
<TextBlock Text="{Binding AllFilesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.AllFilesLabel}" />
|
||||
</CheckBox.Content>
|
||||
</CheckBox>
|
||||
<CheckBox Grid.Row="3"
|
||||
IsChecked="{Binding RecursiveChecked}"
|
||||
IsEnabled="{Binding IsReady}">
|
||||
IsChecked="{Binding RecursiveChecked, Mode=TwoWay}"
|
||||
IsEnabled="{Binding IsReady, Mode=OneWay}">
|
||||
<CheckBox.Content>
|
||||
<TextBlock Text="{Binding RecursiveLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RecursiveLabel}" />
|
||||
</CheckBox.Content>
|
||||
</CheckBox>
|
||||
<TextBlock Grid.Row="4"
|
||||
Text="{Binding StatusMessage}"
|
||||
Text="{Binding StatusMessage, Mode=OneWay}"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center" />
|
||||
<ProgressBar Grid.Row="5"
|
||||
Minimum="{Binding ProgressMinimum}"
|
||||
Maximum="{Binding ProgressMaximum}"
|
||||
Value="{Binding ProgressValue}"
|
||||
IsIndeterminate="{Binding ProgressIsIndeterminate}"
|
||||
IsVisible="{Binding ProgressVisible}" />
|
||||
Minimum="{Binding ProgressMinimum, Mode=OneWay}"
|
||||
Maximum="{Binding ProgressMaximum, Mode=OneWay}"
|
||||
Value="{Binding ProgressValue, Mode=OneWay}"
|
||||
IsIndeterminate="{Binding ProgressIsIndeterminate, Mode=OneWay}"
|
||||
IsVisible="{Binding ProgressVisible, Mode=OneWay}" />
|
||||
<StackPanel Grid.Row="6"
|
||||
IsVisible="{Binding Progress2Visible}">
|
||||
<TextBlock Text="{Binding Status2Message}" />
|
||||
<ProgressBar Minimum="{Binding Progress2Minimum}"
|
||||
Maximum="{Binding Progress2Maximum}"
|
||||
Value="{Binding Progress2Value}"
|
||||
IsIndeterminate="{Binding Progress2IsIndeterminate}" />
|
||||
IsVisible="{Binding Progress2Visible, Mode=OneWay}">
|
||||
<TextBlock Text="{Binding Status2Message, Mode=OneWay}" />
|
||||
<ProgressBar Minimum="{Binding Progress2Minimum, Mode=OneWay}"
|
||||
Maximum="{Binding Progress2Maximum, Mode=OneWay}"
|
||||
Value="{Binding Progress2Value, Mode=OneWay}"
|
||||
IsIndeterminate="{Binding Progress2IsIndeterminate, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<DataGrid Grid.Row="7"
|
||||
ItemsSource="{Binding ImportResults}"
|
||||
ItemsSource="{Binding ImportResults, Mode=OneWay}"
|
||||
HorizontalScrollBarVisibility="Visible"
|
||||
IsVisible="{Binding IsImporting}">
|
||||
IsVisible="{Binding IsImporting, Mode=OneWay}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Filename}"
|
||||
<DataGridTextColumn Binding="{Binding Filename, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding ResultFilenameLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ResultFilenameLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Status}"
|
||||
<DataGridTextColumn Binding="{Binding Status, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding ResultStatusLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ResultStatusLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<StackPanel Grid.Row="8"
|
||||
Orientation="Horizontal"
|
||||
IsVisible="{Binding IsReady}"
|
||||
IsVisible="{Binding IsReady, Mode=OneWay}"
|
||||
HorizontalAlignment="Right">
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanClose}"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
IsEnabled="{Binding CanClose, Mode=OneWay}"
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanStart}"
|
||||
Command="{Binding StartCommand}">
|
||||
<TextBlock Text="{Binding StartLabel}" />
|
||||
IsEnabled="{Binding CanStart, Mode=OneWay}"
|
||||
Command="{Binding StartCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.StartLabel}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,83 +38,78 @@
|
||||
x:Class="RomRepoMgr.Views.ImportRomFolder"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.ImportRomFolderTitle}"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Design.DataContext>
|
||||
<vm:ImportRomFolderViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,*,Auto">
|
||||
<StackPanel Grid.Row="0"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="{Binding PathLabel}"
|
||||
<TextBlock Text="{x:Static resources:Localization.PathLabel}"
|
||||
FontWeight="Bold" />
|
||||
<TextBlock Text="{Binding FolderPath}" />
|
||||
<TextBlock Text="{Binding FolderPath, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<CheckBox Grid.Row="1"
|
||||
IsChecked="{Binding RemoveFilesChecked}"
|
||||
IsEnabled="{Binding RemoveFilesEnabled}"
|
||||
IsVisible="{Binding IsReady}">
|
||||
IsChecked="{Binding RemoveFilesChecked, Mode=TwoWay}"
|
||||
IsEnabled="{Binding RemoveFilesEnabled, Mode=OneWay}"
|
||||
IsVisible="{Binding IsReady, Mode=OneWay}">
|
||||
<CheckBox.Content>
|
||||
<TextBlock Text="{Binding RemoveFilesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RemoveFilesLabel}" />
|
||||
</CheckBox.Content>
|
||||
</CheckBox>
|
||||
<CheckBox Grid.Row="2"
|
||||
IsChecked="{Binding KnownOnlyChecked}"
|
||||
IsVisible="{Binding IsReady}">
|
||||
IsChecked="{Binding KnownOnlyChecked, Mode=TwoWay}"
|
||||
IsVisible="{Binding IsReady, Mode=OneWay}">
|
||||
<CheckBox.Content>
|
||||
<TextBlock Text="{Binding KnownOnlyLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.KnownOnlyLabel}" />
|
||||
</CheckBox.Content>
|
||||
</CheckBox>
|
||||
<CheckBox Grid.Row="3"
|
||||
IsChecked="{Binding RecurseArchivesChecked}"
|
||||
IsEnabled="{Binding RecurseArchivesEnabled}"
|
||||
IsVisible="{Binding IsReady}">
|
||||
IsChecked="{Binding RecurseArchivesChecked, Mode=TwoWay}"
|
||||
IsEnabled="{Binding RecurseArchivesEnabled, Mode=OneWay}"
|
||||
IsVisible="{Binding IsReady, Mode=OneWay}">
|
||||
<CheckBox.Content>
|
||||
<TextBlock Text="{Binding RecurseArchivesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RecurseArchivesLabel}" />
|
||||
</CheckBox.Content>
|
||||
</CheckBox>
|
||||
<TextBlock Grid.Row="4"
|
||||
Text="{Binding StatusMessage}"
|
||||
Text="{Binding StatusMessage, Mode=OneWay}"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center" />
|
||||
<ProgressBar Grid.Row="5"
|
||||
Minimum="{Binding ProgressMinimum}"
|
||||
Maximum="{Binding ProgressMaximum}"
|
||||
Value="{Binding ProgressValue}"
|
||||
IsIndeterminate="{Binding ProgressIsIndeterminate}"
|
||||
IsVisible="{Binding ProgressVisible}" />
|
||||
Minimum="{Binding ProgressMinimum, Mode=OneWay}"
|
||||
Maximum="{Binding ProgressMaximum, Mode=OneWay}"
|
||||
Value="{Binding ProgressValue, Mode=OneWay}"
|
||||
IsIndeterminate="{Binding ProgressIsIndeterminate, Mode=OneWay}"
|
||||
IsVisible="{Binding ProgressVisible, Mode=OneWay}" />
|
||||
<StackPanel Grid.Row="6"
|
||||
IsVisible="{Binding Progress2Visible}">
|
||||
<TextBlock Text="{Binding Status2Message}" />
|
||||
<ProgressBar Minimum="{Binding Progress2Minimum}"
|
||||
Maximum="{Binding Progress2Maximum}"
|
||||
Value="{Binding Progress2Value}"
|
||||
IsIndeterminate="{Binding Progress2IsIndeterminate}" />
|
||||
IsVisible="{Binding Progress2Visible, Mode=OneWay}">
|
||||
<TextBlock Text="{Binding Status2Message, Mode=OneWay}" />
|
||||
<ProgressBar Minimum="{Binding Progress2Minimum, Mode=OneWay}"
|
||||
Maximum="{Binding Progress2Maximum, Mode=OneWay}"
|
||||
Value="{Binding Progress2Value, Mode=OneWay}"
|
||||
IsIndeterminate="{Binding Progress2IsIndeterminate, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<DataGrid Grid.Row="7"
|
||||
ItemsSource="{Binding ImportResults}"
|
||||
ItemsSource="{Binding ImportResults, Mode=OneWay}"
|
||||
HorizontalScrollBarVisibility="Visible"
|
||||
IsVisible="{Binding IsImporting}">
|
||||
IsVisible="{Binding IsImporting, Mode=OneWay}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Filename}"
|
||||
<DataGridTextColumn Binding="{Binding Filename, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding ResultFilenameLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ResultFilenameLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Status}"
|
||||
<DataGridTextColumn Binding="{Binding Status, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding ResultStatusLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ResultStatusLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
@@ -123,15 +119,15 @@
|
||||
HorizontalAlignment="Right">
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanClose}"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
IsEnabled="{Binding CanClose, Mode=OneWay}"
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanStart}"
|
||||
Command="{Binding StartCommand}">
|
||||
<TextBlock Text="{Binding StartLabel}" />
|
||||
IsEnabled="{Binding CanStart, Mode=OneWay}"
|
||||
Command="{Binding StartCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.StartLabel}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -14,172 +15,171 @@
|
||||
</Design.DataContext>
|
||||
<DockPanel>
|
||||
<Menu DockPanel.Dock="Top">
|
||||
<MenuItem Header="{Binding FileMenuText}">
|
||||
<MenuItem Header="{Binding FileMenuImportDatFileText}"
|
||||
Command="{Binding ImportDatCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.FileMenuText}">
|
||||
<MenuItem Header="{x:Static resources:Localization.FileMenuImportDatFileText}"
|
||||
Command="{Binding ImportDatCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
<MenuItem Header="{Binding FileMenuImportDatFolderText}"
|
||||
Command="{Binding ImportDatFolderCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.FileMenuImportDatFolderText}"
|
||||
Command="{Binding ImportDatFolderCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
<MenuItem Header="{Binding FileMenuSettingsText}"
|
||||
IsVisible="{Binding !NativeMenuSupported}"
|
||||
Command="{Binding SettingsCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.FileMenuSettingsText}"
|
||||
IsVisible="{Binding !NativeMenuSupported, Mode=OneWay}"
|
||||
Command="{Binding SettingsCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
<MenuItem Header="{Binding FileMenuExitText}"
|
||||
IsVisible="{Binding !NativeMenuSupported}"
|
||||
Command="{Binding ExitCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.FileMenuExitText}"
|
||||
IsVisible="{Binding !NativeMenuSupported, Mode=OneWay}"
|
||||
Command="{Binding ExitCommand, Mode=OneWay}" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="{Binding FilesystemMenuText}"
|
||||
IsEnabled="{Binding IsVfsAvailable}">
|
||||
<MenuItem Header="{Binding FilesystemMenuMountText}"
|
||||
Command="{Binding MountCommand}"
|
||||
IsEnabled="{Binding Vfs, Converter={x:Static ObjectConverters.IsNull}}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.FilesystemMenuText}">
|
||||
<MenuItem Header="{x:Static resources:Localization.FilesystemMenuMountText}"
|
||||
Command="{Binding MountCommand, Mode=OneWay}"
|
||||
IsEnabled="{Binding Vfs, Converter={x:Static ObjectConverters.IsNull}, Mode=OneWay}" />
|
||||
<Separator />
|
||||
<MenuItem Header="{Binding FilesystemMenuUmountText}"
|
||||
Command="{Binding UmountCommand}"
|
||||
IsEnabled="{Binding Vfs, Converter={x:Static ObjectConverters.IsNotNull}}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.FilesystemMenuUmountText}"
|
||||
Command="{Binding UmountCommand, Mode=OneWay}"
|
||||
IsEnabled="{Binding Vfs, Converter={x:Static ObjectConverters.IsNotNull}, Mode=OneWay}" />
|
||||
<Separator />
|
||||
</MenuItem>
|
||||
<MenuItem Header="{Binding RomsMenuText}">
|
||||
<MenuItem Header="{Binding RomsMenuImportText}"
|
||||
Command="{Binding ImportRomFolderCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.RomsMenuText}">
|
||||
<MenuItem Header="{x:Static resources:Localization.RomsMenuImportText}"
|
||||
Command="{Binding ImportRomFolderCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
</MenuItem>
|
||||
<MenuItem Header="{Binding RomSetsMenuText}"
|
||||
IsEnabled="{Binding SelectedRomSet, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||
<MenuItem Header="{Binding RomSetsMenuSaveRomsText}"
|
||||
Command="{Binding ExportRomsCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.RomSetsMenuText}"
|
||||
IsEnabled="{Binding SelectedRomSet, Converter={x:Static ObjectConverters.IsNotNull}, Mode=OneWay}">
|
||||
<MenuItem Header="{x:Static resources:Localization.RomSetsMenuSaveRomsText}"
|
||||
Command="{Binding ExportRomsCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
<MenuItem Header="{Binding RomSetsMenuSaveDatText}"
|
||||
Command="{Binding ExportDatCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.RomSetsMenuSaveDatText}"
|
||||
Command="{Binding ExportDatCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
<MenuItem Header="{Binding RomSetsMenuEditText}"
|
||||
Command="{Binding EditRomSetCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.RomSetsMenuEditText}"
|
||||
Command="{Binding EditRomSetCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
<MenuItem Header="{Binding RomSetsMenuDeleteText}"
|
||||
Command="{Binding DeleteRomSetCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.RomSetsMenuDeleteText}"
|
||||
Command="{Binding DeleteRomSetCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
</MenuItem>
|
||||
<MenuItem Header="{Binding DatabaseMenuText}">
|
||||
<MenuItem Header="{Binding DatabaseMenuUpdateStatsText}"
|
||||
Command="{Binding UpdateStatsCommand}" />
|
||||
<MenuItem Header="{x:Static resources:Localization.DatabaseMenuText}">
|
||||
<MenuItem Header="{x:Static resources:Localization.DatabaseMenuUpdateStatsText}"
|
||||
Command="{Binding UpdateStatsCommand, Mode=OneWay}" />
|
||||
<Separator />
|
||||
</MenuItem>
|
||||
<MenuItem Header="{Binding HelpMenuText}">
|
||||
<MenuItem Header="{Binding HelpMenuAboutText}"
|
||||
<MenuItem Header="{x:Static resources:Localization.HelpMenuText}">
|
||||
<MenuItem Header="{x:Static resources:Localization.HelpMenuAboutText}"
|
||||
Name="AboutMenuItem"
|
||||
IsVisible="{Binding !NativeMenuSupported}"
|
||||
Command="{Binding AboutCommand}" />
|
||||
IsVisible="{Binding !NativeMenuSupported, Mode=OneWay}"
|
||||
Command="{Binding AboutCommand, Mode=OneWay}" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<TabControl HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<TabItem>
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="{Binding RomSetLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSets}" />
|
||||
</TabItem.Header>
|
||||
<DataGrid ItemsSource="{Binding RomSets}"
|
||||
<DataGrid ItemsSource="{Binding RomSets, Mode=OneWay}"
|
||||
HorizontalScrollBarVisibility="Visible"
|
||||
SelectedItem="{Binding SelectedRomSet, Mode=TwoWay}"
|
||||
CanUserSortColumns="True"
|
||||
CanUserResizeColumns="True">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Name}"
|
||||
<DataGridTextColumn Binding="{Binding Name, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetNameLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetNameLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Version}"
|
||||
<DataGridTextColumn Binding="{Binding Version, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetVersionLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetVersionLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Author}"
|
||||
<DataGridTextColumn Binding="{Binding Author, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetAuthorLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetAuthorLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Category}"
|
||||
<DataGridTextColumn Binding="{Binding Category, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetCategoryLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetCategoryLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Date}"
|
||||
<DataGridTextColumn Binding="{Binding Date, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetDateLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetDateLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Description}"
|
||||
<DataGridTextColumn Binding="{Binding Description, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetDescriptionLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetDescriptionLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Comment}"
|
||||
<DataGridTextColumn Binding="{Binding Comment, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetCommentLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetCommentLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Homepage}"
|
||||
<DataGridTextColumn Binding="{Binding Homepage, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetHomepageLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.HomepageLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding TotalMachines}"
|
||||
<DataGridTextColumn Binding="{Binding TotalMachines, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetTotalMachinesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetTotalMachinesLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding CompleteMachines}"
|
||||
<DataGridTextColumn Binding="{Binding CompleteMachines, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetCompleteMachinesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetCompleteMachinesLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding IncompleteMachines}"
|
||||
<DataGridTextColumn Binding="{Binding IncompleteMachines, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetIncompleteMachinesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetIncompleteMachinesLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding TotalRoms}"
|
||||
<DataGridTextColumn Binding="{Binding TotalRoms, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetTotalRomsLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetTotalRomsLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding HaveRoms}"
|
||||
<DataGridTextColumn Binding="{Binding HaveRoms, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetHaveRomsLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetHaveRomsLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding MissRoms}"
|
||||
<DataGridTextColumn Binding="{Binding MissRoms, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetMissRomsLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetMissRomsLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,18 +38,15 @@
|
||||
x:Class="RomRepoMgr.Views.RemoveDat"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.RemoveDatTitle}"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Design.DataContext>
|
||||
<vm:RemoveDatViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,auto">
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding StatusMessage}"
|
||||
Text="{Binding StatusMessage, Mode=OneWay}"
|
||||
HorizontalAlignment="Center" />
|
||||
<ProgressBar Grid.Row="1"
|
||||
IsIndeterminate="True"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
@@ -37,129 +38,117 @@
|
||||
x:Class="RomRepoMgr.Views.SettingsDialog"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}">
|
||||
Title="{x:Static resources:Localization.SettingsTitle}">
|
||||
<Design.DataContext>
|
||||
<vm:SettingsViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" /> <ColumnDefinition Width="250" /> <ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
<Grid Grid.Row="0"
|
||||
ColumnDefinitions="*,250,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding DatabaseLabel}"
|
||||
Text="{x:Static resources:Localization.DatabaseFileLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding DatabasePath}"
|
||||
Text="{Binding DatabasePath, Mode=TwoWay}"
|
||||
IsReadOnly="True"
|
||||
Padding="5" />
|
||||
<Button Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding DatabaseCommand}"
|
||||
Command="{Binding DatabaseCommand, Mode=OneWay}"
|
||||
Padding="5">
|
||||
<TextBlock Text="{Binding ChooseLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ChooseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" /> <ColumnDefinition Width="250" /> <ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="1"
|
||||
ColumnDefinitions="*,250,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding RepositoryLabel}"
|
||||
Text="{x:Static resources:Localization.RepositoryFolderLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding RepositoryPath}"
|
||||
Text="{Binding RepositoryPath, Mode=TwoWay}"
|
||||
IsReadOnly="True"
|
||||
Padding="5" />
|
||||
<Button Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding RepositoryCommand}"
|
||||
Command="{Binding RepositoryCommand, Mode=OneWay}"
|
||||
Padding="5">
|
||||
<TextBlock Text="{Binding ChooseLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ChooseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" /> <ColumnDefinition Width="250" /> <ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="2"
|
||||
ColumnDefinitions="*,250,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding TemporaryLabel}"
|
||||
Text="{x:Static resources:Localization.TemporaryFolderLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding TemporaryPath}"
|
||||
Text="{Binding TemporaryPath, Mode=TwoWay}"
|
||||
IsReadOnly="True"
|
||||
Padding="5" />
|
||||
<Button Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding TemporaryCommand}"
|
||||
Command="{Binding TemporaryCommand, Mode=OneWay}"
|
||||
Padding="5">
|
||||
<TextBlock Text="{Binding ChooseLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ChooseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid Grid.Row="3">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" /> <ColumnDefinition Width="250" /> <ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Row="3"
|
||||
ColumnDefinitions="*,250,Auto">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding UnArPathLabel}"
|
||||
Text="{x:Static resources:Localization.UnArPathLabel}"
|
||||
FontWeight="Bold"
|
||||
Padding="5" />
|
||||
<TextBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding UnArPath}"
|
||||
Text="{Binding UnArPath, Mode=TwoWay}"
|
||||
IsReadOnly="True"
|
||||
Padding="5" />
|
||||
<Button Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding UnArCommand}"
|
||||
Command="{Binding UnArCommand, Mode=OneWay}"
|
||||
Padding="5">
|
||||
<TextBlock Text="{Binding ChooseLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ChooseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
<TextBlock Grid.Row="4"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding UnArVersion}"
|
||||
Text="{Binding UnArVersion, Mode=OneWay}"
|
||||
FontWeight="Bold" />
|
||||
<StackPanel Grid.Row="5"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding SaveCommand}">
|
||||
<TextBlock Text="{Binding SaveLabel}" />
|
||||
Command="{Binding SaveCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.SaveLabel}" />
|
||||
</Button>
|
||||
<Button HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:svg="clr-namespace:Avalonia.Svg.Skia;assembly=Avalonia.Svg.Skia"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="450"
|
||||
d:DesignHeight="250"
|
||||
@@ -22,7 +23,7 @@
|
||||
VerticalAlignment="Top"
|
||||
Orientation="Vertical"
|
||||
Margin="5">
|
||||
<TextBlock Text="{Binding LoadingText}"
|
||||
<TextBlock Text="{Binding LoadingText, Mode=OneWay}"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top" />
|
||||
@@ -30,136 +31,136 @@
|
||||
Orientation="Horizontal">
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingSettingsOk}">
|
||||
IsVisible="{Binding LoadingSettingsOk, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-checked.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingSettingsError}">
|
||||
IsVisible="{Binding LoadingSettingsError, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-error.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingSettingsUnknown}">
|
||||
IsVisible="{Binding LoadingSettingsUnknown, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-question.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="{Binding LoadingSettingsText}"
|
||||
<TextBlock Text="{x:Static resources:Localization.LoadingSettingsText}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Left"
|
||||
Orientation="Horizontal">
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding CheckingUnArOk}">
|
||||
IsVisible="{Binding CheckingUnArOk, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-checked.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding CheckingUnArError}">
|
||||
IsVisible="{Binding CheckingUnArError, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-error.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding CheckingUnArUnknown}">
|
||||
IsVisible="{Binding CheckingUnArUnknown, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-question.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="{Binding CheckingUnArText}"
|
||||
<TextBlock Text="{x:Static resources:Localization.CheckingUnArText}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Left"
|
||||
Orientation="Horizontal">
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingDatabaseOk}">
|
||||
IsVisible="{Binding LoadingDatabaseOk, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-checked.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingDatabaseError}">
|
||||
IsVisible="{Binding LoadingDatabaseError, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-error.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingDatabaseUnknown}">
|
||||
IsVisible="{Binding LoadingDatabaseUnknown, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-question.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="{Binding LoadingDatabaseText}"
|
||||
<TextBlock Text="{x:Static resources:Localization.LoadingDatabaseText}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Left"
|
||||
Orientation="Horizontal">
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding MigratingDatabaseOk}">
|
||||
IsVisible="{Binding MigratingDatabaseOk, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-checked.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding MigratingDatabaseError}">
|
||||
IsVisible="{Binding MigratingDatabaseError, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-error.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding MigratingDatabaseUnknown}">
|
||||
IsVisible="{Binding MigratingDatabaseUnknown, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-question.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="{Binding MigratingDatabaseText}"
|
||||
<TextBlock Text="{x:Static resources:Localization.MigratingDatabaseText}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Left"
|
||||
Orientation="Horizontal">
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingRomSetsOk}">
|
||||
IsVisible="{Binding LoadingRomSetsOk, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-checked.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingRomSetsError}">
|
||||
IsVisible="{Binding LoadingRomSetsError, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-error.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Image MaxWidth="24"
|
||||
MaxHeight="24"
|
||||
IsVisible="{Binding LoadingRomSetsUnknown}">
|
||||
IsVisible="{Binding LoadingRomSetsUnknown, Mode=OneWay}">
|
||||
<Image.Source>
|
||||
<svg:SvgImage Source="/Assets/emblem-question.svg" />
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="{Binding LoadingRomSetsText}"
|
||||
<TextBlock Text="{x:Static resources:Localization.LoadingRomSetsText}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<Button Command="{Binding ExitCommand}"
|
||||
IsVisible="{Binding ExitVisible}"
|
||||
HorizontalAlignment="Right">
|
||||
<TextBlock Text="{Binding ExitButtonText}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.ExitButtonText}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
@@ -29,136 +29,133 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:RomRepoMgr.ViewModels;assembly=RomRepoMgr"
|
||||
xmlns:resources="clr-namespace:RomRepoMgr.Resources"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="800"
|
||||
d:DesignHeight="450"
|
||||
x:Class="RomRepoMgr.Views.UpdateStats"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
CanResize="False"
|
||||
Title="{Binding Title}"
|
||||
Title="{x:Static resources:Localization.UpdateStatsTitle}"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Design.DataContext>
|
||||
<vm:UpdateStatsViewModel />
|
||||
</Design.DataContext>
|
||||
<Border Padding="15">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid RowDefinitions="Auto,Auto,*,Auto">
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="{Binding StatusMessage}"
|
||||
Text="{Binding StatusMessage, Mode=OneWay}"
|
||||
HorizontalAlignment="Center" />
|
||||
<ProgressBar Grid.Row="1"
|
||||
IsIndeterminate="{Binding IndeterminateProgress}"
|
||||
Maximum="{Binding MaximumValue}"
|
||||
Minimum="{Binding MinimumValue}"
|
||||
Value="{Binding CurrentValue}"
|
||||
IsIndeterminate="{Binding IndeterminateProgress, Mode=OneWay}"
|
||||
Maximum="{Binding MaximumValue, Mode=OneWay}"
|
||||
Minimum="{Binding MinimumValue, Mode=OneWay}"
|
||||
Value="{Binding CurrentValue, Mode=OneWay}"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsVisible="{Binding ProgressVisible}" />
|
||||
IsVisible="{Binding ProgressVisible, Mode=OneWay}" />
|
||||
<DataGrid Grid.Row="2"
|
||||
ItemsSource="{Binding RomSets}"
|
||||
ItemsSource="{Binding RomSets, Mode=OneWay}"
|
||||
HorizontalScrollBarVisibility="Visible"
|
||||
SelectedItem="{Binding SelectedRomSet, Mode=TwoWay}"
|
||||
CanUserSortColumns="True"
|
||||
CanUserResizeColumns="True">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Name}"
|
||||
<DataGridTextColumn Binding="{Binding Name, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetNameLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetNameLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Version}"
|
||||
<DataGridTextColumn Binding="{Binding Version, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetVersionLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetVersionLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Author}"
|
||||
<DataGridTextColumn Binding="{Binding Author, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetAuthorLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetAuthorLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Category}"
|
||||
<DataGridTextColumn Binding="{Binding Category, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetCategoryLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetCategoryLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Date}"
|
||||
<DataGridTextColumn Binding="{Binding Date, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetDateLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetDateLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Description}"
|
||||
<DataGridTextColumn Binding="{Binding Description, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetDescriptionLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetDescriptionLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Comment}"
|
||||
<DataGridTextColumn Binding="{Binding Comment, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetCommentLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetCommentLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding Homepage}"
|
||||
<DataGridTextColumn Binding="{Binding Homepage, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetHomepageLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.HomepageLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding TotalMachines}"
|
||||
<DataGridTextColumn Binding="{Binding TotalMachines, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetTotalMachinesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetTotalMachinesLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding CompleteMachines}"
|
||||
<DataGridTextColumn Binding="{Binding CompleteMachines, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetCompleteMachinesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetCompleteMachinesLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding IncompleteMachines}"
|
||||
<DataGridTextColumn Binding="{Binding IncompleteMachines, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetIncompleteMachinesLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetIncompleteMachinesLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding TotalRoms}"
|
||||
<DataGridTextColumn Binding="{Binding TotalRoms, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetTotalRomsLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetTotalRomsLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding HaveRoms}"
|
||||
<DataGridTextColumn Binding="{Binding HaveRoms, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetHaveRomsLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetHaveRomsLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Binding="{Binding MissRoms}"
|
||||
<DataGridTextColumn Binding="{Binding MissRoms, Mode=OneWay}"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<DataGridTextColumn.Header>
|
||||
<TextBlock Text="{Binding RomSetMissRomsLabel}" />
|
||||
<TextBlock Text="{x:Static resources:Localization.RomSetMissRomsLabel}" />
|
||||
</DataGridTextColumn.Header>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
@@ -166,9 +163,9 @@
|
||||
<Button Grid.Row="3"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsEnabled="{Binding CanClose}"
|
||||
Command="{Binding CloseCommand}">
|
||||
<TextBlock Text="{Binding CloseLabel}" />
|
||||
IsEnabled="{Binding CanClose, Mode=OneWay}"
|
||||
Command="{Binding CloseCommand, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Static resources:Localization.CloseLabel}" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
Reference in New Issue
Block a user