File scoped namespace

This commit is contained in:
2022-05-07 19:40:54 +02:00
parent b161ded92e
commit 9bf95ebe4e
126 changed files with 2562 additions and 2598 deletions

View File

@@ -1,54 +1,53 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public enum ComparisonCondition
{
public enum ComparisonCondition
Equal,
GreaterThan,
LessThan,
LessThanOrEqual,
NotEqual,
GreaterThanOrEqual
}
public class CompareConverter : IValueConverter
{
public ComparisonCondition ComparisonCondition { get; set; } = ComparisonCondition.Equal;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
Equal,
GreaterThan,
LessThan,
LessThanOrEqual,
NotEqual,
GreaterThanOrEqual
return Compare(value, parameter);
}
public class CompareConverter : IValueConverter
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
public ComparisonCondition ComparisonCondition { get; set; } = ComparisonCondition.Equal;
throw new NotImplementedException();
}
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
private bool Compare(object? value, object? parameter)
{
if (ComparisonCondition == ComparisonCondition.GreaterThan)
{
return Compare(value, parameter);
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt > parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble > parameterDouble;
else throw new NotSupportedException();
}
else if (ComparisonCondition == ComparisonCondition.NotEqual)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt != parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble != parameterDouble;
return value != parameter;
}
else if (ComparisonCondition == ComparisonCondition.Equal)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt == parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble == parameterDouble;
else if (value?.GetType().IsEnum ?? false && Enum.TryParse(value.GetType(), parameter?.ToString(), out var _)) return value.ToString() == parameter?.ToString();
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private bool Compare(object? value, object? parameter)
{
if (ComparisonCondition == ComparisonCondition.GreaterThan)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt > parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble > parameterDouble;
else throw new NotSupportedException();
}
else if (ComparisonCondition == ComparisonCondition.NotEqual)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt != parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble != parameterDouble;
return value != parameter;
}
else if (ComparisonCondition == ComparisonCondition.Equal)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt == parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble == parameterDouble;
else if (value?.GetType().IsEnum ?? false && Enum.TryParse(value.GetType(), parameter?.ToString(), out var _)) return value.ToString() == parameter?.ToString();
}
return value == parameter;
}
return value == parameter;
}
}

View File

