diff --git a/components/tvplanit/examples/fulldemo/demomain.pas b/components/tvplanit/examples/fulldemo/demomain.pas index 1a0f7f17a..ce824722a 100644 --- a/components/tvplanit/examples/fulldemo/demomain.pas +++ b/components/tvplanit/examples/fulldemo/demomain.pas @@ -414,6 +414,8 @@ begin datastore.Resources.AddResourceGroup(GROUP_NAME, [1, 2]); if datastore.Resource <> nil then datastore.Resource.Group := GROUP_NAME; + // Important: This is not called internally so far! + datastore.RefreshEvents; end; procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: boolean); diff --git a/components/tvplanit/source/vpbaseds.pas b/components/tvplanit/source/vpbaseds.pas index 65ed81bf9..06cbc5103 100644 --- a/components/tvplanit/source/vpbaseds.pas +++ b/components/tvplanit/source/vpbaseds.pas @@ -263,7 +263,7 @@ type procedure SetResourceByName(Value: string); virtual; abstract; procedure Load; virtual; - procedure LoadEvents; virtual; abstract; + procedure LoadEvents; virtual; procedure LoadEventsOfResource(AResID: Integer); virtual; abstract; procedure LoadContacts; virtual; abstract; procedure LoadTasks; virtual; abstract; @@ -283,6 +283,8 @@ type procedure PostTasks; virtual; abstract; procedure PostResources; virtual; abstract; + procedure UpdateGroupEvents; virtual; + property Connected : boolean read FConnected write SetConnected; property Loading : Boolean read FLoading write FLoading; property Resource: TVpResource read FResource write SetResource; @@ -727,7 +729,17 @@ begin FResources.Sort; NotifyDependents; end; -{=====} + +{ Load this resource's events into memory } +procedure TVpCustomDataStore.LoadEvents; +begin + if Resource <> nil then begin + // Load regular events ... + LoadEventsOfResource(Resource.ResourceID); + // ... and overlayed events + UpdateGroupEvents; + end; +end; procedure TVpCustomDataStore.RefreshEvents; begin @@ -757,7 +769,6 @@ begin end; {=====} -{ - Added} procedure TVpCustomDataStore.PurgeResource(Res: TVpResource); begin Unused(Res); @@ -789,7 +800,34 @@ begin NotifyDependents; end; {=====} -{ - End} + +procedure TVpCustomDatastore.UpdateGroupEvents; +var + i: Integer; + event: TVpEvent; + grp: TVpResourceGroup; + id: Integer; +begin + Resource.Schedule.ClearGroupEvents; + + if Resource.Group = '' then begin + NotifyDependents; + exit; + end; + + grp := Resources.FindResourceGroupByName(Resource.Group); + if grp = nil then + exit; + + for i:=0 to grp.Count-1 do begin + id := grp[i].ResourceID; + if id = ResourceID then + exit; + LoadEventsOfResource(id); + end; + + NotifyDependents; +end; procedure TVpCustomDataStore.RegisterWatcher(Watcher: THandle); var diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas index f03cf5b48..3b8d36798 100644 --- a/components/tvplanit/source/vpdata.pas +++ b/components/tvplanit/source/vpdata.pas @@ -215,6 +215,7 @@ type procedure AllDayEventsByDate(Date: TDateTime; EventList: TList); procedure BatchUpdate(Value: Boolean); procedure ClearEvents; + procedure ClearGroupEvents; procedure DeleteEvent(Event: TVpEvent); function EventCountByDay(Value: TDateTime): Integer; procedure EventsByDate(Date: TDateTime; EventList: TList); @@ -242,6 +243,7 @@ type FAlertDisplayed: Boolean; FAlarmAdvType: TVpAlarmAdvType; FRecordID: Integer; + FResourceID: Integer; FLocation: string; FNotes: string; FDescription: string; @@ -284,7 +286,9 @@ type public constructor Create(Owner: TVpSchedule); destructor Destroy; override; + function IsOverlayed: Boolean; property Owner: TVpSchedule read FOwner; + property ResourceID: Integer read FResourceID write FResourceID; property Loading : Boolean read FLoading write FLoading; property Changed: Boolean read FChanged write SetChanged; property Deleted: Boolean read FDeleted write SetDeleted; @@ -929,7 +933,6 @@ end; procedure TVpResource.SetGroup(const AValue: String); begin FGroup := AValue; - FChanged := true; end; procedure TVpResource.SetNotes(const Value: string); @@ -1080,6 +1083,20 @@ begin inherited; end; +{ The event is overlayed if its ResourceID is different from that of the + resource to which it belongs. } +function TVpEvent.IsOverlayed: Boolean; +var + res: TVpResource; // resource to which the event belongs +begin + Result := false; + if (FOwner <> nil) then begin + res := FOwner.FOwner; + if (res <> nil) and (res.ResourceID <> FResourceID) then + Result := true; + end; +end; + procedure TVpEvent.SetAlarmAdv(Value: Integer); begin if Value <> FAlarmAdv then begin @@ -1369,6 +1386,20 @@ begin end; end; +procedure TVpSchedule.ClearGroupEvents; +var + i: Integer; + event: TVpEvent; +begin + for i := FEventList.Count-1 downto 0 do begin + event := TVpEvent(FEventList[i]); + if event.IsOverlayed then begin + FEventList.Delete(i); + event.Free; + end; + end; +end; + procedure TVpSchedule.BatchUpdate(Value: Boolean); begin if Value then diff --git a/components/tvplanit/source/vpdayviewpainter.pas b/components/tvplanit/source/vpdayviewpainter.pas index 30304d79c..7c8f1e6c0 100644 --- a/components/tvplanit/source/vpdayviewpainter.pas +++ b/components/tvplanit/source/vpdayviewpainter.pas @@ -150,6 +150,7 @@ function TVpDayViewPainter.BuildEventString(AEvent: TVpEvent; var maxW: Integer; timeFmt: String; + res: TVpResource; begin if FDayView.ShowEventTimes then begin timeFmt := IfThen(FDayView.TimeFormat = tf24Hour, 'h:nn', 'h:nnam/pm'); @@ -161,6 +162,11 @@ begin end else Result := AEvent.Description; + if AEvent.IsOverlayed then begin + res := FDayView.Datastore.Resources.GetResource(AEvent.ResourceID); + Result := Format('[%s] %s', [res.Description, Result]); + end; + if FDayView.WrapStyle = wsNone then begin { if the string is longer than the availble space then chop off the end and place those little '...'s at the end } @@ -829,7 +835,10 @@ begin RenderCanvas.Brush.Color := EventCategory.BackgroundColor end else RenderCanvas.Brush.Color := WindowColor; + if AEvent.IsOverlayed then + RenderCanvas.Brush.Style := bsBDiagonal; TPSFillRect(RenderCanvas, Angle, RenderIn, EventRect); + RenderCanvas.Brush.Style := bsSolid; { Paint the little area to the left of the text the color corresponding to the event's category. These colors are used even when printing } diff --git a/components/tvplanit/source/vpdbds.pas b/components/tvplanit/source/vpdbds.pas index 59c59e664..e4740e625 100644 --- a/components/tvplanit/source/vpdbds.pas +++ b/components/tvplanit/source/vpdbds.pas @@ -78,7 +78,6 @@ type destructor Destroy; override; procedure Load; override; - procedure LoadEvents; override; procedure LoadEventsOfResource(AResID: integer); override; procedure LoadContacts; override; procedure LoadTasks; override; @@ -99,10 +98,8 @@ type procedure PurgeTasks(Res: TVpResource); override; procedure SetResourceByName(Value: string); override; - procedure CreateFieldDefs(const TableName : string; - FieldDefs : TFieldDefs); virtual; - procedure CreateIndexDefs(const TableName : string; - IndexDefs : TIndexDefs); virtual; + procedure CreateFieldDefs(const TableName: string; FieldDefs: TFieldDefs); virtual; + procedure CreateIndexDefs(const TableName: string; IndexDefs: TIndexDefs); virtual; published {events} @@ -1030,34 +1027,27 @@ begin inherited; end; -{ Load this resource's events into memory } -procedure TVpCustomDBDataStore.LoadEvents; -begin - if Resource <> nil then - LoadEventsOfResource(Resource.ResourceID); -end; - -{ Load the events of the specified resource into memory } +{ Load the events of the specified resource into memory. The loaded events are + attached to the current resource. Note that if AResID is different from the + current resource id then the events are used for overlaying. } procedure TVpCustomDBDataStore.LoadEventsOfResource(AResID: Integer); var - res: TVpResource; Event: TVpEvent; F: TField; begin - // Find the resource belonging to the specified ID. - res := Resources.GetResource(AResID); - if res <> nil then + if Resource <> nil then with EventsTable do begin SetFilterCriteria(EventsTable, true, AResID, TimeRange.StartTime, TimeRange.EndTime); First; while not EventsTable.EOF do begin - Event := res.Schedule.AddEvent( + Event := Resource.Schedule.AddEvent( FieldByName('RecordID').AsInteger, FieldByName('StartTime').AsDateTime, FieldByName('EndTime').AsDateTime ); if Event <> nil then begin Event.Loading := true; + Event.ResourceID := AResID; Event.Description := FieldByName('Description').AsString; F := FieldByName('Location'); if F <> nil then Event.Location := F.AsString; diff --git a/components/tvplanit/source/vpflxds.pas b/components/tvplanit/source/vpflxds.pas index cd379580b..ba708e247 100644 --- a/components/tvplanit/source/vpflxds.pas +++ b/components/tvplanit/source/vpflxds.pas @@ -573,6 +573,7 @@ begin if Event <> nil then begin Event.Loading := true; + Event.ResourceID := AResID; FN1 := GetFieldName(FEventMappings, 'Description'); if (FN1 <> '') then