Added: Calendar to Date/Date Time components and grid controls. Bug fixes

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2773 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
jujibo
2013-08-18 09:59:00 +00:00
parent 600931ce0e
commit aa771f6036
9 changed files with 745 additions and 43 deletions

View File

@ -5,6 +5,7 @@ Note: Lazarus Trunk required
Version pre-1.1 Version pre-1.1
-------------------------------------------------- --------------------------------------------------
2013-08-18 Added: Calendar to Date/Date Time components and grid controls. Bug fixes
2013-06-17 Added: TJDBImageBlob. Display raw images from blob fields (read only) 2013-06-17 Added: TJDBImageBlob. Display raw images from blob fields (read only)
2013-04-29 Fixed: TJDBGridControl Focus issues 2013-04-29 Fixed: TJDBGridControl Focus issues
2013-01-03 Added: TJDbEnumCombo, like TDbComboBox but, uses itemindex instead of text 2013-01-03 Added: TJDbEnumCombo, like TDbComboBox but, uses itemindex instead of text

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<Package Version="4"> <Package Version="4">
<Name Value="jujiboutils"/> <Name Value="jujiboutils"/>
@ -23,38 +23,38 @@ db and non db controls."/>
<Version Major="1"/> <Version Major="1"/>
<Files Count="19"> <Files Count="19">
<Item1> <Item1>
<Filename Value="src/jcontrolutils.pas"/>
<UnitName Value="jcontrolutils"/>
</Item1>
<Item2>
<Filename Value="src/jdbgridcontrol.pas"/> <Filename Value="src/jdbgridcontrol.pas"/>
<HasRegisterProc Value="True"/> <HasRegisterProc Value="True"/>
<UnitName Value="JDBGridControl"/> <UnitName Value="JDBGridControl"/>
</Item1> </Item2>
<Item2> <Item3>
<Filename Value="src/jdblabelededit.pas"/> <Filename Value="src/jdblabelededit.pas"/>
<HasRegisterProc Value="True"/> <HasRegisterProc Value="True"/>
<UnitName Value="JDBLabeledEdit"/> <UnitName Value="JDBLabeledEdit"/>
</Item2> </Item3>
<Item3> <Item4>
<Filename Value="src/jdblabeledintegeredit.pas"/> <Filename Value="src/jdblabeledintegeredit.pas"/>
<HasRegisterProc Value="True"/> <HasRegisterProc Value="True"/>
<UnitName Value="jdblabeledintegeredit"/> <UnitName Value="jdblabeledintegeredit"/>
</Item3> </Item4>
<Item4> <Item5>
<Filename Value="src/jdblabeledfloatedit.pas"/> <Filename Value="src/jdblabeledfloatedit.pas"/>
<HasRegisterProc Value="True"/> <HasRegisterProc Value="True"/>
<UnitName Value="JDBLabeledFloatEdit"/> <UnitName Value="JDBLabeledFloatEdit"/>
</Item4> </Item5>
<Item5> <Item6>
<Filename Value="src/jdblabeledcurrencyedit.pas"/> <Filename Value="src/jdblabeledcurrencyedit.pas"/>
<HasRegisterProc Value="True"/> <HasRegisterProc Value="True"/>
<UnitName Value="jdblabeledcurrencyedit"/> <UnitName Value="jdblabeledcurrencyedit"/>
</Item5> </Item6>
<Item6> <Item7>
<Filename Value="src/jdblabeleddateedit.pas"/> <Filename Value="src/jdblabeleddateedit.pas"/>
<HasRegisterProc Value="True"/> <HasRegisterProc Value="True"/>
<UnitName Value="jdblabeleddateedit"/> <UnitName Value="jdblabeleddateedit"/>
</Item6>
<Item7>
<Filename Value="src/jcontrolutils.pas"/>
<UnitName Value="jcontrolutils"/>
</Item7> </Item7>
<Item8> <Item8>
<Filename Value="src/jlabeledintegeredit.pas"/> <Filename Value="src/jlabeledintegeredit.pas"/>

View File

@ -7,8 +7,8 @@ unit jujiboutils;
interface interface
uses uses
JDBGridControl, JDBLabeledEdit, jdblabeledintegeredit, JDBLabeledFloatEdit, jcontrolutils, JDBGridControl, JDBLabeledEdit, jdblabeledintegeredit,
jdblabeledcurrencyedit, jdblabeleddateedit, jcontrolutils, JDBLabeledFloatEdit, jdblabeledcurrencyedit, jdblabeleddateedit,
JLabeledIntegerEdit, JLabeledFloatEdit, JLabeledCurrencyEdit, JLabeledIntegerEdit, JLabeledFloatEdit, JLabeledCurrencyEdit,
JLabeledDateEdit, jdbgridutils, JLabeledTimeEdit, JDBLabeledTimeEdit, JLabeledDateEdit, jdbgridutils, JLabeledTimeEdit, JDBLabeledTimeEdit,
JLabeledDateTimeEdit, JDBLabeledDateTimeEdit, jinputconsts, JDbEnumCombo, JLabeledDateTimeEdit, JDBLabeledDateTimeEdit, jinputconsts, JDbEnumCombo,

View File