@@ -1,18 +1,17 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace FileTime.GuiApp.Converters
{
public class DateTimeConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
value is DateTime dateTime && parameter is string parameterS
? dateTime.ToString(parameterS)
: value;
namespace FileTime.GuiApp.Converters;
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public class DateTimeConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
value is DateTime dateTime && parameter is string parameterS
? dateTime.ToString(parameterS)
: value;
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -1,45 +1,44 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public class ExceptionToStringConverter : IValueConverter
{
public class ExceptionToStringConverter : IValueConverter
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
if (value is not Exception e) return value;
if (e is UnauthorizedAccessException)
{
if (value is not Exception e) return value;
if (e is UnauthorizedAccessException)
{
return e.Message;
}
else if (e.InnerException != null)
{
return TraverseInnerException(e);
}
return FormatException(e);
return e.Message;
}
else if (e.InnerException != null)
{
return TraverseInnerException(e);
}
private static string TraverseInnerException(Exception e)
{
string s = "";
if (e.InnerException != null) s += TraverseInnerException(e.InnerException) + Environment.NewLine;
else return FormatException(e);
return FormatException(e);
}
s += "In: " + FormatException(e);
private static string TraverseInnerException(Exception e)
{
string s = "";
if (e.InnerException != null) s += TraverseInnerException(e.InnerException) + Environment.NewLine;
else return FormatException(e);
return s;
}
s += "In: " + FormatException(e);
private static string FormatException(Exception e)
{
return $"{e.Message} ({e.GetType().FullName})";
}
return s;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private static string FormatException(Exception e)
{
return $"{e.Message} ({e.GetType().FullName})";
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -1,47 +1,46 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public class FormatSizeConverter : IValueConverter
{
public class FormatSizeConverter : IValueConverter
private const long OneKiloByte = 1024;
private const long OneMegaByte = OneKiloByte * 1024;
private const long OneGigaByte = OneMegaByte * 1024;
private const long OneTerraByte = OneGigaByte * 1024;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
private const long OneKiloByte = 1024;
private const long OneMegaByte = OneKiloByte * 1024;
private const long OneGigaByte = OneMegaByte * 1024;
private const long OneTerraByte = OneGigaByte * 1024;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
return (value, int.TryParse(parameter?.ToString(), out var prec)) switch
{
return (value, int.TryParse(parameter?.ToString(), out var prec)) switch
{
(long size, true) => ToSizeString(size, prec),
(long size, false) => ToSizeString(size),
(null, _) => "...",
_ => value
};
}
(long size, true) => ToSizeString(size, prec),
(long size, false) => ToSizeString(size),
(null, _) => "...",
_ => value
};
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public static string ToSizeString(long fileSize, int precision = 1)
{
var fileSizeD = (decimal)fileSize;
var (size, suffix) = fileSize switch
{
throw new NotImplementedException();
}
> OneTerraByte => (fileSizeD / OneTerraByte, "T"),
> OneGigaByte => (fileSizeD / OneGigaByte, "G"),
> OneMegaByte => (fileSizeD / OneMegaByte, "M"),
> OneKiloByte => (fileSizeD / OneKiloByte, "K"),
_ => (fileSizeD, "B")
};
public static string ToSizeString(long fileSize, int precision = 1)
{
var fileSizeD = (decimal)fileSize;
var (size, suffix) = fileSize switch
{
> OneTerraByte => (fileSizeD / OneTerraByte, "T"),
> OneGigaByte => (fileSizeD / OneGigaByte, "G"),
> OneMegaByte => (fileSizeD / OneMegaByte, "M"),
> OneKiloByte => (fileSizeD / OneKiloByte, "K"),
_ => (fileSizeD, "B")
};
var result = string.Format("{0:N" + precision + "}", size).Replace(',', '.');
var result = string.Format("{0:N" + precision + "}", size).Replace(',', '.');
if (result.Contains('.')) result = result.TrimEnd('0').TrimEnd('.');
return result + " " + suffix;
}
if (result.Contains('.')) result = result.TrimEnd('0').TrimEnd('.');
return result + " " + suffix;
}
}

View File

@@ -3,22 +3,21 @@ using Avalonia.Data.Converters;
using FileTime.App.Core.Services;
using Microsoft.Extensions.DependencyInjection;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public class GetFileExtensionConverter : IValueConverter
{
public class GetFileExtensionConverter : IValueConverter
private IItemNameConverterService? _itemNameConverterService;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
private IItemNameConverterService? _itemNameConverterService;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not string fullName) return value;
_itemNameConverterService ??= DI.ServiceProvider.GetRequiredService<IItemNameConverterService>();
if (value is not string fullName) return value;
_itemNameConverterService ??= DI.ServiceProvider.GetRequiredService<IItemNameConverterService>();
return _itemNameConverterService.GetFileExtension(fullName);
}
return _itemNameConverterService.GetFileExtension(fullName);
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -3,39 +3,38 @@ using Avalonia.Data.Converters;
using Avalonia.Media;
using FileTime.App.Core.Models.Enums;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public class ItemViewModeToBrushConverter : IValueConverter
{
public class ItemViewModeToBrushConverter : IValueConverter
public Brush? DefaultBrush { get; set; }
public Brush? AlternativeBrush { get; set; }
public Brush? SelectedBrush { get; set; }
public Brush? MarkedBrush { get; set; }
public Brush? MarkedSelectedBrush { get; set; }
public Brush? MarkedAlternativeBrush { get; set; }
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
public Brush? DefaultBrush { get; set; }
public Brush? AlternativeBrush { get; set; }
public Brush? SelectedBrush { get; set; }
public Brush? MarkedBrush { get; set; }
public Brush? MarkedSelectedBrush { get; set; }
public Brush? MarkedAlternativeBrush { get; set; }
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
if (value is ItemViewMode viewMode)
{
if (value is ItemViewMode viewMode)
return viewMode switch
{
return viewMode switch
{
ItemViewMode.Default => DefaultBrush,
ItemViewMode.Alternative => AlternativeBrush,
ItemViewMode.Selected => SelectedBrush,
ItemViewMode.Marked => MarkedBrush,
ItemViewMode.MarkedSelected => MarkedSelectedBrush,
ItemViewMode.MarkedAlternative => MarkedAlternativeBrush,
_ => throw new NotImplementedException()
};
}
return value;
ItemViewMode.Default => DefaultBrush,
ItemViewMode.Alternative => AlternativeBrush,
ItemViewMode.Selected => SelectedBrush,
ItemViewMode.Marked => MarkedBrush,
ItemViewMode.MarkedSelected => MarkedSelectedBrush,
ItemViewMode.MarkedAlternative => MarkedAlternativeBrush,
_ => throw new NotImplementedException()
};
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
return value;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -3,35 +3,34 @@ using Avalonia.Data.Converters;
using FileTime.App.Core.Models.Enums;
using FileTime.App.Core.ViewModels;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public class ItemViewModelIsAttributeTypeConverter : IValueConverter
{
public class ItemViewModelIsAttributeTypeConverter : IValueConverter
public bool Invert { get; set; }
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
public bool Invert { get; set; }
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
var attributeType = GetAttributeType(value);
if (parameter == null) return attributeType;
var result = parameter is ItemAttributeType targetAttribute && attributeType == targetAttribute;
if (Invert && parameter is ItemAttributeType) result = !result;
return result;
}
var attributeType = GetAttributeType(value);
if (parameter == null) return attributeType;
var result = parameter is ItemAttributeType targetAttribute && attributeType == targetAttribute;
if (Invert && parameter is ItemAttributeType) result = !result;
return result;
}
private static ItemAttributeType? GetAttributeType(object? value)
private static ItemAttributeType? GetAttributeType(object? value)
{
return value switch
{
return value switch
{
IFileViewModel => ItemAttributeType.File,
IContainerSizeContainerViewModel => ItemAttributeType.SizeContainer,
IElementViewModel => ItemAttributeType.Element,
IContainerViewModel => ItemAttributeType.Container,
_ => null
};
}
IFileViewModel => ItemAttributeType.File,
IContainerSizeContainerViewModel => ItemAttributeType.SizeContainer,
IElementViewModel => ItemAttributeType.Element,
IContainerViewModel => ItemAttributeType.Container,
_ => null
};
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -4,112 +4,111 @@ using Avalonia.Media;
using FileTime.App.Core.Models;
using FileTime.GuiApp.ViewModels;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public class NamePartShrinkerConverter : IMultiValueConverter
{
public class NamePartShrinkerConverter : IMultiValueConverter
private const int PixelPerChar = 8;
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
{
private const int PixelPerChar = 8;
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
if (values.Count > 0 && values[0] is IList<ItemNamePart> nameParts)
{
if (values.Count > 0 && values[0] is IList<ItemNamePart> nameParts)
var attributeWidth = values[2] is bool b && b ? 340 : 0;
var newNameParts = nameParts;
if (values.Count > 1 && values[1] is double width && width > 0)
{
var attributeWidth = values[2] is bool b && b ? 340 : 0;
var newNameParts = nameParts;
if (values.Count > 1 && values[1] is double width && width > 0)
{
newNameParts = GetNamePartsForWidth(nameParts, width - attributeWidth);
}
return newNameParts.Select(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)).ToList();
newNameParts = GetNamePartsForWidth(nameParts, width - attributeWidth);
}
return null;
return newNameParts.Select(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)).ToList();
}
return null;
}
private static List<ItemNamePart> GetNamePartsForWidth(IList<ItemNamePart> nameParts, double maxWidth)
{
//Best case, we are in the range
var textLength = nameParts.Select(p => p.Text.Length).Sum();
if (textLength * PixelPerChar <= maxWidth)
{
return nameParts.ToList();
}
private static List<ItemNamePart> GetNamePartsForWidth(IList<ItemNamePart> nameParts, double maxWidth)
//Trying at least with the special parts
var newNameParts = new ItemNamePart?[nameParts.Count];
for (var i = 0; i < nameParts.Count; i++)
{
//Best case, we are in the range
var textLength = nameParts.Select(p => p.Text.Length).Sum();
if (textLength * PixelPerChar <= maxWidth)
if (nameParts[i].IsSpecial)
{
return nameParts.ToList();
newNameParts[i] = nameParts[i];
}
//Trying at least with the special parts
var newNameParts = new ItemNamePart?[nameParts.Count];
for (var i = 0; i < nameParts.Count; i++)
{
if (nameParts[i].IsSpecial)
{
newNameParts[i] = nameParts[i];
}
}
return GetNamePartsForWidthOptimistic(nameParts, newNameParts, maxWidth);
}
private static List<ItemNamePart> GetNamePartsForWidthOptimistic(IList<ItemNamePart> nameParts, ItemNamePart?[] newNameParts, double maxWidth)
return GetNamePartsForWidthOptimistic(nameParts, newNameParts, maxWidth);
}
private static List<ItemNamePart> GetNamePartsForWidthOptimistic(IList<ItemNamePart> nameParts, ItemNamePart?[] newNameParts, double maxWidth)
{
var trimmedIndexes = new List<int>();
for (var i = 0; i < newNameParts.Length; i++)
{
var trimmedIndexes = new List<int>();
for (var i = 0; i < newNameParts.Length; i++)
if (newNameParts[i] == null)
{
if (newNameParts[i] == null)
{
trimmedIndexes.Add(i);
newNameParts[i] = new ItemNamePart("...");
}
trimmedIndexes.Add(i);
newNameParts[i] = new ItemNamePart("...");
}
var textLength = newNameParts.Select(p => p?.Text.Length ?? 0).Sum();
if (textLength * PixelPerChar > maxWidth)
{
return GetNamePartsForWidthPessimistic(nameParts, maxWidth);
}
foreach (var trimmedIndex in trimmedIndexes)
{
var baseTextLength = newNameParts.Select((p, i) => i == trimmedIndex ? 0 : (p?.Text.Length ?? 0)).Sum();
var proposedText = nameParts[trimmedIndex].Text;
var trimmed = false;
while ((baseTextLength + proposedText.Length + (trimmed ? 3 : 0)) * PixelPerChar > maxWidth)
{
proposedText = proposedText[0..^1];
trimmed = true;
}
newNameParts[trimmedIndex] = new ItemNamePart(proposedText + (trimmed ? "..." : ""));
if (trimmed) break;
}
return newNameParts.Where(f => f is not null).ToList()!;
}
private static List<ItemNamePart> GetNamePartsForWidthPessimistic(IList<ItemNamePart> nameParts, double maxWidth)
var textLength = newNameParts.Select(p => p?.Text.Length ?? 0).Sum();
if (textLength * PixelPerChar > maxWidth)
{
var newNameParts = new List<ItemNamePart>(nameParts);
foreach (var namePart in nameParts)
{
var baseTextLength = newNameParts.Select(p => p.Text.Length).Sum();
var proposedText = namePart.Text;
var trimmed = false;
while ((baseTextLength + 3) * PixelPerChar > maxWidth && proposedText != "")
{
proposedText = proposedText[0..^1];
trimmed = true;
}
if (!string.IsNullOrWhiteSpace(proposedText)) newNameParts.Add(new ItemNamePart(proposedText, namePart.IsSpecial));
if (trimmed) break;
}
if (newNameParts.Last().IsSpecial)
{
newNameParts.Add(new ItemNamePart("..."));
}
else
{
var last = newNameParts.Last();
last.Text += "...";
}
return newNameParts;
return GetNamePartsForWidthPessimistic(nameParts, maxWidth);
}
foreach (var trimmedIndex in trimmedIndexes)
{
var baseTextLength = newNameParts.Select((p, i) => i == trimmedIndex ? 0 : (p?.Text.Length ?? 0)).Sum();
var proposedText = nameParts[trimmedIndex].Text;
var trimmed = false;
while ((baseTextLength + proposedText.Length + (trimmed ? 3 : 0)) * PixelPerChar > maxWidth)
{
proposedText = proposedText[0..^1];
trimmed = true;
}
newNameParts[trimmedIndex] = new ItemNamePart(proposedText + (trimmed ? "..." : ""));
if (trimmed) break;
}
return newNameParts.Where(f => f is not null).ToList()!;
}
private static List<ItemNamePart> GetNamePartsForWidthPessimistic(IList<ItemNamePart> nameParts, double maxWidth)
{
var newNameParts = new List<ItemNamePart>(nameParts);
foreach (var namePart in nameParts)
{
var baseTextLength = newNameParts.Select(p => p.Text.Length).Sum();
var proposedText = namePart.Text;
var trimmed = false;
while ((baseTextLength + 3) * PixelPerChar > maxWidth && proposedText != "")
{
proposedText = proposedText[0..^1];
trimmed = true;
}
if (!string.IsNullOrWhiteSpace(proposedText)) newNameParts.Add(new ItemNamePart(proposedText, namePart.IsSpecial));
if (trimmed) break;
}
if (newNameParts.Last().IsSpecial)
{
newNameParts.Add(new ItemNamePart("..."));
}
else
{
var last = newNameParts.Last();
last.Text += "...";
}
return newNameParts;
}
}

