tvplanit: Fix WeekView inplace editor sometimes picking wrong events.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4917 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-07-05 10:20:36 +00:00
parent 5370e6afa1
commit 49161f56c1
2 changed files with 37 additions and 22 deletions

View File

@ -258,9 +258,9 @@ type
property BeforeEdit: TVpBeforeEditEvent read FBeforeEdit write FBeforeEdit; property BeforeEdit: TVpBeforeEditEvent read FBeforeEdit write FBeforeEdit;
property OnAddEvent: TVpOnAddNewEvent read FOnAddEvent write FOnAddEvent; property OnAddEvent: TVpOnAddNewEvent read FOnAddEvent write FOnAddEvent;
property OnOwnerEditEvent: TVpEditEvent read FOwnerEditEvent write FOwnerEditEvent; property OnOwnerEditEvent: TVpEditEvent read FOwnerEditEvent write FOwnerEditEvent;
end; end;
implementation implementation
uses uses
@ -749,6 +749,7 @@ procedure TVpWeekView.WMLButtonDown(var Msg: TLMLButtonDown);
{$ENDIF} {$ENDIF}
var var
P: TPoint; P: TPoint;
oldDate: TDate;
begin begin
inherited; inherited;
@ -761,8 +762,16 @@ begin
if (Msg.YPos > wvHeaderHeight) then if (Msg.YPos > wvHeaderHeight) then
begin begin
{ The mouse click landed inside the client area } { The mouse click landed inside the client area }
oldDate := FActiveDate;
wvSetDateByCoord(P); wvSetDateByCoord(P);
{ We must repaint the control here, before evaluation of the click on the
events, because if the day has changed by wvSetDateByCoord then events
will have different indexes in the event array; and index positions are
evaluated during painting. }
if oldDate <> FActiveDate then
Paint;
{ If an active event was clicked, then enable the click timer. If the { If an active event was clicked, then enable the click timer. If the
item is double clicked before the click timer fires, then the edit item is double clicked before the click timer fires, then the edit
dialog will appear, otherwise the in-place editor will appear. } dialog will appear, otherwise the in-place editor will appear. }
@ -1132,15 +1141,9 @@ var
begin begin
result := false; result := false;
for I := 0 to pred(Length(wvEventArray)) do begin for I := 0 to pred(Length(wvEventArray)) do begin
ActiveEvent := nil;
wvActiveEventRec.Top := 0;
wvActiveEventRec.Bottom := 0;
wvActiveEventRec.Right := 0;
wvActiveEventRec.Left := 0;
// We've hit the end of visible events without finding a match // We've hit the end of visible events without finding a match
if wvEventArray[I].Event = nil then if wvEventArray[I].Event = nil then
Exit; Break;
// Point falls inside this event's rectangle // Point falls inside this event's rectangle
if PointInRect(Pt, wvEventArray[I].Rec) then if PointInRect(Pt, wvEventArray[I].Rec) then
@ -1152,6 +1155,13 @@ begin
Exit; Exit;
end; end;
end; end;
// Not found
ActiveEvent := nil;
wvActiveEventRec.Top := 0;
wvActiveEventRec.Bottom := 0;
wvActiveEventRec.Right := 0;
wvActiveEventRec.Left := 0;
end; end;
{=====} {=====}

View File