@ -22,7 +22,7 @@ unit jcontrolutils;
interface interface
uses uses
Classes, SysUtils, Dialogs; Classes, SysUtils, Dialogs, LResources;
function CountChar(const s: string; ch: char): integer; function CountChar(const s: string; ch: char): integer;
procedure Split(const Delimiter: char; Input: string; Strings: TStrings); procedure Split(const Delimiter: char; Input: string; Strings: TStrings);
@ -259,5 +259,31 @@ begin
Result := TryStrToDateTime(Value, bTime); Result := TryStrToDateTime(Value, bTime);
end; end;
initialization
LazarusResources.Add('JCalendarIcon','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a'
+#0#0#0#4'gAMA'#0#0#175#200'7'#5#138#233#0#0#0#25'tEXtSoftware'#0'Adobe Image'
+'Readyq'#201'e<'#0#0#1#206'IDAT8'#203#165#147#177'kTA'#16#135#191'w'#247#188
+#20#167#133#16#13#136#24#21#130' &X'#5'!'#18#4'!`'#149'@'#210#8#150'ZD'#16'['
+'+Q'#208#210#206'?A'#9'B'#130#130#157#160#16'='#177'Pl'#132' DL#Q'#137'E '
+#228#240#237#236#204'X'#236'{'#151'w'#24#4#201#194#176#203'2|'#243#251#205
+#236'f'#238#206'^V'#14#240#232#205#230'mw'#174#169#219'Q3C'#13#162#25#170#134
+#154#19#213'j'#161'ht'#212#236#253#253'+#'#227'9'#128#185#223#152#29'?0'#248
+'?'#149#239'<'#249'2'#214'S'#160'f'#131#0#237#165#235#224#14#26#193#20'D'#210
+'9'#20' '#1#10#1#17#182'o'#189'BD'#7'j'#128#170#15#14'G'#14#129#197#20#30'KH'
+#1'R@'#12#176#242#29#0#137#186#211#3'U+'#1#25#172'o'#128'[Rb'#150#148'h'#181
+#3'CC'#0#132': '#150#128#133#225'{\>'#127#248#159#222#23#223#173's!'#196'~'#5
+#162#134#185#147'7S'#210#179'O'#139't'#214#150#185'zn'#158#207'?Wx'#185#250
+#130#139'#S'#204#140#206'Q'#136#179#213#21#130'$@'#163#178#224'@'#222#204#0
+#152#25#157#163#27#186#0#252#218#222#224#193#244'C:k'#203#0#20'Q'#9'b'#196'h'
+';'#0'Q'#195#13#242#198#223#146#187#161'K'#171#217#234#1#11#177#178#221'u@4'
+#220#157'}'#165#133#206#215'T'#237#227#183#15#28';8'#204#205#167#243'L'#157
+#186'D'#149#11#208#30#200'kM'#180't'#217'l$'#11#19'''&'#153'89Y'#206'%c'#250
+#204',Y'#150#245#1#170#201'%@'#140'x)'#231#241#235#31'ij'#238#136#130#168#18
+#212#8#146#188#183#154'U1'#250#167#224#238#140#29#223#207'i'#173#222#190#247
+#254#194'n'#203#204#173#246#144#252#237#221#133#213#179'A'#173'-Q'#145#168'h'
+'4D'#141#168'qW'#192#230#214#239#231#0#217'^'#191#243#31#2'<4&'#179'.'#211
+#208#0#0#0#0'IEND'#174'B`'#130
]);
end. end.

View File

@ -23,7 +23,7 @@ interface
uses uses
Classes, SysUtils, Grids, Dialogs, LCLType, DBGrids, Controls, DB, Classes, SysUtils, Grids, Dialogs, LCLType, DBGrids, Controls, DB,
jcontrolutils, jinputconsts; jcontrolutils, jinputconsts, CalendarPopup, Calendar, Buttons;
type type
@ -58,12 +58,16 @@ type
theValue: TDateTime; theValue: TDateTime;
fFormat: string; fFormat: string;
function getFormat: string; function getFormat: string;
function EditText: string;
procedure myEditEnter(Sender: TObject); procedure myEditEnter(Sender: TObject);
procedure myEditOnEditingDone(Sender: TObject); procedure myEditOnEditingDone(Sender: TObject);
procedure formatInput; procedure formatInput;
procedure setFormat(const AValue: string); procedure setFormat(const AValue: string);
procedure OnKeyPress(Sender: TObject; var key: char); procedure OnKeyPress(Sender: TObject; var key: char);
procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState); procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
protected
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public public
CellEditor: TStringCellEditor; CellEditor: TStringCellEditor;
theGrid: TDBGrid; theGrid: TDBGrid;
@ -116,6 +120,9 @@ type
procedure setFormat(const AValue: string); procedure setFormat(const AValue: string);
procedure OnKeyPress(Sender: TObject; var key: char); procedure OnKeyPress(Sender: TObject; var key: char);
procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState); procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
protected
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public public
CellEditor: TStringCellEditor; CellEditor: TStringCellEditor;
theGrid: TDBGrid; theGrid: TDBGrid;
@ -178,7 +185,7 @@ type
implementation implementation
uses uses
Math; Math, dateutils;
{ TJDbGridStringCtrl } { TJDbGridStringCtrl }
@ -278,13 +285,22 @@ begin
Result := fFormat; Result := fFormat;
end; end;
function TJDbGridDateTimeCtrl.EditText: string;
begin
if Field.IsNull then
Result := ''
else
Result := FormatDateTime(ShortDateFormat, Field.AsDateTime) + ' ' +
FormatDateTime(ShortTimeFormat, Field.AsDateTime);
end;
procedure TJDbGridDateTimeCtrl.myEditEnter(Sender: TObject); procedure TJDbGridDateTimeCtrl.myEditEnter(Sender: TObject);
begin begin
Field := theGrid.SelectedField; Field := theGrid.SelectedField;
if not Assigned(Field) then if not Assigned(Field) then
abort; abort;
CellEditor.BoundsRect := theGrid.SelectedFieldRect; CellEditor.BoundsRect := theGrid.SelectedFieldRect;
CellEditor.Text := Field.AsString; CellEditor.Text := EditText;
CellEditor.OnKeyPress := @OnKeyPress; // Recuperamos el control :-p CellEditor.OnKeyPress := @OnKeyPress; // Recuperamos el control :-p
CellEditor.OnKeyDown := @OnKeyDown; CellEditor.OnKeyDown := @OnKeyDown;
theValue := Field.AsDateTime; theValue := Field.AsDateTime;
@ -361,6 +377,11 @@ end;
procedure TJDbGridDateTimeCtrl.OnKeyDown(Sender: TObject; var Key: word; procedure TJDbGridDateTimeCtrl.OnKeyDown(Sender: TObject; var Key: word;
Shift: TShiftState); Shift: TShiftState);
begin begin
if (ssAlt in Shift) and (key = 40) then
begin
ShowCalendar(Self);
key := 0;
end;
if Length(CellEditor.Caption) = 0 then if Length(CellEditor.Caption) = 0 then
begin begin
if Field.Value <> Null then if Field.Value <> Null then
@ -417,6 +438,39 @@ begin
end; end;
end; end;
procedure TJDbGridDateTimeCtrl.ShowCalendar(Sender: TObject);
var
PopupOrigin: TPoint;
ADate: TDateTime;
begin
if (not Assigned(Field)) then
exit;
PopupOrigin := CellEditor.ControlToScreen(Point(0, CellEditor.Height));
if Field.IsNull then
ADate := now
else
ADate := Field.AsDateTime;
ShowCalendarPopup(PopupOrigin, ADate, [dsShowHeadings, dsShowDayNames],
@CalendarPopupReturnDate, nil);
end;
procedure TJDbGridDateTimeCtrl.CalendarPopupReturnDate(Sender: TObject;
const ADate: TDateTime);
var
bufdate: TDateTime;
begin
if not (Field.DataSet.State in [dsEdit, dsInsert]) then
Field.DataSet.Edit;
if Field.IsNull then
bufdate := now
else
bufdate := Field.AsDateTime;
Field.AsDateTime :=
EncodeDateTime(YearOf(ADate), MonthOf(ADate), DayOf(ADate),
HourOf(bufdate), MinuteOf(bufdate), SecondOf(bufdate), MilliSecondOf(bufdate));
CellEditor.Text := EditText;
end;
function TJDbGridDateTimeCtrl.isNull: boolean; function TJDbGridDateTimeCtrl.isNull: boolean;
begin begin
Result := theValue = 0; Result := theValue = 0;
@ -741,6 +795,11 @@ end;
procedure TJDbGridDateCtrl.OnKeyDown(Sender: TObject; var Key: word; procedure TJDbGridDateCtrl.OnKeyDown(Sender: TObject; var Key: word;
Shift: TShiftState); Shift: TShiftState);
begin begin
if (ssAlt in Shift) and (key = 40) then
begin
ShowCalendar(Self);
key := 0;
end;
if Length(CellEditor.Caption) = 0 then if Length(CellEditor.Caption) = 0 then
begin begin
if Field.Value <> null then if Field.Value <> null then
@ -797,6 +856,39 @@ begin
end; end;
end; end;
procedure TJDbGridDateCtrl.ShowCalendar(Sender: TObject);
var
PopupOrigin: TPoint;
ADate: TDateTime;
begin
if (not Assigned(Field)) then
exit;
PopupOrigin := CellEditor.ControlToScreen(Point(0, CellEditor.Height));
if Field.IsNull then
ADate := now
else
ADate := Field.AsDateTime;
ShowCalendarPopup(PopupOrigin, ADate, [dsShowHeadings, dsShowDayNames],
@CalendarPopupReturnDate, nil);
end;
procedure TJDbGridDateCtrl.CalendarPopupReturnDate(Sender: TObject;
const ADate: TDateTime);
var
bufdate: TDateTime;
begin
if not (Field.DataSet.State in [dsEdit, dsInsert]) then
Field.DataSet.Edit;
if Field.IsNull then
bufdate := now
else
bufdate := Field.AsDateTime;
Field.AsDateTime :=
EncodeDateTime(YearOf(ADate), MonthOf(ADate), DayOf(ADate),
HourOf(bufdate), MinuteOf(bufdate), SecondOf(bufdate), MilliSecondOf(bufdate));
CellEditor.Text := Field.AsString;
end;
function TJDbGridDateCtrl.isNull: boolean; function TJDbGridDateCtrl.isNull: boolean;
begin begin