View File

@@ -1,27 +1,26 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace FileTime.GuiApp.Converters
namespace FileTime.GuiApp.Converters;
public class SplitStringConverter : IValueConverter
{
public class SplitStringConverter : IValueConverter
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
if (value is string path && parameter is string separator)
{
if (value is string path && parameter is string separator)
{
return path.Split(separator);
}
else if (value is string path2 && parameter is char separator2)
{
return path2.Split(separator2);
}
return value;
return path.Split(separator);
}
else if (value is string path2 && parameter is char separator2)
{
return path2.Split(separator2);
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
return value;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -1,7 +1,6 @@
namespace FileTime.GuiApp
namespace FileTime.GuiApp;
public static class DI
{
public static class DI
{
public static IServiceProvider ServiceProvider { get; set; } = null!;
}
public static IServiceProvider ServiceProvider { get; set; } = null!;
}

View File

@@ -1,10 +1,9 @@
using FileTime.GuiApp.Configuration;
namespace FileTime.GuiApp.Extensions
namespace FileTime.GuiApp.Extensions;
public static class KeyConfigExtensions
{
public static class KeyConfigExtensions
{
public static bool AreKeysEqual(this IReadOnlyList<KeyConfig> collection1, IReadOnlyList<KeyConfig> collection2)
public static bool AreKeysEqual(this IReadOnlyList<KeyConfig> collection1, IReadOnlyList<KeyConfig> collection2)
=> collection1.Count == collection2.Count && collection1.Zip(collection2).All(t => t.First.AreEquals(t.Second));
}
}

View File

@@ -6,6 +6,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
<ItemGroup>
<None Remove="Assets\filetime.ico" />
</ItemGroup>

View File

@@ -1,24 +1,23 @@
using Serilog.Core;
using Serilog.Events;
namespace FileTime.GuiApp.Logging
namespace FileTime.GuiApp.Logging;
public class ToastMessageSink : ILogEventSink
{
public class ToastMessageSink : ILogEventSink
//private readonly IDialogService dialogService;
public ToastMessageSink(/*IDialogService dialogService*/)
{
//private readonly IDialogService dialogService;
public ToastMessageSink(/*IDialogService dialogService*/)
{
//this.dialogService = dialogService;
}
public void Emit(LogEvent logEvent)
{
/*if (logEvent.Level >= LogEventLevel.Error)
{
var message = logEvent.RenderMessage();
dialogService.ShowToastMessage(message);
}*/
}
//this.dialogService = dialogService;
}
}
public void Emit(LogEvent logEvent)
{
/*if (logEvent.Level >= LogEventLevel.Error)
{
var message = logEvent.RenderMessage();
dialogService.ShowToastMessage(message);
}*/
}
}

View File

@@ -1,20 +1,19 @@
namespace FileTime.GuiApp.Models
namespace FileTime.GuiApp.Models;
public class InputElementWrapper
{
public class InputElementWrapper
/*public InputElement InputElement { get; }
public string Value { get; set; }
public object? Option { get; set; }
public char? PasswordChar { get; set; }
public InputElementWrapper(InputElement inputElement, string? defaultValue = null)
{
/*public InputElement InputElement { get; }
public string Value { get; set; }
public object? Option { get; set; }
public char? PasswordChar { get; set; }
public InputElementWrapper(InputElement inputElement, string? defaultValue = null)
{
InputElement = inputElement;
Value = defaultValue ?? "";
PasswordChar = inputElement.InputType == InputType.Password ? '*' : null;
}*/
}
}
InputElement = inputElement;
Value = defaultValue ?? "";
PasswordChar = inputElement.InputType == InputType.Password ? '*' : null;
}*/
}

