From c41e5b4a1fa248899a320c1b63b2e083ee609623 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 6 Dec 2021 22:34:33 +0000 Subject: [PATCH] tvplanit: Implement resource groups for flat-file datastores. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8171 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/tvplanit/source/vpbaseds.pas | 37 +++++++++++++- components/tvplanit/source/vpdata.pas | 39 +++++++++++++- components/tvplanit/source/vpfileds.pas | 67 ++++++++++++++++++++++++- components/tvplanit/source/vpinids.pas | 9 +++- components/tvplanit/source/vpjsonds.pas | 4 ++ components/tvplanit/source/vpxmlds.pas | 4 ++ 6 files changed, 154 insertions(+), 6 deletions(-) diff --git a/components/tvplanit/source/vpbaseds.pas b/components/tvplanit/source/vpbaseds.pas index 8b29c9f26..4680fba93 100644 --- a/components/tvplanit/source/vpbaseds.pas +++ b/components/tvplanit/source/vpbaseds.pas @@ -34,12 +34,13 @@ unit VpBaseDS; { Base DataStore classes } {$I vp.inc} +{.$DEFINE DEBUG_RESOURCE_GROUPS} interface uses {$IFDEF LCL} - LMessages, LCLProc, LCLIntf, LCLVersion, LazFileUtils, + LMessages, LCLProc, LCLIntf, LCLVersion, LazFileUtils, LazLogger, {$ELSE} Windows, Messages, {$ENDIF} @@ -272,6 +273,9 @@ type procedure DeregisterAllWatchers; procedure DeregisterWatcher(Watcher: THandle); + {$IFDEF DEBUG_RESOURCE_GROUPS} + procedure DumpResources; + {$ENDIF} function GetNextID(TableName: string): Integer; virtual; abstract; procedure NotifyDependents; procedure RegisterWatcher(Watcher: THandle); @@ -627,8 +631,37 @@ begin end; { with } end; { if } end; -{=====} +{$IFDEF DEBUG_RESOURCE_GROUPS} +procedure TVpCustomDatastore.DumpResources; +var + i, j: Integer; + res: TVpResource; + ev: TVpEvent; + s: String; +begin + for i := 0 to Resources.Count-1 do + begin + res := Resources.Items[i]; + DebugLn('Resource #' + IntToStr(i)); + DebugLn(' Description: ' + res.Description); + DebugLn(' ResourceID: ' + IntToStr(res.ResourceID)); + if res.Group = nil then + DebugLn(' not grouped') + else + DebugLn(' Group: ' + res.Group.Caption); + for j := 0 to res.Schedule.EventCount-1 do + begin + ev := res.Schedule.GetEvent(j); + DebugLn(' Event #' + IntToStr(j)); + DebugLn(' ResourceID: ' + IntToStr(ev.ResourceID)); + DebugLn(' EventID: ' + IntToStr(ev.RecordID)); + DebugLn(' Description: ' + ev.Description); + end; + end; +end; +{$ENDIF} + function TVpCustomDatastore.IsStoredMediaFolder: Boolean; begin Result := FMediaFolder <> ''; diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas index a13dc04a2..311ac2df8 100644 --- a/components/tvplanit/source/vpdata.pas +++ b/components/tvplanit/source/vpdata.pas @@ -305,6 +305,7 @@ type constructor Create(Owner: TVpSchedule); destructor Destroy; override; function CanEdit: Boolean; + function CopyToSchedule(ASchedule: TVpSchedule): TVpEvent; function GetResource: TVpResource; function IsOverlayed: Boolean; procedure LoadFromICalendar(AEntry: TVpICalEvent); @@ -1049,8 +1050,11 @@ begin for i := Low(AResources) to High(AResources) do grp.AddID(AResources[i].ResourceID); - FGroup := grp; - Result := grp; + if grp.Count > 0 then + FGroup := grp + else + FGroup := nil; + Result := FGroup; // Repaint the events TVpCustomDatastore(FOwner.FOwner).RefreshEvents; @@ -1287,6 +1291,37 @@ begin end; end; +function TVpEvent.CopyToSchedule(ASchedule: TVpSchedule): TVpEvent; +begin + Result := ASchedule.AddEvent(FResourceID, FStartTime, FEndTime); + // ResourceID will be assigned outside + Result.RecordID := FRecordID; + Result.DingPath := FDingPath; + Result.AlertDisplayed := FAlertDisplayed; + Result.AllDayEvent := FAllDayEvent; + Result.Description := FDescription; + Result.Notes := FNotes; + Result.Category := FCategory; + Result.AlarmSet := FAlarmSet; + Result.AlarmAdvance := FAlarmAdv; + Result.Location := FLocation; + Result.AlarmAdvanceType := FAlarmAdvType; + Result.SnoozeTime := FSnoozeTime; + Result.RepeatCode := FRepeatCode; + Result.RepeatRangeEnd := FRepeatRangeEnd; + Result.CustomInterval := FCustInterval; + Result.UserField0 := FUserField0; + Result.UserField1 := FUserField1; + Result.UserField2 := FUserField2; + Result.UserField3 := FUserField3; + Result.UserField4 := FUserField4; + Result.UserField5 := FUserField5; + Result.UserField6 := FUserField6; + Result.UserField7 := FUserField7; + Result.UserField8 := FUserField8; + Result.UserField8 := FUserField9; +end; + { Returns the resource to which the event belongs. } function TVpEvent.GetResource: TVpResource; begin diff --git a/components/tvplanit/source/vpfileds.pas b/components/tvplanit/source/vpfileds.pas index 62c3291ec..472a6d475 100644 --- a/components/tvplanit/source/vpfileds.pas +++ b/components/tvplanit/source/vpfileds.pas @@ -11,15 +11,80 @@ unit VpFileDS; interface uses - VpBase, VpData, VpBaseDS; + VpData, VpBaseDS; type TVpCustomFileDataStore = class(TVpCustomDataStore) private protected public + procedure RefreshEvents; override; + procedure UngroupEvents; virtual; + procedure UpdateGroupEvents; override; end; implementation +procedure TVpCustomFileDataStore.RefreshEvents; +begin + UpdateGroupEvents; + inherited; +end; + +procedure TVpCustomFileDataStore.UngroupEvents; +var + i, j: Integer; + res: TVpResource; + event, newEvent: TVpEvent; + eventRes: TVpResource; +begin + for i := 0 to Resources.Count-1 do + begin + res := Resources.Items[i]; + for j := res.Schedule.EventCount-1 downto 0 do + begin + event := res.Schedule.GetEvent(j); + if event.IsOverlayed then + begin + eventRes := Resources.GetResource(event.ResourceID); + newEvent := event.CopyToSchedule(eventres.Schedule); + newEvent.ResourceID := eventRes.ResourceID; + event.Free; + end; + end; + end; +end; + +{ Iterates through all events and moves them to the resource as specified by the + resource groups. } +procedure TVpCustomFileDataStore.UpdateGroupEvents; +var + i, j, k: Integer; + res, gres: TVpResource; + event, newevent: TVpEvent; +begin + UngroupEvents; + + for i := 0 to Resources.Count-1 do + begin + res := Resources.Items[i]; + if res.Group <> nil then begin + for j := 0 to res.Group.Count-1 do + begin + gres := res.Group.Items[j]; + for k := gres.Schedule.EventCount-1 downto 0 do + begin + event := gres.Schedule.GetEvent(k); + if event.ResourceID = gres.ResourceID then + begin + newEvent := event.CopyToSchedule(res.Schedule); + newEvent.ResourceID := event.ResourceID; + event.Free; + end; + end; + end; + end; + end; +end; + end. diff --git a/components/tvplanit/source/vpinids.pas b/components/tvplanit/source/vpinids.pas index d3aceed53..030420782 100644 --- a/components/tvplanit/source/vpinids.pas +++ b/components/tvplanit/source/vpinids.pas @@ -323,7 +323,7 @@ begin try L.AddDateTimeField('StartTime', AEvent.StartTime, 'c'); // short date + long time L.AddDateTimeField('EndTime', AEvent.EndTime, 'c'); // 1 - L.AddField('ResourceID', IntToStr(AEvent.ResourceID)); + L.AddField('ResourceID', IntToStr(AEvent.ResourceID)); //wp: inserted - don't know how it affects the numbers at the right... L.AddField('Description', AEvent.Description); L.AddField('Location', AEvent.Location); L.AddField('Notes', EncodeLineEndings(AEvent.Notes)); @@ -828,6 +828,9 @@ begin for i:=0 to L.Count-1 do begin L.Extract(i, fn, fv); fn := Lowercase(fn); + if fn = 'resourceid' then begin + // this will be handled outside... + end else if fn = 'starttime' then begin if fv = '' then AEvent.StartTime := 0 else @@ -1236,6 +1239,10 @@ begin if FFileName = '' then exit; + // We do not yet store grouped events. Until this is implemented we must + // move the events back into their original resources. + UngroupEvents; + ini := TMemIniFile.Create(FFileName); try ini.Clear; diff --git a/components/tvplanit/source/vpjsonds.pas b/components/tvplanit/source/vpjsonds.pas index ff7fe2236..b4594a135 100644 --- a/components/tvplanit/source/vpjsonds.pas +++ b/components/tvplanit/source/vpjsonds.pas @@ -766,6 +766,10 @@ begin if not Connected then exit; + // We do not yet store grouped events. Until this is implemented we must + // move the events back into their original resources. + UngroupEvents; + json := TJSONObject.Create; try resObjArray := TJSONArray.Create; diff --git a/components/tvplanit/source/vpxmlds.pas b/components/tvplanit/source/vpxmlds.pas index 5e1b91402..ffd8ee057 100644 --- a/components/tvplanit/source/vpxmlds.pas +++ b/components/tvplanit/source/vpxmlds.pas @@ -1694,6 +1694,10 @@ begin if FFileName = '' then exit; + // We do not yet store grouped events. Until this is implemented we must + // move the events back into their original resources. + UngroupEvents; + doc := nil; try if FileExists(FFileName) then begin