View File

@ -23,7 +23,7 @@ interface
uses uses
Classes, LResources, Controls, ExtCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs, Classes, LResources, Controls, ExtCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs,
SysUtils, jinputconsts; SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons;
type type
@ -34,6 +34,13 @@ type
fFormat: string; fFormat: string;
FDataLink: TFieldDataLink; FDataLink: TFieldDataLink;
FButton: TSpeedButton;
FButtonNeedsFocus: boolean;
function GetButtonWidth: integer;
procedure SetButtonWidth(AValue: integer);
procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS;
procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
procedure DataChange(Sender: TObject); procedure DataChange(Sender: TObject);
procedure UpdateData(Sender: TObject); procedure UpdateData(Sender: TObject);
procedure FocusRequest(Sender: TObject); procedure FocusRequest(Sender: TObject);
@ -64,6 +71,15 @@ type
function GetReadOnly: boolean; override; function GetReadOnly: boolean; override;
procedure SetReadOnly(Value: boolean); override; procedure SetReadOnly(Value: boolean); override;
procedure SetParent(AParent: TWinControl); override;
procedure DoPositionButton; virtual;
procedure CheckButtonVisible;
procedure CMVisibleChanged(var Msg: TLMessage); message CM_VISIBLECHANGED;
procedure CMEnabledChanged(var Msg: TLMessage); message CM_ENABLEDCHANGED;
procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public public
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -76,6 +92,9 @@ type
property DataSource: TDataSource read GetDataSource write SetDataSource; property DataSource: TDataSource read GetDataSource write SetDataSource;
property ReadOnly: boolean read GetReadOnly write SetReadOnly default False; property ReadOnly: boolean read GetReadOnly write SetReadOnly default False;
property Button: TSpeedButton read FButton;
property ButtonWidth: integer read GetButtonWidth write SetButtonWidth;
property Action; property Action;
property Align; property Align;
property Alignment; property Alignment;
@ -128,7 +147,7 @@ procedure Register;
implementation implementation
uses uses
jcontrolutils; jcontrolutils, dateutils;
procedure Register; procedure Register;
begin begin
@ -138,6 +157,28 @@ end;
{ TJDBLabeledDateEdit } { TJDBLabeledDateEdit }
function TJDBLabeledDateEdit.GetButtonWidth: integer;
begin
Result := FButton.Width;
end;
procedure TJDBLabeledDateEdit.SetButtonWidth(AValue: integer);
begin
FButton.Width := AValue;
end;
procedure TJDBLabeledDateEdit.WMSetFocus(var Message: TLMSetFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJDBLabeledDateEdit.WMKillFocus(var Message: TLMKillFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJDBLabeledDateEdit.DataChange(Sender: TObject); procedure TJDBLabeledDateEdit.DataChange(Sender: TObject);
begin begin
if FDataLink.Field <> nil then if FDataLink.Field <> nil then
@ -240,6 +281,85 @@ begin
FDataLink.ReadOnly := Value; FDataLink.ReadOnly := Value;
end; end;
procedure TJDBLabeledDateEdit.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if FButton <> nil then
begin
DoPositionButton;
CheckButtonVisible;
end;
end;
procedure TJDBLabeledDateEdit.DoPositionButton;
begin
if FButton = nil then
exit;
FButton.Parent := Parent;
FButton.Visible := True;
if BiDiMode = bdLeftToRight then
FButton.AnchorToCompanion(akLeft, 0, Self)
else
FButton.AnchorToCompanion(akRight, 0, Self);
end;
procedure TJDBLabeledDateEdit.CheckButtonVisible;
begin
if Assigned(FButton) then
FButton.Visible := True;
end;
procedure TJDBLabeledDateEdit.CMVisibleChanged(var Msg: TLMessage);
begin
inherited CMVisibleChanged(Msg);
CheckButtonVisible;
end;
procedure TJDBLabeledDateEdit.CMEnabledChanged(var Msg: TLMessage);
begin
inherited CMEnabledChanged(Msg);
if (FButton <> nil) then
FButton.Enabled := True;
end;
procedure TJDBLabeledDateEdit.CMBiDiModeChanged(var Message: TLMessage);
begin
inherited;
DoPositionButton;
end;
procedure TJDBLabeledDateEdit.ShowCalendar(Sender: TObject);
var
PopupOrigin: TPoint;
ADate: TDateTime;
begin
if (not Assigned(FDataLink.Field)) or IsReadOnly then
exit;
PopupOrigin := Self.ControlToScreen(Point(0, Self.Height));
if FDataLink.Field.IsNull then
ADate := now
else
ADate := FDataLink.Field.AsDateTime;
ShowCalendarPopup(PopupOrigin, ADate, [dsShowHeadings, dsShowDayNames],
@CalendarPopupReturnDate, nil);
end;
procedure TJDBLabeledDateEdit.CalendarPopupReturnDate(Sender: TObject;
const ADate: TDateTime);
var
bufdate: TDateTime;
begin
if not (DataSource.State in [dsEdit, dsInsert]) then
DataSource.Edit;
if FDataLink.Field.IsNull then
bufdate := now
else
bufdate := FDataLink.Field.AsDateTime;
FDataLink.Field.AsDateTime :=
EncodeDateTime(YearOf(ADate), MonthOf(ADate), DayOf(ADate),
HourOf(bufdate), MinuteOf(bufdate), SecondOf(bufdate), MilliSecondOf(bufdate));
end;
procedure TJDBLabeledDateEdit.SetDataField(const Value: string); procedure TJDBLabeledDateEdit.SetDataField(const Value: string);
begin begin
FDataLink.FieldName := Value; FDataLink.FieldName := Value;
@ -267,6 +387,8 @@ end;
procedure TJDBLabeledDateEdit.Loaded; procedure TJDBLabeledDateEdit.Loaded;
begin begin
inherited Loaded; inherited Loaded;
DoPositionButton;
CheckButtonVisible;
if (csDesigning in ComponentState) then if (csDesigning in ComponentState) then
DataChange(Self); DataChange(Self);
end; end;
@ -275,6 +397,8 @@ procedure TJDBLabeledDateEdit.Notification(AComponent: TComponent;
Operation: TOperation); Operation: TOperation);
begin begin
inherited Notification(AComponent, Operation); inherited Notification(AComponent, Operation);
if (AComponent = FButton) and (Operation = opRemove) then
FButton := nil;
// clean up // clean up
if (Operation = opRemove) then if (Operation = opRemove) then
begin begin
@ -294,6 +418,8 @@ end;
procedure TJDBLabeledDateEdit.KeyDown(var Key: word; Shift: TShiftState); procedure TJDBLabeledDateEdit.KeyDown(var Key: word; Shift: TShiftState);
begin begin
inherited KeyDown(Key, Shift); inherited KeyDown(Key, Shift);
if (ssAlt in Shift) and (key = 40) then
ShowCalendar(Self);
if Key = VK_ESCAPE then if Key = VK_ESCAPE then
begin begin
FDataLink.Reset; FDataLink.Reset;
@ -312,6 +438,8 @@ end;
procedure TJDBLabeledDateEdit.KeyPress(var Key: char); procedure TJDBLabeledDateEdit.KeyPress(var Key: char);
begin begin
if (not Assigned(FDataLink.Field)) or IsReadOnly then
key := #0;
if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then
Key := #0 Key := #0
else else
@ -336,20 +464,32 @@ begin
FDataLink.OnDataChange := @DataChange; FDataLink.OnDataChange := @DataChange;
FDataLink.OnUpdateData := @UpdateData; FDataLink.OnUpdateData := @UpdateData;
FDataLInk.OnActiveChange := @ActiveChange; FDataLInk.OnActiveChange := @ActiveChange;
// Set default values
//fFormat := ShortDateFormat; FButton := TSpeedButton.Create(self);
FButton.Height := Self.Height;
FButton.FreeNotification(Self);
CheckButtonVisible;
FButton.Cursor := crArrow;
FButton.Flat := False;
FButton.OnClick := @ShowCalendar;
FButton.ControlStyle := FButton.ControlStyle + [csNoDesignSelectable];
FButton.LoadGlyphFromLazarusResource('JCalendarIcon');
ControlStyle := ControlStyle - [csSetCaption];
end; end;
destructor TJDBLabeledDateEdit.Destroy; destructor TJDBLabeledDateEdit.Destroy;
begin begin
FDataLink.Free; FreeAndNil(FDataLink);
FDataLink := nil; FreeAndNil(FButton);
inherited Destroy; inherited Destroy;
end; end;
procedure TJDBLabeledDateEdit.EditingDone; procedure TJDBLabeledDateEdit.EditingDone;
begin begin
inherited EditingDone; inherited EditingDone;
if (not Assigned(FDataLink.Field)) or IsReadOnly then
exit;
if DataSource.State in [dsEdit, dsInsert] then if DataSource.State in [dsEdit, dsInsert] then
UpdateData(self) UpdateData(self)
else else
@ -357,4 +497,3 @@ begin
end; end;
end. end.

View File

@ -23,7 +23,7 @@ interface
uses uses
Classes, LResources, Controls, ExtCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs, Classes, LResources, Controls, ExtCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs,
SysUtils, jinputconsts; SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons;
type type
@ -34,6 +34,14 @@ type
fFormat: string; fFormat: string;
FDataLink: TFieldDataLink; FDataLink: TFieldDataLink;
FButton: TSpeedButton;
FButtonNeedsFocus: boolean;
function GetButtonWidth: integer;
procedure SetButtonWidth(AValue: integer);
procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS;
procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
procedure DataChange(Sender: TObject); procedure DataChange(Sender: TObject);
procedure UpdateData(Sender: TObject); procedure UpdateData(Sender: TObject);
procedure FocusRequest(Sender: TObject); procedure FocusRequest(Sender: TObject);
@ -44,6 +52,7 @@ type
function IsReadOnly: boolean; function IsReadOnly: boolean;
function EditText: string;
function getFormat: string; function getFormat: string;
procedure setFormat(const AValue: string); procedure setFormat(const AValue: string);
procedure formatInput; procedure formatInput;
@ -62,6 +71,15 @@ type
function GetReadOnly: boolean; override; function GetReadOnly: boolean; override;
procedure SetReadOnly(Value: boolean); override; procedure SetReadOnly(Value: boolean); override;
procedure SetParent(AParent: TWinControl); override;
procedure DoPositionButton; virtual;
procedure CheckButtonVisible;
procedure CMVisibleChanged(var Msg: TLMessage); message CM_VISIBLECHANGED;
procedure CMEnabledChanged(var Msg: TLMessage); message CM_ENABLEDCHANGED;
procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public public
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -74,6 +92,9 @@ type
property DataSource: TDataSource read GetDataSource write SetDataSource; property DataSource: TDataSource read GetDataSource write SetDataSource;
property ReadOnly: boolean read GetReadOnly write SetReadOnly default False; property ReadOnly: boolean read GetReadOnly write SetReadOnly default False;
property Button: TSpeedButton read FButton;
property ButtonWidth: integer read GetButtonWidth write SetButtonWidth;
// From TEdit // From TEdit
property Action; property Action;
property Align; property Align;
@ -133,7 +154,7 @@ procedure Register;
implementation implementation
uses uses
jcontrolutils; jcontrolutils, dateutils;
procedure Register; procedure Register;
begin begin
@ -141,6 +162,28 @@ begin
RegisterComponents('Data Controls', [TJDBLabeledDateTimeEdit]); RegisterComponents('Data Controls', [TJDBLabeledDateTimeEdit]);
end; end;
function TJDBLabeledDateTimeEdit.GetButtonWidth: integer;
begin
Result := FButton.Width;
end;
procedure TJDBLabeledDateTimeEdit.SetButtonWidth(AValue: integer);
begin
FButton.Width := AValue;
end;
procedure TJDBLabeledDateTimeEdit.WMSetFocus(var Message: TLMSetFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJDBLabeledDateTimeEdit.WMKillFocus(var Message: TLMKillFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJDBLabeledDateTimeEdit.DataChange(Sender: TObject); procedure TJDBLabeledDateTimeEdit.DataChange(Sender: TObject);
begin begin
if FDataLink.Field <> nil then if FDataLink.Field <> nil then
@ -148,7 +191,7 @@ begin
if not Focused then if not Focused then
formatInput formatInput
else else
Caption := FDataLink.Field.AsString; Caption := EditText;
end end
else else
Text := ''; Text := '';
@ -171,7 +214,7 @@ begin
else else
begin begin
ShowMessage(Format(SInvalidDateTime, [Caption])); ShowMessage(Format(SInvalidDateTime, [Caption]));
Caption := FDataLink.Field.AsString; Caption := EditText;
SelectAll; SelectAll;
SetFocus; SetFocus;
end; end;
@ -208,6 +251,15 @@ begin
Result := False; Result := False;
end; end;
function TJDBLabeledDateTimeEdit.EditText: string;
begin
if Field.IsNull then
Result := ''
else
Result := FormatDateTime(ShortDateFormat, FDataLink.Field.AsDateTime) +
' ' + FormatDateTime(ShortTimeFormat, FDataLink.Field.AsDateTime);
end;
function TJDBLabeledDateTimeEdit.getFormat: string; function TJDBLabeledDateTimeEdit.getFormat: string;
begin begin
Result := fFormat; Result := fFormat;
@ -226,7 +278,7 @@ begin
if (fFormat <> '') and (not FDataLink.Field.IsNull) then if (fFormat <> '') and (not FDataLink.Field.IsNull) then
Caption := FormatDateTime(fFormat, FDataLink.Field.AsDateTime) Caption := FormatDateTime(fFormat, FDataLink.Field.AsDateTime)
else else
Caption := FDataLink.Field.DisplayText Caption := EditText
else else
Caption := 'nil'; Caption := 'nil';
end; end;
@ -242,6 +294,85 @@ begin
FDataLink.ReadOnly := Value; FDataLink.ReadOnly := Value;
end; end;
procedure TJDBLabeledDateTimeEdit.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if FButton <> nil then
begin
DoPositionButton;
CheckButtonVisible;
end;
end;
procedure TJDBLabeledDateTimeEdit.DoPositionButton;
begin
if FButton = nil then
exit;
FButton.Parent := Parent;
FButton.Visible := True;
if BiDiMode = bdLeftToRight then
FButton.AnchorToCompanion(akLeft, 0, Self)
else
FButton.AnchorToCompanion(akRight, 0, Self);
end;
procedure TJDBLabeledDateTimeEdit.CheckButtonVisible;
begin
if Assigned(FButton) then
FButton.Visible := True;
end;
procedure TJDBLabeledDateTimeEdit.CMVisibleChanged(var Msg: TLMessage);
begin
inherited CMVisibleChanged(Msg);
CheckButtonVisible;
end;
procedure TJDBLabeledDateTimeEdit.CMEnabledChanged(var Msg: TLMessage);
begin
inherited CMEnabledChanged(Msg);
if (FButton <> nil) then
FButton.Enabled := True;
end;
procedure TJDBLabeledDateTimeEdit.CMBiDiModeChanged(var Message: TLMessage);
begin
inherited;
DoPositionButton;
end;
procedure TJDBLabeledDateTimeEdit.ShowCalendar(Sender: TObject);
var
PopupOrigin: TPoint;
ADate: TDateTime;
begin
if (not Assigned(FDataLink.Field)) or IsReadOnly then
exit;
PopupOrigin := Self.ControlToScreen(Point(0, Self.Height));
if FDataLink.Field.IsNull then
ADate := now
else
ADate := FDataLink.Field.AsDateTime;
ShowCalendarPopup(PopupOrigin, ADate, [dsShowHeadings, dsShowDayNames],
@CalendarPopupReturnDate, nil);
end;
procedure TJDBLabeledDateTimeEdit.CalendarPopupReturnDate(Sender: TObject;
const ADate: TDateTime);
var
bufdate: TDateTime;
begin
if not (DataSource.State in [dsEdit, dsInsert]) then
DataSource.Edit;
if FDataLink.Field.IsNull then
bufdate := now
else
bufdate := FDataLink.Field.AsDateTime;
FDataLink.Field.AsDateTime :=
EncodeDateTime(YearOf(ADate), MonthOf(ADate), DayOf(ADate),
HourOf(bufdate), MinuteOf(bufdate), SecondOf(bufdate), MilliSecondOf(bufdate));
end;
procedure TJDBLabeledDateTimeEdit.SetDataField(const Value: string); procedure TJDBLabeledDateTimeEdit.SetDataField(const Value: string);
begin begin
FDataLink.FieldName := Value; FDataLink.FieldName := Value;
@ -261,6 +392,8 @@ end;
procedure TJDBLabeledDateTimeEdit.Loaded; procedure TJDBLabeledDateTimeEdit.Loaded;
begin begin
inherited Loaded; inherited Loaded;
DoPositionButton;
CheckButtonVisible;
if (csDesigning in ComponentState) then if (csDesigning in ComponentState) then
DataChange(Self); DataChange(Self);
end; end;
@ -269,6 +402,8 @@ procedure TJDBLabeledDateTimeEdit.Notification(AComponent: TComponent;
Operation: TOperation); Operation: TOperation);
begin begin
inherited Notification(AComponent, Operation); inherited Notification(AComponent, Operation);
if (AComponent = FButton) and (Operation = opRemove) then
FButton := nil;
// clean up // clean up
if (Operation = opRemove) then if (Operation = opRemove) then
begin begin
@ -288,6 +423,8 @@ end;
procedure TJDBLabeledDateTimeEdit.KeyDown(var Key: word; Shift: TShiftState); procedure TJDBLabeledDateTimeEdit.KeyDown(var Key: word; Shift: TShiftState);
begin begin
inherited KeyDown(Key, Shift); inherited KeyDown(Key, Shift);
if (ssAlt in Shift) and (key = 40) then
ShowCalendar(Self);
if Key = VK_ESCAPE then if Key = VK_ESCAPE then
begin begin
FDataLink.Reset; FDataLink.Reset;
@ -306,6 +443,8 @@ end;
procedure TJDBLabeledDateTimeEdit.KeyPress(var Key: char); procedure TJDBLabeledDateTimeEdit.KeyPress(var Key: char);
begin begin
if (not Assigned(FDataLink.Field)) or IsReadOnly then
key := #0;
if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then
Key := #0 Key := #0
else else
@ -317,7 +456,7 @@ end;
procedure TJDBLabeledDateTimeEdit.DoEnter; procedure TJDBLabeledDateTimeEdit.DoEnter;
begin begin
if FDataLink.Field <> nil then if FDataLink.Field <> nil then
Caption := FDataLink.Field.AsString; Caption := EditText;
inherited DoEnter; inherited DoEnter;
end; end;
@ -330,20 +469,32 @@ begin
FDataLink.OnDataChange := @DataChange; FDataLink.OnDataChange := @DataChange;
FDataLink.OnUpdateData := @UpdateData; FDataLink.OnUpdateData := @UpdateData;
FDataLInk.OnActiveChange := @ActiveChange; FDataLInk.OnActiveChange := @ActiveChange;
// Set default values
//fFormat := ShortDateFormat; FButton := TSpeedButton.Create(self);
FButton.Height := Self.Height;
FButton.FreeNotification(Self);
CheckButtonVisible;
FButton.Cursor := crArrow;
FButton.Flat := False;
FButton.OnClick := @ShowCalendar;
FButton.ControlStyle := FButton.ControlStyle + [csNoDesignSelectable];
FButton.LoadGlyphFromLazarusResource('JCalendarIcon');
ControlStyle := ControlStyle - [csSetCaption];
end; end;
destructor TJDBLabeledDateTimeEdit.Destroy; destructor TJDBLabeledDateTimeEdit.Destroy;
begin begin
FDataLink.Free; FreeAndNil(FDataLink);
FDataLink := nil; FreeAndNil(FButton);
inherited Destroy; inherited Destroy;
end; end;
procedure TJDBLabeledDateTimeEdit.EditingDone; procedure TJDBLabeledDateTimeEdit.EditingDone;
begin begin
inherited EditingDone; inherited EditingDone;
if (not Assigned(FDataLink.Field)) or IsReadOnly then
exit;
if DataSource.State in [dsEdit, dsInsert] then if DataSource.State in [dsEdit, dsInsert] then
UpdateData(self) UpdateData(self)
else else
@ -352,4 +503,3 @@ end;
end. end.

View File

@ -22,7 +22,8 @@ interface
uses uses
Classes, SysUtils, LResources, Forms, Controls, ExtCtrls, Graphics, Classes, SysUtils, LResources, Forms, Controls, ExtCtrls, Graphics,
Dialogs, jcontrolutils, jinputconsts; Dialogs, Buttons, LMessages, jcontrolutils, jinputconsts, CalendarPopup,
Calendar;
type type
@ -32,16 +33,33 @@ type
private private
theValue: TDateTime; theValue: TDateTime;
fFormat: string; fFormat: string;
FButton: TSpeedButton;
FButtonNeedsFocus: Boolean;
function GetButtonWidth: Integer;
function getFormat: string; function getFormat: string;
function getValue: TDateTime; function getValue: TDateTime;
procedure formatInput; procedure formatInput;
procedure SetButtonWidth(AValue: Integer);
procedure setFormat(const AValue: string); procedure setFormat(const AValue: string);
procedure setValue(const AValue: TDateTime); procedure setValue(const AValue: TDateTime);
procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS;
procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
protected protected
{ Protected declarations } { Protected declarations }
procedure DoEnter; override; procedure DoEnter; override;
procedure DoExit; override; procedure DoExit; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: char); override; procedure KeyPress(var Key: char); override;
procedure SetParent(AParent: TWinControl); override;
procedure DoPositionButton; virtual;
procedure CheckButtonVisible;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure CMVisibleChanged(var Msg: TLMessage); message CM_VISIBLECHANGED;
procedure CMEnabledChanged(var Msg: TLMessage); message CM_ENABLEDCHANGED;
procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
procedure Loaded; override;
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public public
{ Public declarations } { Public declarations }
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
@ -51,6 +69,8 @@ type
function isNull: boolean; function isNull: boolean;
property DisplayFormat: string read getFormat write setFormat; property DisplayFormat: string read getFormat write setFormat;
property Value: TDateTime read getValue write setValue; property Value: TDateTime read getValue write setValue;
property Button: TSpeedButton read FButton;
property ButtonWidth : Integer read GetButtonWidth write SetButtonWidth;
property Action; property Action;
property Align; property Align;
@ -117,6 +137,11 @@ begin
Result := fFormat; Result := fFormat;
end; end;
function TJLabeledDateEdit.GetButtonWidth: Integer;
begin
Result:= FButton.Width;
end;
function TJLabeledDateEdit.getValue: TDateTime; function TJLabeledDateEdit.getValue: TDateTime;
begin begin
Result := theValue; Result := theValue;
@ -128,6 +153,11 @@ begin
Text := FormatDateTime(DisplayFormat, theValue); Text := FormatDateTime(DisplayFormat, theValue);
end; end;
procedure TJLabeledDateEdit.SetButtonWidth(AValue: Integer);
begin
FButton.Width:=AValue;
end;
procedure TJLabeledDateEdit.setFormat(const AValue: string); procedure TJLabeledDateEdit.setFormat(const AValue: string);
begin begin
fFormat := AValue; fFormat := AValue;
@ -140,6 +170,18 @@ begin
formatInput; formatInput;
end; end;
procedure TJLabeledDateEdit.WMSetFocus(var Message: TLMSetFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateEdit.WMKillFocus(var Message: TLMKillFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateEdit.DoEnter; procedure TJLabeledDateEdit.DoEnter;
begin begin
inherited DoEnter; inherited DoEnter;
@ -167,6 +209,13 @@ begin
formatInput; formatInput;
end; end;
procedure TJLabeledDateEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (ssAlt in Shift) and (key = 40) then
ShowCalendar(Self);
end;
procedure TJLabeledDateEdit.KeyPress(var Key: char); procedure TJLabeledDateEdit.KeyPress(var Key: char);
begin begin
if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then
@ -174,17 +223,110 @@ begin
inherited KeyPress(Key); inherited KeyPress(Key);
end; end;
procedure TJLabeledDateEdit.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if FButton <> nil then
begin
DoPositionButton;
CheckButtonVisible;
end;
end;
procedure TJLabeledDateEdit.DoPositionButton;
begin
if FButton = nil then exit;
FButton.Parent := Parent;
FButton.Visible:= True;
if BiDiMode = bdLeftToRight then
FButton.AnchorToCompanion(akLeft,0,Self)
else
FButton.AnchorToCompanion(akRight,0,Self);
end;
procedure TJLabeledDateEdit.CheckButtonVisible;
begin
If Assigned(FButton) then
FButton.Visible:=True;
end;
procedure TJLabeledDateEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = FButton) and (Operation = opRemove) then
FButton := nil;
end;
procedure TJLabeledDateEdit.CMVisibleChanged(var Msg: TLMessage);
begin
inherited CMVisibleChanged(Msg);
CheckButtonVisible;
end;
procedure TJLabeledDateEdit.CMEnabledChanged(var Msg: TLMessage);
begin
inherited CMEnabledChanged(Msg);
if (FButton<>nil) then
FButton.Enabled:=True;
end;
procedure TJLabeledDateEdit.CMBiDiModeChanged(var Message: TLMessage);
begin
inherited;
DoPositionButton;
end;
procedure TJLabeledDateEdit.Loaded;
begin
inherited Loaded;
DoPositionButton;
CheckButtonVisible;
end;
procedure TJLabeledDateEdit.ShowCalendar(Sender: TObject);
var
PopupOrigin: TPoint;
ADate: TDateTime;
begin
PopupOrigin := Self.ControlToScreen(Point(0, Self.Height));
if isNull then
ADate := now
else
ADate:= Value;
ShowCalendarPopup(PopupOrigin, ADate, [dsShowHeadings, dsShowDayNames],
@CalendarPopupReturnDate, nil);
end;
procedure TJLabeledDateEdit.CalendarPopupReturnDate(Sender: TObject;
const ADate: TDateTime);
begin
Value:= ADate;
end;
constructor TJLabeledDateEdit.Create(TheOwner: TComponent); constructor TJLabeledDateEdit.Create(TheOwner: TComponent);
begin begin
inherited Create(TheOwner); inherited Create(TheOwner);
Text := ''; Text := '';
fFormat := ShortDateFormat; fFormat := ShortDateFormat;
theValue := 0; theValue := 0;
FButton := TSpeedButton.Create(self);
FButton.Height := Self.Height;
FButton.FreeNotification(Self);
CheckButtonVisible;
FButton.Cursor := crArrow;
FButton.Flat:= False;
FButton.OnClick := @ShowCalendar;
FButton.ControlStyle := FButton.ControlStyle + [csNoDesignSelectable];
FButton.LoadGlyphFromLazarusResource('JCalendarIcon');
ControlStyle := ControlStyle - [csSetCaption];
formatInput; formatInput;
end; end;
destructor TJLabeledDateEdit.Destroy; destructor TJLabeledDateEdit.Destroy;
begin begin
FreeAndNil(FButton);
inherited Destroy; inherited Destroy;
end; end;

View File

@ -25,24 +25,45 @@ interface
uses uses
Classes, LResources, Controls, ExtCtrls, LCLType, Dialogs, Classes, LResources, Controls, ExtCtrls, LCLType, Dialogs,
SysUtils, jinputconsts; SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons, LMessages;
type type
{ TJLabeledDateTimeEdit }
TJLabeledDateTimeEdit = class(TCustomLabeledEdit) TJLabeledDateTimeEdit = class(TCustomLabeledEdit)
private private
{ Private declarations } { Private declarations }
theValue: TDateTime; theValue: TDateTime;
fFormat: string; fFormat: string;
FButton: TSpeedButton;
FButtonNeedsFocus: boolean;
function GetButtonWidth: integer;
function getFormat: string; function getFormat: string;
function getValue: TDateTime; function getValue: TDateTime;
procedure formatInput; procedure formatInput;
procedure SetButtonWidth(AValue: integer);
procedure setFormat(const AValue: string); procedure setFormat(const AValue: string);
procedure setValue(const AValue: TDateTime); procedure setValue(const AValue: TDateTime);
procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS;
procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
protected protected
{ Protected declarations } { Protected declarations }
procedure DoEnter; override; procedure DoEnter; override;
procedure DoExit; override; procedure DoExit; override;
procedure KeyDown(var Key: word; Shift: TShiftState); override;
procedure KeyPress(var Key: char); override; procedure KeyPress(var Key: char); override;
procedure SetParent(AParent: TWinControl); override;
procedure DoPositionButton; virtual;
procedure CheckButtonVisible;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure CMVisibleChanged(var Msg: TLMessage); message CM_VISIBLECHANGED;
procedure CMEnabledChanged(var Msg: TLMessage); message CM_ENABLEDCHANGED;
procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
procedure Loaded; override;
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public public
{ Public declarations } { Public declarations }
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
@ -52,6 +73,8 @@ type
function isNull: boolean; function isNull: boolean;
property DisplayFormat: string read getFormat write setFormat; property DisplayFormat: string read getFormat write setFormat;
property Value: TDateTime read getValue write setValue; property Value: TDateTime read getValue write setValue;
property Button: TSpeedButton read FButton;
property ButtonWidth: integer read GetButtonWidth write SetButtonWidth;
property Action; property Action;
property Align; property Align;
@ -106,7 +129,7 @@ procedure Register;
implementation implementation
uses uses
jcontrolutils; jcontrolutils, dateutils;
procedure Register; procedure Register;
begin begin
@ -114,6 +137,11 @@ begin
RegisterComponents('Additional', [TJLabeledDateTimeEdit]); RegisterComponents('Additional', [TJLabeledDateTimeEdit]);
end; end;
function TJLabeledDateTimeEdit.GetButtonWidth: integer;
begin
Result := FButton.Width;
end;
function TJLabeledDateTimeEdit.getFormat: string; function TJLabeledDateTimeEdit.getFormat: string;
begin begin
Result := fFormat; Result := fFormat;
@ -130,6 +158,11 @@ begin
Text := FormatDateTime(DisplayFormat, theValue); Text := FormatDateTime(DisplayFormat, theValue);
end; end;
procedure TJLabeledDateTimeEdit.SetButtonWidth(AValue: integer);
begin
FButton.Width := AValue;
end;
procedure TJLabeledDateTimeEdit.setFormat(const AValue: string); procedure TJLabeledDateTimeEdit.setFormat(const AValue: string);
begin begin
fFormat := AValue; fFormat := AValue;
@ -142,6 +175,18 @@ begin
formatInput; formatInput;
end; end;
procedure TJLabeledDateTimeEdit.WMSetFocus(var Message: TLMSetFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateTimeEdit.WMKillFocus(var Message: TLMKillFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateTimeEdit.DoEnter; procedure TJLabeledDateTimeEdit.DoEnter;
begin begin
inherited DoEnter; inherited DoEnter;
@ -178,6 +223,13 @@ begin
formatInput; formatInput;
end; end;
procedure TJLabeledDateTimeEdit.KeyDown(var Key: word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (ssAlt in Shift) and (key = 40) then
ShowCalendar(Self);
end;
procedure TJLabeledDateTimeEdit.KeyPress(var Key: char); procedure TJLabeledDateTimeEdit.KeyPress(var Key: char);
begin begin
if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then
@ -185,6 +237,95 @@ begin
inherited KeyPress(Key); inherited KeyPress(Key);
end; end;
procedure TJLabeledDateTimeEdit.SetParent(AParent: TWinControl);
begin
inherited SetParent(AParent);
if FButton <> nil then
begin
DoPositionButton;
CheckButtonVisible;
end;
end;
procedure TJLabeledDateTimeEdit.DoPositionButton;
begin
if FButton = nil then
exit;
FButton.Parent := Parent;
FButton.Visible := True;
if BiDiMode = bdLeftToRight then
FButton.AnchorToCompanion(akLeft, 0, Self)
else
FButton.AnchorToCompanion(akRight, 0, Self);
end;
procedure TJLabeledDateTimeEdit.CheckButtonVisible;
begin
if Assigned(FButton) then
FButton.Visible := True;
end;
procedure TJLabeledDateTimeEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = FButton) and (Operation = opRemove) then
FButton := nil;
end;
procedure TJLabeledDateTimeEdit.CMVisibleChanged(var Msg: TLMessage);
begin
inherited CMVisibleChanged(Msg);
CheckButtonVisible;
end;
procedure TJLabeledDateTimeEdit.CMEnabledChanged(var Msg: TLMessage);
begin
inherited CMEnabledChanged(Msg);
if (FButton <> nil) then
FButton.Enabled := True;
end;
procedure TJLabeledDateTimeEdit.CMBiDiModeChanged(var Message: TLMessage);
begin
inherited;
DoPositionButton;
end;
procedure TJLabeledDateTimeEdit.Loaded;
begin
inherited Loaded;
DoPositionButton;
CheckButtonVisible;
end;
procedure TJLabeledDateTimeEdit.ShowCalendar(Sender: TObject);
var
PopupOrigin: TPoint;
ADate: TDateTime;
begin
PopupOrigin := Self.ControlToScreen(Point(0, Self.Height));
if isNull then
ADate := Now
else
ADate := Value;
ShowCalendarPopup(PopupOrigin, ADate, [dsShowHeadings, dsShowDayNames],
@CalendarPopupReturnDate, nil);
end;
procedure TJLabeledDateTimeEdit.CalendarPopupReturnDate(Sender: TObject;
const ADate: TDateTime);
var
bufdate: TDateTime;
begin
if isNull then
bufdate := now
else
bufdate := Value;
Value := EncodeDateTime(YearOf(ADate), MonthOf(ADate), DayOf(ADate),
HourOf(bufdate), MinuteOf(bufdate), SecondOf(bufdate), MilliSecondOf(bufdate));
end;
constructor TJLabeledDateTimeEdit.Create(TheOwner: TComponent); constructor TJLabeledDateTimeEdit.Create(TheOwner: TComponent);
begin begin
inherited Create(TheOwner); inherited Create(TheOwner);
@ -192,10 +333,22 @@ begin
fFormat := ShortDateFormat + ' ' + ShortTimeFormat; fFormat := ShortDateFormat + ' ' + ShortTimeFormat;
theValue := 0; theValue := 0;
formatInput; formatInput;
FButton := TSpeedButton.Create(self);
FButton.Height := Self.Height;
FButton.FreeNotification(Self);
CheckButtonVisible;
FButton.Cursor := crArrow;
FButton.Flat := False;
FButton.OnClick := @ShowCalendar;
FButton.ControlStyle := FButton.ControlStyle + [csNoDesignSelectable];
FButton.LoadGlyphFromLazarusResource('JCalendarIcon');
ControlStyle := ControlStyle - [csSetCaption];
end; end;
destructor TJLabeledDateTimeEdit.Destroy; destructor TJLabeledDateTimeEdit.Destroy;
begin begin
FreeAndNil(FButton);
inherited Destroy; inherited Destroy;
end; end;
@ -206,4 +359,3 @@ end;
end. end.