@ -159,7 +159,7 @@ begin
for I := 0 to pred(ADEventsList.Count) do begin for I := 0 to pred(ADEventsList.Count) do begin
Event := ADEventsList[I]; Event := ADEventsList[I];
// Draw ". . ." // Draw "..."
if ADEventsRect.Top + ((I + 1) * ADTextHeight) > DayRect.Bottom then if ADEventsRect.Top + ((I + 1) * ADTextHeight) > DayRect.Bottom then
begin begin
DrawDotDotDot(DayRect, DotDotDotColor); DrawDotDotDot(DayRect, DotDotDotColor);
@ -205,7 +205,9 @@ begin
ADEvRect.Top + TextMargin, ADEvRect.Top + TextMargin,
EventStr EventStr
); );
Result := True; Result := True;
TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Rec := Rect( TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Rec := Rect(
ADEvRect.Left + TextMargin, ADEvRect.Left + TextMargin,
ADEvRect.Top + TextMargin, ADEvRect.Top + TextMargin,
@ -290,7 +292,7 @@ begin
TextRect := DayRect; TextRect := DayRect;
TextRect.Bottom := DayRect.Top + dayHeadHeight; TextRect.Bottom := DayRect.Top + dayHeadHeight;
{ draw day header } // Draw day header
tmpRect := TextRect; tmpRect := TextRect;
inc(tmpRect.Right); inc(tmpRect.Right);
RenderCanvas.Font.Assign(FWeekView.DayHeadAttributes.Font); RenderCanvas.Font.Assign(FWeekView.DayHeadAttributes.Font);
@ -299,29 +301,29 @@ begin
if FWeekView.DayHeadAttributes.Bordered and (FWeekView.DrawingStyle <> dsNoBorder) then if FWeekView.DayHeadAttributes.Bordered and (FWeekView.DrawingStyle <> dsNoBorder) then
TPSRectangle(RenderCanvas, Angle, RenderIn, tmpRect); TPSRectangle(RenderCanvas, Angle, RenderIn, tmpRect);
{ Fix Header String } // Fix header string
DrawDayHeader(ADayIndex, TextRect); DrawDayHeader(ADayIndex, TextRect);
if (FWeekView.DataStore <> nil) and (FWeekView.DataStore.Resource <> nil) and if (FWeekView.DataStore <> nil) and (FWeekView.DataStore.Resource <> nil) and
(FWeekView.DataStore.Resource.Schedule.EventCountByDay(StartDate + ADayIndex) > 0) and (FWeekView.DataStore.Resource.Schedule.EventCountByDay(StartDate + ADayIndex) > 0) and
(HeightOf(DayRect) >= TextMargin * 2 + dayHeadHeight) (HeightOf(DayRect) >= TextMargin * 2 + dayHeadHeight)
then begin then begin
{ events exist for this day } // Events exist for this day
EventList := TList.Create; EventList := TList.Create;
try try
{ populate the eventlist with events for this day } // Populate the event list 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 { Now sort times in ascending order. This must be done because the event
list can contain recurring events which have the wrong date part } list can contain recurring events which have the wrong date part }
EventList.Sort(CompareEventsByTimeOnly); 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;
TextRect.Bottom := TextRect.Top + rowHeight; TextRect.Bottom := TextRect.Top + rowHeight;
{ Handle All Day Events } // Handle all-day events
tmpRect := TextRect; tmpRect := TextRect;
tmpRect.Bottom := DayRect.Bottom; tmpRect.Bottom := DayRect.Bottom;
if DrawAllDayEvents(StartDate + ADayIndex, tmpRect, EAIndex) then if DrawAllDayEvents(StartDate + ADayIndex, tmpRect, EAIndex) then
@ -330,12 +332,12 @@ begin
TextRect.Top := ADEventsRect.Bottom; TextRect.Top := ADEventsRect.Bottom;
end; end;
{ 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
for J := 0 to pred(EventList.Count) do begin for J := 0 to pred(EventList.Count) do begin
{ if the TextRect extends below the available space then draw a } { if the TextRect extends below the available space then draw a }
{ dot dot dot to indicate there are more events than can be drawn } { dot dot dot to indicate there are more events than can be drawn }
@ -346,19 +348,20 @@ begin
break; break;
end; end;
{ write the event text } // Write the event text
DrawEvent(TVpEvent(EventList.List^[J]), DayRect, TextRect, ADayIndex); DrawEvent(TVpEvent(EventList.List^[J]), DayRect, TextRect, ADayIndex);
{ update the EventArray } // Update the EventArray
with TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex] do begin with TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex] do begin
Rec := TextRect; Rec := TextRect;
Event := TVpEvent(EventList.List^[J]); Event := TVpEvent(EventList[J]);
end; end;
Inc(EAIndex); Inc(EAIndex);
TextRect.Top := TextRect.Bottom; TextRect.Top := TextRect.Bottom;
TextRect.Bottom := TextRect.Top + rowHeight; TextRect.Bottom := TextRect.Top + rowHeight;
end; { for loop } end; { for loop }
finally finally
EventList.Free; EventList.Free;
end; end;
@ -430,18 +433,20 @@ end;
procedure TVpWeekViewPainter.DrawDays; procedure TVpWeekViewPainter.DrawDays;
var var
DayRect: TRect; DayRect: TRect;
EAIndex: Integer; EAIndex: Integer; // Index of last-used item in wvEventArray
I: Integer; I: Integer;
headerHeight: Integer; headerHeight: Integer;
realCenter: Integer; realCenter: Integer;
begin begin
with TVpWeekViewOpener(FWeekView) do begin with TVpWeekViewOpener(FWeekView) do begin
{ Initialize weekday array } { Initialize weekday array }
for I := 0 to pred(Length(wvWeekdayArray)) do begin for I := 0 to pred(Length(wvWeekdayArray)) do begin
wvWeekdayArray[I].Rec.TopLeft := Point(-1, -1); wvWeekdayArray[I].Rec.TopLeft := Point(-1, -1);
wvWeekdayArray[I].Rec.BottomRight := Point(-1, -1); wvWeekdayArray[I].Rec.BottomRight := Point(-1, -1);
wvWeekdayArray[I].Day := 0; wvWeekdayArray[I].Day := 0;
end; end;
{ initialize event array } { initialize event array }
EAIndex := 0; EAIndex := 0;
for I := 0 to pred(Length(wvEventArray)) do begin for I := 0 to pred(Length(wvEventArray)) do begin