283 lines
6.9 KiB
ObjectPascal
283 lines
6.9 KiB
ObjectPascal
{
|
|
TDBZVDateTimePicker control for Lazarus
|
|
- - - - - - - - - - - - - - - - - - - -
|
|
Author: Zoran Vučenović, January and February 2010
|
|
Зоран Вученовић, јануар и фебруар 2010.
|
|
|
|
Last change: August 2012
|
|
|
|
This unit is part of ZVDateTimeCtrls package for Lazarus.
|
|
TDBZVDateTimePicker is data-aware version of TZVDateTimePicker control.
|
|
|
|
-----------------------------------------------------------
|
|
LICENCE
|
|
- - - -
|
|
Modified LGPL -- see the file COPYING.modifiedLGPL.
|
|
|
|
-----------------------------------------------------------
|
|
NO WARRANTY
|
|
- - - - - -
|
|
There is no warranty whatsoever.
|
|
|
|
-----------------------------------------------------------
|
|
BEST REGARDS TO LAZARUS COMMUNITY!
|
|
- - - - - - - - - - - - - - - - - -
|
|
I do hope this control will be useful.
|
|
}
|
|
unit DBZVDateTimePicker;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, ZVDateTimePicker, db, DBCtrls;
|
|
|
|
type
|
|
|
|
{ TDBZVDateTimePicker }
|
|
|
|
TDBZVDateTimePicker = class(TCustomZVDateTimePicker)
|
|
private
|
|
{ Private declarations }
|
|
FDataLink: TFieldDataLink;
|
|
FReadOnly: Boolean;
|
|
FDataChangeCount: Integer;
|
|
FChangingCount: Integer;
|
|
function GetDataField: string;
|
|
function GetDataSource: TDataSource;
|
|
procedure SetDataField(const AValue: string);
|
|
procedure SetDataSource(const AValue: TDataSource);
|
|
procedure DataChange(Sender: TObject);
|
|
procedure SetReadOnly(const AValue: Boolean);
|
|
procedure UpdateData(Sender: TObject);
|
|
procedure ActiveChange(Sender: TObject);
|
|
function GetField: TField;
|
|
procedure CheckField;
|
|
protected
|
|
{ Protected declarations }
|
|
procedure Change; override;
|
|
procedure ConfirmChanges; override;
|
|
procedure UndoChanges; override;
|
|
public
|
|
{ Public declarations }
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
property Field: TField read GetField;
|
|
published
|
|
{ Published declarations }
|
|
property DataField: string read GetDataField write SetDataField;
|
|
property DataSource: TDataSource read GetDataSource write SetDataSource;
|
|
property ReadOnly: Boolean read FReadOnly write SetReadOnly;
|
|
|
|
property ArrowShape;
|
|
property ShowCheckBox;
|
|
property Checked;
|
|
property CenturyFrom;
|
|
property DateDisplayOrder;
|
|
property MaxDate;
|
|
property MinDate;
|
|
property AutoSize;
|
|
property Font;
|
|
property ParentFont;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property BorderStyle;
|
|
property BorderSpacing;
|
|
property Enabled;
|
|
property Color;
|
|
property ParentColor;
|
|
property DateSeparator;
|
|
property TrailingSeparator;
|
|
property TextForNullDate;
|
|
property LeadingZeros;
|
|
property ShowHint;
|
|
property ParentShowHint;
|
|
property Align;
|
|
property Anchors;
|
|
property Constraints;
|
|
property Cursor;
|
|
property PopupMenu;
|
|
property Visible;
|
|
property NullInputAllowed;
|
|
property Kind;
|
|
property TimeSeparator;
|
|
property TimeFormat;
|
|
property TimeDisplay;
|
|
{ property Time; This property should NOT be published here, it was
|
|
accidentally added in first release. }
|
|
property DateMode;
|
|
property UseDefaultSeparators;
|
|
//events:
|
|
property OnChange;
|
|
property OnCheckBoxChange;
|
|
property OnDropDown;
|
|
property OnCloseUp;
|
|
property OnChangeBounds;
|
|
property OnClick;
|
|
property OnContextPopup;
|
|
property OnDblClick;
|
|
property OnEditingDone;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnMouseDown;
|
|
property OnMouseEnter;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnMouseLeave;
|
|
property OnResize;
|
|
property OnUTF8KeyPress;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TDBZVDateTimePicker }
|
|
|
|
function TDBZVDateTimePicker.GetDataField: string;
|
|
begin
|
|
Result := FDataLink.FieldName;
|
|
end;
|
|
|
|
function TDBZVDateTimePicker.GetDataSource: TDataSource;
|
|
begin
|
|
Result := FDataLink.DataSource;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.SetDataField(const AValue: string);
|
|
begin
|
|
FDataLink.FieldName := AValue;
|
|
CheckField;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.SetDataSource(const AValue: TDataSource);
|
|
begin
|
|
ChangeDataSource(Self, FDataLink, AValue);
|
|
CheckField;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.DataChange(Sender: TObject);
|
|
begin
|
|
if (FChangingCount = 0) then begin
|
|
Inc(FDataChangeCount);
|
|
try
|
|
if Assigned(FDataLink.Field) and not FDataLink.Field.IsNull then begin
|
|
// Using the SetTheDateJumpMinMax procedure, instead of property
|
|
SetDateTimeJumpMinMax(FDataLink.Field.AsDateTime); // assignment allows
|
|
// this control to display dates from database whose value falls
|
|
// outside of MinDate and MaxDate interval.
|
|
// Note that user still cannot enter such values in the control.
|
|
end else
|
|
DateTime := NullDate;
|
|
|
|
finally
|
|
Dec(FDataChangeCount);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.SetReadOnly(const AValue: Boolean);
|
|
begin
|
|
if FReadOnly <> AValue then begin
|
|
FReadOnly := AValue;
|
|
CheckField;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.UpdateData(Sender: TObject);
|
|
begin
|
|
if Assigned(FDataLink.Field) then begin
|
|
if DateIsNull then
|
|
FDataLink.Field.AsVariant := Null
|
|
else
|
|
FDataLink.Field.AsDateTime := DateTime;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.ActiveChange(Sender: TObject);
|
|
begin
|
|
CheckField;
|
|
end;
|
|
|
|
function TDBZVDateTimePicker.GetField: TField;
|
|
begin
|
|
Result := FDataLink.Field;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.CheckField;
|
|
begin
|
|
if (FDataLink.Active) and Assigned(FDataLink.Field) then
|
|
inherited ReadOnly := FReadOnly or (not FDataLink.CanModify)
|
|
else begin
|
|
inherited ReadOnly := True;
|
|
DateTime := NullDate;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.Change;
|
|
begin
|
|
if (FDataChangeCount <= 0) and Assigned(FDataLink) then begin
|
|
Inc(FChangingCount);
|
|
try
|
|
if FDataLink.Edit then begin
|
|
FDataLink.Modified;
|
|
inherited Change; // calls OnChange event handler
|
|
end else
|
|
FDataLink.Reset; // reverts user changes
|
|
finally
|
|
Dec(FChangingCount);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.ConfirmChanges;
|
|
begin
|
|
inherited ConfirmChanges;
|
|
|
|
if Assigned(FDataLink) then
|
|
try
|
|
FDataLink.UpdateRecord;
|
|
except
|
|
SetFocus;
|
|
raise;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TDBZVDateTimePicker.UndoChanges;
|
|
begin
|
|
FDataLink.Reset;
|
|
|
|
inherited UndoChanges;
|
|
end;
|
|
|
|
constructor TDBZVDateTimePicker.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
FDataChangeCount := 0;
|
|
FChangingCount := 0;
|
|
FDataLink := TFieldDataLink.Create;
|
|
FDataLink.Control := Self;
|
|
DateTime := NullDate;
|
|
FDataLink.OnActiveChange := @ActiveChange;
|
|
FDataLink.OnDataChange := @DataChange;
|
|
FDataLink.OnUpdateData := @UpdateData;
|
|
|
|
CheckField;
|
|
end;
|
|
|
|
destructor TDBZVDateTimePicker.Destroy;
|
|
begin
|
|
FDataLink.OnUpdateData := nil;
|
|
FDataLink.OnDataChange := nil;
|
|
FDataLink.OnActiveChange := nil;
|
|
FreeAndNil(FDataLink);
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
end.
|