View File

@@ -2,12 +2,11 @@ using System.Reactive.Concurrency;
using FileTime.App.Core.Services;
using ReactiveUI;
namespace FileTime.GuiApp.Services
{
public class AvaloniaRxSchedulerService : IRxSchedulerService
{
public IScheduler GetUIScheduler() => RxApp.MainThreadScheduler;
namespace FileTime.GuiApp.Services;
public IScheduler GetWorkerScheduler() => RxApp.TaskpoolScheduler;
}
public class AvaloniaRxSchedulerService : IRxSchedulerService
{
public IScheduler GetUIScheduler() => RxApp.MainThreadScheduler;
public IScheduler GetWorkerScheduler() => RxApp.TaskpoolScheduler;
}

View File

@@ -10,142 +10,141 @@ using FileTime.GuiApp.Models;
using FileTime.GuiApp.ViewModels;
using Microsoft.Extensions.Logging;
namespace FileTime.GuiApp.Services
namespace FileTime.GuiApp.Services;
public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
{
public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
private readonly IGuiAppState _appState;
private readonly IKeyboardConfigurationService _keyboardConfigurationService;
private readonly List<KeyConfig[]> _keysToSkip = new();
private ITabViewModel? _selectedTab;
private IContainer? _currentLocation;
private readonly ILogger<DefaultModeKeyInputHandler> _logger;
private readonly ICommandHandlerService _commandHandlerService;
public DefaultModeKeyInputHandler(
IGuiAppState appState,
IKeyboardConfigurationService keyboardConfigurationService,
ILogger<DefaultModeKeyInputHandler> logger,
ICommandHandlerService commandHandlerService)
{
private readonly IGuiAppState _appState;
private readonly IKeyboardConfigurationService _keyboardConfigurationService;
private readonly List<KeyConfig[]> _keysToSkip = new();
private ITabViewModel? _selectedTab;
private IContainer? _currentLocation;
private readonly ILogger<DefaultModeKeyInputHandler> _logger;
private readonly ICommandHandlerService _commandHandlerService;
_appState = appState;
_keyboardConfigurationService = keyboardConfigurationService;
_logger = logger;
_commandHandlerService = commandHandlerService;
public DefaultModeKeyInputHandler(
IGuiAppState appState,
IKeyboardConfigurationService keyboardConfigurationService,
ILogger<DefaultModeKeyInputHandler> logger,
ICommandHandlerService commandHandlerService)
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation!).Switch().Subscribe(l => _currentLocation = l);
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Up) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Down) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Tab) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageDown) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageUp) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.F4, alt: true) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.LWin) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.RWin) });
}
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
{
var keyWithModifiers = new KeyConfig(key, shift: specialKeysStatus.IsShiftPressed, alt: specialKeysStatus.IsAltPressed, ctrl: specialKeysStatus.IsCtrlPressed);
_appState.PreviousKeys.Add(keyWithModifiers);
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(_appState.PreviousKeys));
selectedCommandBinding ??= _keyboardConfigurationService.CommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(_appState.PreviousKeys));
if (key == Key.Escape)
{
_appState = appState;
_keyboardConfigurationService = keyboardConfigurationService;
_logger = logger;
_commandHandlerService = commandHandlerService;
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation!).Switch().Subscribe(l => _currentLocation = l);
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Up) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Down) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Tab) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageDown) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageUp) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.F4, alt: true) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.LWin) });
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.RWin) });
}
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
{
var keyWithModifiers = new KeyConfig(key, shift: specialKeysStatus.IsShiftPressed, alt: specialKeysStatus.IsAltPressed, ctrl: specialKeysStatus.IsCtrlPressed);
_appState.PreviousKeys.Add(keyWithModifiers);
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(_appState.PreviousKeys));
selectedCommandBinding ??= _keyboardConfigurationService.CommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(_appState.PreviousKeys));
if (key == Key.Escape)
var doGeneralReset = false;
if (_appState.PreviousKeys.Count > 1 || _appState.IsAllShortcutVisible || _appState.MessageBoxText != null)
{
var doGeneralReset = false;
if (_appState.PreviousKeys.Count > 1 || _appState.IsAllShortcutVisible || _appState.MessageBoxText != null)
{
doGeneralReset = true;
}
/*else if (_currentLocation.Container.CanHandleEscape)
{
var escapeResult = await _currentLocation.Container.HandleEscape();
if (escapeResult.NavigateTo != null)
{
setHandled(true);
_appState.PreviousKeys.Clear();
await _appState.SelectedTab.OpenContainer(escapeResult.NavigateTo);
}
else
{
if (escapeResult.Handled)
{
_appState.PreviousKeys.Clear();
}
else
{
doGeneralReset = true;
}
}
}*/
if (doGeneralReset)
doGeneralReset = true;
}
/*else if (_currentLocation.Container.CanHandleEscape)
{
var escapeResult = await _currentLocation.Container.HandleEscape();
if (escapeResult.NavigateTo != null)
{
setHandled(true);
_appState.IsAllShortcutVisible = false;
_appState.MessageBoxText = null;
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
}
}
else if (key == Key.Enter
&& _appState.MessageBoxText != null)
{
_appState.PreviousKeys.Clear();
//_dialogService.ProcessMessageBox();
setHandled(true);
}
else if (selectedCommandBinding != null)
{
setHandled(true);
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
await CallCommandAsync(selectedCommandBinding.Command);
}
else if (_keysToSkip.Any(k => k.AreKeysEqual(_appState.PreviousKeys)))
{
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
return;
}
else if (_appState.PreviousKeys.Count == 2)
{
setHandled(true);
_appState.NoCommandFound = true;
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
}
else
{
setHandled(true);
var possibleCommands = _keyboardConfigurationService.AllShortcut.Where(c => c.Keys[0].AreEquals(keyWithModifiers)).ToList();
if (possibleCommands.Count == 0)
{
_appState.NoCommandFound = true;
_appState.PreviousKeys.Clear();
await _appState.SelectedTab.OpenContainer(escapeResult.NavigateTo);
}
else
{
_appState.PossibleCommands = possibleCommands;
if (escapeResult.Handled)
{
_appState.PreviousKeys.Clear();
}
else
{
doGeneralReset = true;
}
}
}*/
if (doGeneralReset)
{
setHandled(true);
_appState.IsAllShortcutVisible = false;
_appState.MessageBoxText = null;
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
}
}
private async Task CallCommandAsync(Commands command)
else if (key == Key.Enter
&& _appState.MessageBoxText != null)
{
try
_appState.PreviousKeys.Clear();
//_dialogService.ProcessMessageBox();
setHandled(true);
}
else if (selectedCommandBinding != null)
{
setHandled(true);
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
await CallCommandAsync(selectedCommandBinding.Command);
}
else if (_keysToSkip.Any(k => k.AreKeysEqual(_appState.PreviousKeys)))
{
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
return;
}
else if (_appState.PreviousKeys.Count == 2)
{
setHandled(true);
_appState.NoCommandFound = true;
_appState.PreviousKeys.Clear();
_appState.PossibleCommands = new();
}
else
{
setHandled(true);
var possibleCommands = _keyboardConfigurationService.AllShortcut.Where(c => c.Keys[0].AreEquals(keyWithModifiers)).ToList();
if (possibleCommands.Count == 0)
{
await _commandHandlerService.HandleCommandAsync(command);
_appState.NoCommandFound = true;
_appState.PreviousKeys.Clear();
}
catch (Exception e)
else
{
_logger.LogError(e, "Unknown error while running command. {Command} {Error}", command, e);
_appState.PossibleCommands = possibleCommands;
}
}
}
private async Task CallCommandAsync(Commands command)
{
try
{
await _commandHandlerService.HandleCommandAsync(command);
}
catch (Exception e)
{
_logger.LogError(e, "Unknown error while running command. {Command} {Error}", command, e);
}
}
}

