Group rename WIP
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using FileTime.Core.Interactions;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.Interactions;
|
||||||
|
|
||||||
|
public class DoubleTextListPreview : IPreviewElement
|
||||||
|
{
|
||||||
|
public ObservableCollection<DoubleTextPreview> Items { get; } = new();
|
||||||
|
public PreviewType PreviewType { get; } = PreviewType.DoubleTextList;
|
||||||
|
object IPreviewElement.PreviewType => PreviewType;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Reactive.Subjects;
|
||||||
|
using FileTime.App.Core.Models;
|
||||||
|
using FileTime.Core.Interactions;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.Interactions;
|
||||||
|
|
||||||
|
public class DoubleTextPreview : IPreviewElement
|
||||||
|
{
|
||||||
|
public IObservable<List<ItemNamePart>> Text1 { get; init; } = new BehaviorSubject<List<ItemNamePart>>(new());
|
||||||
|
public IObservable<List<ItemNamePart>> Text2 { get; init; } = new BehaviorSubject<List<ItemNamePart>>(new());
|
||||||
|
|
||||||
|
public PreviewType PreviewType { get; } = PreviewType.DoubleTextList;
|
||||||
|
object IPreviewElement.PreviewType => PreviewType;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace FileTime.App.Core.Interactions;
|
||||||
|
|
||||||
|
public enum PreviewType
|
||||||
|
{
|
||||||
|
DoubleText,
|
||||||
|
DoubleTextList
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Subjects;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using DynamicData;
|
||||||
|
using FileTime.App.Core.Interactions;
|
||||||
|
using FileTime.App.Core.Models;
|
||||||
using FileTime.App.Core.Models.Enums;
|
using FileTime.App.Core.Models.Enums;
|
||||||
using FileTime.App.Core.UserCommand;
|
using FileTime.App.Core.UserCommand;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
@@ -175,25 +180,143 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi
|
|||||||
|
|
||||||
private async Task Rename(RenameCommand command)
|
private async Task Rename(RenameCommand command)
|
||||||
{
|
{
|
||||||
//TODO: group rename
|
if ((_markedItems?.Collection?.Count ?? 0) > 0)
|
||||||
List<ItemToMove> itemsToMove = new();
|
{
|
||||||
if (_currentSelectedItem?.BaseItem?.FullName is null) return;
|
BehaviorSubject<string> templateRegexValue = new(string.Empty);
|
||||||
|
BehaviorSubject<string> newNameSchemaValue = new(string.Empty);
|
||||||
|
|
||||||
var item = await _timelessContentProvider.GetItemByFullNameAsync(_currentSelectedItem.BaseItem.FullName, PointInTime.Present);
|
var itemPreviews = _markedItems!.Collection!
|
||||||
|
.Select(item =>
|
||||||
|
{
|
||||||
|
var originalName = item.GetName();
|
||||||
|
|
||||||
if (item is null) return;
|
var decoratedOriginalName = templateRegexValue.Select(templateRegex =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(templateRegex))
|
||||||
|
return new List<ItemNamePart> {new(originalName)};
|
||||||
|
|
||||||
var renameInput = new TextInputElement("New name", item.Name);
|
var regex = new Regex(templateRegex);
|
||||||
|
var match = regex.Match(originalName);
|
||||||
|
if (!match.Success) return new List<ItemNamePart> {new(originalName)};
|
||||||
|
|
||||||
await _userCommunicationService.ReadInputs(renameInput);
|
var matchGroups = match.Groups;
|
||||||
|
|
||||||
//TODO: should check these...
|
var indices = Enumerable.Empty<int>()
|
||||||
var newPath = item.FullName!.GetParent()!.GetChild(renameInput.Value!);
|
.Prepend(0)
|
||||||
itemsToMove.Add(new ItemToMove(item.FullName, newPath));
|
.Concat(
|
||||||
|
((IList<Group>) match.Groups).Skip(1).SelectMany(g => new[] {g.Index, g.Index + g.Length})
|
||||||
|
)
|
||||||
|
.Append(originalName.Length)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var moveCommandFactory = _serviceProvider.GetRequiredService<MoveCommandFactory>();
|
var itemNameParts = new List<ItemNamePart>();
|
||||||
var moveCommand = moveCommandFactory.GenerateCommand(itemsToMove);
|
for (var i = 0; i < indices.Count - 1; i++)
|
||||||
await AddCommand(moveCommand);
|
{
|
||||||
|
var text = originalName.Substring(indices[i], indices[i + 1] - indices[i]);
|
||||||
|
itemNameParts.Add(new ItemNamePart(text, i % 2 == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemNameParts;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new List<ItemNamePart> {new(originalName)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var text2 = Observable.CombineLatest(
|
||||||
|
templateRegexValue,
|
||||||
|
newNameSchemaValue,
|
||||||
|
(templateRegex, newNameSchema) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(templateRegex)
|
||||||
|
|| string.IsNullOrWhiteSpace(newNameSchema)) return new List<ItemNamePart> {new(originalName)};
|
||||||
|
|
||||||
|
var regex = new Regex(templateRegex);
|
||||||
|
var match = regex.Match(originalName);
|
||||||
|
if (!match.Success) return new List<ItemNamePart> {new(originalName)};
|
||||||
|
|
||||||
|
var matchGroups = match.Groups;
|
||||||
|
|
||||||
|
var newNameParts = Enumerable.Range(1, matchGroups.Count).Aggregate(
|
||||||
|
(IEnumerable<string>) new List<string> {newNameSchema},
|
||||||
|
(acc, i) =>
|
||||||
|
acc.SelectMany(item2 =>
|
||||||
|
item2
|
||||||
|
.Split($"/{i}/")
|
||||||
|
.SelectMany(e => new[] {e, $"/{i}/"})
|
||||||
|
.SkipLast(1)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
var itemNameParts = newNameParts.Select(namePart =>
|
||||||
|
namePart.StartsWith("/")
|
||||||
|
&& namePart.EndsWith("/")
|
||||||
|
&& namePart.Length > 2
|
||||||
|
&& int.TryParse(namePart.AsSpan(1, namePart.Length - 2), out var index)
|
||||||
|
&& index > 0
|
||||||
|
&& index <= matchGroups.Count
|
||||||
|
? new ItemNamePart(matchGroups[index].Value, true)
|
||||||
|
: new ItemNamePart(namePart, false)
|
||||||
|
);
|
||||||
|
|
||||||
|
return itemNameParts.ToList();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new List<ItemNamePart> {new(originalName)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var preview = new DoubleTextPreview
|
||||||
|
{
|
||||||
|
Text1 = decoratedOriginalName,
|
||||||
|
Text2 = text2
|
||||||
|
};
|
||||||
|
return preview;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
DoubleTextListPreview doubleTextListPreview = new();
|
||||||
|
doubleTextListPreview.Items.AddRange(itemPreviews);
|
||||||
|
|
||||||
|
var templateRegex = new TextInputElement("Template regex", string.Empty,
|
||||||
|
s => templateRegexValue.OnNext(s!));
|
||||||
|
var newNameSchema = new TextInputElement("New name schema", string.Empty,
|
||||||
|
s => newNameSchemaValue.OnNext(s!));
|
||||||
|
await _userCommunicationService.ReadInputs(
|
||||||
|
new[] {templateRegex, newNameSchema},
|
||||||
|
new[] {doubleTextListPreview}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<ItemToMove> itemsToMove = new();
|
||||||
|
if (_currentSelectedItem?.BaseItem?.FullName is null) return;
|
||||||
|
|
||||||
|
var item = await _timelessContentProvider.GetItemByFullNameAsync(_currentSelectedItem.BaseItem.FullName, PointInTime.Present);
|
||||||
|
|
||||||
|
if (item is null) return;
|
||||||
|
|
||||||
|
var renameInput = new TextInputElement("New name", item.Name);
|
||||||
|
|
||||||
|
await _userCommunicationService.ReadInputs(renameInput);
|
||||||
|
|
||||||
|
//TODO: should check these...
|
||||||
|
var newPath = item.FullName!.GetParent()!.GetChild(renameInput.Value!);
|
||||||
|
itemsToMove.Add(new ItemToMove(item.FullName, newPath));
|
||||||
|
|
||||||
|
var moveCommandFactory = _serviceProvider.GetRequiredService<MoveCommandFactory>();
|
||||||
|
var moveCommand = moveCommandFactory.GenerateCommand(itemsToMove);
|
||||||
|
await AddCommand(moveCommand);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Delete(DeleteCommand command)
|
private async Task Delete(DeleteCommand command)
|
||||||
|
|||||||
@@ -4,4 +4,7 @@ public interface IInputElement
|
|||||||
{
|
{
|
||||||
InputType Type { get; }
|
InputType Type { get; }
|
||||||
string Label { get; }
|
string Label { get; }
|
||||||
|
IObservable<bool> IsValid { get; }
|
||||||
|
void SetValid();
|
||||||
|
void SetInvalid();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace FileTime.Core.Interactions;
|
||||||
|
|
||||||
|
public interface IPreviewElement
|
||||||
|
{
|
||||||
|
object PreviewType { get; }
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ namespace FileTime.Core.Interactions;
|
|||||||
public interface IUserCommunicationService
|
public interface IUserCommunicationService
|
||||||
{
|
{
|
||||||
Task<bool> ReadInputs(params IInputElement[] fields);
|
Task<bool> ReadInputs(params IInputElement[] fields);
|
||||||
|
Task<bool> ReadInputs(IInputElement field, IEnumerable<IPreviewElement>? previews = null);
|
||||||
|
Task<bool> ReadInputs(IEnumerable<IInputElement> fields, IEnumerable<IPreviewElement>? previews = null);
|
||||||
void ShowToastMessage(string text);
|
void ShowToastMessage(string text);
|
||||||
Task<MessageBoxResult> ShowMessageBox(string text);
|
Task<MessageBoxResult> ShowMessageBox(string text);
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,23 @@
|
|||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Subjects;
|
||||||
|
|
||||||
namespace FileTime.Core.Interactions;
|
namespace FileTime.Core.Interactions;
|
||||||
|
|
||||||
public abstract class InputElementBase : IInputElement
|
public abstract class InputElementBase : IInputElement
|
||||||
{
|
{
|
||||||
|
private readonly BehaviorSubject<bool> _isValid = new(true);
|
||||||
public InputType Type { get; }
|
public InputType Type { get; }
|
||||||
public string Label { get; }
|
public string Label { get; }
|
||||||
|
public IObservable<bool> IsValid { get; }
|
||||||
|
|
||||||
protected InputElementBase(string label, InputType type)
|
protected InputElementBase(string label, InputType type)
|
||||||
{
|
{
|
||||||
Label = label;
|
Label = label;
|
||||||
Type = type;
|
Type = type;
|
||||||
|
IsValid = _isValid.AsObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetValid() => _isValid.OnNext(true);
|
||||||
|
|
||||||
|
public void SetInvalid() => _isValid.OnNext(false);
|
||||||
}
|
}
|
||||||
@@ -3,12 +3,19 @@ using PropertyChanged.SourceGenerator;
|
|||||||
|
|
||||||
namespace FileTime.Core.Interactions;
|
namespace FileTime.Core.Interactions;
|
||||||
|
|
||||||
public partial class TextInputElement : InputElementBase, INotifyPropertyChanged
|
public partial class TextInputElement : InputElementBase
|
||||||
{
|
{
|
||||||
[Notify] private string? _value;
|
[Notify] private string? _value;
|
||||||
|
private readonly Action<string?>? _update;
|
||||||
|
|
||||||
public TextInputElement(string label, string? value = null) : base(label, InputType.Text)
|
public TextInputElement(
|
||||||
|
string label,
|
||||||
|
string? value = null,
|
||||||
|
Action<string?>? update = null) : base(label, InputType.Text)
|
||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
|
_update = update;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnValueChanged(string? oldValue, string? newValue) => _update?.Invoke(newValue);
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,4 @@ public interface IDialogService : IUserCommunicationService
|
|||||||
{
|
{
|
||||||
IObservable<ReadInputsViewModel?> ReadInput { get; }
|
IObservable<ReadInputsViewModel?> ReadInput { get; }
|
||||||
IObservable<MessageBoxViewModel?> LastMessageBox { get; }
|
IObservable<MessageBoxViewModel?> LastMessageBox { get; }
|
||||||
void ReadInputs(IEnumerable<IInputElement> inputs, Action inputHandler, Action? cancelHandler = null);
|
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,33 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
using FileTime.Core.Interactions;
|
using FileTime.Core.Interactions;
|
||||||
using MvvmGen;
|
using PropertyChanged.SourceGenerator;
|
||||||
|
|
||||||
namespace FileTime.GuiApp.ViewModels;
|
namespace FileTime.GuiApp.ViewModels;
|
||||||
|
|
||||||
[ViewModel]
|
public class ReadInputsViewModel : IModalViewModel
|
||||||
[Inject(typeof(Action<ReadInputsViewModel>), "_cancel")]
|
|
||||||
[Inject(typeof(Action<ReadInputsViewModel>), "_process")]
|
|
||||||
public partial class ReadInputsViewModel : IModalViewModel
|
|
||||||
{
|
{
|
||||||
public string Name => "ReadInputs";
|
public string Name => "ReadInputs";
|
||||||
public List<IInputElement> Inputs { get; set; }
|
public required List<IInputElement> Inputs { get; init; }
|
||||||
public Action SuccessHandler { get; set; }
|
public required Action<ReadInputsViewModel> SuccessHandler { get; init; }
|
||||||
public Action? CancelHandler { get; set; }
|
public required Action<ReadInputsViewModel>? CancelHandler { get; init; }
|
||||||
|
public ObservableCollection<IPreviewElement> Previews { get; } = new();
|
||||||
|
|
||||||
[Command]
|
public ReadInputsViewModel()
|
||||||
public void Process()
|
|
||||||
{
|
{
|
||||||
_process.Invoke(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Command]
|
public ReadInputsViewModel(
|
||||||
public void Cancel()
|
List<IInputElement> inputs,
|
||||||
|
Action<ReadInputsViewModel> successHandler,
|
||||||
|
Action<ReadInputsViewModel>? cancelHandler = null)
|
||||||
{
|
{
|
||||||
_cancel.Invoke(this);
|
Inputs = inputs;
|
||||||
|
SuccessHandler = successHandler;
|
||||||
|
CancelHandler = cancelHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Process() => SuccessHandler.Invoke(this);
|
||||||
|
|
||||||
|
public void Cancel() => CancelHandler?.Invoke(this);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Avalonia.Media;
|
||||||
|
|
||||||
|
namespace FileTime.GuiApp.Converters;
|
||||||
|
|
||||||
|
public class TextDecorationConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (value is bool b && b) return TextDecorations.Underline;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) => throw new NotImplementedException();
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
<ResourceDictionary
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:converters="using:FileTime.GuiApp.Converters">
|
xmlns:converters="using:FileTime.GuiApp.Converters"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Brushes.axaml"></ResourceInclude>
|
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Brushes.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
@@ -26,18 +27,20 @@
|
|||||||
x:Key="ItemViewModeToBackgroundConverter" />
|
x:Key="ItemViewModeToBackgroundConverter" />
|
||||||
<converters:NamePartShrinkerConverter x:Key="NamePartShrinkerConverter" />
|
<converters:NamePartShrinkerConverter x:Key="NamePartShrinkerConverter" />
|
||||||
<converters:ItemViewModelIsAttributeTypeConverter x:Key="ItemViewModelIsAttributeTypeConverter" />
|
<converters:ItemViewModelIsAttributeTypeConverter x:Key="ItemViewModelIsAttributeTypeConverter" />
|
||||||
<converters:ItemViewModelIsAttributeTypeConverter Invert="true"
|
<converters:ItemViewModelIsAttributeTypeConverter Invert="true" x:Key="ItemViewModelIsNotAttributeTypeConverter" />
|
||||||
x:Key="ItemViewModelIsNotAttributeTypeConverter" />
|
|
||||||
<converters:GetFileExtensionConverter x:Key="GetFileExtensionConverter" />
|
<converters:GetFileExtensionConverter x:Key="GetFileExtensionConverter" />
|
||||||
<converters:FormatSizeConverter x:Key="FormatSizeConverter" />
|
<converters:FormatSizeConverter x:Key="FormatSizeConverter" />
|
||||||
<converters:DateTimeConverter x:Key="DateTimeConverter" />
|
<converters:DateTimeConverter x:Key="DateTimeConverter" />
|
||||||
<converters:SplitStringConverter x:Key="SplitStringConverter" />
|
<converters:SplitStringConverter x:Key="SplitStringConverter" />
|
||||||
<converters:CompareConverter x:Key="EqualityConverter" />
|
<converters:CompareConverter x:Key="EqualityConverter" />
|
||||||
<converters:CompareConverter ComparisonCondition="{x:Static converters:ComparisonCondition.NotEqual}"
|
<converters:CompareConverter ComparisonCondition="{x:Static converters:ComparisonCondition.NotEqual}" x:Key="NotEqualsConverter" />
|
||||||
x:Key="NotEqualsConverter" />
|
|
||||||
<converters:ExceptionToStringConverter x:Key="ExceptionToStringConverter" />
|
<converters:ExceptionToStringConverter x:Key="ExceptionToStringConverter" />
|
||||||
<converters:CommandToCommandNameConverter x:Key="CommandToCommandNameConverter" />
|
<converters:CommandToCommandNameConverter x:Key="CommandToCommandNameConverter" />
|
||||||
<converters:ItemToImageConverter x:Key="ItemToImageConverter" />
|
<converters:ItemToImageConverter x:Key="ItemToImageConverter" />
|
||||||
<converters:StringReplaceConverter x:Key="PathPreformatter" OldValue="://" NewValue="/"/>
|
<converters:StringReplaceConverter
|
||||||
<converters:ContextMenuGenerator x:Key="ContextMenuGenerator"/>
|
NewValue="/"
|
||||||
|
OldValue="://"
|
||||||
|
x:Key="PathPreformatter" />
|
||||||
|
<converters:ContextMenuGenerator x:Key="ContextMenuGenerator" />
|
||||||
|
<converters:TextDecorationConverter x:Key="TextDecorationConverter" />
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
@@ -37,16 +37,76 @@ public class DialogService : IDialogService
|
|||||||
.Select(m => m.LastOrDefault());
|
.Select(m => m.LastOrDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadInputs(IEnumerable<IInputElement> inputs, Action inputHandler, Action? cancelHandler = null)
|
private void ReadInputs(
|
||||||
|
IEnumerable<IInputElement> inputs,
|
||||||
|
Action inputHandler,
|
||||||
|
Action? cancelHandler = null,
|
||||||
|
IEnumerable<IPreviewElement>? previews = null)
|
||||||
{
|
{
|
||||||
var modalViewModel = new ReadInputsViewModel(HandleReadInputsSuccess, HandleReadInputsCancel)
|
var modalViewModel = new ReadInputsViewModel
|
||||||
{
|
{
|
||||||
Inputs = inputs.ToList(),
|
Inputs = inputs.ToList(),
|
||||||
SuccessHandler = inputHandler,
|
SuccessHandler = HandleReadInputsSuccess,
|
||||||
CancelHandler = cancelHandler
|
CancelHandler = HandleReadInputsCancel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (previews is not null)
|
||||||
|
{
|
||||||
|
modalViewModel.Previews.AddRange(previews);
|
||||||
|
}
|
||||||
|
|
||||||
_modalService.OpenModal(modalViewModel);
|
_modalService.OpenModal(modalViewModel);
|
||||||
|
|
||||||
|
void HandleReadInputsSuccess(ReadInputsViewModel readInputsViewModel)
|
||||||
|
{
|
||||||
|
_modalService.CloseModal(readInputsViewModel);
|
||||||
|
inputHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleReadInputsCancel(ReadInputsViewModel readInputsViewModel)
|
||||||
|
{
|
||||||
|
_modalService.CloseModal(readInputsViewModel);
|
||||||
|
cancelHandler?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> ReadInputs(IEnumerable<IInputElement> fields, IEnumerable<IPreviewElement>? previews = null)
|
||||||
|
{
|
||||||
|
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
ReadInputs(
|
||||||
|
fields,
|
||||||
|
() => taskCompletionSource.SetResult(true),
|
||||||
|
() => taskCompletionSource.SetResult(false),
|
||||||
|
previews
|
||||||
|
);
|
||||||
|
|
||||||
|
return taskCompletionSource.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Task<bool> ReadInputs(params IInputElement[] fields)
|
||||||
|
{
|
||||||
|
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
ReadInputs(
|
||||||
|
fields,
|
||||||
|
() => taskCompletionSource.SetResult(true),
|
||||||
|
() => taskCompletionSource.SetResult(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
return taskCompletionSource.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> ReadInputs(IInputElement field, IEnumerable<IPreviewElement>? previews = null)
|
||||||
|
{
|
||||||
|
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
ReadInputs(
|
||||||
|
new[] {field},
|
||||||
|
() => taskCompletionSource.SetResult(true),
|
||||||
|
() => taskCompletionSource.SetResult(false),
|
||||||
|
previews
|
||||||
|
);
|
||||||
|
|
||||||
|
return taskCompletionSource.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowToastMessage(string text)
|
public void ShowToastMessage(string text)
|
||||||
@@ -70,24 +130,4 @@ public class DialogService : IDialogService
|
|||||||
|
|
||||||
return taskCompletionSource.Task;
|
return taskCompletionSource.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleReadInputsSuccess(ReadInputsViewModel readInputsViewModel)
|
|
||||||
{
|
|
||||||
_modalService.CloseModal(readInputsViewModel);
|
|
||||||
readInputsViewModel.SuccessHandler.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleReadInputsCancel(ReadInputsViewModel readInputsViewModel)
|
|
||||||
{
|
|
||||||
_modalService.CloseModal(readInputsViewModel);
|
|
||||||
readInputsViewModel.CancelHandler?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<bool> ReadInputs(params IInputElement[] fields)
|
|
||||||
{
|
|
||||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
|
||||||
ReadInputs(fields, () => taskCompletionSource.SetResult(true), () => taskCompletionSource.SetResult(false));
|
|
||||||
|
|
||||||
return taskCompletionSource.Task;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
x:DataType="vm:IMainWindowViewModelBase"
|
x:DataType="vm:IMainWindowViewModelBase"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:appCoreModels="using:FileTime.App.Core.Models"
|
xmlns:appCoreModels="using:FileTime.App.Core.Models"
|
||||||
|
xmlns:appInteractions="using:FileTime.App.Core.Interactions"
|
||||||
xmlns:config="using:FileTime.GuiApp.Configuration"
|
xmlns:config="using:FileTime.GuiApp.Configuration"
|
||||||
xmlns:corevm="using:FileTime.App.Core.ViewModels"
|
xmlns:corevm="using:FileTime.App.Core.ViewModels"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
@@ -578,7 +579,7 @@
|
|||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Padding="20"
|
Padding="20"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
<Grid RowDefinitions="Auto,Auto">
|
<Grid RowDefinitions="Auto,Auto,Auto">
|
||||||
|
|
||||||
<ItemsControl
|
<ItemsControl
|
||||||
ItemsSource="{Binding DialogService.ReadInput^.Inputs}"
|
ItemsSource="{Binding DialogService.ReadInput^.Inputs}"
|
||||||
@@ -621,18 +622,92 @@
|
|||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|
||||||
|
<ItemsControl Grid.Row="1" ItemsSource="{Binding DialogService.ReadInput^.Previews}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid>
|
||||||
|
<Grid IsVisible="{Binding PreviewType, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static appInteractions:PreviewType.DoubleTextList}}">
|
||||||
|
<ItemsControl ItemsSource="{Binding Items}" x:DataType="appInteractions:DoubleTextListPreview">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid ColumnDefinitions="*,*">
|
||||||
|
<ItemsControl ItemsSource="{Binding Text1^}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Text}" TextDecorations="{Binding IsSpecial, Converter={StaticResource TextDecorationConverter}}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
<ItemsControl Grid.Column="1" ItemsSource="{Binding Text2^}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Text}" TextDecorations="{Binding IsSpecial, Converter={StaticResource TextDecorationConverter}}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
<!--DataGrid ItemsSource="{Binding Items}" x:DataType="appInteractions:DoubleTextListPreview">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTemplateColumn>
|
||||||
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<ItemsControl
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
ItemsSource="{Binding Text1^}"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="x:String">
|
||||||
|
<Grid>
|
||||||
|
<TextBlock Text="{Binding}" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</DataTemplate>
|
||||||
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
|
</DataGridTemplateColumn>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid-->
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
DataContext="{Binding DialogService.ReadInput^}"
|
DataContext="{Binding DialogService.ReadInput^}"
|
||||||
Grid.Row="1"
|
Grid.Row="2"
|
||||||
Margin="0,10,0,0"
|
Margin="0,10,0,0"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<Button
|
<Button
|
||||||
Command="{Binding ProcessCommand}"
|
Command="{Binding Process}"
|
||||||
Content="Ok"
|
Content="Ok"
|
||||||
HorizontalContentAlignment="Center"
|
HorizontalContentAlignment="Center"
|
||||||
Width="80" />
|
Width="80" />
|
||||||
<Button
|
<Button
|
||||||
Command="{Binding CancelCommand}"
|
Command="{Binding Cancel}"
|
||||||
Content="Cancel"
|
Content="Cancel"
|
||||||
HorizontalContentAlignment="Center"
|
HorizontalContentAlignment="Center"
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
|
|||||||
Reference in New Issue
Block a user