Refinements
This commit is contained in:
parent
f8e9c16bc1
commit
5f45d28b9f
BIN
Source/LibationWinForms/AvaloniaUI/Assets/edit_25x25.png
Normal file
BIN
Source/LibationWinForms/AvaloniaUI/Assets/edit_25x25.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 747 B |
@ -1,52 +1,9 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
{
|
||||
public class BookTags
|
||||
{
|
||||
private static Bitmap _buttonImage;
|
||||
|
||||
static BookTags()
|
||||
{
|
||||
var memoryStream = new System.IO.MemoryStream();
|
||||
|
||||
Properties.Resources.edit_25x25.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
memoryStream.Position = 0;
|
||||
_buttonImage = new Bitmap(memoryStream);
|
||||
|
||||
}
|
||||
|
||||
public string Tags { get; init; }
|
||||
public bool IsSeries { get; init; }
|
||||
|
||||
public Control Control
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsSeries)
|
||||
return null;
|
||||
|
||||
if (string.IsNullOrEmpty(Tags))
|
||||
{
|
||||
return new Image
|
||||
{
|
||||
Stretch = Avalonia.Media.Stretch.None,
|
||||
Source = _buttonImage
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TextBlock
|
||||
{
|
||||
Text = Tags,
|
||||
Margin = new Avalonia.Thickness(0, 0),
|
||||
TextWrapping = Avalonia.Media.TextWrapping.WrapWithOverflow
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool HasTags => !string.IsNullOrEmpty(Tags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
Category = string.Join(" > ", Book.CategoriesNames());
|
||||
Misc = GetMiscDisplay(libraryBook);
|
||||
LongDescription = GetDescriptionDisplay(Book);
|
||||
Description = LongDescription;
|
||||
Description = TrimTextToWord(LongDescription, 62);
|
||||
SeriesIndex = Book.SeriesLink.FirstOrDefault()?.Index ?? 0;
|
||||
|
||||
NotifyPropertyChanged(nameof(Title));
|
||||
|
||||
@ -53,8 +53,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
private Bitmap _cover;
|
||||
|
||||
#region Properties exposed to the view
|
||||
public ProcessBookResult Result { get => _result; private set { _result = value; NotifyPropertyChanged(); NotifyPropertyChanged(nameof(StatusText)); } }
|
||||
public ProcessBookStatus Status { get => _status; private set { _status = value; NotifyPropertyChanged(); NotifyPropertyChanged(nameof(BackgroundColor)); NotifyPropertyChanged(nameof(IsFinished)); NotifyPropertyChanged(nameof(IsDownloading)); NotifyPropertyChanged(nameof(Queued)); } }
|
||||
public ProcessBookResult Result { get => _result; set { _result = value; NotifyPropertyChanged(); NotifyPropertyChanged(nameof(StatusText)); } }
|
||||
public ProcessBookStatus Status { get => _status; set { _status = value; NotifyPropertyChanged(); NotifyPropertyChanged(nameof(BackgroundColor)); NotifyPropertyChanged(nameof(IsFinished)); NotifyPropertyChanged(nameof(IsDownloading)); NotifyPropertyChanged(nameof(Queued)); } }
|
||||
public string Narrator { get => _narrator; set { _narrator = value; NotifyPropertyChanged(); } }
|
||||
public string Author { get => _author; set { _author = value; NotifyPropertyChanged(); } }
|
||||
public string Title { get => _title; set { _title = value; NotifyPropertyChanged(); } }
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
using ReactiveUI;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
{
|
||||
public class ProcessQueueViewModel : ViewModelBase
|
||||
public class ProcessQueueViewModel : ViewModelBase, ProcessQueue.ILogForm
|
||||
{
|
||||
|
||||
public string QueueHeader => "this is a header!";
|
||||
@ -24,6 +21,17 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
public ObservableCollection<LogEntry> LogEntries { get; } = new();
|
||||
|
||||
public ProcessBook2 SelectedItem { get; set; }
|
||||
|
||||
public void WriteLine(string text)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
LogEntries.Add(new()
|
||||
{
|
||||
LogDate = DateTime.Now,
|
||||
LogMessage = text.Trim()
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class LogEntry
|
||||
|
||||
@ -91,13 +91,11 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
Category = string.Join(" > ", Book.CategoriesNames());
|
||||
Misc = GetMiscDisplay(LibraryBook);
|
||||
LongDescription = GetDescriptionDisplay(Book);
|
||||
Description = LongDescription;
|
||||
Description = TrimTextToWord(LongDescription, 62);
|
||||
|
||||
int bookLenMins = Children.Sum(c => c.LibraryBook.Book.LengthInMinutes);
|
||||
Length = bookLenMins == 0 ? "" : $"{bookLenMins / 60} hr {bookLenMins % 60} min";
|
||||
|
||||
|
||||
|
||||
NotifyPropertyChanged(nameof(Title));
|
||||
NotifyPropertyChanged(nameof(Series));
|
||||
NotifyPropertyChanged(nameof(Length));
|
||||
@ -110,8 +108,6 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
NotifyPropertyChanged(nameof(Misc));
|
||||
NotifyPropertyChanged(nameof(LongDescription));
|
||||
NotifyPropertyChanged(nameof(Description));
|
||||
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
|
||||
#region Data Sorting
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:views="clr-namespace:LibationWinForms.AvaloniaUI.Views"
|
||||
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="850"
|
||||
x:Class="LibationWinForms.AvaloniaUI.Views.ProcessQueueControl2">
|
||||
|
||||
<UserControl.Resources>
|
||||
|
||||
@ -4,6 +4,7 @@ using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Threading;
|
||||
using DataLayer;
|
||||
using LibationWinForms.AvaloniaUI.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -13,7 +14,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace LibationWinForms.AvaloniaUI.Views
|
||||
{
|
||||
public partial class ProcessQueueControl2 : UserControl, ProcessQueue.ILogForm
|
||||
public partial class ProcessQueueControl2 : UserControl
|
||||
{
|
||||
private readonly ProcessQueueViewModel _viewModel;
|
||||
private ItemsRepeater _repeater;
|
||||
@ -65,6 +66,7 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
_repeater.PointerPressed += RepeaterClick;
|
||||
_repeater.KeyDown += RepeaterOnKeyDown;
|
||||
DataContext = _viewModel = new ProcessQueueViewModel();
|
||||
Logger = ProcessQueue.LogMe.RegisterForm(_viewModel);
|
||||
|
||||
ProcessBookControl2.PositionButtonClicked += ProcessBookControl2_ButtonClicked;
|
||||
ProcessBookControl2.CancelButtonClicked += ProcessBookControl2_CancelButtonClicked;
|
||||
@ -81,19 +83,68 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
|
||||
toolStripProgressBar1 = this.FindControl<ProgressBar>(nameof(toolStripProgressBar1));
|
||||
|
||||
Logger = ProcessQueue.LogMe.RegisterForm(this);
|
||||
|
||||
Queue.QueuededCountChanged += Queue_QueuededCountChanged;
|
||||
Queue.CompletedCountChanged += Queue_CompletedCountChanged;
|
||||
|
||||
#region Design Mode Testing
|
||||
if (Design.IsDesignMode)
|
||||
return;
|
||||
{
|
||||
using var context = DbContexts.GetContext();
|
||||
var book = context.GetLibraryBook_Flat_NoTracking("B017V4IM1G");
|
||||
List<ProcessBook2> testList = new()
|
||||
{
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.FailedAbort,
|
||||
Status = ProcessBookStatus.Failed,
|
||||
},
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.FailedSkip,
|
||||
Status = ProcessBookStatus.Failed,
|
||||
},
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.FailedRetry,
|
||||
Status = ProcessBookStatus.Failed,
|
||||
},
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.ValidationFail,
|
||||
Status = ProcessBookStatus.Failed,
|
||||
},
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.Cancelled,
|
||||
Status = ProcessBookStatus.Cancelled,
|
||||
},
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.Success,
|
||||
Status = ProcessBookStatus.Completed,
|
||||
},
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.None,
|
||||
Status = ProcessBookStatus.Working,
|
||||
},
|
||||
new ProcessBook2(book, Logger)
|
||||
{
|
||||
Result = ProcessBookResult.None,
|
||||
Status = ProcessBookStatus.Queued,
|
||||
},
|
||||
};
|
||||
|
||||
runningTimeLbl.Text = string.Empty;
|
||||
QueuedCount = 0;
|
||||
ErrorCount = 0;
|
||||
CompletedCount = 0;
|
||||
_viewModel.Items.Enqueue(testList);
|
||||
return;
|
||||
}
|
||||
#endregion
|
||||
|
||||
runningTimeLbl.Text = string.Empty;
|
||||
QueuedCount = 0;
|
||||
ErrorCount = 0;
|
||||
CompletedCount = 0;
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
@ -156,19 +207,19 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
}
|
||||
|
||||
|
||||
private bool isBookInQueue(DataLayer.LibraryBook libraryBook)
|
||||
private bool isBookInQueue(LibraryBook libraryBook)
|
||||
=> Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId);
|
||||
|
||||
public void AddDownloadPdf(DataLayer.LibraryBook libraryBook)
|
||||
=> AddDownloadPdf(new List<DataLayer.LibraryBook>() { libraryBook });
|
||||
public void AddDownloadPdf(LibraryBook libraryBook)
|
||||
=> AddDownloadPdf(new List<LibraryBook>() { libraryBook });
|
||||
|
||||
public void AddDownloadDecrypt(DataLayer.LibraryBook libraryBook)
|
||||
=> AddDownloadDecrypt(new List<DataLayer.LibraryBook>() { libraryBook });
|
||||
public void AddDownloadDecrypt(LibraryBook libraryBook)
|
||||
=> AddDownloadDecrypt(new List<LibraryBook>() { libraryBook });
|
||||
|
||||
public void AddConvertMp3(DataLayer.LibraryBook libraryBook)
|
||||
=> AddConvertMp3(new List<DataLayer.LibraryBook>() { libraryBook });
|
||||
public void AddConvertMp3(LibraryBook libraryBook)
|
||||
=> AddConvertMp3(new List<LibraryBook>() { libraryBook });
|
||||
|
||||
public void AddDownloadPdf(IEnumerable<DataLayer.LibraryBook> entries)
|
||||
public void AddDownloadPdf(IEnumerable<LibraryBook> entries)
|
||||
{
|
||||
List<ProcessBook2> procs = new();
|
||||
foreach (var entry in entries)
|
||||
@ -185,7 +236,7 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
AddToQueue(procs);
|
||||
}
|
||||
|
||||
public void AddDownloadDecrypt(IEnumerable<DataLayer.LibraryBook> entries)
|
||||
public void AddDownloadDecrypt(IEnumerable<LibraryBook> entries)
|
||||
{
|
||||
List<ProcessBook2> procs = new();
|
||||
foreach (var entry in entries)
|
||||
@ -203,7 +254,7 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
AddToQueue(procs);
|
||||
}
|
||||
|
||||
public void AddConvertMp3(IEnumerable<DataLayer.LibraryBook> entries)
|
||||
public void AddConvertMp3(IEnumerable<LibraryBook> entries)
|
||||
{
|
||||
List<ProcessBook2> procs = new();
|
||||
foreach (var entry in entries)
|
||||
@ -266,17 +317,6 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
Serilog.Log.Logger.Error(ex, "An error was encountered while processing queued items");
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteLine(string text)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
_viewModel.LogEntries.Add(new()
|
||||
{
|
||||
LogDate = DateTime.Now,
|
||||
LogMessage = text.Trim()
|
||||
}));
|
||||
}
|
||||
|
||||
#region Control event handlers
|
||||
|
||||
private void Queue_CompletedCountChanged(object sender, int e)
|
||||
|
||||
@ -6,13 +6,11 @@
|
||||
xmlns:controls="clr-namespace:LibationWinForms.AvaloniaUI.Controls"
|
||||
mc:Ignorable="d" d:DesignWidth="1560" d:DesignHeight="400"
|
||||
x:Class="LibationWinForms.AvaloniaUI.Views.ProductsDisplay2">
|
||||
|
||||
|
||||
|
||||
<Grid>
|
||||
<DataGrid Name="productsGrid" AutoGenerateColumns="False" Items="{Binding GridEntries}">
|
||||
|
||||
<DataGrid.Columns>
|
||||
|
||||
|
||||
<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">
|
||||
@ -25,8 +23,7 @@
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="80" Header="Cover">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
@ -36,7 +33,7 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="200" Header="Title" CanUserSort="True" SortMemberPath="Title">
|
||||
<DataGridTemplateColumn MinWidth="150" Width="2*" Header="Title" CanUserSort="True" SortMemberPath="Title">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderThickness="3" Height="80">
|
||||
@ -46,7 +43,7 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="100" Header="Authors" CanUserSort="True" SortMemberPath="Authors">
|
||||
<DataGridTemplateColumn MinWidth="80" Width="1*" Header="Authors" CanUserSort="True" SortMemberPath="Authors">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderThickness="3" Height="80">
|
||||
@ -56,7 +53,7 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="100" Header="Narrators" CanUserSort="True" SortMemberPath="Narrators">
|
||||
<DataGridTemplateColumn MinWidth="80" Width="1*" Header="Narrators" CanUserSort="True" SortMemberPath="Narrators">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderThickness="3" Height="80">
|
||||
@ -66,7 +63,7 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="100" Header="Length" CanUserSort="True" SortMemberPath="Length">
|
||||
<DataGridTemplateColumn MinWidth="80" Width="1*" Header="Length" CanUserSort="True" SortMemberPath="Length">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderThickness="3" Height="80">
|
||||
@ -76,7 +73,7 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="100" Header="Series" CanUserSort="True" SortMemberPath="Series">
|
||||
<DataGridTemplateColumn MinWidth="80" Width="1*" Header="Series" CanUserSort="True" SortMemberPath="Series">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderThickness="3" Height="80">
|
||||
@ -150,7 +147,12 @@
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Width="100" Height="80" Click="OnTagsButtonClick" ToolTip.Tip="Click to edit tags" Content="{Binding BookTags.Control}" />
|
||||
<Button IsVisible="{Binding !BookTags.IsSeries}" Width="100" Height="80" Click="OnTagsButtonClick" ToolTip.Tip="Click to edit tags" >
|
||||
<Panel>
|
||||
<Image IsVisible="{Binding !BookTags.HasTags}" Stretch="None" Source="/AvaloniaUI/Assets/edit_25x25.png" />
|
||||
<TextBlock IsVisible="{Binding BookTags.HasTags}" FontSize="12" TextWrapping="WrapWithOverflow" Text="{Binding BookTags.Tags}"/>
|
||||
</Panel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
|
||||
@ -3,6 +3,7 @@ using AudibleUtilities;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
using DataLayer;
|
||||
using Dinah.Core.DataBinding;
|
||||
using FileLiberator;
|
||||
@ -26,7 +27,7 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
public event EventHandler InitialLoaded;
|
||||
|
||||
private ProductsDisplayViewModel _viewModel;
|
||||
private GridEntryBindingList2 bindingList => productsGrid.Items as GridEntryBindingList2;
|
||||
private GridEntryBindingList2 bindingList => _viewModel.GridEntries;
|
||||
private IEnumerable<LibraryBookEntry2> GetAllBookEntries()
|
||||
=> bindingList.AllItems().BookEntries();
|
||||
|
||||
@ -46,12 +47,14 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
productsGrid.CanUserSortColumns = true;
|
||||
|
||||
removeGVColumn = productsGrid.Columns[0];
|
||||
}
|
||||
public override void EndInit()
|
||||
{
|
||||
base.EndInit();
|
||||
}
|
||||
|
||||
if (Design.IsDesignMode)
|
||||
{
|
||||
using var context = DbContexts.GetContext();
|
||||
var book = context.GetLibraryBook_Flat_NoTracking("B017V4IM1G");
|
||||
productsGrid.DataContext = _viewModel = new ProductsDisplayViewModel(new List<LibraryBook> { book });
|
||||
}
|
||||
}
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
@ -325,7 +328,8 @@ namespace LibationWinForms.AvaloniaUI.Views
|
||||
InitialLoaded?.Invoke(this, EventArgs.Empty);
|
||||
VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count());
|
||||
}
|
||||
UpdateGrid(dbBooks);
|
||||
else
|
||||
UpdateGrid(dbBooks);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
<None Remove="AvaloniaUI\Assets\cancel.png" />
|
||||
<None Remove="AvaloniaUI\Assets\completed.png" />
|
||||
<None Remove="AvaloniaUI\Assets\down.png" />
|
||||
<None Remove="AvaloniaUI\Assets\edit_25x25.png" />
|
||||
<None Remove="AvaloniaUI\Assets\errored.png" />
|
||||
<None Remove="AvaloniaUI\Assets\first.png" />
|
||||
<None Remove="AvaloniaUI\Assets\import_16x16.png" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user