diff --git a/App.axaml b/App.axaml
index c800ae1..3f67de4 100644
--- a/App.axaml
+++ b/App.axaml
@@ -94,6 +94,9 @@
+
+
+
diff --git a/App.axaml.cs b/App.axaml.cs
index b27b8f8..90042c9 100644
--- a/App.axaml.cs
+++ b/App.axaml.cs
@@ -3,7 +3,9 @@ using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
+using DialogHostAvalonia;
using ReceiptPDFBuilder;
+using ReceiptPDFBuilder.ViewModels;
namespace ReceiptPDFBuilder;
@@ -26,6 +28,6 @@ public partial class App : Application
public void AboutOnClick(object? sender, EventArgs args)
{
- new AboutWindow().Show();
+ DialogHost.Show(new AboutViewModel());
}
}
\ No newline at end of file
diff --git a/Models/ReportFile.cs b/Models/ReportFile.cs
index 051b38e..00fe9b3 100644
--- a/Models/ReportFile.cs
+++ b/Models/ReportFile.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Text.Json.Serialization;
using ReceiptPDFBuilder.Helpers;
namespace ReceiptPDFBuilder.Models;
@@ -44,6 +45,7 @@ class ReportFile : ChangeNotifier
}
}
+ [JsonIgnore]
public DateOnly ReceiptDate
{
get => DateOnly.FromDateTime(_receiptDateTime);
@@ -61,6 +63,7 @@ class ReportFile : ChangeNotifier
set { _filePath = value; NotifyPropertyChanged(); }
}
+ [JsonIgnore]
public string FileName
{
get => Path.GetFileName(_filePath);
diff --git a/Models/Settings.cs b/Models/Settings.cs
new file mode 100644
index 0000000..09df28f
--- /dev/null
+++ b/Models/Settings.cs
@@ -0,0 +1,86 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+using ReceiptPDFBuilder.Helpers;
+
+namespace ReceiptPDFBuilder.Models;
+
+class Settings : ChangeNotifier
+{
+ private string _lastUsedPath;
+
+ public Settings()
+ {
+ _lastUsedPath = "";
+ }
+
+ [JsonInclude]
+ public string LastUsedPath
+ {
+ get => _lastUsedPath;
+ set { _lastUsedPath = value; NotifyPropertyChanged(); }
+ }
+
+ public static string GetSettingsFileName()
+ {
+ return "settings.json";
+ }
+
+ public static string GetSettingsPath()
+ {
+ var path = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
+ "ReceiptPDFBuilder"
+ );
+ if (!Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
+ }
+ return Path.Combine(path, GetSettingsFileName());
+ }
+
+ private static JsonSerializerOptions GetSerializerOptions()
+ {
+ var opts = new JsonSerializerOptions
+ {
+ WriteIndented = false,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ };
+ return opts;
+ }
+
+ public async Task SaveSettingsAsync()
+ {
+ var jsonContext = new SourceGenerationContext(GetSerializerOptions());
+ using MemoryStream memoryStream = new MemoryStream();
+ await JsonSerializer.SerializeAsync(memoryStream, this, jsonContext.Settings);
+ memoryStream.Position = 0;
+ using var reader = new StreamReader(memoryStream);
+ var json = await reader.ReadToEndAsync();
+ await File.WriteAllTextAsync(GetSettingsPath(), json);
+ return json;
+ }
+
+ public static Settings LoadSettings()
+ {
+ var path = GetSettingsPath();
+ if (!File.Exists(path))
+ {
+ return new Settings();
+ }
+ var json = File.ReadAllText(GetSettingsPath());
+ var jsonContext = new SourceGenerationContext(GetSerializerOptions());
+ return JsonSerializer.Deserialize(json, jsonContext.Settings) ?? new Settings();
+ }
+
+ public static async Task LoadSettingsAsync()
+ {
+ using FileStream fileStream = File.OpenRead(GetSettingsPath());
+ var jsonContext = new SourceGenerationContext(GetSerializerOptions());
+ var output = await JsonSerializer.DeserializeAsync(fileStream, jsonContext.Settings) ?? new Settings();
+ return output;
+ }
+}
\ No newline at end of file
diff --git a/ViewModels/AboutViewModel.cs b/ViewModels/AboutViewModel.cs
new file mode 100644
index 0000000..8f9404f
--- /dev/null
+++ b/ViewModels/AboutViewModel.cs
@@ -0,0 +1,33 @@
+#nullable enable
+
+using System;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Avalonia.Platform.Storage;
+using Avalonia.Themes.Fluent;
+using DialogHostAvalonia;
+using ImageMagick;
+using MigraDoc.DocumentObjectModel;
+using MigraDoc.Rendering;
+using PdfSharp.Fonts;
+using PdfSharp.Pdf.IO;
+using PdfSharp.Snippets.Font;
+using ReceiptPDFBuilder.Interfaces;
+using ReceiptPDFBuilder.Models;
+
+namespace ReceiptPDFBuilder.ViewModels;
+
+class AboutViewModel
+{
+ public AboutViewModel()
+ {
+ }
+
+ public void Close()
+ {
+ DialogHost.Close("DialogHost", null);
+ }
+}
\ No newline at end of file
diff --git a/ViewModels/MainViewModel.cs b/ViewModels/MainViewModel.cs
index c6f2119..e95676f 100644
--- a/ViewModels/MainViewModel.cs
+++ b/ViewModels/MainViewModel.cs
@@ -30,6 +30,8 @@ class MainViewModel : BaseViewModel, IFontResolver
private string _reportTitle;
private ObservableCollection _reportFiles;
+ private Settings _settings;
+
public MainViewModel(IChangeViewModel viewModelChanger) : base(viewModelChanger)
{
_baseDir = Path.GetDirectoryName(Environment.ProcessPath) ?? "";
@@ -39,6 +41,12 @@ class MainViewModel : BaseViewModel, IFontResolver
_reportFiles = new ObservableCollection();
_reportFiles.CollectionChanged += ( sender, e ) => { NotifyPropertyChanged(nameof(IsCreatePDFButtonEnabled)); };
_reportTitle = "";
+ _settings = Settings.LoadSettings();
+ if (!string.IsNullOrWhiteSpace(_settings.LastUsedPath))
+ {
+ LogInfo("Loading data at last used path of {0}", _settings.LastUsedPath);
+ ScanFolder(_settings.LastUsedPath);
+ }
}
public string ReportTitle
@@ -95,20 +103,27 @@ class MainViewModel : BaseViewModel, IFontResolver
if (folders.Count == 1)
{
var folder = folders[0];
- LogInfo("Chosen folder: " + folder.Path.LocalPath);
- if (Directory.Exists(folder.Path.LocalPath))
- {
- _workingFolder = folder.Path.LocalPath;
- NotifyPropertyChanged(nameof(IsTitleBoxVisible));
- // TODO: Scan folder for saved info from previous reports and reload that first
- // Scan folder for files and display in DataGrid
- var filePaths = Directory.GetFiles(_workingFolder);
- filePaths.Sort();
- foreach (var filePath in filePaths)
- {
- AddFileBasedOnPath(filePath);
- }
- }
+ LogInfo("Loading items in folder: " + folder.Path.LocalPath);
+ ScanFolder(folder.Path.LocalPath);
+ _settings.LastUsedPath = folder.Path.LocalPath;
+ await _settings.SaveSettingsAsync();
+ }
+ }
+ }
+
+ private void ScanFolder(string path)
+ {
+ if (Directory.Exists(path))
+ {
+ _workingFolder = path;
+ NotifyPropertyChanged(nameof(IsTitleBoxVisible));
+ // TODO: Scan folder for saved info from previous reports and reload that first
+ // Scan folder for files and display in DataGrid
+ var filePaths = Directory.GetFiles(_workingFolder);
+ filePaths.Sort();
+ foreach (var filePath in filePaths)
+ {
+ AddFileBasedOnPath(filePath);
}
}
}
diff --git a/Views/AboutView.axaml b/Views/AboutView.axaml
new file mode 100644
index 0000000..90d13af
--- /dev/null
+++ b/Views/AboutView.axaml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
diff --git a/Views/AboutView.axaml.cs b/Views/AboutView.axaml.cs
new file mode 100644
index 0000000..2d56b73
--- /dev/null
+++ b/Views/AboutView.axaml.cs
@@ -0,0 +1,15 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ReceiptPDFBuilder.Views
+{
+ public partial class AboutView : UserControl
+ {
+ public AboutView()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
diff --git a/Views/AboutWindow.axaml b/Views/AboutWindow.axaml
deleted file mode 100644
index 73c2126..0000000
--- a/Views/AboutWindow.axaml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
diff --git a/Views/AboutWindow.axaml.cs b/Views/AboutWindow.axaml.cs
deleted file mode 100644
index 18d98c7..0000000
--- a/Views/AboutWindow.axaml.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-
-namespace ReceiptPDFBuilder;
-
-public partial class AboutWindow : Window
-{
- public AboutWindow()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file