You've already forked lazarus-ccr
tvplanit: Extend TVpGanttView such that it can be painted only over a given date interval.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8480 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -89,8 +89,10 @@ type
|
|||||||
FActiveDate: TDateTime; // Selected date
|
FActiveDate: TDateTime; // Selected date
|
||||||
FFirstDate: TDateTime; // Date of the first event in the resource
|
FFirstDate: TDateTime; // Date of the first event in the resource
|
||||||
FLastDate: TDateTime; // Date of the last event in the resource
|
FLastDate: TDateTime; // Date of the last event in the resource
|
||||||
FStartDate: TDateTime; // Date of the first event to be displayed/printed
|
FStartDate: TDateTime; // Date of the first event to be displayed/printed (0 = first event ever)
|
||||||
FEndDate: TDateTime; // Date of the last event to be displayed/printed
|
FEndDate: TDateTime; // Date of the last event to be displayed/printed (0 = last event ever)
|
||||||
|
FRealStartDate: TDate; // Date of the first event to be displayed/printed (0 replaced)
|
||||||
|
FRealEndDate: TDate; // Date of the last event to be displayed/printed (0 repalaced)
|
||||||
|
|
||||||
FLeftCol: Integer; // Index of the left-most day column
|
FLeftCol: Integer; // Index of the left-most day column
|
||||||
FTopRow: Integer; // Index of the top-most event row
|
FTopRow: Integer; // Index of the top-most event row
|
||||||
@ -181,10 +183,11 @@ type
|
|||||||
function GetDateTimeAtCoord(X: Integer): TDateTime;
|
function GetDateTimeAtCoord(X: Integer): TDateTime;
|
||||||
function GetEventAtCoord(X, Y: Integer): TVpEvent;
|
function GetEventAtCoord(X, Y: Integer): TVpEvent;
|
||||||
function GetEventOfRow(ARow: Integer): TVpEvent;
|
function GetEventOfRow(ARow: Integer): TVpEvent;
|
||||||
|
procedure GetRealEventDateRange(out AStartDate, AEndDate: TDate);
|
||||||
function GetRowAtCoord(Y: Integer): Integer;
|
function GetRowAtCoord(Y: Integer): Integer;
|
||||||
function GetRowOfEvent(AEvent: TVpEvent): Integer;
|
function GetRowOfEvent(AEvent: TVpEvent): Integer;
|
||||||
procedure GetEventDateRange;
|
procedure GetEventDateRange(out AFirstDate, ALastDate: TDate);
|
||||||
function IsEventOnDate(AEvent: TVpEvent; ADate: TDateTime): Boolean;
|
function IsEventOnDate(AEvent: TVpEvent; ADate: TDate): Boolean;
|
||||||
procedure Hookup;
|
procedure Hookup;
|
||||||
procedure Populate;
|
procedure Populate;
|
||||||
procedure PopulateDayRecords;
|
procedure PopulateDayRecords;
|
||||||
@ -251,6 +254,7 @@ type
|
|||||||
Angle: TVpRotationAngle; Scale: Extended; RenderDate: TDateTime;
|
Angle: TVpRotationAngle; Scale: Extended; RenderDate: TDateTime;
|
||||||
StartLine, StopLine: Integer; UseGran: TVpGranularity;
|
StartLine, StopLine: Integer; UseGran: TVpGranularity;
|
||||||
DisplayOnly: Boolean); override;
|
DisplayOnly: Boolean); override;
|
||||||
|
procedure SetDateLimits(AStartDate, AEndDate: TDateTime);
|
||||||
|
|
||||||
{$IF VP_LCL_SCALING = 2}
|
{$IF VP_LCL_SCALING = 2}
|
||||||
procedure FixDesignFontsPPI(const ADesignTimePPI: Integer); override;
|
procedure FixDesignFontsPPI(const ADesignTimePPI: Integer); override;
|
||||||
@ -261,16 +265,18 @@ type
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
// Methods to be called by painter
|
// Methods/properties used by painter. Not meant to be called by user.
|
||||||
function CalcVisibleCols(AWidth, AFixedColWidth, AColWidth: Integer): Integer;
|
function CalcVisibleCols(AWidth, AFixedColWidth, AColWidth: Integer): Integer;
|
||||||
function CalcVisibleRows(AHeight, AHeaderHeight, ARowHeight: Integer): Integer;
|
function CalcVisibleRows(AHeight, AHeaderHeight, ARowHeight: Integer): Integer;
|
||||||
|
property FirstDate: TDateTime read FFirstDate;
|
||||||
|
property LastDate: TDateTime read FLastDate;
|
||||||
|
property RealStartDate: TDateTime read FRealStartDate;
|
||||||
|
property RealEndDate: TDateTime read FRealEndDate;
|
||||||
|
|
||||||
property ActiveCol: Integer read FActiveCol write SetActiveCol;
|
property ActiveCol: Integer read FActiveCol write SetActiveCol;
|
||||||
property ActiveEvent: TVpEvent read FActiveEvent write SetActiveEvent;
|
property ActiveEvent: TVpEvent read FActiveEvent write SetActiveEvent;
|
||||||
property ActiveDate: TDateTime read FActiveDate write SetActiveDate;
|
property ActiveDate: TDateTime read FActiveDate write SetActiveDate;
|
||||||
property ActiveRow: Integer read FActiveRow write SetActiveRow;
|
property ActiveRow: Integer read FActiveRow write SetActiveRow;
|
||||||
property FirstDate: TDateTime read FFirstDate;
|
|
||||||
property LastDate: TDateTime read FLastDate;
|
|
||||||
property StartDate: TDateTime read FStartDate write FStartDate;
|
property StartDate: TDateTime read FStartDate write FStartDate;
|
||||||
property EndDate: TDateTime read FEndDate write FEndDate;
|
property EndDate: TDateTime read FEndDate write FEndDate;
|
||||||
property ColCount: Integer read FColCount write FColCount;
|
property ColCount: Integer read FColCount write FColCount;
|
||||||
@ -502,7 +508,7 @@ begin
|
|||||||
if UseAsHint then begin
|
if UseAsHint then begin
|
||||||
{ Usage as hint }
|
{ Usage as hint }
|
||||||
startDateStr := FormatDateTime(DATE_FORMAT, AEvent.StartTime);
|
startDateStr := FormatDateTime(DATE_FORMAT, AEvent.StartTime);
|
||||||
if trunc(AEvent.StartTime) = trunc(AEvent.EndTime) then
|
if SameDate(AEvent.StartTime, AEvent.EndTime) then
|
||||||
endDateStr := ''
|
endDateStr := ''
|
||||||
else
|
else
|
||||||
endDateStr := FormatDateTime(DATE_FORMAT, AEvent.EndTime);
|
endDateStr := FormatDateTime(DATE_FORMAT, AEvent.EndTime);
|
||||||
@ -612,9 +618,7 @@ var
|
|||||||
dt, startTime, endTime: TDateTime;
|
dt, startTime, endTime: TDateTime;
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
// dvClickTimer.Enabled := false;
|
|
||||||
FMouseDown := false;
|
FMouseDown := false;
|
||||||
//FDragging := false;
|
|
||||||
|
|
||||||
// If the mouse was pressed down in the client area, then select the cell.
|
// If the mouse was pressed down in the client area, then select the cell.
|
||||||
if not Focused then
|
if not Focused then
|
||||||
@ -626,15 +630,18 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Is there an event at the clicked cell?
|
||||||
FActiveEvent := GetEventAtCoord(FMouseDownPoint.X, FMouseDownPoint.Y);
|
FActiveEvent := GetEventAtCoord(FMouseDownPoint.X, FMouseDownPoint.Y);
|
||||||
if (FActiveEvent <> nil) then
|
if (FActiveEvent <> nil) then
|
||||||
|
// yes: edit the event
|
||||||
SpawnEventEditDialog(False)
|
SpawnEventEditDialog(False)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
// no: add a new event
|
||||||
dt := GetDateTimeAtCoord(FMouseDownPoint.X);
|
dt := GetDateTimeAtCoord(FMouseDownPoint.X);
|
||||||
if dt <> NO_DATE then
|
if dt <> NO_DATE then
|
||||||
begin
|
begin
|
||||||
startTime := trunc(dt);
|
startTime := DatePart(dt);
|
||||||
endTime := startTime + 1.0;
|
endTime := startTime + 1.0;
|
||||||
ActiveEvent := Datastore.Resource.Schedule.AddEvent(
|
ActiveEvent := Datastore.Resource.Schedule.AddEvent(
|
||||||
Datastore.GetNextID(EventsTableName),
|
Datastore.GetNextID(EventsTableName),
|
||||||
@ -645,33 +652,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
FMouseDownPoint := Point(0, 0);
|
FMouseDownPoint := Point(0, 0);
|
||||||
|
|
||||||
(*
|
|
||||||
|
|
||||||
if (Msg.XPos > dvRowHeadWidth - 9) and (Msg.YPos > dvColHeadHeight) then
|
|
||||||
begin
|
|
||||||
{ The mouse click landed inside the client area }
|
|
||||||
dvSetActiveRowByCoord(Point(Msg.XPos, Msg.YPos), True);
|
|
||||||
{ See if we hit an active event }
|
|
||||||
if (FActiveEvent <> nil) and (not ReadOnly) then begin
|
|
||||||
{ edit this event }
|
|
||||||
dvSpawnEventEditDialog(False);
|
|
||||||
end else if not ReadOnly then begin
|
|
||||||
if not CheckCreateResource then
|
|
||||||
Exit;
|
|
||||||
if (DataStore = nil) or (DataStore.Resource = nil) then
|
|
||||||
Exit;
|
|
||||||
{ otherwise, we must want to create a new event }
|
|
||||||
StartTime := trunc(FDisplayDate + ActiveCol)
|
|
||||||
+ dvLineMatrix[ActiveCol, ActiveRow].Time;
|
|
||||||
EndTime := StartTime + dvTimeIncSize * FRowLinesStep;
|
|
||||||
FActiveEvent := DataStore.Resource.Schedule.AddEvent(
|
|
||||||
DataStore.GetNextID(EventsTableName), StartTime, EndTime);
|
|
||||||
{ edit this new event }
|
|
||||||
dvSpawnEventEditDialog(True);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TVpGanttView.DeleteActiveEvent(Prompt: Boolean);
|
procedure TVpGanttView.DeleteActiveEvent(Prompt: Boolean);
|
||||||
@ -786,7 +766,7 @@ end;
|
|||||||
|
|
||||||
function TVpGanttView.GetDateOfCol(ACol: Integer): TDateTime;
|
function TVpGanttView.GetDateOfCol(ACol: Integer): TDateTime;
|
||||||
begin
|
begin
|
||||||
Result := FStartDate + ACol;
|
Result := FRealStartDate + ACol;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TVpGanttView.GetDateTimeAtCoord(X: Integer): TDateTime;
|
function TVpGanttView.GetDateTimeAtCoord(X: Integer): TDateTime;
|
||||||
@ -795,7 +775,7 @@ var
|
|||||||
begin
|
begin
|
||||||
days := (X - FixedColWidth) / FColWidth + FLeftCol;
|
days := (X - FixedColWidth) / FColWidth + FLeftCol;
|
||||||
if (days >= 0) and (days < NumDays) then
|
if (days >= 0) and (days < NumDays) then
|
||||||
Result := FStartDate + days
|
Result := FRealStartDate + days
|
||||||
else
|
else
|
||||||
Result := NO_DATE;
|
Result := NO_DATE;
|
||||||
end;
|
end;
|
||||||
@ -827,7 +807,7 @@ begin
|
|||||||
Result := eventRec.Event;
|
Result := eventRec.Event;
|
||||||
if Result.AllDayEvent then
|
if Result.AllDayEvent then
|
||||||
begin
|
begin
|
||||||
if (dt < trunc(Result.StartTime)) or (dt > trunc(Result.EndTime) + 1) then
|
if (dt < DatePart(Result.StartTime)) or (dt > DatePart(Result.EndTime) + 1) then
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end else
|
end else
|
||||||
if (dt < Result.StartTime) or (dt > Result.EndTime) then
|
if (dt < Result.StartTime) or (dt > Result.EndTime) then
|
||||||
@ -837,8 +817,8 @@ end;
|
|||||||
|
|
||||||
{ Determines the date when the earliest event starts, and the date when the
|
{ Determines the date when the earliest event starts, and the date when the
|
||||||
latest event ends.
|
latest event ends.
|
||||||
Stores them in the internal variables FStartdate and FEndDate. }
|
Stores them in the internal variables FFirstDate and FLastDate. }
|
||||||
procedure TVpGanttView.GetEventDateRange;
|
procedure TVpGanttView.GetEventDateRange(out AFirstDate, ALastDate: TDate);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
event: TVpEvent;
|
event: TVpEvent;
|
||||||
@ -851,20 +831,15 @@ begin
|
|||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
event := Datastore.Resource.Schedule.GetEvent(0);
|
event := Datastore.Resource.Schedule.GetEvent(0);
|
||||||
FFirstDate := trunc(event.StartTime);
|
FFirstDate := DatePart(event.StartTime);
|
||||||
FLastDate := -99999;
|
FLastDate := -99999;
|
||||||
for i := 0 to Datastore.Resource.Schedule.EventCount-1 do
|
for i := 0 to Datastore.Resource.Schedule.EventCount-1 do
|
||||||
begin
|
begin
|
||||||
event := Datastore.Resource.Schedule.GetEvent(i);
|
event := Datastore.Resource.Schedule.GetEvent(i);
|
||||||
d := trunc(event.EndTime);
|
d := DatePart(event.EndTime);
|
||||||
if d > FLastDate then FLastDate := d;
|
if d > FLastDate then FLastDate := d;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FStartDate = 0 then
|
|
||||||
FStartDate := FFirstDate;
|
|
||||||
if FEndDate = 0 then
|
|
||||||
FEndDate := FLastDate;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TVpGanttView.GetEventOfRow(ARow: Integer): TVpEvent;
|
function TVpGanttView.GetEventOfRow(ARow: Integer): TVpEvent;
|
||||||
@ -882,12 +857,12 @@ begin
|
|||||||
Result := FMonthRecords[AIndex];
|
Result := FMonthRecords[AIndex];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Determines the number days between the first and last Gantt event. This is
|
{ Determines the number of days between the first and last Gantt event. This is
|
||||||
the number of day columns in the view. }
|
the number of day columns in the view. }
|
||||||
function TVpGanttView.GetNumDays: Integer;
|
function TVpGanttView.GetNumDays: Integer;
|
||||||
begin
|
begin
|
||||||
if (FStartDate <> NO_DATE) then
|
if (FRealStartDate <> NO_DATE) then
|
||||||
Result := trunc(FEndDate) - trunc(FStartDate) + 1
|
Result := trunc(FRealEndDate) - trunc(FRealStartDate) + 1
|
||||||
else
|
else
|
||||||
Result := 0;
|
Result := 0;
|
||||||
end;
|
end;
|
||||||
@ -895,10 +870,7 @@ end;
|
|||||||
{ Determines the number of events (= rows) to be displayed in the GanttView. }
|
{ Determines the number of events (= rows) to be displayed in the GanttView. }
|
||||||
function TVpGanttView.GetNumEvents: Integer;
|
function TVpGanttView.GetNumEvents: Integer;
|
||||||
begin
|
begin
|
||||||
if (Datastore <> nil) and (Datastore.Resource <> nil) then
|
Result := Length(FEventRecords);
|
||||||
Result := Datastore.Resource.Schedule.EventCount
|
|
||||||
else
|
|
||||||
Result := 0;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Determines the number of months (complete or partial) between the first and
|
{ Determines the number of months (complete or partial) between the first and
|
||||||
@ -908,10 +880,10 @@ var
|
|||||||
y1, m1, d1: Word;
|
y1, m1, d1: Word;
|
||||||
y2, m2, d2: Word;
|
y2, m2, d2: Word;
|
||||||
begin
|
begin
|
||||||
if (FStartDate <> NO_DATE) then
|
if (FRealStartDate <> NO_DATE) then
|
||||||
begin
|
begin
|
||||||
DecodeDate(FStartDate, y1, m1, d1);
|
DecodeDate(FRealStartDate, y1, m1, d1);
|
||||||
DecodeDate(FEndDate, y2, m2, d2);
|
DecodeDate(FRealEndDate, y2, m2, d2);
|
||||||
if (y1 = y2) then
|
if (y1 = y2) then
|
||||||
Result := m2 - m1 + 1
|
Result := m2 - m1 + 1
|
||||||
else
|
else
|
||||||
@ -920,6 +892,15 @@ begin
|
|||||||
Result := 0;
|
Result := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Calculates the first and last date to be displayed in the GanttView. This
|
||||||
|
is necessary because the properties StartDate and EndDate may be 0 which
|
||||||
|
means the very first/last event. }
|
||||||
|
procedure TVpGanttView.GetRealEventDateRange(out AStartDate, AEndDate: TDate);
|
||||||
|
begin
|
||||||
|
if FStartDate > 0 then AStartDate := DatePart(FStartDate) else AStartDate := FFirstDate;
|
||||||
|
if FEndDate > 0 then AEndDate := DatePart(FEndDate) else AEndDate := FLastDate;
|
||||||
|
end;
|
||||||
|
|
||||||
function TVpGanttView.GetRowAtCoord(Y: Integer): Integer;
|
function TVpGanttView.GetRowAtCoord(Y: Integer): Integer;
|
||||||
begin
|
begin
|
||||||
Result := (Y - FTotalColHeaderHeight) div FRowHeight + FTopRow;
|
Result := (Y - FTotalColHeaderHeight) div FRowHeight + FTopRow;
|
||||||
@ -958,7 +939,8 @@ begin
|
|||||||
CalcRowHeight;
|
CalcRowHeight;
|
||||||
CalcColHeaderHeight;
|
CalcColHeaderHeight;
|
||||||
|
|
||||||
GetEventDateRange;
|
GetEventDateRange(FFirstDate, FLastDate);
|
||||||
|
GetRealEventDateRange(FRealStartDate, FRealEndDate);
|
||||||
FColCount := GetNumDays;
|
FColCount := GetNumDays;
|
||||||
FRowCount := GetNumEvents;
|
FRowCount := GetNumEvents;
|
||||||
|
|
||||||
@ -966,16 +948,18 @@ begin
|
|||||||
PopulateMonthRecords;
|
PopulateMonthRecords;
|
||||||
PopulateEventRecords;
|
PopulateEventRecords;
|
||||||
end;
|
end;
|
||||||
|
{ Checks whether the specified date belongs to the specified event.
|
||||||
function TVpGanttView.IsEventOnDate(AEvent: TVpEvent; ADate: TDateTime): Boolean;
|
The function returns true if the event begins before or at the date and ends
|
||||||
|
at or after it. }
|
||||||
|
function TVpGanttView.IsEventOnDate(AEvent: TVpEvent; ADate: TDate): Boolean;
|
||||||
var
|
var
|
||||||
tEv1, tEv2: TDateTime;
|
dEv1, dEv2: TDate;
|
||||||
begin
|
begin
|
||||||
if AEvent <> nil then
|
if AEvent <> nil then
|
||||||
begin
|
begin
|
||||||
tEv1 := trunc(AEvent.StartTime);
|
dEv1 := DatePart(AEvent.StartTime);
|
||||||
tEv2 := trunc(AEvent.EndTime);
|
dEv2 := DatePart(AEvent.EndTime);
|
||||||
Result := (tEv1 <= ADate) and (tEv2 >= ADate);
|
Result := (dEv1 <= ADate) and (ADate <= dEv2);
|
||||||
end else
|
end else
|
||||||
Result := false;
|
Result := false;
|
||||||
end;
|
end;
|
||||||
@ -1188,7 +1172,7 @@ begin
|
|||||||
Rect(0, 0, Width, Height), // Paint Rectangle
|
Rect(0, 0, Width, Height), // Paint Rectangle
|
||||||
ra0, // Rotation angle: none
|
ra0, // Rotation angle: none
|
||||||
1, // Scale
|
1, // Scale
|
||||||
FStartDate, // Date
|
FActiveDate, // Date
|
||||||
-1, // Start At
|
-1, // Start At
|
||||||
-1, // End At
|
-1, // End At
|
||||||
gr30Min, // Granularity
|
gr30Min, // Granularity
|
||||||
@ -1219,7 +1203,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
x2 := x1 + ColWidth;
|
x2 := x1 + ColWidth;
|
||||||
FDayRecords[i].Rect := Rect(x1, y1, x2, y2);
|
FDayRecords[i].Rect := Rect(x1, y1, x2, y2);
|
||||||
FDayRecords[i].Date := FStartDate + i;
|
FDayRecords[i].Date := FRealStartDate + i;
|
||||||
x1 := x2;
|
x1 := x2;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1233,37 +1217,54 @@ var
|
|||||||
totalWidth: Integer;
|
totalWidth: Integer;
|
||||||
list: TFPList;
|
list: TFPList;
|
||||||
begin
|
begin
|
||||||
SetLength(FEventRecords, GetNumEvents);
|
|
||||||
if (Datastore = nil) or (DataStore.Resource = nil) then
|
if (Datastore = nil) or (DataStore.Resource = nil) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
list := TFPList.Create;
|
list := TFPList.Create;
|
||||||
try
|
try
|
||||||
// Sort events by date/time
|
// Consider only events which are, fully or partly, inside the
|
||||||
|
// displayed date range between FRealStartDate and FRealEndDate
|
||||||
for i := 0 to Datastore.Resource.Schedule.EventCount-1 do
|
for i := 0 to Datastore.Resource.Schedule.EventCount-1 do
|
||||||
list.Add(Datastore.Resource.Schedule.GetEvent(i));
|
begin
|
||||||
|
event := Datastore.Resource.Schedule.GetEvent(i);
|
||||||
|
if DatePart(event.EndTime) < FRealStartDate then
|
||||||
|
continue;
|
||||||
|
if DatePart(event.StartTime) > FRealEndDate then
|
||||||
|
continue;
|
||||||
|
list.Add(event);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Sort events by date/time - this is a general requirement for Gantt
|
||||||
list.Sort(@CompareEvents);
|
list.Sort(@CompareEvents);
|
||||||
|
|
||||||
|
// Prepare array for the event records simplifying work for the Gantt view
|
||||||
|
SetLength(FEventRecords, list.Count);
|
||||||
|
|
||||||
|
// Iterate over all considered events, fill the event record and store it
|
||||||
|
// in the array
|
||||||
xh1 := 0;
|
xh1 := 0;
|
||||||
xh2 := FixedColWidth;
|
xh2 := FixedColWidth;
|
||||||
y1 := FTotalColHeaderHeight;
|
y1 := FTotalColHeaderHeight;
|
||||||
totalWidth := GetNumDays * ColWidth;
|
totalWidth := GetNumDays * ColWidth;
|
||||||
for i := 0 to High(FEventRecords) do
|
for i := 0 to list.Count-1 do
|
||||||
begin
|
begin
|
||||||
event := TVpEvent(list[i]);
|
event := TVpEvent(list[i]);
|
||||||
|
|
||||||
|
// The time range of events reaching out of the displayed date range
|
||||||
|
// must be clipped at the edges.
|
||||||
|
t1 := IfThen(event.StartTime >= FRealStartDate, event.StartTime, FRealStartDate);
|
||||||
|
t2 := IfThen(event.EndTime <= FRealEndDate + 1, event.EndTime, FRealEndDate + 1);
|
||||||
if event.AllDayEvent then
|
if event.AllDayEvent then
|
||||||
begin
|
begin
|
||||||
t1 := trunc(event.StartTime);
|
t1 := DatePart(t1);
|
||||||
t2 := trunc(event.EndTime) + 1;
|
t2 := DatePart(t2) + 1;
|
||||||
if frac(event.EndTime) = 0 then t2 := t2 + 1;
|
if TimePart(t2) = 0 then t2 := t2 + 1;
|
||||||
end else
|
|
||||||
begin
|
|
||||||
t1 := event.StartTime;
|
|
||||||
t2 := event.EndTime;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Store event, caption and its rectangle coordinates in the EventRec
|
||||||
y2 := y1 + FRowHeight;
|
y2 := y1 + FRowHeight;
|
||||||
xe1 := round((t1 - FStartDate) / numDays * totalWidth) + FixedColWidth;
|
xe1 := round((t1 - FRealStartDate) / numDays * totalWidth) + FixedColWidth;
|
||||||
xe2 := round((t2 - FStartDate) / numDays * totalWidth) + FixedColWidth;
|
xe2 := round((t2 - FRealStartDate) / numDays * totalWidth) + FixedColWidth;
|
||||||
if xe1 = xe2 then xe2 := xe1 + 1;
|
if xe1 = xe2 then xe2 := xe1 + 1;
|
||||||
FEventRecords[i].Event := event;
|
FEventRecords[i].Event := event;
|
||||||
FEventRecords[i].Caption := event.Description;
|
FEventRecords[i].Caption := event.Description;
|
||||||
@ -1297,7 +1298,8 @@ begin
|
|||||||
|
|
||||||
if n > 1 then
|
if n > 1 then
|
||||||
begin
|
begin
|
||||||
dm := FStartDate;
|
// Date interval crosses one or more month boundaries
|
||||||
|
dm := FRealStartDate;
|
||||||
for i := 0 to n - 1 do
|
for i := 0 to n - 1 do
|
||||||
begin
|
begin
|
||||||
if i = 0 then begin
|
if i = 0 then begin
|
||||||
@ -1305,11 +1307,11 @@ begin
|
|||||||
dm := StartOfTheMonth(dm);
|
dm := StartOfTheMonth(dm);
|
||||||
end else
|
end else
|
||||||
if i = n-1 then
|
if i = n-1 then
|
||||||
nDays := DayOf(FEndDate)
|
nDays := DayOf(FRealEndDate)
|
||||||
else
|
else
|
||||||
nDays := DaysInMonth(dm);
|
nDays := DaysInMonth(dm);
|
||||||
if dm + nDays > FEndDate then
|
if dm + nDays > FRealEndDate then
|
||||||
nDays := trunc(FEndDate) - trunc(dm) + 1;
|
nDays := trunc(FRealEndDate) - trunc(dm) + 1;
|
||||||
x2 := x1 + nDays * ColWidth;
|
x2 := x1 + nDays * ColWidth;
|
||||||
FMonthRecords[i].Rect := Rect(x1, y1, x2, y2);
|
FMonthRecords[i].Rect := Rect(x1, y1, x2, y2);
|
||||||
FMonthRecords[i].Date := dm;
|
FMonthRecords[i].Date := dm;
|
||||||
@ -1318,10 +1320,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
nDays := DayOf(FEndDate) - DayOf(FStartDate) + 1;
|
// Date interval is within the same month
|
||||||
|
nDays := DayOf(FRealEndDate) - DayOf(FRealStartDate) + 1;
|
||||||
x2 := x1 + nDays * ColWidth;
|
x2 := x1 + nDays * ColWidth;
|
||||||
FMonthRecords[0].Rect := Rect(x1, y1, x2, y2);
|
FMonthRecords[0].Rect := Rect(x1, y1, x2, y2);
|
||||||
FMonthRecords[0].Date := FStartDate;
|
FMonthRecords[0].Date := FRealStartDate;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1342,6 +1345,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TVpGanttView.SetDateLimits(AStartDate, AEndDate: TDateTime);
|
||||||
|
var
|
||||||
|
oldDate: TDateTime;
|
||||||
|
begin
|
||||||
|
oldDate := FActiveDate;
|
||||||
|
|
||||||
|
FStartDate := AStartDate;
|
||||||
|
FEndDate := AEndDate;
|
||||||
|
Init;
|
||||||
|
|
||||||
|
FActiveDate := 0;
|
||||||
|
SetActiveDate(oldDate);
|
||||||
|
end;
|
||||||
|
|
||||||
{$IF VP_LCL_SCALING = 2}
|
{$IF VP_LCL_SCALING = 2}
|
||||||
procedure TVpGanttView.FixDesignFontsPPI(const ADesignTimePPI: Integer);
|
procedure TVpGanttView.FixDesignFontsPPI(const ADesignTimePPI: Integer);
|
||||||
begin
|
begin
|
||||||
@ -1371,26 +1388,26 @@ end;
|
|||||||
|
|
||||||
procedure TVpGanttView.ScrollDateIntoView(ADate: TDateTime);
|
procedure TVpGanttView.ScrollDateIntoView(ADate: TDateTime);
|
||||||
begin
|
begin
|
||||||
if (FStartDate = 0) or (FStartDate = NO_DATE) then
|
if (FRealStartDate = 0) or (FRealStartDate = NO_DATE) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if ADate < FStartDate then
|
if ADate < FRealStartDate then
|
||||||
begin
|
begin
|
||||||
FStartDate := trunc(ADate);
|
FRealStartDate := DatePart(ADate);
|
||||||
FColCount := GetNumDays;
|
FColCount := GetNumDays;
|
||||||
SetLeftCol(-MaxInt);
|
SetLeftCol(-MaxInt);
|
||||||
end else
|
end else
|
||||||
if ADate > FEndDate then
|
if ADate > FRealEndDate then
|
||||||
begin
|
begin
|
||||||
FEndDate := trunc(ADate);
|
FRealEndDate := DatePart(ADate);
|
||||||
FColCount := GetNumDays;
|
FColCount := GetNumDays;
|
||||||
SetLeftCol(FColCount - 1 - FVisibleCols);
|
SetLeftCol(FColCount - 1 - FVisibleCols);
|
||||||
end else
|
end else
|
||||||
if ADate < FStartDate + FLeftCol then
|
if ADate < FRealStartDate + FLeftCol then
|
||||||
SetLeftCol(trunc(ADate) - trunc(FStartDate))
|
SetLeftCol(trunc(ADate) - trunc(FRealStartDate))
|
||||||
else
|
else
|
||||||
if ADate > FStartDate + VisibleCols then
|
if ADate > FRealStartDate + FVisibleCols then
|
||||||
SetLeftCol(trunc(ADate) - VisibleCols)
|
SetLeftCol(trunc(ADate) - FVisibleCols)
|
||||||
else
|
else
|
||||||
exit;
|
exit;
|
||||||
Invalidate;
|
Invalidate;
|
||||||
@ -1446,14 +1463,14 @@ end;
|
|||||||
|
|
||||||
procedure TVpGanttView.SetActiveDate(AValue: TDateTime);
|
procedure TVpGanttView.SetActiveDate(AValue: TDateTime);
|
||||||
begin
|
begin
|
||||||
if FActiveDate <> trunc(AValue) then begin
|
if FActiveDate <> DatePart(AValue) then begin
|
||||||
FActiveDate := trunc(AValue);
|
FActiveDate := DatePart(AValue);
|
||||||
|
|
||||||
if FLoaded then
|
if FLoaded then
|
||||||
Populate;
|
Populate;
|
||||||
|
|
||||||
ScrollDateIntoView(FActiveDate);
|
ScrollDateIntoView(FActiveDate);
|
||||||
FActiveCol := trunc(FActiveDate) - trunc(FStartDate);
|
FActiveCol := trunc(FActiveDate) - trunc(FRealStartDate);
|
||||||
Invalidate;
|
Invalidate;
|
||||||
|
|
||||||
if (not FInLinkHandler) and (ControlLink <> nil) then
|
if (not FInLinkHandler) and (ControlLink <> nil) then
|
||||||
@ -1871,7 +1888,7 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
|
|
||||||
// Create the new event as an all-day event for the clicked day.
|
// Create the new event as an all-day event for the clicked day.
|
||||||
startTime := trunc(FActiveDate);
|
startTime := DatePart(FActiveDate);
|
||||||
endTime := startTime + 1 - OneMilliSecond;
|
endTime := startTime + 1 - OneMilliSecond;
|
||||||
FActiveEvent := DataStore.Resource.Schedule.AddEvent(
|
FActiveEvent := DataStore.Resource.Schedule.AddEvent(
|
||||||
DataStore.GetNextID(EventsTableName),
|
DataStore.GetNextID(EventsTableName),
|
||||||
|
@ -333,6 +333,10 @@ begin
|
|||||||
begin
|
begin
|
||||||
eventRec := FGanttView.EventRecords[i];
|
eventRec := FGanttView.EventRecords[i];
|
||||||
event := eventRec.Event;
|
event := eventRec.Event;
|
||||||
|
if event.EndTime < FGanttView.FirstDate then
|
||||||
|
Continue;
|
||||||
|
if event.StartTime > FGanttView.LastDate then
|
||||||
|
exit;
|
||||||
R := ScaleRect(eventRec.EventRect);
|
R := ScaleRect(eventRec.EventRect);
|
||||||
OffsetRect(R, -dx, -dy);
|
OffsetRect(R, -dx, -dy);
|
||||||
inc(R.Top, top_margin);
|
inc(R.Top, top_margin);
|
||||||
@ -409,18 +413,17 @@ begin
|
|||||||
eventRec := FGanttView.EventRecords[numEvents-1];
|
eventRec := FGanttView.EventRecords[numEvents-1];
|
||||||
R := ScaleRect(eventRec.EventRect);
|
R := ScaleRect(eventRec.EventRect);
|
||||||
y2 := R.Bottom - dy;
|
y2 := R.Bottom - dy;
|
||||||
end else
|
n := FGanttView.NumDays;
|
||||||
y2 := RealBottom;
|
for i := 0 to n-1 do
|
||||||
n := FGanttView.NumDays;
|
|
||||||
for i := 0 to n-1 do
|
|
||||||
begin
|
|
||||||
dayRec := FGanttView.DayRecords[i];
|
|
||||||
R := ScaleRect(dayRec.Rect);
|
|
||||||
x1 := R.Right - dx;
|
|
||||||
if x1 >= FScaledFixedColWidth then
|
|
||||||
begin
|
begin
|
||||||
TPSMoveTo(RenderCanvas, Angle, RenderIn, x1, y1);
|
dayRec := FGanttView.DayRecords[i];
|
||||||
TPSLineTo(RenderCanvas, Angle, RenderIn, x1, y2)
|
R := ScaleRect(dayRec.Rect);
|
||||||
|
x1 := R.Right - dx;
|
||||||
|
if x1 >= FScaledFixedColWidth then
|
||||||
|
begin
|
||||||
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, x1, y1);
|
||||||
|
TPSLineTo(RenderCanvas, Angle, RenderIn, x1, y2)
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -507,7 +510,7 @@ var
|
|||||||
begin
|
begin
|
||||||
with FGanttView do
|
with FGanttView do
|
||||||
begin
|
begin
|
||||||
if (StartDate = NO_DATE) or (SpecialDayMode <> sdmColumn) then
|
if (RealStartDate = NO_DATE) or (SpecialDayMode <> sdmColumn) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
nEvents := NumEvents;
|
nEvents := NumEvents;
|
||||||
@ -515,9 +518,13 @@ begin
|
|||||||
dx := LeftCol * FScaledColWidth;
|
dx := LeftCol * FScaledColWidth;
|
||||||
dy := TopRow * FScaledRowHeight;
|
dy := TopRow * FScaledRowHeight;
|
||||||
|
|
||||||
R := ScaleRect(EventRecords[nEvents-1].HeadRect);
|
|
||||||
y1 := RealTop + FScaledTotalColHeaderHeight;
|
y1 := RealTop + FScaledTotalColHeaderHeight;
|
||||||
y2 := R.Bottom - dy;
|
if nEvents > 0 then
|
||||||
|
begin
|
||||||
|
R := ScaleRect(EventRecords[nEvents-1].HeadRect);
|
||||||
|
y2 := R.Bottom - dy;
|
||||||
|
end else
|
||||||
|
y2 := y1;
|
||||||
|
|
||||||
RenderCanvas.Brush.style := bsSolid;
|
RenderCanvas.Brush.style := bsSolid;
|
||||||
for i := 0 to nDays-1 do
|
for i := 0 to nDays-1 do
|
||||||
|
@ -146,6 +146,9 @@ function DaysInAMonth(Year, Month: Integer): Integer;
|
|||||||
{-return the number of days in the specified month of a given year}
|
{-return the number of days in the specified month of a given year}
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}{$ENDIF}
|
||||||
|
|
||||||
|
function DatePart(ADateTime: TDateTime): TDateTime; inline;
|
||||||
|
function TimePart(ADateTime: TDateTime): TDateTime; inline;
|
||||||
|
|
||||||
function GetJulianDate(Date: TDateTime): Word;
|
function GetJulianDate(Date: TDateTime): Word;
|
||||||
function GetWeekOfYear(ADate: TDateTime): byte;
|
function GetWeekOfYear(ADate: TDateTime): byte;
|
||||||
function IsWeekend(ADate: TDateTime): Boolean;
|
function IsWeekend(ADate: TDateTime): Boolean;
|
||||||
@ -710,6 +713,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}{$ENDIF}
|
||||||
|
|
||||||
|
function DatePart(ADateTime: TDateTime): TDateTime;
|
||||||
|
begin
|
||||||
|
Result := trunc(ADateTime);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TimePart(ADateTime: TDateTime): TDateTime;
|
||||||
|
begin
|
||||||
|
Result := frac(ADateTime);
|
||||||
|
end;
|
||||||
|
|
||||||
function GetJulianDate(Date: TDateTime): Word;
|
function GetJulianDate(Date: TDateTime): Word;
|
||||||
var
|
var
|
||||||
y, m, d, I: word;
|
y, m, d, I: word;
|
||||||
|
Reference in New Issue
Block a user