Przeglądaj źródła

Autosave: immediately persist books.xml after editing a book

- Add unitAppEvents with NotifyBooksChanged callback
- main: register @SaveBooksNow and implement it
- book: call NotifyBooksChanged after dialog OK to autosave changes
Codex CLI 4 miesięcy temu
rodzic
commit
92b11b9da0
3 zmienionych plików z 42 dodań i 2 usunięć
  1. 3 1
      src/book.pas
  2. 15 1
      src/main.pas
  3. 24 0
      src/unitAppEvents.pas

+ 3 - 1
src/book.pas

@@ -53,7 +53,7 @@ procedure SetPdfCoverGenerationEnabled(AEnabled: Boolean);
 
 
 implementation
 implementation
 
 
-uses UnitBookDialog, Forms;
+uses UnitBookDialog, Forms, unitAppEvents;
 
 
 procedure TBook.OpenEditDialogAsync({%H-}Data: PtrInt);
 procedure TBook.OpenEditDialogAsync({%H-}Data: PtrInt);
 var
 var
@@ -66,6 +66,8 @@ begin
     begin
     begin
       EnsureScaledToCoverSize;
       EnsureScaledToCoverSize;
       if Assigned(mCover) then mCover.Invalidate;
       if Assigned(mCover) then mCover.Invalidate;
+      // Persist changes immediately
+      NotifyBooksChanged;
     end;
     end;
   finally
   finally
     dlg.Free;
     dlg.Free;

+ 15 - 1
src/main.pas

@@ -7,7 +7,7 @@ interface
 uses
 uses
   Classes, Sysutils, Fileutil, Forms, Controls, Graphics, Dialogs, ExtCtrls, LazFileUtils,
   Classes, Sysutils, Fileutil, Forms, Controls, Graphics, Dialogs, ExtCtrls, LazFileUtils,
   Book, BookCollection, LCLIntf, LResources, StdCtrls, LCLType, IniFiles, unitSettingsDialog,
   Book, BookCollection, LCLIntf, LResources, StdCtrls, LCLType, IniFiles, unitSettingsDialog,
-  unitCoverWorker, unitStorageXML, unitMetadata, LazUTF8;
+  unitCoverWorker, unitStorageXML, unitMetadata, unitAppEvents, LazUTF8;
 
 
 
 
 type
 type
@@ -52,6 +52,7 @@ type
     procedure LayoutTimerTick(Sender: TObject);
     procedure LayoutTimerTick(Sender: TObject);
     procedure ApplyFilterAndLayout;
     procedure ApplyFilterAndLayout;
     function AppConfigPath: String;
     function AppConfigPath: String;
+    procedure SaveBooksNow;
   public
   public
     { public declarations }
     { public declarations }
   end;
   end;
@@ -93,6 +94,16 @@ begin
   Result := IncludeTrailingPathDelimiter(GetAppConfigDirUTF8(False)) + 'config.ini';
   Result := IncludeTrailingPathDelimiter(GetAppConfigDirUTF8(False)) + 'config.ini';
 end;
 end;
 
 
+procedure TForm1.SaveBooksNow;
+begin
+  try
+    if Assigned(bookList) then
+      SaveBooksXML(dataXmlPath, bookList);
+  except
+    // ignore save errors during runtime autosave
+  end;
+end;
+
 procedure TForm1.PanelBackgroundClick({%H-}Sender: TObject);
 procedure TForm1.PanelBackgroundClick({%H-}Sender: TObject);
 begin
 begin
  ActiveControl:=PanelBackground;
  ActiveControl:=PanelBackground;
@@ -549,6 +560,9 @@ begin
 
 
  bookList:=TBookCollection.Create;
  bookList:=TBookCollection.Create;
 
 
+  // Register autosave callback for book edits
+  OnBooksChanged := @SaveBooksNow;
+
   // speed up startup: we skipped synchronous PDF generation during load
   // speed up startup: we skipped synchronous PDF generation during load
   SetPdfCoverGenerationEnabled(False);
   SetPdfCoverGenerationEnabled(False);
   try
   try

+ 24 - 0
src/unitAppEvents.pas

@@ -0,0 +1,24 @@
+unit unitAppEvents;
+
+{$mode objfpc}{$H+}
+
+interface
+
+type
+  TNotifyProc = procedure;
+
+var
+  OnBooksChanged: TNotifyProc = nil;
+
+procedure NotifyBooksChanged;
+
+implementation
+
+procedure NotifyBooksChanged;
+begin
+  if Assigned(OnBooksChanged) then
+    OnBooksChanged();
+end;
+
+end.
+