diff --git a/App.axaml b/App.axaml
index 36da22d..c1073a1 100644
--- a/App.axaml
+++ b/App.axaml
@@ -8,6 +8,7 @@
+
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..c67685f
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,5 @@
+
+
+ 11.3.12
+
+
diff --git a/MainWindow.axaml b/MainWindow.axaml
index 0976566..8a74edb 100644
--- a/MainWindow.axaml
+++ b/MainWindow.axaml
@@ -7,9 +7,9 @@
Title="Receipt PDF Builder"
xmlns:vm="clr-namespace:ReceiptPDFBuilder.ViewModels"
x:DataType="vm:MainWindowViewModel"
- Width="500"
- MinWidth="300"
- Height="350"
- MinHeight="300">
+ Width="800"
+ MinWidth="400"
+ Height="600"
+ MinHeight="400">
diff --git a/Models/ReportFile.cs b/Models/ReportFile.cs
new file mode 100644
index 0000000..93b1932
--- /dev/null
+++ b/Models/ReportFile.cs
@@ -0,0 +1,78 @@
+using System;
+using System.IO;
+using ReceiptPDFBuilder.Helpers;
+
+namespace ReceiptPDFBuilder.Models;
+
+class ReportFile : ChangeNotifier
+{
+ private string _title;
+ private DateOnly _date;
+ private DateTime _dateTime;
+ private DateTimeOffset _dto;
+ private string _notes;
+ private string _filePath;
+
+ public ReportFile()
+ {
+ _title = "";
+ _date = DateOnly.FromDateTime(DateTime.Now);
+ _notes = "";
+ _filePath = "";
+ }
+
+ public string Title
+ {
+ get => _title;
+ set { _title = value; NotifyPropertyChanged(); }
+ }
+
+ public DateOnly Date
+ {
+ get => _date;
+ set
+ {
+ _date = value;
+ DateTime = value.ToDateTime(TimeOnly.MinValue);
+ DTO = new DateTimeOffset(value.ToDateTime(TimeOnly.MinValue));
+ NotifyPropertyChanged();
+ }
+ }
+
+ public DateTime DateTime
+ {
+ get => _dateTime;
+ set
+ {
+ _dateTime = value;
+ NotifyPropertyChanged();
+ }
+ }
+
+ public DateTimeOffset DTO
+ {
+ get => _dto;
+ set
+ {
+ _dto = value;
+ NotifyPropertyChanged();
+ }
+ }
+
+ public string Notes
+ {
+ get => _notes;
+ set { _notes = value; NotifyPropertyChanged(); }
+ }
+
+ public string FilePath
+ {
+ get => _filePath;
+ set { _filePath = value; NotifyPropertyChanged(); }
+ }
+
+ public string FileName
+ {
+ get => Path.GetFileName(_filePath);
+ }
+}
\ No newline at end of file
diff --git a/ReceiptPDFBuilder.csproj b/ReceiptPDFBuilder.csproj
index 681c2b7..52414ce 100644
--- a/ReceiptPDFBuilder.csproj
+++ b/ReceiptPDFBuilder.csproj
@@ -34,17 +34,17 @@
-
-
-
-
-
-
+
+
+
+
+
+
None
All
-
+
diff --git a/ViewModels/MainViewModel.cs b/ViewModels/MainViewModel.cs
index 83e2e44..f2fe4d0 100644
--- a/ViewModels/MainViewModel.cs
+++ b/ViewModels/MainViewModel.cs
@@ -1,4 +1,7 @@
+#nullable enable
+
using System;
+using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Threading.Tasks;
@@ -10,6 +13,7 @@ using PdfSharp.Fonts;
using PdfSharp.Pdf.IO;
using PdfSharp.Snippets.Font;
using ReceiptPDFBuilder.Interfaces;
+using ReceiptPDFBuilder.Models;
namespace ReceiptPDFBuilder.ViewModels;
@@ -18,12 +22,17 @@ class MainViewModel : BaseViewModel, IFontResolver
private string _baseDir;
private bool _isCreatingPDF;
private string _createPDFLog;
+ private string _workingFolder;
+
+ private ObservableCollection _reportFiles;
public MainViewModel(IChangeViewModel viewModelChanger) : base(viewModelChanger)
{
_baseDir = Path.GetDirectoryName(Environment.ProcessPath) ?? "";
_isCreatingPDF = false;
- _createPDFLog = "Ready to create PDF!";
+ _createPDFLog = "Ready to create PDF! Choose a folder to begin...";
+ _reportFiles = new ObservableCollection();
+ _workingFolder = "";
}
public bool IsCreatingPDF
@@ -38,10 +47,17 @@ class MainViewModel : BaseViewModel, IFontResolver
set { _createPDFLog = value; NotifyPropertyChanged(); }
}
- private void LogInfo(string log)
+ public ObservableCollection ReportFiles
{
- Console.WriteLine(log);
- CreatePDFLog += Environment.NewLine + log;
+ get => _reportFiles;
+ set { _reportFiles = value; NotifyPropertyChanged(); }
+ }
+
+ private void LogInfo(string message, params object[]? arguments)
+ {
+ var timestamp = string.Format("[{0:s}]", DateTime.Now);
+ Console.WriteLine(timestamp + " " + message, arguments);
+ CreatePDFLog += Environment.NewLine + string.Format(message, arguments ?? []);
}
public async void ChooseFolder()
@@ -60,23 +76,23 @@ class MainViewModel : BaseViewModel, IFontResolver
LogInfo("Chosen folder: " + folder.Path.LocalPath);
if (Directory.Exists(folder.Path.LocalPath))
{
- try
+ _workingFolder = folder.Path.LocalPath;
+ // TODO: Scan folder for saved info from previous reports and reload if needed
+ // Scan folder for files and display in DataGrid
+ var filePaths = Directory.GetFiles(_workingFolder);
+ filePaths.Sort();
+ foreach (var filePath in filePaths)
{
- await Task.Run(() => CreatePDF(folder.Path.LocalPath));
- } catch (Exception e)
- {
- LogInfo("PDF process failed! Reason: " + e.Message);
- if (e.StackTrace != null)
+ if (!filePath.Contains(".DS_Store"))
{
- LogInfo(e.StackTrace);
- }
- if (e.InnerException != null)
- {
- LogInfo("Inner exception: " + e.InnerException.Message);
- if (e.InnerException.StackTrace != null)
+ // TODO: if date in file name, pull out that date instead
+ ReportFiles.Add(new ReportFile()
{
- LogInfo(e.InnerException.StackTrace);
- }
+ Title = Path.GetFileName(filePath),
+ Date = DateOnly.FromDateTime(File.GetCreationTime(filePath)),
+ Notes = "",
+ FilePath = filePath
+ });
}
}
}
@@ -84,6 +100,63 @@ class MainViewModel : BaseViewModel, IFontResolver
}
}
+ public void MoveItemUp(ReportFile file)
+ {
+ var idx = ReportFiles.IndexOf(file);
+ Console.WriteLine("{0} at idx {1}", file.Title, idx);
+ if (idx != 0)
+ {
+ // .Move() is not observed -_-
+ // https://github.com/AvaloniaUI/Avalonia.Controls.DataGrid/issues/74
+ // ReportFiles.Move(idx, idx - 1);
+ // So, remove and insert.
+ ReportFiles.RemoveAt(idx);
+ ReportFiles.Insert(idx - 1, file);
+ }
+ }
+
+ public void MoveItemDown(ReportFile file)
+ {
+ var idx = ReportFiles.IndexOf(file);
+ if (idx != ReportFiles.Count - 1)
+ {
+ ReportFiles.RemoveAt(idx);
+ ReportFiles.Insert(idx + 1, file);
+ }
+ }
+
+ public void RemoveFile(ReportFile file)
+ {
+ var idx = ReportFiles.IndexOf(file);
+ if (idx != -1)
+ {
+ ReportFiles.RemoveAt(idx);
+ }
+ }
+
+ private async void BuildPDF()
+ {
+ try
+ {
+ await Task.Run(() => CreatePDF(_workingFolder));
+ } catch (Exception e)
+ {
+ LogInfo("PDF process failed! Reason: " + e.Message);
+ if (e.StackTrace != null)
+ {
+ LogInfo(e.StackTrace);
+ }
+ if (e.InnerException != null)
+ {
+ LogInfo("Inner exception: " + e.InnerException.Message);
+ if (e.InnerException.StackTrace != null)
+ {
+ LogInfo(e.InnerException.StackTrace);
+ }
+ }
+ }
+ }
+
public byte[]? GetFont(string faceName)
{
LogInfo(string.Format("Loading font {0}", faceName));
diff --git a/Views/MainView.axaml b/Views/MainView.axaml
index 8b36833..73842eb 100644
--- a/Views/MainView.axaml
+++ b/Views/MainView.axaml
@@ -4,11 +4,12 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ReceiptPDFBuilder.Views.MainView"
+ xmlns:models="clr-namespace:ReceiptPDFBuilder.Models"
xmlns:vm="clr-namespace:ReceiptPDFBuilder.ViewModels"
xmlns:progRing="clr-namespace:AvaloniaProgressRing;assembly=AvaloniaProgressRing"
x:DataType="vm:MainViewModel">
+ RowDefinitions="Auto, Auto, *, *">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+