{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvPickDate.PAS, released on 2002-07-04.
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 2001,2002 SGB Software
All Rights Reserved.
Contributor(s):
Polaris Software
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.delphi-jedi.org
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvPickDate.pas 130 2009-08-09 17:59:21Z obones $
unit JvPickDate;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
Variants, Windows, Messages,
Controls, Graphics, Forms, Buttons, StdCtrls, Grids, ExtCtrls,
SysUtils, Classes,
JclBase,
JvTypes, JvExGrids;
//below added by DJS to create less crowed looking day titles in popup calendar.
// it is referenced in popup calendar draw further down in this unit.
type
TDayOfWeek = 0..6;
TJvCalendar = class(TJvExCustomGrid)
private
FMinDate: TDateTime; // Polaris
FMaxDate: TDateTime; // Polaris
FDate: TDateTime;
FMonthOffset: Integer;
FOnChange: TNotifyEvent;
FReadOnly: Boolean;
FStartOfWeek: TDayOfWeekName;
FUpdating: Boolean;
FUseCurrentDate: Boolean;
FWeekends: TDaysOfWeek;
FWeekendColor: TColor;
function GetCellText(ACol, ARow: Integer): string;
function GetDateElement(Index: Integer): Integer;
procedure SetCalendarDate(Value: TDateTime);
procedure SetDateElement(Index: Integer; Value: Integer);
procedure SetStartOfWeek(Value: TDayOfWeekName);
procedure SetUseCurrentDate(Value: Boolean);
procedure SetWeekendColor(Value: TColor);
procedure SetWeekends(Value: TDaysOfWeek);
function IsWeekend(ACol, ARow: Integer): Boolean;
procedure CalendarUpdate(DayOnly: Boolean);
function StoreCalendarDate: Boolean;
//>Polaris
procedure SetMinDate(Value: TDateTime);
procedure SetMaxDate(Value: TDateTime);
//Polaris
function GetCellDate(ACol, ARow: Integer): TDateTime;
function CellInRange(ACol, ARow: Integer): Boolean;
function DateInRange(ADate: TDateTime): Boolean;
//Polaris
FMinDate := NullDate;
FMaxDate := NullDate;
// '' then
Day := StrToInt(TheCellText);
end;
function TJvCalendar.DaysThisMonth: Integer;
begin
Result := DaysPerMonth(Year, Month);
end;
procedure TJvCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
TheText: string;
//>Polaris
procedure DefaultDraw;
begin
if TheText <> '' then
with ARect, Canvas do
begin
Brush.Style := bsClear;
TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
end;
end;
procedure PoleDraw;
begin
with ARect, Canvas do
begin
if (ARow > 0) and ((FMinDate <> NullDate) or (FMaxDate <> NullDate)) then
if not CellInRange(ACol, ARow) then
if TheText <> '' then
begin
Font.Color := clBtnFace;
if Color = clBtnFace then
begin
Font.Color := clBtnHighlight;
TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2 + 1,
Top + (Bottom - Top - TextHeight(TheText)) div 2 + 1, TheText);
Font.Color := clBtnShadow;
end;
end;
DefaultDraw;
end;
end;
// DaysThisMonth) then
Result := ''
else
Result := IntToStr(DayNum);
end;
end;
//>Polaris
procedure TJvCalendar.SetMinDate(Value: TDateTime);
begin
if FMinDate <> Value then
begin
FMinDate := Value;
if FDate < FMinDate then
SetCalendarDate(FMinDate);
// else
UpdateCalendar;
end;
end;
procedure TJvCalendar.SetMaxDate(Value: TDateTime);
begin
if FMaxDate <> Value then
begin
FMaxDate := Value;
if FDate > FMaxDate then
SetCalendarDate(FMaxDate);
// else
UpdateCalendar;
end;
end;
function TJvCalendar.GetCellDate(ACol, ARow: Integer): TDateTime;
var
DayNum: Integer;
begin
Result := NullDate;
if (ARow > 0) and (GetCellText(ACol, ARow) <> '') then
begin
DayNum := FMonthOffset + ACol + (ARow - 1) * 7;
if (DayNum < 1) or (DayNum > DaysThisMonth) then
Result := NullDate
else
Result := EncodeDate(GetDateElement(1), GetDateElement(2), DayNum);
end;
end;
function TJvCalendar.CellInRange(ACol, ARow: Integer): Boolean;
begin
if (Row < 1) {or ((FMinDate = NullDate) and (FMaxDate = NullDate))} then
Result := True
else
Result := DateInRange(GetCellDate(ACol, ARow));
end;
function TJvCalendar.DateInRange(ADate: TDateTime): Boolean;
begin
if ((FMinDate = NullDate) and (FMaxDate = NullDate)) or (ADate = NullDate) then
Result := True
else
begin
Result := False;
if ADate = NullDate then
Result := True
else
if (FMinDate <> NullDate) and (FMaxDate <> NullDate) then
Result := (ADate >= FMinDate) and (ADate <= FMaxDate)
else
if FMinDate <> NullDate then
Result := ADate >= FMinDate
else
if FMaxDate <> NullDate then
Result := ADate <= FMaxDate
end;
end;
//Polaris
var
OldDay: Integer;
// 1 then
Day := Day - 1
else
CalendarDate := CalendarDate - 1;
if not DateInRange(FDate) then
Day := OldDay;
Exit;
end;
VK_RIGHT, VK_ADD:
begin
if Day < DaysThisMonth then
Day := Day + 1
else
CalendarDate := CalendarDate + 1;
if not DateInRange(FDate) then
Day := OldDay;
Exit;
end;
end;
inherited KeyDown(Key, Shift);
end;
procedure TJvCalendar.KeyPress(var Key: Char);
begin
if (Key = 'T') or (Key = 't') then
begin
CalendarDate := Trunc(Now);
Key := #0;
end;
inherited KeyPress(Key);
end;
function TJvCalendar.SelectCell(ACol, ARow: Longint): Boolean;
begin
if ((not FUpdating) and FReadOnly) or (CellText[ACol, ARow] = '') or
//>Polaris
not CellInRange(ACol, ARow) then {// Value then
//begin
if (FMinDate <> NullDate) and (Value < FMinDate) then
Value := FMinDate
else
if (FMaxDate <> NullDate) and (Value > FMaxDate) then
Value := FMaxDate;
FDate := Value;
UpdateCalendar;
Change;
//end;
end;
function TJvCalendar.StoreCalendarDate: Boolean;
begin
Result := not FUseCurrentDate;
end;
function TJvCalendar.GetDateElement(Index: Integer): Integer;
var
AYear, AMonth, ADay: Word;
begin
DecodeDate(FDate, AYear, AMonth, ADay);
case Index of
1:
Result := AYear;
2:
Result := AMonth;
3:
Result := ADay;
else
Result := -1;
end;
end;
procedure TJvCalendar.SetDateElement(Index: Integer; Value: Integer);
var
iValue: Word;
TYear, TMonth, TDay: Word;
AYear, AMonth, ADay: Word;
//>Polaris
TmpDate: TDateTime;
// 0 then
begin
DecodeDate(FDate, AYear, AMonth, ADay);
iValue := Value;
case Index of
1:
begin
//>Polaris
if FMinDate <> NullDate then
begin
DecodeDate(FMinDate, TYear, TMonth, TDay);
if Value < TYear then
Value := TYear;
if (Value = TYear) and (AMonth < TMonth) then
AMonth := TMonth;
if (Value = TYear) and (AMonth = TMonth) and (ADay < TDay) then
ADay := TDay;
end;
if FMaxDate <> NullDate then
begin
DecodeDate(FMaxDate, TYear, TMonth, TDay);
if Value > TYear then
Value := TYear;
if (Value = TYear) and (AMonth > TMonth) then
AMonth := TMonth;
if (Value = TYear) and (AMonth = TMonth) and (ADay > TDay) then
ADay := TDay;
end;
// Value then
AYear := Value
else
Exit;
end;
2:
if (Value <= 12) and (Value <> AMonth) then
begin
//>Polaris
if FMinDate <> NullDate then
begin
DecodeDate(FMinDate, TYear, TMonth, TDay);
if (AYear = TYear) and (Value < TMonth) then
Value := TMonth;
if (Value = TYear) and (AMonth = TMonth) and (ADay < TDay) then
ADay := TDay;
end;
if FMaxDate <> NullDate then
begin
DecodeDate(FMaxDate, TYear, TMonth, TDay);
if (AYear = TYear) and (Value > TMonth) then
Value := TMonth;
if (Value = TYear) and (AMonth = TMonth) and (ADay > TDay) then
ADay := TDay;
end;
// DaysPerMonth(Year, Value) then
ADay := DaysPerMonth(Year, Value);
//>Polaris
{
TmpDate := EncodeDate(AYear, AMonth, ADay);
if (FMinDate <> NullDate) and (TmpDate < FMinDate) then DecodeDate(FMinDate, TYear, TMonth, ADay);
if (FMaxDate <> NullDate) and (TmpDate > FMaxDate) then DecodeDate(FMaxDate, TYear, TMonth, ADay)
}
// ADay) then
begin
//>Polaris
TmpDate := EncodeDate(AYear, AMonth, Value);
if (FMinDate <> NullDate) and (TmpDate < FMinDate) then
DecodeDate(FMinDate, TYear, TMonth, iValue);
if (FMaxDate <> NullDate) and (TmpDate > FMaxDate) then
DecodeDate(FMaxDate, TYear, TMonth, iValue);
// FWeekendColor then
begin
FWeekendColor := Value;
Invalidate;
end;
end;
procedure TJvCalendar.SetWeekends(Value: TDaysOfWeek);
begin
if Value <> FWeekends then
begin
FWeekends := Value;
UpdateCalendar;
end;
end;
function TJvCalendar.IsWeekend(ACol, ARow: Integer): Boolean;
begin
Result := TDayOfWeekName((Integer(StartOfWeek) + ACol) mod 7) in FWeekends;
end;
procedure TJvCalendar.SetStartOfWeek(Value: TDayOfWeekName);
begin
if Value <> FStartOfWeek then
begin
FStartOfWeek := Value;
UpdateCalendar;
end;
end;
procedure TJvCalendar.SetUseCurrentDate(Value: Boolean);
begin
if Value <> FUseCurrentDate then
begin
FUseCurrentDate := Value;
if Value then
begin
FDate := Date; { use the current date, then }
UpdateCalendar;
end;
end;
end;
{ Given a value of 1 or -1, moves to Next or Prev month accordingly }
procedure TJvCalendar.ChangeMonth(Delta: Integer);
var
AYear, AMonth, ADay: Word;
NewDate: TDateTime;
CurDay: Integer;
begin
DecodeDate(FDate, AYear, AMonth, ADay);
CurDay := ADay;
if Delta > 0 then
ADay := DaysPerMonth(AYear, AMonth)
else
ADay := 1;
NewDate := EncodeDate(AYear, AMonth, ADay);
NewDate := NewDate + Delta;
DecodeDate(NewDate, AYear, AMonth, ADay);
if DaysPerMonth(AYear, AMonth) > CurDay then
ADay := CurDay
else
ADay := DaysPerMonth(AYear, AMonth);
CalendarDate := EncodeDate(AYear, AMonth, ADay);
end;
procedure TJvCalendar.PrevMonth;
begin
ChangeMonth(-1);
end;
procedure TJvCalendar.NextMonth;
begin
ChangeMonth(1);
end;
procedure TJvCalendar.NextYear;
begin
if IsLeapYear(Year) and (Month = 2) and (Day = 29) then
Day := 28;
Year := Year + 1;
end;
procedure TJvCalendar.PrevYear;
begin
if IsLeapYear(Year) and (Month = 2) and (Day = 29) then
Day := 28;
Year := Year - 1;
end;
procedure TJvCalendar.CalendarUpdate(DayOnly: Boolean);
var
AYear, AMonth, ADay: Word;
FirstDate: TDateTime;
begin
FUpdating := True;
try
DecodeDate(FDate, AYear, AMonth, ADay);
FirstDate := EncodeDate(AYear, AMonth, 1);
FMonthOffset := 2 - ((DayOfWeek(FirstDate) - Ord(StartOfWeek) + 7) mod 7);
{ day of week for 1st of month }
if FMonthOffset = 2 then
FMonthOffset := -5;
MoveColRow((ADay - FMonthOffset) mod 7, (ADay - FMonthOffset) div 7 + 1, False, False);
if DayOnly then
Update
else
Invalidate;
finally
FUpdating := False;
end;
end;
procedure TJvCalendar.UpdateCalendar;
begin
CalendarUpdate(False);
end;
procedure TJvCalendar.BoundsChanged;
var
GridLinesH, GridLinesW: Integer;
begin
GridLinesH := 6 * GridLineWidth;
if (goVertLine in Options) or (goFixedVertLine in Options) then
GridLinesW := 6 * GridLineWidth
else
GridLinesW := 0;
DefaultColWidth := (ClientWidth - GridLinesW) div 7;
DefaultRowHeight := (ClientHeight - GridLinesH) div 7;
inherited BoundsChanged;
end;
//=== { TJvLocCalendar } =====================================================
type
TJvLocCalendar = class(TJvCalendar)
protected
procedure EnabledChanged; override;
procedure ParentColorChanged; override;
procedure CreateParams(var Params: TCreateParams); override;
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
public
constructor Create(AOwner: TComponent); override;
procedure MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
property GridLineWidth;
property DefaultColWidth;
property DefaultRowHeight;
end;
constructor TJvLocCalendar.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := [csCaptureMouse, csClickEvents, csDoubleClicks];
ControlStyle := ControlStyle + [csReplicatable];
Ctl3D := False;
Enabled := False;
BorderStyle := bsNone;
ParentColor := True;
CalendarDate := Trunc(Now);
UseCurrentDate := False;
FixedColor := Self.Color;
Options := [goFixedHorzLine];
TabStop := False;
end;
procedure TJvLocCalendar.ParentColorChanged;
begin
inherited ParentColorChanged;
if ParentColor then
FixedColor := Self.Color;
end;
procedure TJvLocCalendar.EnabledChanged;
begin
inherited EnabledChanged;
if HandleAllocated and not (csDesigning in ComponentState) then
EnableWindow(Handle, True);
end;
procedure TJvLocCalendar.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style := Style and not (WS_BORDER or WS_TABSTOP or WS_DISABLED);
end;
procedure TJvLocCalendar.MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
var
Coord: TGridCoord;
begin
Coord := MouseCoord(X, Y);
ACol := Coord.X;
ARow := Coord.Y;
end;
procedure TJvLocCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect;
AState: TGridDrawState);
var
D, M, Y: Word;
begin
inherited DrawCell(ACol, ARow, ARect, AState);
DecodeDate(CalendarDate, Y, M, D);
D := StrToIntDef(CellText[ACol, ARow], 0);
if (D > 0) and (D <= DaysPerMonth(Y, M)) then
if EncodeDate(Y, M, D) = SysUtils.Date then
Frame3D(Canvas, ARect, clBtnShadow, clBtnHighlight, 1);
end;
//=== { TJvPopupCalendar } ===================================================
type
TJvPopupCalendar = class(TJvPopupWindow)
private
FCalendar: TJvCalendar;
FTitleLabel: TLabel;
FFourDigitYear: Boolean;
FBtns: array [0..3] of TJvSpeedButton;
procedure CalendarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PrevMonthBtnClick(Sender: TObject);
procedure NextMonthBtnClick(Sender: TObject);
procedure PrevYearBtnClick(Sender: TObject);
procedure NextYearBtnClick(Sender: TObject);
procedure CalendarChange(Sender: TObject);
procedure TopPanelDblClick(Sender: TObject);
//>Polaris
// function GetDate(Index: Integer): TDate;
procedure SetDate(Index: Integer; Value: TDateTime);
//Polaris
procedure CheckButton;
//Polaris
procedure Invalidate; override;
procedure Update; override;
property MinDate: TDateTime index 0 {read GetDate} write SetDate;
property MaxDate: TDateTime index 1 {read GetDate} write SetDate;
// nil) and not (csDesigning in AOwner.ComponentState) and
(Screen.PixelsPerInch <> 96) then
begin { scale to screen res }
Result.ScaleBy(Screen.PixelsPerInch, 96);
{ The ScaleBy method does not scale the font well, so set the
font back to the original info. }
TJvPopupCalendar(Result).FCalendar.ParentFont := True;
TJvPopupCalendar(Result).FCalendar.MinDate := MinDate;
TJvPopupCalendar(Result).FCalendar.MaxDate := MaxDate;
FontSetDefault(TJvPopupCalendar(Result).Font);
{$IFDEF VCL}
Result.BiDiMode := ABiDiMode;
{$ENDIF VCL}
end;
*)
end;
procedure SetupPopupCalendar(PopupCalendar: TWinControl;
AStartOfWeek: TDayOfWeekName; AWeekends: TDaysOfWeek;
AWeekendColor: TColor; BtnHints: TStrings; FourDigitYear: Boolean;
MinDate: TDateTime; MaxDate: TDateTime);
var
I: Integer;
begin
if (PopupCalendar = nil) or not (PopupCalendar is TJvPopupCalendar) then
Exit;
// Polaris
if not (csDesigning in PopupCalendar.Owner.ComponentState) then
begin
TJvPopupCalendar(PopupCalendar).SetDate(0, MinDate);
TJvPopupCalendar(PopupCalendar).SetDate(1, MaxDate);
end;
// Polaris
// TJvPopupCalendar(PopupCalendar).MaxDate := MaxDate;
TJvPopupCalendar(PopupCalendar).FFourDigitYear := FourDigitYear;
if TJvPopupCalendar(PopupCalendar).FCalendar <> nil then
begin
with TJvPopupCalendar(PopupCalendar).FCalendar do
begin
StartOfWeek := AStartOfWeek;
WeekendColor := AWeekendColor;
Weekends := AWeekends;
end;
if BtnHints <> nil then
for I := 0 to Min(BtnHints.Count - 1, 3) do
if BtnHints[I] <> '' then
TJvPopupCalendar(PopupCalendar).FBtns[I].Hint := BtnHints[I];
end;
end;
constructor TJvPopupCalendar.Create(AOwner: TComponent);
{$IFDEF JVCLThemesEnabled}
var
BtnSide: Integer;
VertOffset: Integer;
HorzOffset: Integer;
Control, BackPanel: TWinControl;
{$ELSE}
const
BtnSide = 14;
VertOffset = -1;
HorzOffset = 1;
var
Control, BackPanel: TWinControl;
{$ENDIF JVCLThemesEnabled}
begin
inherited Create(AOwner);
FFourDigitYear := IsFourDigitYear;
Height := Max(PopupCalendarSize.Y, 120);
Width := Max(PopupCalendarSize.X, 180);
Color := clBtnFace;
FontSetDefault(Font);
if AOwner is TControl then
ShowHint := TControl(AOwner).ShowHint
else
ShowHint := True;
if csDesigning in ComponentState then
Exit;
{$IFDEF JVCLThemesEnabled}
if ThemeServices.ThemesEnabled then
begin
VertOffset := 0;
HorzOffset := 0;
BtnSide := 16
end
else
begin
VertOffset := -1;
HorzOffset := 1;
BtnSide := 14;
end;
{$ENDIF JVCLThemesEnabled}
BackPanel := TPanel.Create(Self);
with BackPanel as TPanel do
begin
Parent := Self;
Align := alClient;
ParentColor := True;
ControlStyle := ControlStyle + [csReplicatable];
BevelOuter := bvNone;
BevelInner := bvNone;
end;
Control := TPanel.Create(Self);
with Control as TPanel do
begin
Parent := BackPanel;
Align := alTop;
Width := Self.Width - 4;
Height := 18;
BevelOuter := bvNone;
ParentColor := True;
ControlStyle := ControlStyle + [csReplicatable];
end;
FCalendar := TJvLocCalendar.Create(Self);
with TJvLocCalendar(FCalendar) do
begin
Parent := BackPanel;
Align := alClient;
OnChange := CalendarChange;
OnMouseUp := CalendarMouseUp;
end;
FBtns[0] := TJvTimerSpeedButton.Create(Self);
with FBtns[0] do
begin
Parent := Control;
SetBounds(0 - HorzOffset, VertOffset, BtnSide, BtnSide);
CreateButtonGlyph(Glyph, 0);
OnClick := PrevYearBtnClick;
Hint := RsPrevYearHint;
end;
FBtns[1] := TJvTimerSpeedButton.Create(Self);
with FBtns[1] do
begin
Parent := Control;
SetBounds(BtnSide - 1 - HorzOffset, VertOffset, BtnSide, BtnSide);
CreateButtonGlyph(Glyph, 1);
OnClick := PrevMonthBtnClick;
Hint := RsPrevMonthHint;
end;
FTitleLabel := TLabel.Create(Self);
with FTitleLabel do
begin
Parent := Control;
AutoSize := False;
Alignment := taCenter;
SetBounds(BtnSide * 2 + 1, 1, Control.Width - 4 * BtnSide - 2, 14);
Transparent := True;
OnDblClick := TopPanelDblClick;
ControlStyle := ControlStyle + [csReplicatable];
end;
FBtns[2] := TJvTimerSpeedButton.Create(Self);
with FBtns[2] do
begin
Parent := Control;
SetBounds(Control.Width - 2 * BtnSide + 1 + HorzOffset, VertOffset, BtnSide, BtnSide);
CreateButtonGlyph(Glyph, 2);
OnClick := NextMonthBtnClick;
Hint := RsNextMonthHint;
end;
FBtns[3] := TJvTimerSpeedButton.Create(Self);
with FBtns[3] do
begin
Parent := Control;
SetBounds(Control.Width - BtnSide + HorzOffset, VertOffset, BtnSide, BtnSide);
CreateButtonGlyph(Glyph, 3);
OnClick := NextYearBtnClick;
Hint := RsNextYearHint;
end;
//Polaris
CheckButton;
end;
//>Polaris
procedure TJvPopupCalendar.CheckButton;
var
// CurDate: TDate;
AYear, AMonth, ADay: Word;
begin
if not Assigned(FCalendar) then
Exit;
// CurDate := TJvLocCalendar(FCalendar).CalendarDate;
if TJvLocCalendar(FCalendar).MinDate = NullDate then
for AYear := 0 to 1 do
FBtns[AYear].Enabled := True
else
begin
DecodeDate(TJvLocCalendar(FCalendar).MinDate, AYear, AMonth, ADay);
FBtns[0].Enabled := TJvLocCalendar(FCalendar).Year > AYear;
FBtns[1].Enabled := (TJvLocCalendar(FCalendar).Year > AYear) or ((TJvLocCalendar(FCalendar).Year = AYear) and
(TJvLocCalendar(FCalendar).Month > AMonth));
end;
if TJvLocCalendar(FCalendar).MaxDate = NullDate then
for AYear := 2 to 3 do
FBtns[AYear].Enabled := True
else
begin
DecodeDate(TJvLocCalendar(FCalendar).MaxDate, AYear, AMonth, ADay);
FBtns[2].Enabled := (TJvLocCalendar(FCalendar).Year < AYear) or ((TJvLocCalendar(FCalendar).Year = AYear) and
(TJvLocCalendar(FCalendar).Month < AMonth));
FBtns[3].Enabled := TJvLocCalendar(FCalendar).Year < AYear;
end;
end;
procedure TJvPopupCalendar.Invalidate;
begin
CheckButton;
inherited Invalidate;
end;
procedure TJvPopupCalendar.Update;
begin
CheckButton;
inherited Update;
end;
{
function TJvPopupCalendar.GetDate(Index: Integer): TDateTime;
begin
FCalendar.Min
case Index of
0:
Result := TJvLocCalendar(FCalendar).FMinDate;
1:
Result := TJvLocCalendar(FCalendar).FMaxDate;
else
Result := NullDate;
end;
end;
}
procedure TJvPopupCalendar.SetDate(Index: Integer; Value: TDateTime);
begin
case Index of
0:
TJvLocCalendar(FCalendar).FMinDate := Value;
1:
TJvLocCalendar(FCalendar).FMaxDate := Value;
end;
end;
// 0) and (FCalendar.CellText[Col, Row] <> '') then
CloseUp(True);
end;
end;
procedure TJvPopupCalendar.TopPanelDblClick(Sender: TObject);
begin
FCalendar.CalendarDate := Trunc(Now);
end;
procedure TJvPopupCalendar.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if FCalendar <> nil then
case Key of
VK_NEXT:
if ssCtrl in Shift then
FCalendar.NextYear
else
FCalendar.NextMonth;
VK_PRIOR:
if ssCtrl in Shift then
FCalendar.PrevYear
else
FCalendar.PrevMonth;
VK_RETURN:
Click;
else
TJvLocCalendar(FCalendar).KeyDown(Key, Shift);
end;
end;
procedure TJvPopupCalendar.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
if (FCalendar <> nil) and (Key <> #0) then
FCalendar.KeyPress(Key);
end;
function TJvPopupCalendar.GetValue: Variant;
begin
if csDesigning in ComponentState then
Result := VarFromDateTime(SysUtils.Date)
else
Result := VarFromDateTime(FCalendar.CalendarDate);
end;
procedure TJvPopupCalendar.SetValue(const Value: Variant);
begin
if not (csDesigning in ComponentState) then
begin
try
if (Trim(ReplaceStr(VarToStr(Value), DateSeparator, '')) = '') or
VarIsNull(Value) or VarIsEmpty(Value) then
FCalendar.CalendarDate := VarToDateTime(SysUtils.Date)
else
FCalendar.CalendarDate := VarToDateTime(Value);
CalendarChange(nil);
except
FCalendar.CalendarDate := VarToDateTime(SysUtils.Date);
end;
end;
end;
procedure TJvPopupCalendar.PrevYearBtnClick(Sender: TObject);
begin
FCalendar.PrevYear;
end;
procedure TJvPopupCalendar.NextYearBtnClick(Sender: TObject);
begin
FCalendar.NextYear;
end;
procedure TJvPopupCalendar.PrevMonthBtnClick(Sender: TObject);
begin
FCalendar.PrevMonth;
end;
procedure TJvPopupCalendar.NextMonthBtnClick(Sender: TObject);
begin
FCalendar.NextMonth;
end;
procedure TJvPopupCalendar.CalendarChange(Sender: TObject);
begin
FTitleLabel.Caption := FormatDateTime('MMMM, YYYY', FCalendar.CalendarDate);
CheckButton; // Polaris
end;
//=== { TJvSelectDateDlg } ===================================================
type
TJvSelectDateDlg = class(TJvForm)
Calendar: TJvCalendar;
TitleLabel: TLabel;
procedure PrevMonthBtnClick(Sender: TObject);
procedure NextMonthBtnClick(Sender: TObject);
procedure PrevYearBtnClick(Sender: TObject);
procedure NextYearBtnClick(Sender: TObject);
procedure CalendarChange(Sender: TObject);
procedure CalendarDblClick(Sender: TObject);
procedure TopPanelDblClick(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private
FBtns: array [0..3] of TJvSpeedButton;
procedure SetDate(Date: TDateTime);
procedure CheckButton; // Polaris
function GetDate: TDateTime;
public
constructor Create(AOwner: TComponent); override;
property Date: TDateTime read GetDate write SetDate;
end;
constructor TJvSelectDateDlg.Create(AOwner: TComponent);
var
Control: TWinControl;
begin
inherited CreateNew(AOwner, 0); // BCB compatible
Caption := RsDateDlgCaption;
BorderStyle := bsToolWindow;
Color := clBtnFace;
BorderIcons := [biSystemMenu];
ClientHeight := 158; // Polaris
ClientWidth := 222;
FontSetDefault(Font);
Position := poScreenCenter;
ShowHint := True;
KeyPreview := True;
Control := TPanel.Create(Self);
with Control as TPanel do
begin
Parent := Self;
SetBounds(0, 0, 222, 22);
Align := alTop;
BevelOuter := bvNone;
BevelInner := bvNone;
ParentColor := True;
ParentFont := True;
end;
TitleLabel := TLabel.Create(Self);
with TitleLabel do
begin
Parent := Control;
SetBounds(35, 4, 152, 14);
Alignment := taCenter;
AutoSize := False;
Caption := '';
ParentFont := True;
Font.Color := clNavy;
Font.Style := [fsBold];
Transparent := True;
OnDblClick := TopPanelDblClick;
end;
FBtns[0] := TJvTimerSpeedButton.Create(Self);
with FBtns[0] do
begin
Parent := Control;
SetBounds(3, 3, 16, 16);
CreateButtonGlyph(Glyph, 0);
OnClick := PrevYearBtnClick;
Flat := True;
Hint := RsPrevYearHint;
end;
FBtns[1] := TJvTimerSpeedButton.Create(Self);
with FBtns[1] do
begin
Parent := Control;
SetBounds(19, 3, 16, 16);
CreateButtonGlyph(Glyph, 1);
OnClick := PrevMonthBtnClick;
Flat := True;
Hint := RsPrevMonthHint;
end;
FBtns[2] := TJvTimerSpeedButton.Create(Self);
with FBtns[2] do
begin
Parent := Control;
SetBounds(188, 3, 16, 16);
CreateButtonGlyph(Glyph, 2);
OnClick := NextMonthBtnClick;
Flat := True;
Hint := RsNextMonthHint;
end;
FBtns[3] := TJvTimerSpeedButton.Create(Self);
with FBtns[3] do
begin
Parent := Control;
SetBounds(204, 3, 16, 16);
CreateButtonGlyph(Glyph, 3);
OnClick := NextYearBtnClick;
Flat := True;
Hint := RsNextYearHint;
end;
Control := TPanel.Create(Self);
with Control as TPanel do
begin
Parent := Self;
SetBounds(0, 133, 222, 25); // Polaris
Align := alBottom;
BevelInner := bvNone;
BevelOuter := bvNone;
ParentFont := True;
ParentColor := True;
end;
{ with TButton.Create(Self) do
begin
Parent := Control;
SetBounds(0, 0, 112, 21);
Caption := ResStr(SOKButton);
ModalResult := mrOk;
end;
with TButton.Create(Self) do
begin
Parent := Control;
SetBounds(111, 0, 111, 21);
Caption := ResStr(SCancelButton);
ModalResult := mrCancel;
Cancel := True;
end; }// Polaris
with TButton.Create(Self) do
begin // Polaris
Parent := Control;
SetBounds(0, 0, 111, 25);
Default := True;
ModalResult := mrOk;
Caption := RsButtonOKCaption;
// Kind := bkOk;
end;
with TButton.Create(Self) do
begin // Polaris
Parent := Control;
SetBounds(111, 0, 111, 25);
Cancel := True;
ModalResult := mrCancel;
Caption := RsButtonCancelCaption;
// Kind := bkCancel;
end;
Control := TPanel.Create(Self);
with Control as TPanel do
begin
Parent := Self;
SetBounds(0, 22, 222, 111);
Align := alClient;
BevelInner := bvLowered;
ParentFont := True;
ParentColor := True;
end;
Calendar := TJvCalendar.Create(Self);
with Calendar do
begin
Parent := Control;
Align := alClient;
ParentFont := True;
SetBounds(2, 2, 218, 113);
Color := clWhite;
TabOrder := 0;
UseCurrentDate := False;
Options := Options - [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine];
OnChange := CalendarChange;
OnDblClick := CalendarDblClick;
end;
OnKeyDown := FormKeyDown;
Calendar.CalendarDate := Trunc(Now);
ActiveControl := Calendar;
end;
procedure TJvSelectDateDlg.SetDate(Date: TDateTime);
begin
if Date = NullDate then
Date := SysUtils.Date;
try
Calendar.CalendarDate := Date;
CalendarChange(nil);
except
Calendar.CalendarDate := SysUtils.Date;
end;
end;
function TJvSelectDateDlg.GetDate: TDateTime;
begin
Result := Calendar.CalendarDate;
end;
procedure TJvSelectDateDlg.TopPanelDblClick(Sender: TObject);
begin
SetDate(Trunc(Now));
end;
procedure TJvSelectDateDlg.PrevYearBtnClick(Sender: TObject);
begin
Calendar.PrevYear;
end;
procedure TJvSelectDateDlg.NextYearBtnClick(Sender: TObject);
begin
Calendar.NextYear;
end;
procedure TJvSelectDateDlg.PrevMonthBtnClick(Sender: TObject);
begin
Calendar.PrevMonth;
end;
procedure TJvSelectDateDlg.NextMonthBtnClick(Sender: TObject);
begin
Calendar.NextMonth;
end;
//>Polaris
procedure TJvSelectDateDlg.CheckButton;
var
// CurDate: TDate;
AYear, AMonth, ADay: Word;
begin
if not Assigned(Calendar) then
Exit;
// CurDate := Calendar.CalendarDate;
if Calendar.MinDate = NullDate then
for AYear := 0 to 1 do
FBtns[AYear].Enabled := True
else
begin
DecodeDate(Calendar.MinDate, AYear, AMonth, ADay);
FBtns[0].Enabled := Calendar.Year > AYear;
FBtns[1].Enabled := (Calendar.Year > AYear) or ((Calendar.Year = AYear) and (Calendar.Month > AMonth));
end;
if Calendar.MaxDate = NullDate then
for AYear := 2 to 3 do
FBtns[AYear].Enabled := True
else
begin
DecodeDate(Calendar.MaxDate, AYear, AMonth, ADay);
FBtns[2].Enabled := (Calendar.Year < AYear) or ((Calendar.Year = AYear) and (Calendar.Month < AMonth));
FBtns[3].Enabled := Calendar.Year < AYear;
end;
end;
// '' then
Result.Caption := DlgCaption;
Result.Calendar.MinDate := MinDate; // Polaris
Result.Calendar.MaxDate := MaxDate; // Polaris
if Screen.PixelsPerInch <> 96 then
begin { scale to screen res }
Result.ScaleBy(Screen.PixelsPerInch, 96);
{ The ScaleBy method does not scale the font well, so set the
font back to the original info. }
Result.Calendar.ParentFont := True;
FontSetDefault(Result.Font);
Result.Left := (Screen.Width div 2) - (Result.Width div 2);
Result.Top := (Screen.Height div 2) - (Result.Height div 2);
end;
except
Result.Free;
raise;
end;
end;
function PopupDate(var Date: TDateTime; Edit: TWinControl;
MinDate: TDateTime; MaxDate: TDateTime): Boolean;
var
D: TJvSelectDateDlg;
P: TPoint;
W, H, X, Y: Integer;
begin
Result := False;
D := CreateDateDialog('', MinDate, MaxDate);
try
D.BorderIcons := [];
D.HandleNeeded;
D.Position := poDesigned;
W := D.Width;
H := D.Height;
P := (Edit.ClientOrigin);
Y := P.Y + Edit.Height - 1;
if (Y + H) > Screen.Height then
Y := P.Y - H + 1;
if Y < 0 then
Y := P.Y + Edit.Height - 1;
X := (P.X + Edit.Width) - W;
if X < 0 then
X := P.X;
D.Left := X;
D.Top := Y;
D.Date := Date;
if D.ShowModal = mrOk then
begin
Date := D.Date;
Result := True;
end;
finally
D.Free;
end;
end;
function SelectDate(Sender: TWinControl; var Date: TDateTime; const DlgCaption: TCaption;
AStartOfWeek: TDayOfWeekName; AWeekends: TDaysOfWeek;
AWeekendColor: TColor; BtnHints: TStrings;
MinDate: TDateTime; MaxDate: TDateTime): Boolean;
var
D: TJvSelectDateDlg;
I: Integer;
P: TPoint;
Rect: TRect;
Monitor: TMonitor;
begin
Result := False;
D := CreateDateDialog(DlgCaption, MinDate, MaxDate);
try
// for popup position
if Assigned(Sender) then
begin
D.Position := poDesigned;
P := Sender.ClientOrigin;
D.Top := P.Y + Sender.Height - 1;
Monitor := FindMonitor(MonitorFromWindow(Sender.Handle, MONITOR_DEFAULTTONEAREST));
Rect := GetWorkAreaRect(Monitor);
if (D.Top + D.Height) > Rect.Bottom then
D.Top := P.Y - D.Height + 1;
if D.Top < 0 then
D.Top := P.Y + Sender.Height - 1;
D.Left := (P.X + Sender.Width) - D.Width;
if (D.Left + D.Width) > Rect.Right then
D.Left := Rect.Right - D.Width;
if D.Left < 0 then
D.Left := Max(P.X, 0);
end;
D.Date := Date;
with D.Calendar do
begin
StartOfWeek := AStartOfWeek;
Weekends := AWeekends;
WeekendColor := AWeekendColor;
end;
if BtnHints <> nil then
for I := 0 to Min(BtnHints.Count - 1, 3) do
begin
if BtnHints[I] <> '' then
D.FBtns[I].Hint := BtnHints[I];
end;
if D.ShowModal = mrOk then
begin
Date := D.Date;
Result := True;
end;
finally
D.Free;
end;
end;
function SelectDateStr(Sender: TWinControl; var StrDate: string; const DlgCaption: TCaption;
AStartOfWeek: TDayOfWeekName; AWeekends: TDaysOfWeek;
AWeekendColor: TColor; BtnHints: TStrings;
MinDate: TDateTime; MaxDate: TDateTime): Boolean;
var
DateValue: TDateTime;
begin
if StrDate <> '' then
begin
try
DateValue := StrToDateFmt(ShortDateFormat, StrDate);
except
DateValue := Date;
end;
end
else
DateValue := Date;
Result := SelectDate(Sender, DateValue, DlgCaption, AStartOfWeek, AWeekends,
AWeekendColor, BtnHints, MinDate, MaxDate); // Polaris
if Result then
StrDate := FormatDateTime(ShortDateFormat, DateValue);
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.