View File

@@ -4,53 +4,52 @@ using FileTime.GuiApp.Configuration;
using FileTime.GuiApp.Models;
using FileTime.GuiApp.ViewModels;
namespace FileTime.GuiApp.Services
{
public class KeyInputHandlerService : IKeyInputHandlerService
{
private readonly IGuiAppState _appState;
private readonly IDefaultModeKeyInputHandler _defaultModeKeyInputHandler;
private readonly IRapidTravelModeKeyInputHandler _rapidTravelModeKeyInputHandler;
namespace FileTime.GuiApp.Services;
public KeyInputHandlerService(
IGuiAppState appState,
IDefaultModeKeyInputHandler defaultModeKeyInputHandler,
IRapidTravelModeKeyInputHandler rapidTravelModeKeyInputHandler
)
public class KeyInputHandlerService : IKeyInputHandlerService
{
private readonly IGuiAppState _appState;
private readonly IDefaultModeKeyInputHandler _defaultModeKeyInputHandler;
private readonly IRapidTravelModeKeyInputHandler _rapidTravelModeKeyInputHandler;
public KeyInputHandlerService(
IGuiAppState appState,
IDefaultModeKeyInputHandler defaultModeKeyInputHandler,
IRapidTravelModeKeyInputHandler rapidTravelModeKeyInputHandler
)
{
_appState = appState;
_defaultModeKeyInputHandler = defaultModeKeyInputHandler;
_rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler;
}
public async Task ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
{
if (key == Key.LeftAlt
|| key == Key.RightAlt
|| key == Key.LeftShift
|| key == Key.RightShift
|| key == Key.LeftCtrl
|| key == Key.RightCtrl)
{
_appState = appState;
_defaultModeKeyInputHandler = defaultModeKeyInputHandler;
_rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler;
return;
}
public async Task ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
//_appState.NoCommandFound = false;
var isAltPressed = (keyModifiers & KeyModifiers.Alt) == KeyModifiers.Alt;
var isShiftPressed = (keyModifiers & KeyModifiers.Shift) == KeyModifiers.Shift;
var isCtrlPressed = (keyModifiers & KeyModifiers.Control) == KeyModifiers.Control;
var specialKeyStatus = new SpecialKeysStatus(isAltPressed, isShiftPressed, isCtrlPressed);
if (_appState.ViewMode == ViewMode.Default)
{
if (key == Key.LeftAlt
|| key == Key.RightAlt
|| key == Key.LeftShift
|| key == Key.RightShift
|| key == Key.LeftCtrl
|| key == Key.RightCtrl)
{
return;
}
//_appState.NoCommandFound = false;
var isAltPressed = (keyModifiers & KeyModifiers.Alt) == KeyModifiers.Alt;
var isShiftPressed = (keyModifiers & KeyModifiers.Shift) == KeyModifiers.Shift;
var isCtrlPressed = (keyModifiers & KeyModifiers.Control) == KeyModifiers.Control;
var specialKeyStatus = new SpecialKeysStatus(isAltPressed, isShiftPressed, isCtrlPressed);
if (_appState.ViewMode == ViewMode.Default)
{
await _defaultModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
}
else
{
await _rapidTravelModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
}
await _defaultModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
}
else
{
await _rapidTravelModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
}
}
}

View File

@@ -2,60 +2,59 @@ using FileTime.App.Core.Command;
using FileTime.GuiApp.Configuration;
using Microsoft.Extensions.Options;
namespace FileTime.GuiApp.Services
namespace FileTime.GuiApp.Services;
public class KeyboardConfigurationService : IKeyboardConfigurationService
{
public class KeyboardConfigurationService : IKeyboardConfigurationService
public IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
public IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
public IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
public KeyboardConfigurationService(IOptions<KeyBindingConfiguration> keyBindingConfiguration)
{
public IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
public IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
public IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
var commandBindings = new List<CommandBindingConfiguration>();
var universalCommandBindings = new List<CommandBindingConfiguration>();
IEnumerable<CommandBindingConfiguration> keyBindings = keyBindingConfiguration.Value.KeyBindings;
public KeyboardConfigurationService(IOptions<KeyBindingConfiguration> keyBindingConfiguration)
if (keyBindingConfiguration.Value.UseDefaultBindings)
{
var commandBindings = new List<CommandBindingConfiguration>();
var universalCommandBindings = new List<CommandBindingConfiguration>();
IEnumerable<CommandBindingConfiguration> keyBindings = keyBindingConfiguration.Value.KeyBindings;
if (keyBindingConfiguration.Value.UseDefaultBindings)
{
keyBindings = keyBindings.Concat(keyBindingConfiguration.Value.DefaultKeyBindings);
}
foreach (var keyBinding in keyBindings)
{
if (keyBinding.Command == Commands.None)
{
throw new FormatException($"No command is set in keybinding for keys '{keyBinding.KeysDisplayText}'");
}
else if (keyBinding.Keys.Count == 0)
{
throw new FormatException($"No keys set in keybinding for command '{keyBinding.Command}'.");
}
if (IsUniversal(keyBinding))
{
universalCommandBindings.Add(keyBinding);
}
else
{
commandBindings.Add(keyBinding);
}
}
CommandBindings = commandBindings.AsReadOnly();
UniversalCommandBindings = universalCommandBindings.AsReadOnly();
AllShortcut = new List<CommandBindingConfiguration>(CommandBindings.Concat(UniversalCommandBindings)).AsReadOnly();
keyBindings = keyBindings.Concat(keyBindingConfiguration.Value.DefaultKeyBindings);
}
private static bool IsUniversal(CommandBindingConfiguration keyMapping)
foreach (var keyBinding in keyBindings)
{
return keyMapping.Command == Commands.GoUp
|| keyMapping.Command == Commands.Open
|| keyMapping.Command == Commands.OpenOrRun
|| keyMapping.Command == Commands.MoveCursorUp
|| keyMapping.Command == Commands.MoveCursorDown
|| keyMapping.Command == Commands.MoveCursorUpPage
|| keyMapping.Command == Commands.MoveCursorDownPage;
if (keyBinding.Command == Commands.None)
{
throw new FormatException($"No command is set in keybinding for keys '{keyBinding.KeysDisplayText}'");
}
else if (keyBinding.Keys.Count == 0)
{
throw new FormatException($"No keys set in keybinding for command '{keyBinding.Command}'.");
}
if (IsUniversal(keyBinding))
{
universalCommandBindings.Add(keyBinding);
}
else
{
commandBindings.Add(keyBinding);
}
}
CommandBindings = commandBindings.AsReadOnly();
UniversalCommandBindings = universalCommandBindings.AsReadOnly();
AllShortcut = new List<CommandBindingConfiguration>(CommandBindings.Concat(UniversalCommandBindings)).AsReadOnly();
}
private static bool IsUniversal(CommandBindingConfiguration keyMapping)
{
return keyMapping.Command == Commands.GoUp
|| keyMapping.Command == Commands.Open
|| keyMapping.Command == Commands.OpenOrRun
|| keyMapping.Command == Commands.MoveCursorUp
|| keyMapping.Command == Commands.MoveCursorDown
|| keyMapping.Command == Commands.MoveCursorUpPage
|| keyMapping.Command == Commands.MoveCursorDownPage;
}
}

View File

@@ -1,88 +1,87 @@
using Avalonia.Input;
using FileTime.GuiApp.Models;
namespace FileTime.GuiApp.Services
{
public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
{
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
{
/*var keyString = key.ToString();
var updateRapidTravelFilter = false;
namespace FileTime.GuiApp.Services;
if (key == Key.Escape)
public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
{
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
{
/*var keyString = key.ToString();
var updateRapidTravelFilter = false;
if (key == Key.Escape)
{
setHandled(true);
if (_appState.IsAllShortcutVisible)
{
setHandled(true);
if (_appState.IsAllShortcutVisible)
{
_appState.IsAllShortcutVisible = false;
}
else if (_appState.MessageBoxText != null)
{
_appState.MessageBoxText = null;
}
else
{
await _appState.ExitRapidTravelMode();
}
_appState.IsAllShortcutVisible = false;
}
else if (key == Key.Back)
else if (_appState.MessageBoxText != null)
{
if (_appState.RapidTravelText.Length > 0)
{
setHandled(true);
_appState.RapidTravelText = _appState.RapidTravelText.Substring(0, _appState.RapidTravelText.Length - 1);
updateRapidTravelFilter = true;
}
}
else if (keyString.Length == 1)
{
setHandled(true);
_appState.RapidTravelText += keyString.ToLower();
updateRapidTravelFilter = true;
_appState.MessageBoxText = null;
}
else
{
var currentKeyAsList = new List<KeyConfig>() { new KeyConfig(key) };
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => AreKeysEqual(c.Keys, currentKeyAsList));
if (selectedCommandBinding != null)
{
setHandled(true);
await CallCommandAsync(selectedCommandBinding.Command);
}
await _appState.ExitRapidTravelMode();
}
if (updateRapidTravelFilter)
{
var currentLocation = await _appState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(MainPageViewModel.RAPIDTRAVEL);
var newLocation = new VirtualContainer(
currentLocation,
new List<Func<IEnumerable<IContainer>, IEnumerable<IContainer>>>()
{
container => container.Where(c => c.Name.ToLower().Contains(_appState.RapidTravelText))
},
new List<Func<IEnumerable<IElement>, IEnumerable<IElement>>>()
{
element => element.Where(e => e.Name.ToLower().Contains(_appState.RapidTravelText))
},
virtualContainerName: MainPageViewModel.RAPIDTRAVEL
);
await newLocation.Init();
await _appState.SelectedTab.OpenContainer(newLocation);
var selectedItemName = _appState.SelectedTab.SelectedItem?.Item.Name;
var currentLocationItems = await _appState.SelectedTab.CurrentLocation.GetItems();
if (currentLocationItems.FirstOrDefault(i => string.Equals(i.Item.Name, _appState.RapidTravelText, StringComparison.OrdinalIgnoreCase)) is IItemViewModel matchItem)
{
await _appState.SelectedTab.SetCurrentSelectedItem(matchItem.Item);
}
else if (!currentLocationItems.Select(i => i.Item.Name).Any(n => n == selectedItemName))
{
await _appState.SelectedTab.MoveCursorToFirst();
}
}*/
}
else if (key == Key.Back)
{
if (_appState.RapidTravelText.Length > 0)
{
setHandled(true);
_appState.RapidTravelText = _appState.RapidTravelText.Substring(0, _appState.RapidTravelText.Length - 1);
updateRapidTravelFilter = true;
}
}
else if (keyString.Length == 1)
{
setHandled(true);
_appState.RapidTravelText += keyString.ToLower();
updateRapidTravelFilter = true;
}
else
{
var currentKeyAsList = new List<KeyConfig>() { new KeyConfig(key) };
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => AreKeysEqual(c.Keys, currentKeyAsList));
if (selectedCommandBinding != null)
{
setHandled(true);
await CallCommandAsync(selectedCommandBinding.Command);
}
}
if (updateRapidTravelFilter)
{
var currentLocation = await _appState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(MainPageViewModel.RAPIDTRAVEL);
var newLocation = new VirtualContainer(
currentLocation,
new List<Func<IEnumerable<IContainer>, IEnumerable<IContainer>>>()
{
container => container.Where(c => c.Name.ToLower().Contains(_appState.RapidTravelText))
},
new List<Func<IEnumerable<IElement>, IEnumerable<IElement>>>()
{
element => element.Where(e => e.Name.ToLower().Contains(_appState.RapidTravelText))
},
virtualContainerName: MainPageViewModel.RAPIDTRAVEL
);
await newLocation.Init();
await _appState.SelectedTab.OpenContainer(newLocation);
var selectedItemName = _appState.SelectedTab.SelectedItem?.Item.Name;
var currentLocationItems = await _appState.SelectedTab.CurrentLocation.GetItems();
if (currentLocationItems.FirstOrDefault(i => string.Equals(i.Item.Name, _appState.RapidTravelText, StringComparison.OrdinalIgnoreCase)) is IItemViewModel matchItem)
{
await _appState.SelectedTab.SetCurrentSelectedItem(matchItem.Item);
}
else if (!currentLocationItems.Select(i => i.Item.Name).Any(n => n == selectedItemName))
{
await _appState.SelectedTab.MoveCursorToFirst();
}
}*/
}
}

View File

@@ -1,7 +1,6 @@
namespace FileTime.GuiApp.ViewModels
namespace FileTime.GuiApp.ViewModels;
public interface IMainWindowViewModelBase
{
public interface IMainWindowViewModelBase
{
bool Loading { get; }
}
bool Loading { get; }
}

View File

@@ -1,16 +1,15 @@
using Avalonia.Media;
namespace FileTime.GuiApp.ViewModels
{
public class ItemNamePartViewModel
{
public string Text { get; set; }
public TextDecorationCollection? TextDecorations { get; set; }
namespace FileTime.GuiApp.ViewModels;
public ItemNamePartViewModel(string text, TextDecorationCollection? textDecorations)
{
Text = text;
TextDecorations = textDecorations;
}
public class ItemNamePartViewModel
{
public string Text { get; set; }
public TextDecorationCollection? TextDecorations { get; set; }
public ItemNamePartViewModel(string text, TextDecorationCollection? textDecorations)
{
Text = text;
TextDecorations = textDecorations;
}
}

View File

@@ -1,7 +1,6 @@
namespace FileTime.GuiApp.ViewModels
namespace FileTime.GuiApp.ViewModels;
public class MainWindowLoadingViewModel : IMainWindowViewModelBase
{
public class MainWindowLoadingViewModel : IMainWindowViewModelBase
{
public bool Loading => true;
}
public bool Loading => true;
}

View File

@@ -11,49 +11,48 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MvvmGen;
namespace FileTime.GuiApp.ViewModels
namespace FileTime.GuiApp.ViewModels;
[ViewModel]
[Inject(typeof(IAppState), "_appState")]
[Inject(typeof(ILocalContentProvider), "_localContentProvider")]
[Inject(typeof(IServiceProvider), PropertyName = "_serviceProvider")]
[Inject(typeof(ILogger<MainWindowViewModel>), PropertyName = "_logger")]
[Inject(typeof(IKeyInputHandlerService), PropertyName = "_keyInputHandlerService")]
public partial class MainWindowViewModel : IMainWindowViewModelBase
{
[ViewModel]
[Inject(typeof(IAppState), "_appState")]
[Inject(typeof(ILocalContentProvider), "_localContentProvider")]
[Inject(typeof(IServiceProvider), PropertyName = "_serviceProvider")]
[Inject(typeof(ILogger<MainWindowViewModel>), PropertyName = "_logger")]
[Inject(typeof(IKeyInputHandlerService), PropertyName = "_keyInputHandlerService")]
public partial class MainWindowViewModel : IMainWindowViewModelBase
public bool Loading => false;
public IAppState AppState => _appState;
public string Title { get; private set; }
partial void OnInitialize()
{
public bool Loading => false;
public IAppState AppState => _appState;
public string Title { get; private set; }
_logger?.LogInformation($"Starting {nameof(MainWindowViewModel)} initialization...");
partial void OnInitialize()
var version = Assembly.GetEntryAssembly()!.GetName().Version;
var versionString = "Unknwon version";
if (version != null)
{
_logger?.LogInformation($"Starting {nameof(MainWindowViewModel)} initialization...");
var version = Assembly.GetEntryAssembly()!.GetName().Version;
var versionString = "Unknwon version";
if (version != null)
versionString = $"{version.Major}.{version.Minor}.{version.Build}";
if (version.Revision != 0)
{
versionString = $"{version.Major}.{version.Minor}.{version.Build}";
if (version.Revision != 0)
{
versionString += $" ({version.Revision})";
}
}
Title = "FileTime " + versionString;
//TODO: refactor
if (AppState.Tabs.Count == 0)
{
var tab = _serviceProvider.GetInitableResolver<IContainer>(_localContentProvider).GetRequiredService<ITab>();
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
_appState.AddTab(tabViewModel);
versionString += $" ({version.Revision})";
}
}
Title = "FileTime " + versionString;
public void ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
//TODO: refactor
if (AppState.Tabs.Count == 0)
{
_keyInputHandlerService.ProcessKeyDown(key, keyModifiers, setHandled);
var tab = _serviceProvider.GetInitableResolver<IContainer>(_localContentProvider).GetRequiredService<ITab>();
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
_appState.AddTab(tabViewModel);
}
}
}
public void ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
{
_keyInputHandlerService.ProcessKeyDown(key, keyModifiers, setHandled);
}
}

View File

@@ -1,21 +1,20 @@
using Avalonia;
using Avalonia.Controls;
namespace FileTime.GuiApp.Views
namespace FileTime.GuiApp.Views;
public partial class ItemView : UserControl
{
public partial class ItemView : UserControl
public static readonly StyledProperty<bool> ShowAttributesProperty = AvaloniaProperty.Register<ItemView, bool>(nameof(ShowAttributes), true);
public bool ShowAttributes
{
public static readonly StyledProperty<bool> ShowAttributesProperty = AvaloniaProperty.Register<ItemView, bool>(nameof(ShowAttributes), true);
public bool ShowAttributes
{
get => GetValue(ShowAttributesProperty);
set => SetValue(ShowAttributesProperty, value);
}
public ItemView()
{
InitializeComponent();
}
get => GetValue(ShowAttributesProperty);
set => SetValue(ShowAttributesProperty, value);
}
}
public ItemView()
{
InitializeComponent();
}
}

View File

@@ -7,66 +7,65 @@ using FileTime.GuiApp.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace FileTime.GuiApp.Views
namespace FileTime.GuiApp.Views;
public partial class MainWindow : Window
{
public partial class MainWindow : Window
private readonly ILogger<MainWindow>? _logger;
private InputElementWrapper? _inputElementWrapper;
public MainWindowViewModel? ViewModel
{
private readonly ILogger<MainWindow>? _logger;
private InputElementWrapper? _inputElementWrapper;
public MainWindowViewModel? ViewModel
get => DataContext as MainWindowViewModel;
set
{
get => DataContext as MainWindowViewModel;
set
if (value != DataContext)
{
if (value != DataContext)
{
DataContext = value;
}
}
}
public MainWindow()
{
_logger = DI.ServiceProvider.GetService<ILogger<MainWindow>>();
_logger?.LogInformation($"Starting {nameof(MainWindow)} initialization...");
InitializeComponent();
}
private void OnWindowOpened(object sender, EventArgs e)
{
if (DataContext is not MainWindowViewModel)
{
_logger?.LogInformation($"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization...");
ViewModel = DI.ServiceProvider.GetRequiredService<MainWindowViewModel>();
}
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (_inputElementWrapper == null)
{
ViewModel?.ProcessKeyDown(e.Key, e.KeyModifiers, h => e.Handled = h);
}
}
private void HeaderPointerPressed(object sender, PointerPressedEventArgs e)
{
if (e.ClickCount == 2)
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
}
else
{
WindowState = WindowState.Maximized;
}
}
else
{
BeginMoveDrag(e);
DataContext = value;
}
}
}
public MainWindow()
{
_logger = DI.ServiceProvider.GetService<ILogger<MainWindow>>();
_logger?.LogInformation($"Starting {nameof(MainWindow)} initialization...");
InitializeComponent();
}
private void OnWindowOpened(object sender, EventArgs e)
{
if (DataContext is not MainWindowViewModel)
{
_logger?.LogInformation($"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization...");
ViewModel = DI.ServiceProvider.GetRequiredService<MainWindowViewModel>();
}
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (_inputElementWrapper == null)
{
ViewModel?.ProcessKeyDown(e.Key, e.KeyModifiers, h => e.Handled = h);
}
}
private void HeaderPointerPressed(object sender, PointerPressedEventArgs e)
{
if (e.ClickCount == 2)
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
}
else
{
WindowState = WindowState.Maximized;
}
}
else
{
BeginMoveDrag(e);
}
}
}