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
--------------------------------------------------
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-04-29 Fixed: TJDBGridControl Focus issues
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>
<Package Version="4">
<Name Value="jujiboutils"/>
@ -23,38 +23,38 @@ db and non db controls."/>
<Version Major="1"/>
<Files Count="19">
<Item1>
<Filename Value="src/jcontrolutils.pas"/>
<UnitName Value="jcontrolutils"/>
</Item1>
<Item2>
<Filename Value="src/jdbgridcontrol.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="JDBGridControl"/>
</Item1>
<Item2>
</Item2>
<Item3>
<Filename Value="src/jdblabelededit.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="JDBLabeledEdit"/>
</Item2>
<Item3>
</Item3>
<Item4>
<Filename Value="src/jdblabeledintegeredit.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="jdblabeledintegeredit"/>
</Item3>
<Item4>
</Item4>
<Item5>
<Filename Value="src/jdblabeledfloatedit.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="JDBLabeledFloatEdit"/>
</Item4>
<Item5>
</Item5>
<Item6>
<Filename Value="src/jdblabeledcurrencyedit.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="jdblabeledcurrencyedit"/>
</Item5>
<Item6>
</Item6>
<Item7>
<Filename Value="src/jdblabeleddateedit.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="jdblabeleddateedit"/>
</Item6>
<Item7>
<Filename Value="src/jcontrolutils.pas"/>
<UnitName Value="jcontrolutils"/>
</Item7>
<Item8>
<Filename Value="src/jlabeledintegeredit.pas"/>

View File

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

View File

@ -22,7 +22,7 @@ unit jcontrolutils;
interface
uses
Classes, SysUtils, Dialogs;
Classes, SysUtils, Dialogs, LResources;
function CountChar(const s: string; ch: char): integer;
procedure Split(const Delimiter: char; Input: string; Strings: TStrings);
@ -259,5 +259,31 @@ begin
Result := TryStrToDateTime(Value, bTime);
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.

View File

@ -23,7 +23,7 @@ interface
uses
Classes, SysUtils, Grids, Dialogs, LCLType, DBGrids, Controls, DB,
jcontrolutils, jinputconsts;
jcontrolutils, jinputconsts, CalendarPopup, Calendar, Buttons;
type
@ -58,12 +58,16 @@ type
theValue: TDateTime;
fFormat: string;
function getFormat: string;
function EditText: string;
procedure myEditEnter(Sender: TObject);
procedure myEditOnEditingDone(Sender: TObject);
procedure formatInput;
procedure setFormat(const AValue: string);
procedure OnKeyPress(Sender: TObject; var key: char);
procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
protected
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public
CellEditor: TStringCellEditor;
theGrid: TDBGrid;
@ -116,6 +120,9 @@ type
procedure setFormat(const AValue: string);
procedure OnKeyPress(Sender: TObject; var key: char);
procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
protected
procedure ShowCalendar(Sender: TObject);
procedure CalendarPopupReturnDate(Sender: TObject; const ADate: TDateTime);
public
CellEditor: TStringCellEditor;
theGrid: TDBGrid;
@ -178,7 +185,7 @@ type
implementation
uses
Math;
Math, dateutils;
{ TJDbGridStringCtrl }
@ -278,13 +285,22 @@ begin
Result := fFormat;
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);
begin
Field := theGrid.SelectedField;
if not Assigned(Field) then
abort;
CellEditor.BoundsRect := theGrid.SelectedFieldRect;
CellEditor.Text := Field.AsString;
CellEditor.Text := EditText;
CellEditor.OnKeyPress := @OnKeyPress; // Recuperamos el control :-p
CellEditor.OnKeyDown := @OnKeyDown;
theValue := Field.AsDateTime;
@ -361,6 +377,11 @@ end;
procedure TJDbGridDateTimeCtrl.OnKeyDown(Sender: TObject; var Key: word;
Shift: TShiftState);
begin
if (ssAlt in Shift) and (key = 40) then
begin
ShowCalendar(Self);
key := 0;
end;
if Length(CellEditor.Caption) = 0 then
begin
if Field.Value <> Null then
@ -417,6 +438,39 @@ begin
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;
begin
Result := theValue = 0;
@ -741,6 +795,11 @@ end;
procedure TJDbGridDateCtrl.OnKeyDown(Sender: TObject; var Key: word;
Shift: TShiftState);
begin
if (ssAlt in Shift) and (key = 40) then
begin
ShowCalendar(Self);
key := 0;
end;
if Length(CellEditor.Caption) = 0 then
begin
if Field.Value <> null then
@ -797,6 +856,39 @@ begin
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;
begin

