diff --git a/src/Helpers/Constants.cs b/src/Helpers/Constants.cs index 5d11ae5..11fc5c9 100644 --- a/src/Helpers/Constants.cs +++ b/src/Helpers/Constants.cs @@ -8,6 +8,8 @@ class Constants public static string[] AllowedFileExtensionPatterns = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp", "*.webp", "*.pdf", "*.heic", ]; public static string[] AllowedFileExtensionsNoStar = [ "png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "heic", ]; + public static string ReportSavedDataFileName = "report_data.json"; + public static string[] GetQuotes() { // sources: diff --git a/src/Models/Settings.cs b/src/Models/Settings.cs index 5d40ff0..c1b7002 100644 --- a/src/Models/Settings.cs +++ b/src/Models/Settings.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Text; using System.Text.Json; @@ -16,6 +17,9 @@ class Settings : ChangeNotifier private bool _saveOutputPdfInWorkingDir; private string _outputPdfDir; private decimal _imageResizeThreshold; + private bool _saveReportJsonDataInInternalDir; + private Dictionary _workingFolderToInternalFolderName; + public int _settingsVersion; public Settings() { @@ -24,6 +28,9 @@ class Settings : ChangeNotifier _saveOutputPdfInWorkingDir = true; _outputPdfDir = ""; _imageResizeThreshold = 1.5m; + _saveReportJsonDataInInternalDir = false; + _workingFolderToInternalFolderName = []; + _settingsVersion = 1; } public Settings(Settings other) @@ -33,6 +40,9 @@ class Settings : ChangeNotifier _saveOutputPdfInWorkingDir = other.SaveOutputPdfInWorkingDir; _outputPdfDir = other.OutputPdfDir; _imageResizeThreshold = other.ImageResizeThreshold; + _saveReportJsonDataInInternalDir = other.SaveReportJsonDataInInternalDir; + _workingFolderToInternalFolderName = other.WorkingFolderToInternalFolderName; + _settingsVersion = other.SettingsVersion; } [JsonInclude] @@ -71,15 +81,46 @@ class Settings : ChangeNotifier set { _imageResizeThreshold = value; NotifyPropertyChanged(); } } - public static string GetSettingsFileName() + [JsonInclude] + public bool SaveReportJsonDataInInternalDir { - return "settings.json"; + get => _saveReportJsonDataInInternalDir; + set { _saveReportJsonDataInInternalDir = value; NotifyPropertyChanged(); } } + [JsonInclude] + public Dictionary WorkingFolderToInternalFolderName + { + get => _workingFolderToInternalFolderName; + set { _workingFolderToInternalFolderName = value; NotifyPropertyChanged(); } + } + + [JsonInclude] + public int SettingsVersion + { + get => _settingsVersion; + set { _settingsVersion = value; NotifyPropertyChanged(); } + } + + public static string SettingsFileName = "settings.json"; + public static string GetSettingsPath() { var path = Utilities.GetInternalDataPath(); - return Path.Combine(path, GetSettingsFileName()); + return Path.Combine(path, SettingsFileName); + } + + + public string SaveSettingsNotAsync() + { + var jsonContext = new SourceGenerationContext(Utilities.GetSerializerOptions()); + using MemoryStream memoryStream = new MemoryStream(); + JsonSerializer.Serialize(memoryStream, this, jsonContext.Settings); + memoryStream.Position = 0; + using var reader = new StreamReader(memoryStream); + var json = reader.ReadToEnd(); + File.WriteAllText(GetSettingsPath(), json); + return json; } public async Task SaveSettingsAsync() diff --git a/src/ViewModels/MainViewModel.cs b/src/ViewModels/MainViewModel.cs index 11b9a87..6d0e81d 100644 --- a/src/ViewModels/MainViewModel.cs +++ b/src/ViewModels/MainViewModel.cs @@ -51,7 +51,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown { _isPerformingInitialLoad = true; _processDir = Path.GetDirectoryName(Environment.ProcessPath) ?? ""; - Console.WriteLine("Process is running from: {0}", _processDir); + Console.WriteLine("Internal storage directory is: {0}", Utilities.GetInternalDataPath()); _isCreatingPDF = false; var quotes = Constants.GetQuotes(); Random random = new Random(); @@ -93,7 +93,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown public bool IsTitleBoxVisible { - get => !string.IsNullOrWhiteSpace(_workingFolder); + get => !string.IsNullOrWhiteSpace(WorkingFolder); } public bool CanAddItem @@ -121,12 +121,12 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown public bool HasWorkingFolder { - get => !string.IsNullOrWhiteSpace(_workingFolder) && Directory.Exists(_workingFolder); + get => !string.IsNullOrWhiteSpace(WorkingFolder) && Directory.Exists(WorkingFolder); } public bool HasWorkingFolderAndNotMakingPDF { - get => !string.IsNullOrWhiteSpace(_workingFolder) && Directory.Exists(_workingFolder) && !_isCreatingPDF; + get => !string.IsNullOrWhiteSpace(WorkingFolder) && Directory.Exists(WorkingFolder) && !_isCreatingPDF; } public string WorkingFolder @@ -203,14 +203,49 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown } } + private string GetReportSavedDataPath(string folderPath) + { + if (_settings.SaveReportJsonDataInInternalDir) + { + var internalPath = Utilities.GetInternalDataPath(); + if (!_settings.WorkingFolderToInternalFolderName.ContainsKey(folderPath)) + { + var uuid = ""; + var potentialPath = ""; + var isDone = false; + // make sure uuid not already used...just in case...because paranoia... + do + { + uuid = Guid.NewGuid().ToString(); + potentialPath = Path.Combine(internalPath, uuid); + isDone = !Directory.Exists(potentialPath); + } while (!isDone); + // make internal dir -- using dir so we have option to copy data into dir later if needed + // (if we ever implement a more robust report system where we keep all files) + Directory.CreateDirectory(potentialPath); + _settings.WorkingFolderToInternalFolderName[folderPath] = uuid; + _settings.SaveSettingsNotAsync(); // save new key/value pair + } + return Path.Combine( + internalPath, + _settings.WorkingFolderToInternalFolderName[folderPath], + Constants.ReportSavedDataFileName + ); + } + else + { + return Path.Combine(folderPath, Constants.ReportSavedDataFileName); + } + } + private void ScanFolder(string path) { if (Directory.Exists(path)) { WorkingFolder = path; NotifyPropertyChanged(nameof(IsTitleBoxVisible)); - NotifyPropertyChanged(nameof(CanAddItem)); - var reportFilePath = Path.Combine(path, GetReportSavedDataFileName()); + NotifyPropertyChanged(nameof(CanAddItem)); + var reportFilePath = GetReportSavedDataPath(path); var successfullyLoadedPriorReport = false; if (File.Exists(reportFilePath)) { @@ -220,6 +255,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown var report = JsonSerializer.Deserialize(json, jsonContext.PDFReport); if (report != null && report.Files.Count > 0) { + Console.WriteLine("Loading prior report data at {0}", reportFilePath); ReportFiles = new ObservableCollection(report.Files); ReportTitle = report.Title; WorkingFolder = report.BaseFolder; @@ -233,7 +269,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown // Scan folder for files and display in DataGrid ReportFiles.Clear(); ReportTitle = ""; - var filePaths = Directory.GetFiles(_workingFolder); + var filePaths = Directory.GetFiles(WorkingFolder); foreach (var filePath in filePaths) { AddFileBasedOnPath(filePath); @@ -350,7 +386,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown } if (!didMatch) { - if (!filePath.EndsWith(GetReportSavedDataFileName())) + if (!filePath.EndsWith(Constants.ReportSavedDataFileName)) { LogInfo("File {0} did not match allowed file extension types, so it was not added.", filePath); } @@ -464,7 +500,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown { try { - await Task.Run(() => CreatePDF(_workingFolder)); + await Task.Run(() => CreatePDF(WorkingFolder)); } catch (Exception e) { LogInfo("PDF process failed! Reason: " + e.Message); @@ -492,7 +528,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown { Title = ReportTitle, Files = ReportFiles.ToList(), - BaseFolder = _workingFolder, + BaseFolder = WorkingFolder, LastSaved = DateTime.Now, LastGenerated = _lastGeneratedTime, }; @@ -507,7 +543,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown memoryStream.Position = 0; using var reader = new StreamReader(memoryStream); var json = await reader.ReadToEndAsync(); - var savePath = Path.Combine(_workingFolder, GetReportSavedDataFileName()); + var savePath = GetReportSavedDataPath(WorkingFolder); await File.WriteAllTextAsync(savePath, json); LogInfo("Saved report information to {0}", savePath); HasUnsavedWork = false; @@ -519,7 +555,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown { Title = ReportTitle, Files = ReportFiles.ToList(), - BaseFolder = _workingFolder, + BaseFolder = WorkingFolder, LastSaved = DateTime.Now, LastGenerated = DateTime.Now, }; @@ -527,11 +563,6 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown await SavePDFReportDataToDisk(report); } - private string GetReportSavedDataFileName() - { - return "report_data.json"; - } - public byte[]? GetFont(string faceName) { LogInfo(string.Format("Loading font {0}", faceName)); diff --git a/src/ViewModels/SettingsViewModel.cs b/src/ViewModels/SettingsViewModel.cs index 7a6ebd6..4b11678 100644 --- a/src/ViewModels/SettingsViewModel.cs +++ b/src/ViewModels/SettingsViewModel.cs @@ -94,7 +94,17 @@ class SettingsViewModel: ChangeNotifier set { _settings.ImageResizeThreshold = value; - NotifyPropertyChanged(nameof(ImageResizeThreshold)); + NotifyPropertyChanged(); + } + } + + public bool SaveReportJsonDataInInternalDir + { + get => _settings.SaveReportJsonDataInInternalDir; + set + { + _settings.SaveReportJsonDataInInternalDir = value; + NotifyPropertyChanged(); } } diff --git a/src/Views/SettingsView.axaml b/src/Views/SettingsView.axaml index 81746bd..9187843 100644 --- a/src/Views/SettingsView.axaml +++ b/src/Views/SettingsView.axaml @@ -35,7 +35,7 @@ Always save report PDF in working directory -