Add queue log and improve display styles
This commit is contained in:
parent
3b42b52ff4
commit
a66b7a6eab
@ -1,12 +1,9 @@
|
|||||||
using ApplicationServices;
|
using ApplicationServices;
|
||||||
using Dinah.Core.DataBinding;
|
|
||||||
using LibationSearchEngine;
|
using LibationSearchEngine;
|
||||||
using LibationWinForms.GridView;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace LibationWinForms.AvaloniaUI.ViewModels
|
namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||||
|
|||||||
@ -70,7 +70,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
ProcessBookStatus.Cancelled => "Khaki",
|
ProcessBookStatus.Cancelled => "Khaki",
|
||||||
ProcessBookStatus.Completed => "PaleGreen",
|
ProcessBookStatus.Completed => "PaleGreen",
|
||||||
ProcessBookStatus.Failed => "LightCoral",
|
ProcessBookStatus.Failed => "LightCoral",
|
||||||
_ => string.Empty,
|
_ => "White",
|
||||||
};
|
};
|
||||||
public string StatusText => Result switch
|
public string StatusText => Result switch
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -9,6 +10,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
{
|
{
|
||||||
public class ProcessQueueViewModel : ViewModelBase
|
public class ProcessQueueViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public string QueueHeader => "this is a header!";
|
||||||
private TrackedQueue2<ProcessBook2> _items = new();
|
private TrackedQueue2<ProcessBook2> _items = new();
|
||||||
public ProcessQueueViewModel() { }
|
public ProcessQueueViewModel() { }
|
||||||
public TrackedQueue2<ProcessBook2> Items
|
public TrackedQueue2<ProcessBook2> Items
|
||||||
@ -17,6 +20,17 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
set => this.RaiseAndSetIfChanged(ref _items, value);
|
set => this.RaiseAndSetIfChanged(ref _items, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ObservableCollection<LogEntry> LogEntries { get; } = new();
|
||||||
|
|
||||||
public ProcessBook2 SelectedItem { get; set; }
|
public ProcessBook2 SelectedItem { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class LogEntry
|
||||||
|
{
|
||||||
|
public DateTime LogDate { get; init; }
|
||||||
|
public string LogDateString => LogDate.ToShortTimeString();
|
||||||
|
public string LogMessage { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||||||
Fisrt,
|
Fisrt,
|
||||||
OneUp,
|
OneUp,
|
||||||
OneDown,
|
OneDown,
|
||||||
Last
|
Last,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -1,22 +1,17 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using System;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using LibationWinForms.AvaloniaUI.ViewModels;
|
using LibationWinForms.AvaloniaUI.ViewModels;
|
||||||
|
|
||||||
namespace LibationWinForms.AvaloniaUI.Views
|
namespace LibationWinForms.AvaloniaUI.Views
|
||||||
{
|
{
|
||||||
public enum QueueButton
|
public delegate void QueueItemPositionButtonClicked(ProcessBook2 item, QueuePosition queueButton);
|
||||||
{
|
public delegate void QueueItemCancelButtonClicked(ProcessBook2 item);
|
||||||
Cancel,
|
|
||||||
MoveFirst,
|
|
||||||
MoveUp,
|
|
||||||
MoveDown,
|
|
||||||
MoveLast
|
|
||||||
}
|
|
||||||
public delegate void QueueItemButtonClicked(ProcessBook2 item, QueueButton queueButton);
|
|
||||||
public partial class ProcessBookControl2 : UserControl
|
public partial class ProcessBookControl2 : UserControl
|
||||||
{
|
{
|
||||||
public static event QueueItemButtonClicked ButtonClicked;
|
public static event QueueItemPositionButtonClicked PositionButtonClicked;
|
||||||
|
public static event QueueItemCancelButtonClicked CancelButtonClicked;
|
||||||
public ProcessBookControl2()
|
public ProcessBookControl2()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -25,15 +20,15 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
private ProcessBook2 DataItem => DataContext is null ? null : DataContext as ProcessBook2;
|
private ProcessBook2 DataItem => DataContext is null ? null : DataContext as ProcessBook2;
|
||||||
|
|
||||||
public void Cancel_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
public void Cancel_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
=> ButtonClicked?.Invoke(DataItem, QueueButton.Cancel);
|
=> CancelButtonClicked?.Invoke(DataItem);
|
||||||
public void MoveFirst_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
public void MoveFirst_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
=> ButtonClicked?.Invoke(DataItem, QueueButton.MoveFirst);
|
=> PositionButtonClicked?.Invoke(DataItem, QueuePosition.Fisrt);
|
||||||
public void MoveUp_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
public void MoveUp_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
=> ButtonClicked?.Invoke(DataItem, QueueButton.MoveUp);
|
=> PositionButtonClicked?.Invoke(DataItem, QueuePosition.OneUp);
|
||||||
public void MoveDown_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
public void MoveDown_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
=> ButtonClicked?.Invoke(DataItem, QueueButton.MoveDown);
|
=> PositionButtonClicked?.Invoke(DataItem, QueuePosition.OneDown);
|
||||||
public void MoveLast_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
public void MoveLast_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
=> ButtonClicked?.Invoke(DataItem, QueueButton.MoveLast);
|
=> PositionButtonClicked?.Invoke(DataItem, QueuePosition.Last);
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<UserControl
|
<UserControl
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@ -7,7 +7,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
mc:Ignorable="d" d:DesignWidth="450" d:DesignHeight="700"
|
mc:Ignorable="d" d:DesignWidth="450" d:DesignHeight="700"
|
||||||
x:Class="LibationWinForms.AvaloniaUI.Views.ProcessQueueControl2">
|
x:Class="LibationWinForms.AvaloniaUI.Views.ProcessQueueControl2">
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<RecyclePool x:Key="RecyclePool" />
|
<RecyclePool x:Key="RecyclePool" />
|
||||||
<DataTemplate x:Key="odd">
|
<DataTemplate x:Key="odd">
|
||||||
@ -19,21 +19,66 @@
|
|||||||
</RecyclingElementFactory.Templates>
|
</RecyclingElementFactory.Templates>
|
||||||
</RecyclingElementFactory>
|
</RecyclingElementFactory>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<UserControl.Styles>
|
||||||
|
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
|
||||||
|
<Setter Property="Height" Value="20"/>
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
|
|
||||||
<Grid RowDefinitions="1*,30">
|
<Grid RowDefinitions="1*,30">
|
||||||
<TabControl Grid.Row="0">
|
<TabControl Grid.Row="0">
|
||||||
<!-- Queue Tab -->
|
<!-- Queue Tab -->
|
||||||
<TabItem>
|
<TabItem>
|
||||||
<TabItem.Header>
|
<TabItem.Header>
|
||||||
<TextBlock FontSize="14" Height="15" VerticalAlignment="Center">Process Queue</TextBlock>
|
<TextBlock FontSize="14" VerticalAlignment="Center">Process Queue</TextBlock>
|
||||||
</TabItem.Header>
|
</TabItem.Header>
|
||||||
<Grid ColumnDefinitions="1*" RowDefinitions="1*,40">
|
<Grid ColumnDefinitions="*" RowDefinitions="*,40">
|
||||||
<ScrollViewer Grid.Column="0" Grid.Row="0" Name="scroller" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Visible" >
|
<Border Grid.Column="0" Grid.Row="0" BorderThickness="1" BorderBrush="Black" Background="WhiteSmoke">
|
||||||
<ItemsRepeater Name="repeater" VerticalCacheLength="1.2" HorizontalCacheLength="1" Background="Transparent" Items="{Binding Items}" ItemTemplate="{StaticResource elementFactory}" />
|
<ScrollViewer
|
||||||
</ScrollViewer>
|
Name="scroller"
|
||||||
<Grid Grid.Column="0" Grid.Row="1" ColumnDefinitions="2*,1*,2*">
|
HorizontalScrollBarVisibility="Disabled"
|
||||||
<Button Grid.Column="0" FontSize="13" HorizontalAlignment="Left" Click="CancelAllBtn_Click">Cancel All</Button>
|
VerticalScrollBarVisibility="Auto">
|
||||||
<Button Grid.Column="2" FontSize="13" HorizontalAlignment="Right" Click="ClearFinishedBtn_Click">Clear Finished</Button>
|
<ItemsRepeater IsVisible="True"
|
||||||
|
Grid.Column="0"
|
||||||
|
Name="repeater"
|
||||||
|
VerticalCacheLength="1.2"
|
||||||
|
HorizontalCacheLength="1"
|
||||||
|
Background="Transparent"
|
||||||
|
Items="{Binding Items}"
|
||||||
|
ItemTemplate="{StaticResource elementFactory}" />
|
||||||
|
</ScrollViewer>
|
||||||
|
</Border>
|
||||||
|
<Grid Grid.Column="0" Grid.Row="1" ColumnDefinitions="*,Auto" Margin="6,0,6,0">
|
||||||
|
<Button Grid.Column="0" FontSize="12" HorizontalAlignment="Left" Click="CancelAllBtn_Click">Cancel All</Button>
|
||||||
|
<Button Grid.Column="1" FontSize="12" HorizontalAlignment="Right" Click="ClearFinishedBtn_Click">Clear Finished</Button>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
<TabItem>
|
||||||
|
<TabItem.Header>
|
||||||
|
<TextBlock FontSize="14" VerticalAlignment="Center">Queue Log</TextBlock>
|
||||||
|
</TabItem.Header>
|
||||||
|
<Grid ColumnDefinitions="*" RowDefinitions="*,40">
|
||||||
|
<Border Grid.Column="0" Grid.Row="0" BorderThickness="1" BorderBrush="Black" Background="WhiteSmoke">
|
||||||
|
<DataGrid AutoGenerateColumns="False" Items="{Binding LogEntries}">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn SortMemberPath="LogDate" Header="Timestamp" CanUserSort="True" Binding="{Binding LogDateString}" Width="90"/>
|
||||||
|
<DataGridTemplateColumn SortMemberPath="LogMessage" Width="*" Header="Message" CanUserSort="True">
|
||||||
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border BorderThickness="3">
|
||||||
|
<TextBlock VerticalAlignment="Center" TextWrapping="Wrap" Text="{Binding LogMessage}" />
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
|
</DataGridTemplateColumn>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
</Border>
|
||||||
|
<Grid Grid.Column="0" Grid.Row="1" ColumnDefinitions="*,Auto" Margin="6,0,6,0">
|
||||||
|
<Button Grid.Column="0" FontSize="12" HorizontalAlignment="Left" Click="LogCopyBtn_Click">Copy Log Entries to Clipboard</Button>
|
||||||
|
<Button Grid.Column="1" FontSize="12" HorizontalAlignment="Right" Click="ClearLogBtn_Click">Clear Log</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|||||||
@ -7,6 +7,7 @@ using Avalonia.Threading;
|
|||||||
using LibationWinForms.AvaloniaUI.ViewModels;
|
using LibationWinForms.AvaloniaUI.ViewModels;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -65,7 +66,8 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
_repeater.KeyDown += RepeaterOnKeyDown;
|
_repeater.KeyDown += RepeaterOnKeyDown;
|
||||||
DataContext = _viewModel = new ProcessQueueViewModel();
|
DataContext = _viewModel = new ProcessQueueViewModel();
|
||||||
|
|
||||||
ProcessBookControl2.ButtonClicked += ProcessBookControl2_ButtonClicked;
|
ProcessBookControl2.PositionButtonClicked += ProcessBookControl2_ButtonClicked;
|
||||||
|
ProcessBookControl2.CancelButtonClicked += ProcessBookControl2_CancelButtonClicked;
|
||||||
|
|
||||||
queueNumberLbl_Icon = this.FindControl<Image>(nameof(queueNumberLbl_Icon));
|
queueNumberLbl_Icon = this.FindControl<Image>(nameof(queueNumberLbl_Icon));
|
||||||
errorNumberLbl_Icon = this.FindControl<Image>(nameof(errorNumberLbl_Icon));
|
errorNumberLbl_Icon = this.FindControl<Image>(nameof(errorNumberLbl_Icon));
|
||||||
@ -99,29 +101,17 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ProcessBookControl2_ButtonClicked(ProcessBook2 item, QueueButton queueButton)
|
private async void ProcessBookControl2_CancelButtonClicked(ProcessBook2 item)
|
||||||
|
{
|
||||||
|
if (item is not null)
|
||||||
|
await item.CancelAsync();
|
||||||
|
Queue.RemoveQueued(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessBookControl2_ButtonClicked(ProcessBook2 item, QueuePosition queueButton)
|
||||||
{
|
{
|
||||||
switch (queueButton)
|
Queue.MoveQueuePosition(item, queueButton);
|
||||||
{
|
}
|
||||||
case QueueButton.MoveFirst:
|
|
||||||
Queue.MoveQueuePosition(item, QueuePosition.Fisrt);
|
|
||||||
break;
|
|
||||||
case QueueButton.MoveUp:
|
|
||||||
Queue.MoveQueuePosition(item, QueuePosition.OneUp);
|
|
||||||
break;
|
|
||||||
case QueueButton.MoveDown:
|
|
||||||
Queue.MoveQueuePosition(item, QueuePosition.OneDown);
|
|
||||||
break;
|
|
||||||
case QueueButton.MoveLast:
|
|
||||||
Queue.MoveQueuePosition(item, QueuePosition.Last);
|
|
||||||
break;
|
|
||||||
case QueueButton.Cancel:
|
|
||||||
if (item is not null)
|
|
||||||
await item.CancelAsync();
|
|
||||||
Queue.RemoveQueued(item);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RepeaterClick(object sender, PointerPressedEventArgs e)
|
private void RepeaterClick(object sender, PointerPressedEventArgs e)
|
||||||
{
|
{
|
||||||
@ -154,6 +144,18 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
runningTimeLbl.Text = string.Empty;
|
runningTimeLbl.Text = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearLogBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_viewModel.LogEntries.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogCopyBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
string logText = string.Join("\r\n", _viewModel.LogEntries.Select(r => $"{r.LogDate.ToShortDateString()} {r.LogDate.ToShortTimeString()}\t{r.LogMessage}"));
|
||||||
|
System.Windows.Forms.Clipboard.SetDataObject(logText, false, 5, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool isBookInQueue(DataLayer.LibraryBook libraryBook)
|
private bool isBookInQueue(DataLayer.LibraryBook libraryBook)
|
||||||
=> Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId);
|
=> Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId);
|
||||||
|
|
||||||
@ -267,7 +269,12 @@ namespace LibationWinForms.AvaloniaUI.Views
|
|||||||
|
|
||||||
public void WriteLine(string text)
|
public void WriteLine(string text)
|
||||||
{
|
{
|
||||||
|
Dispatcher.UIThread.Post(() =>
|
||||||
|
_viewModel.LogEntries.Add(new()
|
||||||
|
{
|
||||||
|
LogDate = DateTime.Now,
|
||||||
|
LogMessage = text.Trim()
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Control event handlers
|
#region Control event handlers
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
|
|
||||||
<controls:DataGridCheckBoxColumnExt IsVisible="True" Header="Remove" IsThreeState="True" IsReadOnly="False" CanUserSort="True" Binding="{Binding Remove, Mode=TwoWay}" Width="70" SortMemberPath="Remove"/>
|
<controls:DataGridCheckBoxColumnExt IsVisible="False" Header="Remove" IsThreeState="True" IsReadOnly="False" CanUserSort="True" Binding="{Binding Remove, Mode=TwoWay}" Width="70" SortMemberPath="Remove"/>
|
||||||
|
|
||||||
<DataGridTemplateColumn CanUserSort="True" Width="75" Header="Liberate" SortMemberPath="Liberate">
|
<DataGridTemplateColumn CanUserSort="True" Width="75" Header="Liberate" SortMemberPath="Liberate">
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user