View File

@ -23,7 +23,7 @@ interface
uses
Classes, LResources, Controls, ExtCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs,
SysUtils, jinputconsts;
SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons;
type
@ -34,6 +34,13 @@ type
fFormat: string;
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 UpdateData(Sender: TObject);
procedure FocusRequest(Sender: TObject);
@ -64,6 +71,15 @@ type
function GetReadOnly: 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
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
@ -76,6 +92,9 @@ type
property DataSource: TDataSource read GetDataSource write SetDataSource;
property ReadOnly: boolean read GetReadOnly write SetReadOnly default False;
property Button: TSpeedButton read FButton;
property ButtonWidth: integer read GetButtonWidth write SetButtonWidth;
property Action;
property Align;
property Alignment;
@ -128,7 +147,7 @@ procedure Register;
implementation
uses
jcontrolutils;
jcontrolutils, dateutils;
procedure Register;
begin
@ -138,6 +157,28 @@ end;
{ 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);
begin
if FDataLink.Field <> nil then
@ -240,6 +281,85 @@ begin
FDataLink.ReadOnly := Value;
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);
begin
FDataLink.FieldName := Value;
@ -267,6 +387,8 @@ end;
procedure TJDBLabeledDateEdit.Loaded;
begin
inherited Loaded;
DoPositionButton;
CheckButtonVisible;
if (csDesigning in ComponentState) then
DataChange(Self);
end;
@ -275,6 +397,8 @@ procedure TJDBLabeledDateEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = FButton) and (Operation = opRemove) then
FButton := nil;
// clean up
if (Operation = opRemove) then
begin
@ -294,6 +418,8 @@ end;
procedure TJDBLabeledDateEdit.KeyDown(var Key: word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (ssAlt in Shift) and (key = 40) then
ShowCalendar(Self);
if Key = VK_ESCAPE then
begin
FDataLink.Reset;
@ -312,6 +438,8 @@ end;
procedure TJDBLabeledDateEdit.KeyPress(var Key: char);
begin
if (not Assigned(FDataLink.Field)) or IsReadOnly then
key := #0;
if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then
Key := #0
else
@ -336,20 +464,32 @@ begin
FDataLink.OnDataChange := @DataChange;
FDataLink.OnUpdateData := @UpdateData;
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;
destructor TJDBLabeledDateEdit.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
FreeAndNil(FDataLink);
FreeAndNil(FButton);
inherited Destroy;
end;
procedure TJDBLabeledDateEdit.EditingDone;
begin
inherited EditingDone;
if (not Assigned(FDataLink.Field)) or IsReadOnly then
exit;
if DataSource.State in [dsEdit, dsInsert] then
UpdateData(self)
else
@ -357,4 +497,3 @@ begin
end;
end.

View File

@ -23,7 +23,7 @@ interface
uses
Classes, LResources, Controls, ExtCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs,
SysUtils, jinputconsts;
SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons;
type
@ -34,6 +34,14 @@ type
fFormat: string;
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 UpdateData(Sender: TObject);
procedure FocusRequest(Sender: TObject);
@ -44,6 +52,7 @@ type
function IsReadOnly: boolean;
function EditText: string;
function getFormat: string;
procedure setFormat(const AValue: string);
procedure formatInput;
@ -62,6 +71,15 @@ type
function GetReadOnly: 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
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
@ -74,6 +92,9 @@ type
property DataSource: TDataSource read GetDataSource write SetDataSource;
property ReadOnly: boolean read GetReadOnly write SetReadOnly default False;
property Button: TSpeedButton read FButton;
property ButtonWidth: integer read GetButtonWidth write SetButtonWidth;
// From TEdit
property Action;
property Align;
@ -133,7 +154,7 @@ procedure Register;
implementation
uses
jcontrolutils;
jcontrolutils, dateutils;
procedure Register;
begin
@ -141,6 +162,28 @@ begin
RegisterComponents('Data Controls', [TJDBLabeledDateTimeEdit]);
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);
begin
if FDataLink.Field <> nil then
@ -148,7 +191,7 @@ begin
if not Focused then
formatInput
else
Caption := FDataLink.Field.AsString;
Caption := EditText;
end
else
Text := '';
@ -171,7 +214,7 @@ begin
else
begin
ShowMessage(Format(SInvalidDateTime, [Caption]));
Caption := FDataLink.Field.AsString;
Caption := EditText;
SelectAll;
SetFocus;
end;
@ -208,6 +251,15 @@ begin
Result := False;
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;
begin
Result := fFormat;
@ -226,7 +278,7 @@ begin
if (fFormat <> '') and (not FDataLink.Field.IsNull) then
Caption := FormatDateTime(fFormat, FDataLink.Field.AsDateTime)
else
Caption := FDataLink.Field.DisplayText
Caption := EditText
else
Caption := 'nil';
end;
@ -242,6 +294,85 @@ begin
FDataLink.ReadOnly := Value;
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);
begin
FDataLink.FieldName := Value;
@ -261,6 +392,8 @@ end;
procedure TJDBLabeledDateTimeEdit.Loaded;
begin
inherited Loaded;
DoPositionButton;
CheckButtonVisible;
if (csDesigning in ComponentState) then
DataChange(Self);
end;
@ -269,6 +402,8 @@ procedure TJDBLabeledDateTimeEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = FButton) and (Operation = opRemove) then
FButton := nil;
// clean up
if (Operation = opRemove) then
begin
@ -288,6 +423,8 @@ end;
procedure TJDBLabeledDateTimeEdit.KeyDown(var Key: word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (ssAlt in Shift) and (key = 40) then
ShowCalendar(Self);
if Key = VK_ESCAPE then
begin
FDataLink.Reset;
@ -306,6 +443,8 @@ end;
procedure TJDBLabeledDateTimeEdit.KeyPress(var Key: char);
begin
if (not Assigned(FDataLink.Field)) or IsReadOnly then
key := #0;
if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then
Key := #0
else
@ -317,7 +456,7 @@ end;
procedure TJDBLabeledDateTimeEdit.DoEnter;
begin
if FDataLink.Field <> nil then
Caption := FDataLink.Field.AsString;
Caption := EditText;
inherited DoEnter;
end;
@ -330,20 +469,32 @@ begin
FDataLink.OnDataChange := @DataChange;
FDataLink.OnUpdateData := @UpdateData;
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;
destructor TJDBLabeledDateTimeEdit.Destroy;
begin
FDataLink.Free;
FDataLink := nil;
FreeAndNil(FDataLink);
FreeAndNil(FButton);
inherited Destroy;
end;
procedure TJDBLabeledDateTimeEdit.EditingDone;
begin
inherited EditingDone;
if (not Assigned(FDataLink.Field)) or IsReadOnly then
exit;
if DataSource.State in [dsEdit, dsInsert] then
UpdateData(self)
else
@ -352,4 +503,3 @@ end;
end.

View File

@ -22,7 +22,8 @@ interface
uses
Classes, SysUtils, LResources, Forms, Controls, ExtCtrls, Graphics,
Dialogs, jcontrolutils, jinputconsts;
Dialogs, Buttons, LMessages, jcontrolutils, jinputconsts, CalendarPopup,
Calendar;
type
@ -32,16 +33,33 @@ type
private
theValue: TDateTime;
fFormat: string;
FButton: TSpeedButton;
FButtonNeedsFocus: Boolean;
function GetButtonWidth: Integer;
function getFormat: string;
function getValue: TDateTime;
procedure formatInput;
procedure SetButtonWidth(AValue: Integer);
procedure setFormat(const AValue: string);
procedure setValue(const AValue: TDateTime);
procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS;
procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
protected
{ Protected declarations }
procedure DoEnter; override;
procedure DoExit; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); 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 declarations }
constructor Create(TheOwner: TComponent); override;
@ -51,6 +69,8 @@ type
function isNull: boolean;
property DisplayFormat: string read getFormat write setFormat;
property Value: TDateTime read getValue write setValue;
property Button: TSpeedButton read FButton;
property ButtonWidth : Integer read GetButtonWidth write SetButtonWidth;
property Action;
property Align;
@ -117,6 +137,11 @@ begin
Result := fFormat;
end;
function TJLabeledDateEdit.GetButtonWidth: Integer;
begin
Result:= FButton.Width;
end;
function TJLabeledDateEdit.getValue: TDateTime;
begin
Result := theValue;
@ -128,6 +153,11 @@ begin
Text := FormatDateTime(DisplayFormat, theValue);
end;
procedure TJLabeledDateEdit.SetButtonWidth(AValue: Integer);
begin
FButton.Width:=AValue;
end;
procedure TJLabeledDateEdit.setFormat(const AValue: string);
begin
fFormat := AValue;
@ -140,6 +170,18 @@ begin
formatInput;
end;
procedure TJLabeledDateEdit.WMSetFocus(var Message: TLMSetFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateEdit.WMKillFocus(var Message: TLMKillFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateEdit.DoEnter;
begin
inherited DoEnter;
@ -167,6 +209,13 @@ begin
formatInput;
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);
begin
if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then
@ -174,17 +223,110 @@ begin
inherited KeyPress(Key);
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);
begin
inherited Create(TheOwner);
Text := '';
fFormat := ShortDateFormat;
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;
end;
destructor TJLabeledDateEdit.Destroy;
begin
FreeAndNil(FButton);
inherited Destroy;
end;

