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
This commit is contained in:
wp_xxyyzz
2016-06-30 18:45:39 +00:00
parent 8804d54e20
commit f268a8663b
4 changed files with 50 additions and 26 deletions

View File

@ -55,15 +55,15 @@ type
neInvalidate); neInvalidate);
{ Printing events } { Printing events }
TVpOnGetVariableEvent = procedure (Sender : TObject; VarName : string; TVpOnGetVariableEvent = procedure (Sender: TObject; VarName: string;
Found : Boolean; var Value : string; var Change : TVpChangeVar) Found: Boolean; var Value: string; var Change: TVpChangeVar)
of object; of object;
TVpOnPageStartEvent = procedure (Sender : TObject; PageNum : Integer; TVpOnPageStartEvent = procedure (Sender: TObject; PageNum: Integer;
ADate : TDateTime) of object; ADate: TDateTime) of object;
TVpOnPageEndEvent = procedure (Sender : TObject; PageNum : Integer; TVpOnPageEndEvent = procedure (Sender: TObject; PageNum: Integer;
ADate : TDateTime; LastPage : Boolean) of object; ADate: TDateTime; LastPage: Boolean) of object;
{ generic events } { generic events }
TVpControlNotifyEvent = procedure(Sender: TComponent; TVpControlNotifyEvent = procedure(Sender: TComponent;
@ -72,8 +72,8 @@ type
TVpNoResources = procedure(Sender: TObject; TVpNoResources = procedure(Sender: TObject;
Resource: TVpResource) of object; Resource: TVpResource) of object;
TVpNoLocalizationFile = procedure (Sender : TObject; TVpNoLocalizationFile = procedure (Sender: TObject;
FileName : string) of object; FileName: string) of object;
TVpDateChangedEvent = procedure (Sender: TObject; TVpDateChangedEvent = procedure (Sender: TObject;
Date: TDateTime) of object; Date: TDateTime) of object;

View File

@ -167,7 +167,7 @@ type
FEventList: TList; FEventList: TList;
FBatchUpdate: Integer; FBatchUpdate: Integer;
function Compare(Time1, Time2: TDateTime): Integer; function Compare(Time1, Time2: TDateTime): Integer;
function FindTimeSlot(StartTime, EndTime: TDateTime): Boolean; // function FindTimeSlot(StartTime, EndTime: TDateTime): Boolean;
function GetCount: Integer; function GetCount: Integer;
public public
constructor Create(Owner: TVpResource); constructor Create(Owner: TVpResource);
@ -556,9 +556,14 @@ type
property UserField9 : string read FUserField9 write FUserField9; property UserField9 : string read FUserField9 write FUserField9;
end; end;
function CompareEventsByTimeOnly(P1, P2: Pointer): Integer;
implementation implementation
uses uses
Math,
VpException, VpMisc; VpException, VpMisc;
{ TVpResources } { TVpResources }
@ -1355,13 +1360,13 @@ begin
end; end;
{=====} {=====}
(* wp: Commented because it is not called from anywhere...
{ binary search } { binary search }
function TVpSchedule.FindTimeSlot(StartTime, EndTime: TDateTime): Boolean; function TVpSchedule.FindTimeSlot(StartTime, EndTime: TDateTime): Boolean;
var var
L, R, M: Integer; L, R, M: Integer;
CStart, CEnd, CompStart, CompEnd: integer; { comparison results } CStart, CEnd, CompStart, CompEnd: integer; { comparison results }
HitStart, HitEnd, HitStraddle: Boolean; HitStart, HitEnd, HitStraddle: Boolean;
begin begin
HitStart := false; HitStart := false;
@ -1403,7 +1408,7 @@ begin
if not HItStraddle then if not HItStraddle then
{ Check to see if the middle item falls completely inside our times } { 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); CompEnd := Compare(TVpEvent(FEventList.List^[M]).EndTime, EndTime);
{ if the middle item's starttime is less than our starttime AND its } { if the middle item's starttime is less than our starttime AND its }
{ endtime is greater than our endtime, then teh middle item straddles } { 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 } { if we got here then we didn't hit an existing item }
result := false; result := false;
end; end;
{=====} {=====} *)
function TVpSchedule.GetCount: Integer; function TVpSchedule.GetCount: Integer;
begin begin
@ -2310,4 +2315,15 @@ begin
end; 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. end.

View File

@ -85,7 +85,7 @@ type
procedure DrawCells(R: TRect; ColDate: TDateTime; Col: Integer); procedure DrawCells(R: TRect; ColDate: TDateTime; Col: Integer);
procedure DrawColHeader(R: TRect; ARenderDate: TDateTime; Col: Integer); procedure DrawColHeader(R: TRect; ARenderDate: TDateTime; Col: Integer);
procedure DrawEditFrame(R: TRect; AGutter, ALevel: Integer; AColor: TColor); 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); ARenderDate: TDateTime; Col: Integer);
procedure DrawEvents(ARenderDate: TDateTime; Col: Integer); procedure DrawEvents(ARenderDate: TDateTime; Col: Integer);
procedure DrawEventText(const AText: String; const AEventRect, AIconRect: TRect; procedure DrawEventText(const AText: String; const AEventRect, AIconRect: TRect;
@ -119,7 +119,7 @@ type
implementation implementation
uses uses
StrUtils, StrUtils, Math,
VpCanvasUtils, VpMisc; VpCanvasUtils, VpMisc;
const const
@ -510,7 +510,6 @@ begin
RenderCanvas.Brush.Color := FDayView.TimeSlotColors.Weekend; RenderCanvas.Brush.Color := FDayView.TimeSlotColors.Weekend;
TPSFillRect(RenderCanvas, Angle, RenderIn, LineRect); TPSFillRect(RenderCanvas, Angle, RenderIn, LineRect);
end end
else begin else begin
{ ColDate is a weekday, so check to see if the active } { ColDate is a weekday, so check to see if the active }
{ range is set. If it isn't then paint all rows the color } { 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); TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Bottom);
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Top - 1); TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Top - 1);
RenderCanvas.Font.Assign(SavedFont);
finally finally
RenderCanvas.Font.Assign(SavedFont);
SavedFont.Free; SavedFont.Free;
end; end;
end; end;
@ -680,7 +679,7 @@ begin
end; end;
end; end;
procedure TVpDayViewPainter.DrawEvent(AEvent: TVpEvent; AEventRec: TVpDvEventRec; procedure TVpDayViewPainter.DrawEvent(AEvent: TVpEvent; var AEventRec: TVpDvEventRec;
ARenderDate: TDateTime; Col: Integer); ARenderDate: TDateTime; Col: Integer);
var var
EventCategory: TVpCategoryInfo; EventCategory: TVpCategoryInfo;
@ -705,6 +704,8 @@ begin
{ remove the date portion from the start and end times } { remove the date portion from the start and end times }
PrepareEventTimes(AEvent, ARenderDate, EventSTime, EventETime); PrepareEventTimes(AEvent, ARenderDate, EventSTime, EventETime);
AEventRec.RealStartTime := EventSTime;
AEventRec.RealEndTime := EventETime;
{ Find the lines on which this event starts and ends } { Find the lines on which this event starts and ends }
EventSLine := GetStartLine(EventSTime, FDayView.Granularity); EventSLine := GetStartLine(EventSTime, FDayView.Granularity);
@ -859,7 +860,8 @@ var
level: Integer; level: Integer;
begin begin
if (FDayView.DataStore = nil) or (FDayView.DataStore.Resource = nil) or if (FDayView.DataStore = nil) or (FDayView.DataStore.Resource = nil) or
(not FDayView.DataStore.Connected) then (not FDayView.DataStore.Connected)
then
Exit; Exit;
{ Save the canvas color and font } { Save the canvas color and font }
@ -999,7 +1001,6 @@ begin
if AEventIsEditing then if AEventIsEditing then
exit; exit;
} }
if (FDayView.WrapStyle <> wsNone) then begin if (FDayView.WrapStyle <> wsNone) then begin
if (AEventRect.Bottom <> AIconRect.Bottom) and (AEventRect.Left <> AIconRect.Right) if (AEventRect.Bottom <> AIconRect.Bottom) and (AEventRect.Left <> AIconRect.Right)
then begin then begin
@ -1627,12 +1628,16 @@ begin
EventList.Delete(I); EventList.Delete(I);
end; 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 } { Arrange this day's events in the event matrix }
level := 0; level := 0;
I := 0; I := 0;
while EventList.Count > 0 do begin while EventList.Count > 0 do begin
{ Iterate through the events, and place them all in the proper } { Iterate through the (corrected) events, and place them all at the proper place
{ place in the EventMatrix, according to their start and end times } in the EventMatrix, according to their start and end times }
J := 0; J := 0;
ThisTime := 0.0; ThisTime := 0.0;
while (J < EventList.Count) and (J < MaxVisibleEvents) do begin while (J < EventList.Count) and (J < MaxVisibleEvents) do begin

View File

@ -14,9 +14,6 @@ type
FWeekView: TVpWeekView; FWeekView: TVpWeekView;
// local parameters of the old TVpWeekView method // local parameters of the old TVpWeekView method
HeadRect: TRect; HeadRect: TRect;
SaveBrushColor: TColor;
SavePenStyle: TPenStyle;
SavePenColor: TColor;
DayRectHeight: Integer; DayRectHeight: Integer;
// StrLn: Integer; // StrLn: Integer;
StartDate: TDateTime; StartDate: TDateTime;
@ -58,7 +55,7 @@ type
implementation implementation
uses uses
StrUtils, StrUtils, Math,
VpCanvasUtils, VpMisc, VpSR; VpCanvasUtils, VpMisc, VpSR;
type type
@ -272,6 +269,7 @@ var
rowHeight: Integer; rowHeight: Integer;
headerHeight: Integer; headerHeight: Integer;
tmpRect: TRect; tmpRect: TRect;
event: TVpEvent;
begin begin
// Abbreviations // Abbreviations
dayHeadHeight := TVpWeekviewOpener(FWeekView).wvDayHeadHeight; dayHeadHeight := TVpWeekviewOpener(FWeekView).wvDayHeadHeight;
@ -299,6 +297,11 @@ begin
try try
{ populate the eventlist with events for this day } { populate the eventlist with events for this day }
FWeekView.DataStore.Resource.Schedule.EventsByDate(StartDate + ADayIndex, EventList); 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 } { initialize TextRect for this day }
TextRect := DayRect; TextRect := DayRect;
TextRect.Top := DayRect.Top + dayHeadHeight; TextRect.Top := DayRect.Top + dayHeadHeight;
@ -315,7 +318,7 @@ begin
{ Discard AllDayEvents, because they are drawn above. } { Discard AllDayEvents, because they are drawn above. }
for J := pred(EventList.Count) downto 0 do for J := pred(EventList.Count) downto 0 do
if TVpEvent (EventList[J]).AllDayEvent then if TVpEvent(EventList[J]).AllDayEvent then
EventList.Delete(J); EventList.Delete(J);
{ iterate the events, painting them one by one } { iterate the events, painting them one by one }