From f268a8663b3e450da22f2229781d67b75c75e9e4 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Thu, 30 Jun 2016 18:45:39 +0000 Subject: [PATCH] tvplanit: Fix recurring events being hidden or in wrong order because DayView's and WeekViews' temporary event lists are not correctly sorted. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4873 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/tvplanit/source/vpbaseds.pas | 16 ++++++------- components/tvplanit/source/vpdata.pas | 24 +++++++++++++++---- .../tvplanit/source/vpdayviewpainter.pas | 23 +++++++++++------- .../tvplanit/source/vpweekviewpainter.pas | 13 ++++++---- 4 files changed, 50 insertions(+), 26 deletions(-) diff --git a/components/tvplanit/source/vpbaseds.pas b/components/tvplanit/source/vpbaseds.pas index d648035ae..30a795ded 100644 --- a/components/tvplanit/source/vpbaseds.pas +++ b/components/tvplanit/source/vpbaseds.pas @@ -55,15 +55,15 @@ type neInvalidate); { Printing events } - TVpOnGetVariableEvent = procedure (Sender : TObject; VarName : string; - Found : Boolean; var Value : string; var Change : TVpChangeVar) + TVpOnGetVariableEvent = procedure (Sender: TObject; VarName: string; + Found: Boolean; var Value: string; var Change: TVpChangeVar) of object; - TVpOnPageStartEvent = procedure (Sender : TObject; PageNum : Integer; - ADate : TDateTime) of object; + TVpOnPageStartEvent = procedure (Sender: TObject; PageNum: Integer; + ADate: TDateTime) of object; - TVpOnPageEndEvent = procedure (Sender : TObject; PageNum : Integer; - ADate : TDateTime; LastPage : Boolean) of object; + TVpOnPageEndEvent = procedure (Sender: TObject; PageNum: Integer; + ADate: TDateTime; LastPage: Boolean) of object; { generic events } TVpControlNotifyEvent = procedure(Sender: TComponent; @@ -72,8 +72,8 @@ type TVpNoResources = procedure(Sender: TObject; Resource: TVpResource) of object; - TVpNoLocalizationFile = procedure (Sender : TObject; - FileName : string) of object; + TVpNoLocalizationFile = procedure (Sender: TObject; + FileName: string) of object; TVpDateChangedEvent = procedure (Sender: TObject; Date: TDateTime) of object; diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas index 77c1a8858..17e0e7975 100644 --- a/components/tvplanit/source/vpdata.pas +++ b/components/tvplanit/source/vpdata.pas @@ -167,7 +167,7 @@ type FEventList: TList; FBatchUpdate: Integer; function Compare(Time1, Time2: TDateTime): Integer; - function FindTimeSlot(StartTime, EndTime: TDateTime): Boolean; +// function FindTimeSlot(StartTime, EndTime: TDateTime): Boolean; function GetCount: Integer; public constructor Create(Owner: TVpResource); @@ -556,9 +556,14 @@ type property UserField9 : string read FUserField9 write FUserField9; end; + +function CompareEventsByTimeOnly(P1, P2: Pointer): Integer; + + implementation uses + Math, VpException, VpMisc; { TVpResources } @@ -1355,13 +1360,13 @@ begin end; {=====} +(* wp: Commented because it is not called from anywhere... { binary search } function TVpSchedule.FindTimeSlot(StartTime, EndTime: TDateTime): Boolean; var L, R, M: Integer; CStart, CEnd, CompStart, CompEnd: integer; { comparison results } - HitStart, HitEnd, HitStraddle: Boolean; begin HitStart := false; @@ -1403,7 +1408,7 @@ begin if not HItStraddle then { Check to see if the middle item falls completely inside our times } - CompStart := Compare(TVpEvent(FEventList.List^[M]).StartTime, StartTime); + CompStart := Compare(TVpEvent(FEventList.List^[M]).StartTime, StartTime); // wp: Is this correct? Strange indentation! CompEnd := Compare(TVpEvent(FEventList.List^[M]).EndTime, EndTime); { if the middle item's starttime is less than our starttime AND its } { endtime is greater than our endtime, then teh middle item straddles } @@ -1430,7 +1435,7 @@ begin { if we got here then we didn't hit an existing item } result := false; end; -{=====} +{=====} *) function TVpSchedule.GetCount: Integer; begin @@ -2310,4 +2315,15 @@ begin end; {=====} +{ Call back function for TList.Sort. Sorting of events by time onla, date part + is ignored. } +function CompareEventsByTimeOnly(P1, P2: Pointer): Integer; +var + event1, event2: TVpEvent; +begin + event1 := TVpEvent(P1); + event2 := TVpEvent(P2); + Result := CompareValue(frac(event1.StartTime), frac(event2.EndTime)); +end; + end. diff --git a/components/tvplanit/source/vpdayviewpainter.pas b/components/tvplanit/source/vpdayviewpainter.pas index cc7a26dc0..dad5e9725 100644 --- a/components/tvplanit/source/vpdayviewpainter.pas +++ b/components/tvplanit/source/vpdayviewpainter.pas @@ -85,7 +85,7 @@ type procedure DrawCells(R: TRect; ColDate: TDateTime; Col: Integer); procedure DrawColHeader(R: TRect; ARenderDate: TDateTime; Col: Integer); procedure DrawEditFrame(R: TRect; AGutter, ALevel: Integer; AColor: TColor); - procedure DrawEvent(AEvent: TVpEvent; AEventRec: TVpDvEventRec; + procedure DrawEvent(AEvent: TVpEvent; var AEventRec: TVpDvEventRec; ARenderDate: TDateTime; Col: Integer); procedure DrawEvents(ARenderDate: TDateTime; Col: Integer); procedure DrawEventText(const AText: String; const AEventRect, AIconRect: TRect; @@ -119,7 +119,7 @@ type implementation uses - StrUtils, + StrUtils, Math, VpCanvasUtils, VpMisc; const @@ -510,7 +510,6 @@ begin RenderCanvas.Brush.Color := FDayView.TimeSlotColors.Weekend; TPSFillRect(RenderCanvas, Angle, RenderIn, LineRect); end - else begin { ColDate is a weekday, so check to see if the active } { range is set. If it isn't then paint all rows the color } @@ -561,8 +560,8 @@ begin TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Bottom); TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Top - 1); - RenderCanvas.Font.Assign(SavedFont); finally + RenderCanvas.Font.Assign(SavedFont); SavedFont.Free; end; end; @@ -680,7 +679,7 @@ begin end; end; -procedure TVpDayViewPainter.DrawEvent(AEvent: TVpEvent; AEventRec: TVpDvEventRec; +procedure TVpDayViewPainter.DrawEvent(AEvent: TVpEvent; var AEventRec: TVpDvEventRec; ARenderDate: TDateTime; Col: Integer); var EventCategory: TVpCategoryInfo; @@ -705,6 +704,8 @@ begin { remove the date portion from the start and end times } PrepareEventTimes(AEvent, ARenderDate, EventSTime, EventETime); + AEventRec.RealStartTime := EventSTime; + AEventRec.RealEndTime := EventETime; { Find the lines on which this event starts and ends } EventSLine := GetStartLine(EventSTime, FDayView.Granularity); @@ -859,7 +860,8 @@ var level: Integer; begin if (FDayView.DataStore = nil) or (FDayView.DataStore.Resource = nil) or - (not FDayView.DataStore.Connected) then + (not FDayView.DataStore.Connected) + then Exit; { Save the canvas color and font } @@ -999,7 +1001,6 @@ begin if AEventIsEditing then exit; } - if (FDayView.WrapStyle <> wsNone) then begin if (AEventRect.Bottom <> AIconRect.Bottom) and (AEventRect.Left <> AIconRect.Right) then begin @@ -1627,12 +1628,16 @@ begin EventList.Delete(I); end; + { Now sort times in ascending order. This must be done because the event + list can contain recurring events which have the wrong date part } + EventList.Sort(CompareEventsByTimeOnly); + { Arrange this day's events in the event matrix } level := 0; I := 0; while EventList.Count > 0 do begin - { Iterate through the events, and place them all in the proper } - { place in the EventMatrix, according to their start and end times } + { Iterate through the (corrected) events, and place them all at the proper place + in the EventMatrix, according to their start and end times } J := 0; ThisTime := 0.0; while (J < EventList.Count) and (J < MaxVisibleEvents) do begin diff --git a/components/tvplanit/source/vpweekviewpainter.pas b/components/tvplanit/source/vpweekviewpainter.pas index c576a35b6..c874bbbf4 100644 --- a/components/tvplanit/source/vpweekviewpainter.pas +++ b/components/tvplanit/source/vpweekviewpainter.pas @@ -14,9 +14,6 @@ type FWeekView: TVpWeekView; // local parameters of the old TVpWeekView method HeadRect: TRect; - SaveBrushColor: TColor; - SavePenStyle: TPenStyle; - SavePenColor: TColor; DayRectHeight: Integer; // StrLn: Integer; StartDate: TDateTime; @@ -58,7 +55,7 @@ type implementation uses - StrUtils, + StrUtils, Math, VpCanvasUtils, VpMisc, VpSR; type @@ -272,6 +269,7 @@ var rowHeight: Integer; headerHeight: Integer; tmpRect: TRect; + event: TVpEvent; begin // Abbreviations dayHeadHeight := TVpWeekviewOpener(FWeekView).wvDayHeadHeight; @@ -299,6 +297,11 @@ begin try { populate the eventlist with events for this day } FWeekView.DataStore.Resource.Schedule.EventsByDate(StartDate + ADayIndex, EventList); + + { Now sort times in ascending order. This must be done because the event + list can contain recurring events which have the wrong date part } + EventList.Sort(CompareEventsByTimeOnly); + { initialize TextRect for this day } TextRect := DayRect; TextRect.Top := DayRect.Top + dayHeadHeight; @@ -315,7 +318,7 @@ begin { Discard AllDayEvents, because they are drawn above. } for J := pred(EventList.Count) downto 0 do - if TVpEvent (EventList[J]).AllDayEvent then + if TVpEvent(EventList[J]).AllDayEvent then EventList.Delete(J); { iterate the events, painting them one by one }