View File

@ -25,24 +25,45 @@ interface
uses
Classes, LResources, Controls, ExtCtrls, LCLType, Dialogs,
SysUtils, jinputconsts;
SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons, LMessages;
type
{ TJLabeledDateTimeEdit }
TJLabeledDateTimeEdit = class(TCustomLabeledEdit)
private
{ Private declarations }
theValue: TDateTime;
fFormat: string;
FButton: TSpeedButton;
FButtonNeedsFocus: boolean;
function GetButtonWidth: integer;
function getFormat: string;
function getValue: TDateTime;
procedure formatInput;
procedure SetButtonWidth(AValue: integer);
procedure setFormat(const AValue: string);
procedure setValue(const AValue: TDateTime);
procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS;
procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
protected
{ Protected declarations }
procedure DoEnter; override;
procedure DoExit; override;
procedure KeyDown(var Key: word; Shift: TShiftState); 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 declarations }
constructor Create(TheOwner: TComponent); override;
@ -52,6 +73,8 @@ type
function isNull: boolean;
property DisplayFormat: string read getFormat write setFormat;
property Value: TDateTime read getValue write setValue;
property Button: TSpeedButton read FButton;
property ButtonWidth: integer read GetButtonWidth write SetButtonWidth;
property Action;
property Align;
@ -106,7 +129,7 @@ procedure Register;
implementation
uses
jcontrolutils;
jcontrolutils, dateutils;
procedure Register;
begin
@ -114,6 +137,11 @@ begin
RegisterComponents('Additional', [TJLabeledDateTimeEdit]);
end;
function TJLabeledDateTimeEdit.GetButtonWidth: integer;
begin
Result := FButton.Width;
end;
function TJLabeledDateTimeEdit.getFormat: string;
begin
Result := fFormat;
@ -130,6 +158,11 @@ begin
Text := FormatDateTime(DisplayFormat, theValue);
end;
procedure TJLabeledDateTimeEdit.SetButtonWidth(AValue: integer);
begin
FButton.Width := AValue;
end;
procedure TJLabeledDateTimeEdit.setFormat(const AValue: string);
begin
fFormat := AValue;
@ -142,6 +175,18 @@ begin
formatInput;
end;
procedure TJLabeledDateTimeEdit.WMSetFocus(var Message: TLMSetFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateTimeEdit.WMKillFocus(var Message: TLMKillFocus);
begin
CheckButtonVisible;
inherited;
end;
procedure TJLabeledDateTimeEdit.DoEnter;
begin
inherited DoEnter;
@ -178,6 +223,13 @@ begin
formatInput;
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);
begin
if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then
@ -185,6 +237,95 @@ begin
inherited KeyPress(Key);
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);
begin
inherited Create(TheOwner);
@ -192,10 +333,22 @@ begin
fFormat := ShortDateFormat + ' ' + ShortTimeFormat;
theValue := 0;
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;
destructor TJLabeledDateTimeEdit.Destroy;
begin
FreeAndNil(FButton);
inherited Destroy;
end;
@ -206,4 +359,3 @@ end;
end.