From ab8248724bd2401f322e86dffe3841cb908fcc61 Mon Sep 17 00:00:00 2001 From: jujibo Date: Tue, 14 Jun 2022 10:45:54 +0000 Subject: [PATCH] Added new files and icons git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8301 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/jujiboutils/src/jcurrencyedit.pas | 260 +++++++++ .../jujiboutils/src/jcurrencyedit_icon.lrs | 17 + components/jujiboutils/src/jdateedit.pas | 362 +++++++++++++ components/jujiboutils/src/jdateedit_icon.lrs | 18 + components/jujiboutils/src/jdatetimeedit.pas | 389 ++++++++++++++ .../jujiboutils/src/jdatetimeedit_icon.lrs | 41 ++ .../jujiboutils/src/jdbcurrencyedit.pas | 428 +++++++++++++++ .../jujiboutils/src/jdbcurrencyedit_icon.lrs | 28 + components/jujiboutils/src/jdbdateedit.pas | 495 +++++++++++++++++ .../jujiboutils/src/jdbdateedit_icon.lrs | 22 + .../jujiboutils/src/jdbdatetimeedit.pas | 500 ++++++++++++++++++ .../jujiboutils/src/jdbdatetimeedit_icon.lrs | 45 ++ components/jujiboutils/src/jdbedit.pas | 292 ++++++++++ components/jujiboutils/src/jdbedit_icon.lrs | 27 + components/jujiboutils/src/jdbfloatedit.pas | 448 ++++++++++++++++ .../jujiboutils/src/jdbfloatedit_icon.lrs | 28 + components/jujiboutils/src/jdbintegeredit.pas | 387 ++++++++++++++ .../jujiboutils/src/jdbintegeredit_icon.lrs | 27 + components/jujiboutils/src/jdbtimeedit.pas | 343 ++++++++++++ .../jujiboutils/src/jdbtimeedit_icon.lrs | 48 ++ components/jujiboutils/src/jfloatedit.pas | 256 +++++++++ .../jujiboutils/src/jfloatedit_icon.lrs | 14 + components/jujiboutils/src/jintegeredit.pas | 238 +++++++++ .../jujiboutils/src/jintegeredit_icon.lrs | 13 + components/jujiboutils/src/jtimeedit.pas | 230 ++++++++ components/jujiboutils/src/jtimeedit_icon.lrs | 40 ++ 26 files changed, 4996 insertions(+) create mode 100644 components/jujiboutils/src/jcurrencyedit.pas create mode 100644 components/jujiboutils/src/jcurrencyedit_icon.lrs create mode 100644 components/jujiboutils/src/jdateedit.pas create mode 100644 components/jujiboutils/src/jdateedit_icon.lrs create mode 100644 components/jujiboutils/src/jdatetimeedit.pas create mode 100644 components/jujiboutils/src/jdatetimeedit_icon.lrs create mode 100644 components/jujiboutils/src/jdbcurrencyedit.pas create mode 100644 components/jujiboutils/src/jdbcurrencyedit_icon.lrs create mode 100644 components/jujiboutils/src/jdbdateedit.pas create mode 100644 components/jujiboutils/src/jdbdateedit_icon.lrs create mode 100644 components/jujiboutils/src/jdbdatetimeedit.pas create mode 100644 components/jujiboutils/src/jdbdatetimeedit_icon.lrs create mode 100644 components/jujiboutils/src/jdbedit.pas create mode 100644 components/jujiboutils/src/jdbedit_icon.lrs create mode 100644 components/jujiboutils/src/jdbfloatedit.pas create mode 100644 components/jujiboutils/src/jdbfloatedit_icon.lrs create mode 100644 components/jujiboutils/src/jdbintegeredit.pas create mode 100644 components/jujiboutils/src/jdbintegeredit_icon.lrs create mode 100644 components/jujiboutils/src/jdbtimeedit.pas create mode 100644 components/jujiboutils/src/jdbtimeedit_icon.lrs create mode 100644 components/jujiboutils/src/jfloatedit.pas create mode 100644 components/jujiboutils/src/jfloatedit_icon.lrs create mode 100644 components/jujiboutils/src/jintegeredit.pas create mode 100644 components/jujiboutils/src/jintegeredit_icon.lrs create mode 100644 components/jujiboutils/src/jtimeedit.pas create mode 100644 components/jujiboutils/src/jtimeedit_icon.lrs diff --git a/components/jujiboutils/src/jcurrencyedit.pas b/components/jujiboutils/src/jcurrencyedit.pas new file mode 100644 index 000000000..8c536113c --- /dev/null +++ b/components/jujiboutils/src/jcurrencyedit.pas @@ -0,0 +1,260 @@ +{ JCurrencyEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit JCurrencyEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Graphics, + Dialogs, jinputconsts; + +type + + { TJCurrencyEdit } + + TJCurrencyEdit = class(TCustomEdit) + private + fEFormat: string; + fNColor: TColor; + fPColor: TColor; + theValue: currency; + fFormat: string; + fDecimals: integer; + function getDecimals: integer; + function getFormat: string; + function getValue: currency; + function getCurrentValue: Currency; + procedure formatInput; + procedure setDecimals(const AValue: integer); + procedure setFormat(const AValue: string); + function scaleTo(const AValue: currency; const NDecimals: integer): currency; + function IsValidFloat(const Value: string): boolean; + procedure setNegativeColor(AValue: TColor); + procedure setValue(const AValue: currency); + protected + procedure DoEnter; override; + procedure DoExit; override; + procedure KeyPress(var Key: char); override; + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + property CurrentValue: currency read getCurrentValue; + published + property DisplayFormat: string read getFormat write setFormat; + property EditFormat: string read fEFormat write fEFormat; + property Decimals: integer read getDecimals write setDecimals; + property Value: currency read getValue write setValue; + property NegativeColor: TColor read fNColor write setNegativeColor; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ReadOnly; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + + +uses + Math; + +procedure Register; +begin + {$I jcurrencyedit_icon.lrs} + RegisterComponents('Jujibo', [TJCurrencyEdit]); +end; + +{ TJCurrencyEdit } + +function TJCurrencyEdit.getDecimals: integer; +begin + Result := fDecimals; +end; + +function TJCurrencyEdit.getFormat: string; +begin + Result := fFormat; +end; + +function TJCurrencyEdit.getValue: currency; +begin + Result := theValue; +end; + +function TJCurrencyEdit.getCurrentValue: Currency; +begin + Result := StrToCurrDef(Text, Value); +end; + +procedure TJCurrencyEdit.formatInput; +begin + if Font.Color <> fNColor then + fPColor := Font.Color; // store original font color + Caption := FormatFloat(DisplayFormat, theValue); + if theValue < 0 then + font.Color := fNColor + else + font.Color := fPColor; +end; + +procedure TJCurrencyEdit.setDecimals(const AValue: integer); +begin + if (AValue >= 0) and (AValue < 5) then + fDecimals := AValue; +end; + +procedure TJCurrencyEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + formatInput; +end; + +function TJCurrencyEdit.scaleTo(const AValue: currency; + const NDecimals: integer): currency; +begin + Result := round(AValue * power(10, NDecimals)) / power(10, NDecimals); +end; + +function TJCurrencyEdit.IsValidFloat(const Value: string): boolean; +begin + if StrToCurrDef(Value, MaxCurrency) = MaxCurrency then + Result := False + else + Result := True; +end; + +procedure TJCurrencyEdit.setNegativeColor(AValue: TColor); +begin + if fNColor = AValue then + Exit; + fNColor := AValue; + formatInput; +end; + +procedure TJCurrencyEdit.setValue(const AValue: currency); +begin + if fDecimals > 0 then + theValue := scaleTo(AValue, fDecimals) + else + theValue := AValue; + formatInput; +end; + +procedure TJCurrencyEdit.DoEnter; +begin + inherited DoEnter; + if ReadOnly then + exit; + if EditFormat <> '' then + Text := FormatFloat(EditFormat, theValue) + else + Text := FloatToStr(theValue); + SelectAll; +end; + +procedure TJCurrencyEdit.DoExit; +begin + inherited DoExit; + if ReadOnly then + exit; + if IsValidFloat(Text) then + theValue := StrToCurr(Text) + else + begin + ShowMessage(Format(SInvalidNumber, [Text])); + SetFocus; + end; + if fDecimals > 0 then + theValue := scaleTo(theValue, fDecimals); + formatInput; +end; + +procedure TJCurrencyEdit.KeyPress(var Key: char); +begin + if (Key in ['.', ',']) then + Key := DefaultFormatSettings.Decimalseparator; + if (key = DefaultFormatSettings.DecimalSeparator) and (Pos(key, Text) > 0) then + key := #0; + if not (Key in ['0'..'9', DefaultFormatSettings.DecimalSeparator, + '+', '-', #8, #9]) then + Key := #0; + if (Key = DefaultFormatSettings.DecimalSeparator) and (fDecimals = 0) then + Key := #0; + inherited KeyPress(Key); +end; + +constructor TJCurrencyEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + Text := ''; + fFormat := '#,0.00'; + fDecimals := 2; + fPColor := Font.Color; + fNColor := Font.Color; + formatInput; +end; + +destructor TJCurrencyEdit.Destroy; +begin + inherited Destroy; +end; + +end. diff --git a/components/jujiboutils/src/jcurrencyedit_icon.lrs b/components/jujiboutils/src/jcurrencyedit_icon.lrs new file mode 100644 index 000000000..5285b7808 --- /dev/null +++ b/components/jujiboutils/src/jcurrencyedit_icon.lrs @@ -0,0 +1,17 @@ +LazarusResources.Add('TJCurrencyEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#1'-IDATH'#199#237#149#189'N'#195'0'#20#133#207'E'#252#140'U_'#160'/aK'#12 + +#217#202#131't('#211#237#128'X'#202#134#186'f'#1#6#226#165#202#208#7#201'V' + +#182'<'#5'<'#0'?#?'#185'L'#182'l'''#13'j'#18#9#9'q'#164'('#247'X'#202#249'l' + +#235':'#6#254#245#231'E'#182'`f'#177#181'1'#134#6#165'0'#179#136#192'=>l'#240 + +#240#161'!'#7#0#176'Xp0'#24#251'>:'#4#128',3Ah'#236'{'#3'lh'#172'<'#223#244 + +#218#166#249'|Fd'#247#218#7#216#217#159#28#189'w'#14'_'#173#174'1'#26'O'#168 + +'u'#139'n'#238#214#157#1'o/O?w'#145#136#200't'#185#21'_'#211#229#214#141'}|~' + +#5'^)'#229#222#175#207#143#226#0'M'#231'`'#23#192#7'UU'#21'x'#31'b'#1'{w'#145 + +#136#128#136#2#223#185#139'v'#5#159']='#160'H'#19'W'#3'p'#190#243'A'#179#225 + +#241#236#139'4A'#145'&'#14'T['#129'1'#134#152'Y'#226#208#219#251#172#241#3 + +#127#246'>'#172#245'W'#161#212'i-'#252#152#234#193'~m'#189#173#139'4'#129#214 + +#26'eYBk'#221'N'#205#243#141'\^'#156#215#186'f'#31#217'.j\'#163#235#225#158 + +#26#141''''#195#222'+'#191#162'o6'#202'W'#188#251#206'It'#0#0#0#0'IEND'#174 + +'B`'#130 +]); diff --git a/components/jujiboutils/src/jdateedit.pas b/components/jujiboutils/src/jdateedit.pas new file mode 100644 index 000000000..db4c1b3dc --- /dev/null +++ b/components/jujiboutils/src/jdateedit.pas @@ -0,0 +1,362 @@ +{ JDateEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} +unit JDateEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Graphics, + Dialogs, Buttons, LMessages, jcontrolutils, jinputconsts, CalendarPopup, + Calendar; + +type + + { TJDateEdit } + + TJDateEdit = class(TCustomEdit) + private + fEFormat: string; + theValue: TDateTime; + fFormat: string; + FButton: TSpeedButton; + FButtonNeedsFocus: boolean; + function GetButtonWidth: integer; + function getFormat: string; + function getValue: TDateTime; + function getCurrentValue: 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 + 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 + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + property CurrentValue: TDateTime read getCurrentValue; + published + function isNull: boolean; + property DisplayFormat: string read getFormat write setFormat; + property EditFormat: string read fEFormat write fEFormat; + property Value: TDateTime read getValue write setValue; + property Button: TSpeedButton read FButton; + property ButtonWidth: integer read GetButtonWidth write SetButtonWidth; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ReadOnly; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + +procedure Register; +begin + {$I jdateedit_icon.lrs} + RegisterComponents('Jujibo', [TJDateEdit]); +end; + +{ TJDateEdit } + +function TJDateEdit.getFormat: string; +begin + Result := fFormat; +end; + +function TJDateEdit.GetButtonWidth: integer; +begin + Result := FButton.Width; +end; + +function TJDateEdit.getValue: TDateTime; +begin + Result := theValue; +end; + +function TJDateEdit.getCurrentValue: TDateTime; +var + aText: string; + aValue: TDateTime; +begin + aText := NormalizeDate(Text, theValue); + if Length(aText) = 0 then + aValue := 0 + else + if not ValidateDateString(aText, aValue) then + Result:= Value + else + Result:= aValue; +end; + +procedure TJDateEdit.formatInput; +begin + if theValue <> 0 then + Text := FormatDateTime(DisplayFormat, theValue) + else + Text := ''; +end; + +procedure TJDateEdit.SetButtonWidth(AValue: integer); +begin + FButton.Width := AValue; +end; + +procedure TJDateEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + formatInput; +end; + +procedure TJDateEdit.setValue(const AValue: TDateTime); +begin + theValue := AValue; + formatInput; +end; + +procedure TJDateEdit.WMSetFocus(var Message: TLMSetFocus); +begin + CheckButtonVisible; + inherited; +end; + +procedure TJDateEdit.WMKillFocus(var Message: TLMKillFocus); +begin + CheckButtonVisible; + inherited; +end; + +procedure TJDateEdit.DoEnter; +begin + inherited DoEnter; + if ReadOnly then + exit; + if theValue <> 0 then + begin + if EditFormat <> '' then + Text := FormatDateTime(EditFormat, theValue) + else + Text := FormatDateTime(DefaultFormatSettings.ShortDateFormat, theValue); + end + else + Text := ''; + SelectAll; +end; + +procedure TJDateEdit.DoExit; +begin + inherited DoExit; + if ReadOnly then + exit; + Text := NormalizeDate(Text, theValue); + if Length(Text) = 0 then + theValue := 0 + else + if not ValidateDateString(Text, theValue) then + begin + ShowMessage(Format(SInvalidDate, [Text])); + SetFocus; + end; + formatInput; +end; + +procedure TJDateEdit.KeyDown(var Key: word; Shift: TShiftState); +begin + inherited KeyDown(Key, Shift); + if (ssAlt in Shift) and (key = 40) then + ShowCalendar(Self); +end; + +procedure TJDateEdit.KeyPress(var Key: char); +begin + if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then + Key := #0; + inherited KeyPress(Key); +end; + +procedure TJDateEdit.SetParent(AParent: TWinControl); +begin + inherited SetParent(AParent); + if FButton <> nil then + begin + DoPositionButton; + CheckButtonVisible; + end; +end; + +procedure TJDateEdit.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 TJDateEdit.CheckButtonVisible; +begin + if Assigned(FButton) then + FButton.Visible := True; +end; + +procedure TJDateEdit.Notification(AComponent: TComponent; Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + if (AComponent = FButton) and (Operation = opRemove) then + FButton := nil; +end; + +procedure TJDateEdit.CMVisibleChanged(var Msg: TLMessage); +begin + inherited CMVisibleChanged(Msg); + CheckButtonVisible; +end; + +procedure TJDateEdit.CMEnabledChanged(var Msg: TLMessage); +begin + inherited CMEnabledChanged(Msg); + if (FButton <> nil) then + FButton.Enabled := True; +end; + +procedure TJDateEdit.CMBiDiModeChanged(var Message: TLMessage); +begin + inherited; + DoPositionButton; +end; + +procedure TJDateEdit.Loaded; +begin + inherited Loaded; + DoPositionButton; + CheckButtonVisible; +end; + +procedure TJDateEdit.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 TJDateEdit.CalendarPopupReturnDate(Sender: TObject; + const ADate: TDateTime); +begin + Value := ADate; + EditingDone; +end; + +constructor TJDateEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + Text := ''; + fFormat := DefaultFormatSettings.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 TJDateEdit.Destroy; +begin + FreeAndNil(FButton); + inherited Destroy; +end; + +function TJDateEdit.isNull: boolean; +begin + Result := theValue = 0; +end; + +end. + diff --git a/components/jujiboutils/src/jdateedit_icon.lrs b/components/jujiboutils/src/jdateedit_icon.lrs new file mode 100644 index 000000000..97985af88 --- /dev/null +++ b/components/jujiboutils/src/jdateedit_icon.lrs @@ -0,0 +1,18 @@ +LazarusResources.Add('TJDateEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#1'?IDATH'#199'c`'#24#5#195#30'02000'#148#151'O'#250#143'.'#193#204#204#196 + +#240#247#239'?'#162#12#233#236#204'c'#196'%'#199#2'c'#20#20#4#146#229#194#9 + +#19#214'3'#28'8x'#248#191#131#189'-#^'#11#144'5'#16#235'zb'#28#197'B'#142'&R' + +#0#11'6'#193#192#214#219#12#12#12#12#12#235#171'U1'#196'`'#0'Y'#142'$'#11#208 + +#13'B'#6'!'#14#242#12#209#214'lX'#229#230#206']'#136#145'P'#146#147#227#25 + +#153#208#5#215'W'#171'2'#132'8'#200'c5d'#205#129#135'8'#29'p'#229#210'a'#20 + +#28#18#228#136';'#136#176#1'X'#144',='#250#139'!'#176#245'6F'#16#245'M'#152 + +#141#194#255#244#225'1'#3#3#3#3#3#19#177#22',='#250#11#175#188#137#137#9#10 + +#141'7'#146'q'#5#15#3#131''#205#164#24#140'a'#193#132#9#235'iR' + +#216#177#192#10#171#3#7#15#255#167'['#17';w'#238#194#255#133#249')'#255#255 + +#255#255#255#223#169#236#200#255#223#127#254#254'w*;'#2#199'0q'#24#251#255 + +#255#255#255#141#141#141'Q'#232#143#239#31#253''''#202#2'r'#1#204#2#172'E,^' + +#219'I'#0#252#130'r'#140'C'#191#202#4#0'K'#4#219'*'#193#26#230#167#0#0#0#0'I' + +'END'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jdatetimeedit.pas b/components/jujiboutils/src/jdatetimeedit.pas new file mode 100644 index 000000000..0ecae7347 --- /dev/null +++ b/components/jujiboutils/src/jdatetimeedit.pas @@ -0,0 +1,389 @@ +{ TJDateTimeEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + + + +unit JDateTimeEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, LResources, Controls, StdCtrls, LCLType, Dialogs, + SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons, LMessages; + +type + + { TJDateTimeEdit } + + TJDateTimeEdit = class(TCustomEdit) + private + fEFormat: string; + theValue: TDateTime; + fFormat: string; + FButton: TSpeedButton; + FButtonNeedsFocus: boolean; + function GetButtonWidth: integer; + function getFormat: string; + function getValue: TDateTime; + function getCurrentValue: 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 + 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 + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + property CurrentValue: TDateTime read getCurrentValue; + published + function isNull: boolean; + property DisplayFormat: string read getFormat write setFormat; + property EditFormat: string read fEFormat write fEFormat; + property Value: TDateTime read getValue write setValue; + property Button: TSpeedButton read FButton; + property ButtonWidth: integer read GetButtonWidth write SetButtonWidth; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + + end; + +procedure Register; + +implementation + +uses + jcontrolutils, dateutils; + +procedure Register; +begin + {$I jdatetimeedit_icon.lrs} + RegisterComponents('Jujibo', [TJDateTimeEdit]); +end; + +function TJDateTimeEdit.GetButtonWidth: integer; +begin + Result := FButton.Width; +end; + +function TJDateTimeEdit.getFormat: string; +begin + Result := fFormat; +end; + +function TJDateTimeEdit.getValue: TDateTime; +begin + Result := theValue; +end; + +function TJDateTimeEdit.getCurrentValue: TDateTime; +var + aText: string; + aValue: TDateTime; +begin + aText := NormalizeDateTime(Text, theValue); + if Length(aText) = 0 then + aValue := 0 + else + if IsValidDateTimeString(aText) then + aValue := StrToDateTime(aText) + else + begin + aValue:= Value; + end; + Result:= aValue; +end; + +procedure TJDateTimeEdit.formatInput; +begin + if theValue <> 0 then + Text := FormatDateTime(DisplayFormat, theValue) + else + Text := ''; +end; + +procedure TJDateTimeEdit.SetButtonWidth(AValue: integer); +begin + FButton.Width := AValue; +end; + +procedure TJDateTimeEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + formatInput; +end; + +procedure TJDateTimeEdit.setValue(const AValue: TDateTime); +begin + theValue := AValue; + formatInput; +end; + +procedure TJDateTimeEdit.WMSetFocus(var Message: TLMSetFocus); +begin + CheckButtonVisible; + inherited; +end; + +procedure TJDateTimeEdit.WMKillFocus(var Message: TLMKillFocus); +begin + CheckButtonVisible; + inherited; +end; + +procedure TJDateTimeEdit.DoEnter; +begin + inherited DoEnter; + if ReadOnly then + exit; + if theValue <> 0 then + begin + if EditFormat <> '' then + Text := FormatDateTime(EditFormat, theValue) + else + Text := FormatDateTime(DefaultFormatSettings.ShortDateFormat + + ' ' + DefaultFormatSettings.ShortTimeFormat, theValue); + end + else + Text := ''; + SelectAll; +end; + +procedure TJDateTimeEdit.DoExit; +var + bufText: string; +begin + inherited DoExit; + if ReadOnly then + exit; + bufText := Text; + Text := NormalizeDateTime(Text, theValue); + if (Length(bufText) > 0) and (Length(Text) = 0) then + begin + ShowMessage(Format(SInvalidDateTime, [bufText])); + SetFocus; + end + else + if Length(Text) = 0 then + theValue := 0 + else + if IsValidDateTimeString(Text) then + theValue := StrToDateTime(Text) + else + begin + ShowMessage(Format(SInvalidDateTime, [Text])); + SetFocus; + end; + formatInput; +end; + +procedure TJDateTimeEdit.KeyDown(var Key: word; Shift: TShiftState); +begin + inherited KeyDown(Key, Shift); + if (ssAlt in Shift) and (key = 40) then + ShowCalendar(Self); +end; + +procedure TJDateTimeEdit.KeyPress(var Key: char); +begin + if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then + Key := #0; + inherited KeyPress(Key); +end; + +procedure TJDateTimeEdit.SetParent(AParent: TWinControl); +begin + inherited SetParent(AParent); + if FButton <> nil then + begin + DoPositionButton; + CheckButtonVisible; + end; +end; + +procedure TJDateTimeEdit.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 TJDateTimeEdit.CheckButtonVisible; +begin + if Assigned(FButton) then + FButton.Visible := True; +end; + +procedure TJDateTimeEdit.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + if (AComponent = FButton) and (Operation = opRemove) then + FButton := nil; +end; + +procedure TJDateTimeEdit.CMVisibleChanged(var Msg: TLMessage); +begin + inherited CMVisibleChanged(Msg); + CheckButtonVisible; +end; + +procedure TJDateTimeEdit.CMEnabledChanged(var Msg: TLMessage); +begin + inherited CMEnabledChanged(Msg); + if (FButton <> nil) then + FButton.Enabled := True; +end; + +procedure TJDateTimeEdit.CMBiDiModeChanged(var Message: TLMessage); +begin + inherited; + DoPositionButton; +end; + +procedure TJDateTimeEdit.Loaded; +begin + inherited Loaded; + DoPositionButton; + CheckButtonVisible; +end; + +procedure TJDateTimeEdit.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 TJDateTimeEdit.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 TJDateTimeEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + Text := ''; + fFormat := DefaultFormatSettings.ShortDateFormat + ' ' + + DefaultFormatSettings.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 TJDateTimeEdit.Destroy; +begin + FreeAndNil(FButton); + inherited Destroy; +end; + +function TJDateTimeEdit.isNull: boolean; +begin + Result := theValue = 0; +end; + + +end. diff --git a/components/jujiboutils/src/jdatetimeedit_icon.lrs b/components/jujiboutils/src/jdatetimeedit_icon.lrs new file mode 100644 index 000000000..4a210ef48 --- /dev/null +++ b/components/jujiboutils/src/jdatetimeedit_icon.lrs @@ -0,0 +1,41 @@ +LazarusResources.Add('TJDateTimeEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#3'bIDATH'#199#213#149'[h'#219'U'#28#128#191#164'Iso.'#166's'#149#217#184 + +#142#180#216#226#172'k'#237#236'"u'#173'S'#182#249#176'u*>'#136#136':'#152 + +#136'l'#221'K'#251#144#151#129'n'#16#161'0d'#8'>'#236'a'#131#130#136#152#135 + +#217#13#231#165#237#150'4'#189'D\'#215#205'u'#196'Ekk'#183#165']'#154#180#185 + +#223#142#15#165'e3]M*'#8'~p8'#183'?'#191#239#156#223#143#195'_'#194':'#233 + +#251#226#147'6EI'#196#174'P'#166#234'K'#228'%'#186'lF'#16#143#198#131#209#8 + +'C'#241#140#202#177#255#208#9#15#128'd='#193'/}y'#226'3'#131'a'#225'='#163'e' + +#127#169#162#172#28#133#218#136#16'9"'#161#25#130#211#191'03'#209#23#13'/' + +#202#29'o'#28'='#245'Q'#209#130#222's_'#139#154#138#187#152',{'#153#141#233 + +#24#191#21'&0'#31'#'#147#21#24'uJ'#234#182'h1'#10'?7.'#157#229'n '#211')+V`' + +#206'y0<'#254#1#215#166#229#204#133#194#212'[M'#24#202#204#8'$'#4#195'YF&f' + +#209'*6'#242'd'#227'>'#130#223#156'9VRL'#240#207'Ou'#139#218#167#154#136#200 + +#170#240#207'Dy'#181'u3'#18#145#224'^4F'#185#217#132'^'#175#160#186#202#132 + +#231'z'#16#173'a#'#138#212#13#185#12#160#171#235'SQ'#136#160'R'#229'Gcz'#153 + +#31''''#130'l'#171#221'@,#'#144#203#229'|'#247#173#147#215#14#180#147#139'/2' + +'x'#213'Gm'#245'6'#238'F'#173'['#250#182'`'#193'R'#202 + +',+s'#211#163#155'h~'#229'm'#134'}N'#246#236'}'#134#23'Z'#158#167#177#177#17 + +#175#215#11#192'Bhju'#193#253'E^'#30';'#237'V'#156'v'#235#3#243'B'#145'=,' + +#215'k'#213#161#24'd'#133#188#224#127#131#12#192#225'8,'#233#31#184','#248 + +#175'8}'#250#140'8z'#228#160#16'B'#136#182'N'#151'Hg'#178#162#173#211#181#210 + +#150#215#151#199'B'#8#209#208#208#240'@'#31#158#255'C'#20'$X/'#203#130'U'#127 + +#153'k'#218#139'@o'#172#148#240#191#231'/'#233'Q'#193#133'-'#210'3~'#0#0#0#0 + +'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jdbcurrencyedit.pas b/components/jujiboutils/src/jdbcurrencyedit.pas new file mode 100644 index 000000000..8cf2ff60a --- /dev/null +++ b/components/jujiboutils/src/jdbcurrencyedit.pas @@ -0,0 +1,428 @@ +{ JDBCurrencyEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit jdbcurrencyedit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, LResources, Controls, StdCtrls, DB, DBCtrls, Graphics, + LMessages, LCLType, Dialogs, + SysUtils, jinputconsts; + +type + + { TJDBCurrencyEdit } + + TJDBCurrencyEdit = class(TCustomEdit) + private + fFormat: string; + FDataLink: TFieldDataLink; + fDecimales: integer; + fNColor: TColor; + fPColor: TColor; + fNull: boolean; + + procedure DataChange(Sender: TObject); + function getDecimals: integer; + procedure setDecimals(AValue: integer); + procedure setNegativeColor(AValue: TColor); + procedure UpdateData(Sender: TObject); + procedure FocusRequest(Sender: TObject); + + function GetDataField: string; + function GetDataSource: TDataSource; + function GetField: TField; + + function IsReadOnly: boolean; + + function getFormat: string; + procedure setFormat(const AValue: string); + procedure formatInput; + + procedure SetDataField(const Value: string); + procedure SetDataSource(Value: TDataSource); + procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK; + + function IsValidCurrency(const Value: string): boolean; + function ScaleTo(const AValue: currency; const NDecimals: integer): currency; + + protected + procedure Loaded; override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure ActiveChange(Sender: TObject); virtual; + procedure KeyDown(var Key: word; Shift: TShiftState); override; + procedure KeyPress(var Key: char); override; + procedure DoEnter; override; + function GetReadOnly: boolean; override; + procedure SetReadOnly(Value: boolean); override; + + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + procedure EditingDone; override; + property Field: TField read GetField; + + published + property DisplayFormat: string read getFormat write setFormat; + property DataField: string read GetDataField write SetDataField; + property DataSource: TDataSource read GetDataSource write SetDataSource; + property Decimals: integer read getDecimals write setDecimals; + property ReadOnly: boolean read GetReadOnly write SetReadOnly default False; + property AllowNull: boolean read fNull write fNull default False; + property NegativeColor: TColor read fNColor write setNegativeColor; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + +uses + Math, jdbutils; + +procedure Register; +begin + {$I jdbcurrencyedit_icon.lrs} + RegisterComponents('JujiboDB', [TJDBCurrencyEdit]); +end; + +{ TJDBCurrencyEdit } + +procedure TJDBCurrencyEdit.DataChange(Sender: TObject); +begin + if FDataLink.Field <> nil then + begin + if not Focused then + formatInput + else + Caption := FDataLink.Field.AsString; + end + else + Text := ''; +end; + +function TJDBCurrencyEdit.getDecimals: integer; +begin + Result := fDecimales; +end; + +procedure TJDBCurrencyEdit.setDecimals(AValue: integer); +begin + if (AValue >= 0) and (AValue < 5) then + fDecimales := AValue; +end; + +procedure TJDBCurrencyEdit.setNegativeColor(AValue: TColor); +begin + if fNColor = AValue then + Exit; + fNColor := AValue; + formatInput; +end; + + +procedure TJDBCurrencyEdit.UpdateData(Sender: TObject); +var + theValue: currency; +begin + if FDataLink.Field <> nil then + begin + if fNull and (Length(Caption) = 0) then + FDataLink.Field.Value := Null + else + if IsValidCurrency(Text) then + begin + theValue := StrToCurr(Text); + if fDecimales > 0 then + theValue := ScaleTo(theValue, fDecimales); + Text := CurrToStr(theValue); + FDataLink.Field.Value := theValue; + end + else + begin + if FDataLink.Field <> nil then + begin + ShowMessage(Format(SInvalidNumber, [Caption])); + Caption := FDataLink.Field.AsString; + SelectAll; + SetFocus; + end; + end; + end + else + Text := ''; +end; + +procedure TJDBCurrencyEdit.FocusRequest(Sender: TObject); +begin + SetFocus; +end; + +function TJDBCurrencyEdit.GetDataField: string; +begin + Result := FDataLink.FieldName; +end; + +function TJDBCurrencyEdit.GetDataSource: TDataSource; +begin + Result := FDataLink.DataSource; +end; + +function TJDBCurrencyEdit.GetField: TField; +begin + Result := FDataLink.Field; +end; + +function TJDBCurrencyEdit.IsReadOnly: boolean; +begin + if FDatalink.Active then + Result := not FDatalink.CanModify + else + Result := False; +end; + +function TJDBCurrencyEdit.getFormat: string; +begin + Result := fFormat; +end; + +procedure TJDBCurrencyEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + if not Focused then + formatInput; +end; + +procedure TJDBCurrencyEdit.formatInput; +begin + if Font.Color <> fNColor then + fPColor := Font.Color; // store original font color + if FDataLink.Field <> nil then + begin + //FDataLink.Field.DisplayText -> formatted (tdbgridcolumns/persistent field DisplayFormat + if FDataLink.Field.IsNull then + Caption := '' + else + if fFormat <> '' then + Caption := FormatFloat(fFormat, FDataLink.Field.AsCurrency) + else + Caption := FDataLink.Field.DisplayText; + if FDataLink.Field.AsCurrency < 0 then + font.Color := fNColor + else + font.Color := fPColor; + end + else + begin + Caption := 'nil'; + font.Color := fPColor; + end; +end; + +function TJDBCurrencyEdit.GetReadOnly: boolean; +begin + Result := FDataLink.ReadOnly; +end; + +procedure TJDBCurrencyEdit.SetReadOnly(Value: boolean); +begin + inherited; + FDataLink.ReadOnly := Value; +end; + +procedure TJDBCurrencyEdit.SetDataField(const Value: string); +begin + FDataLink.FieldName := Value; +end; + +procedure TJDBCurrencyEdit.SetDataSource(Value: TDataSource); +begin + if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then + ChangeDataSource(Self, FDataLink, Value); +end; + +procedure TJDBCurrencyEdit.CMGetDataLink(var Message: TLMessage); +begin + Message.Result := PtrUInt(FDataLink); // Delphi dbctrls compatibility? +end; + +function TJDBCurrencyEdit.IsValidCurrency(const Value: string): boolean; +begin + if StrToCurrDef(Value, MaxCurrency) = MaxCurrency then + Result := False + else + Result := True; +end; + +function TJDBCurrencyEdit.ScaleTo(const AValue: currency; + const NDecimals: integer): currency; +begin + Result := round(AValue * power(10, NDecimals)) / power(10, NDecimals); +end; + +procedure TJDBCurrencyEdit.Loaded; +begin + inherited Loaded; + if (csDesigning in ComponentState) then + DataChange(Self); +end; + +procedure TJDBCurrencyEdit.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + // clean up + if (Operation = opRemove) then + begin + if (FDataLink <> nil) and (AComponent = DataSource) then + DataSource := nil; + end; +end; + +procedure TJDBCurrencyEdit.ActiveChange(Sender: TObject); +begin + if FDatalink.Active then + datachange(Sender) + else + Text := ''; +end; + +procedure TJDBCurrencyEdit.KeyDown(var Key: word; Shift: TShiftState); +begin + inherited KeyDown(Key, Shift); + if Key = VK_ESCAPE then + begin + FDataLink.Reset; + SelectAll; + Key := VK_UNKNOWN; + end + else + if Key in [VK_DELETE, VK_BACK] then + begin + if not IsReadOnly then + FDatalink.Edit + else + Key := VK_UNKNOWN; + end; +end; + +procedure TJDBCurrencyEdit.KeyPress(var Key: char); +begin + if not FieldIsEditable(Field) or not FDatalink.Edit then + Key := #0; + if (Key in ['.', ',']) then + Key := DefaultFormatSettings.Decimalseparator; + if (key = DefaultFormatSettings.DecimalSeparator) and (Pos(key, Text) > 0) then + key := #0; + if not (Key in ['0'..'9', DefaultFormatSettings.DecimalSeparator, + '+', '-', #8, #9]) then + Key := #0; + + if (Key <> #0) and (not IsReadOnly) then + FDatalink.Edit; + inherited KeyPress(Key); +end; + +procedure TJDBCurrencyEdit.DoEnter; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if FDataLink.Field <> nil then + Caption := FDataLink.Field.AsString; + inherited DoEnter; +end; + +constructor TJDBCurrencyEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + ControlStyle := ControlStyle + [csReplicatable]; + FDataLink := TFieldDataLink.Create; + FDataLink.Control := Self; + FDataLink.OnDataChange := @DataChange; + FDataLink.OnUpdateData := @UpdateData; + FDataLInk.OnActiveChange := @ActiveChange; + fPColor := Font.Color; + fNColor := Font.Color; + // Set default values + //fDecimales := 2; + //fFormat := '0.00'; +end; + +destructor TJDBCurrencyEdit.Destroy; +begin + FDataLink.Free; + FDataLink := nil; + inherited Destroy; +end; + +procedure TJDBCurrencyEdit.EditingDone; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if DataSource.State in [dsEdit, dsInsert] then + UpdateData(self) + else + formatInput; + inherited EditingDone; +end; + +end. diff --git a/components/jujiboutils/src/jdbcurrencyedit_icon.lrs b/components/jujiboutils/src/jdbcurrencyedit_icon.lrs new file mode 100644 index 000000000..216bd3f17 --- /dev/null +++ b/components/jujiboutils/src/jdbcurrencyedit_icon.lrs @@ -0,0 +1,28 @@ +LazarusResources.Add('TJDBCurrencyEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#2'*IDATH'#199#213#148#191'k'#19'a'#24#199'?'#23#210#138#16'--VQ0b'#160'X' + +#164'i'#134#28'H'#9'8'#164#139'C'#255#1#237#224'P'#187#188#25#196'%'#29#4#233 + +#226#16#7#181'`'#162#16'3t'#240#199#26#136'c'#28#244#170' Y'#140#5#139#133 + +#160#149'8'#156#210'&'#146#193#164'5'#175'Cz'#231'].'#9#222#137#131#15#28#247 + +'<'#15'w'#223#207#243'<'#247#220#11#255#216#20'k'#240#228#197#23#153'-Tz>' + +#184'8'#23#226#226#249#19#138''''#128'Ux%'#17'a*'#24'`}'#171#129'^k'#162#215 + +'['#232#181'&y'#173#234#9#228#7#200#22'*LO'#140'q'#250#216'A'#244'Z'#147'u0' + +#197#1#244'z'#139#233#137'1'#26'?'#246#232#215'a?'#243#1#132'N'#30#166#188 + +#185'M^'#171#154#21#27#226#0'S'#167#14'Q'#222#220#230#194#241#15','#206#133 + +'\'#1#252#134'3'#217'x'#12#192#203#167#176#17#184#196#243'[1'#226#201'5'#243 + +#193#153#240'8'#187'GC'#20#223'~s'#15#24'~'#255#128't:c&'#19#9'X'#249#20'A' + +#175'M::'#154#141#28#225#161#155#17#9'!'#164'U'#28' '#157#206'p?'#181'd'#203 + +#189'~'#247#213#211#154#250':'#21#11'['#210#136'o>'#218' ['#168#144#215#170 + +#204#132#199#25#210'_'#185#6#248#141#138#173#16'#'#190'>o'#31#145#182's'#150 + +#242#155#138#183#143#220'=&'#128#143#165'g'#0#4#246'/|'#16'>'#3#243#185'U' + +#249''''#226#11#11#151#21'E'#8'!'#187#1'F7'#7#134'Z'#158#143#136#229#229#27 + +#140#140#6#149#129'#'#186'}7'#235#25#240#189#246#185#227#8'!'#164#148'8'#174 + +'N^'#202'xR'#147'V'#139'''53'#183#187#247#211#22'G'#163'Q'#243'^'#223#217#146 + +'&'#160#27#242';'#231#4'XA'#237'v'#219#22'[!'#6'`'#224#136'z'#153#148#18'EQl' + +#177#231'-'#234'''<'#187#180'F1'#21'3}'#192#140']'#253'h'#182's}_'#188#187 + +#250'b*F1'#21'3A'#142#14'2'#153#140'"'#132#144#221#162'w'#238#165'{'#190'`' + +#173#222#10#27'xTD'#163#231#28#226#195#138'S'#216#234#27#177#225#23'S1TU'#165 + +'T*'#161#170#234'`j.'#183'*'#175']'#189#226#216#26'7flQ'#207#30#205#29#254'K' + +#27#25#13'*'#252#247#246#11#209'E'#182#243'<'#219'\K'#0#0#0#0'IEND'#174'B`' + +#130 +]); diff --git a/components/jujiboutils/src/jdbdateedit.pas b/components/jujiboutils/src/jdbdateedit.pas new file mode 100644 index 000000000..9eb0758f2 --- /dev/null +++ b/components/jujiboutils/src/jdbdateedit.pas @@ -0,0 +1,495 @@ +{ JDBDateEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit jdbdateedit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, LResources, Controls, StdCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs, + SysUtils, jinputconsts, CalendarPopup, Calendar, Buttons; + +type + + { TJDBDateEdit } + + TJDBDateEdit = class(TCustomEdit) + private + 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); + + function GetDataField: string; + function GetDataSource: TDataSource; + function GetField: TField; + + function IsReadOnly: boolean; + + function getFormat: string; + procedure setFormat(const AValue: string); + procedure formatInput; + + procedure SetDataField(const Value: string); + procedure SetDataSource(Value: TDataSource); + procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK; + + function IsValidCurrency(const Value: string): boolean; + + protected + procedure Loaded; override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure ActiveChange(Sender: TObject); virtual; + procedure KeyDown(var Key: word; Shift: TShiftState); override; + procedure KeyPress(var Key: char); override; + procedure DoEnter; override; + 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; + procedure EditingDone; override; + property Field: TField read GetField; + + published + property DisplayFormat: string read getFormat write setFormat; + property DataField: string read GetDataField write SetDataField; + 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; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + +uses + jcontrolutils, dateutils, jdbutils; + +procedure Register; +begin + {$I jdbdateedit_icon.lrs} + RegisterComponents('JujiboDB', [TJDBDateEdit]); +end; + +{ TJDBDateEdit } + +function TJDBDateEdit.GetButtonWidth: integer; +begin + Result := FButton.Width; +end; + +procedure TJDBDateEdit.SetButtonWidth(AValue: integer); +begin + FButton.Width := AValue; +end; + +procedure TJDBDateEdit.WMSetFocus(var Message: TLMSetFocus); +begin + CheckButtonVisible; + inherited; +end; + +procedure TJDBDateEdit.WMKillFocus(var Message: TLMKillFocus); +begin + CheckButtonVisible; + inherited; +end; + +procedure TJDBDateEdit.DataChange(Sender: TObject); +begin + if FDataLink.Field <> nil then + begin + if not Focused then + formatInput + else + Caption := FDataLink.Field.AsString; + end + else + Text := ''; +end; + +procedure TJDBDateEdit.UpdateData(Sender: TObject); +var + theValue: string; +begin + if FDataLink.Field <> nil then + begin + theValue := NormalizeDate(Text, FDataLink.Field.AsDateTime); + if Text = '' then + FDataLink.Field.Text := Text + else + if IsValidDateString(theValue) then + begin + FDataLink.Field.Text := theValue; + end + else + begin + ShowMessage(Format(SInvalidDate, [Caption])); + Caption := FDataLink.Field.AsString; + SelectAll; + SetFocus; + end; + end + else + Text := ''; +end; + +procedure TJDBDateEdit.FocusRequest(Sender: TObject); +begin + SetFocus; +end; + +function TJDBDateEdit.GetDataField: string; +begin + Result := FDataLink.FieldName; +end; + +function TJDBDateEdit.GetDataSource: TDataSource; +begin + Result := FDataLink.DataSource; +end; + +function TJDBDateEdit.GetField: TField; +begin + Result := FDataLink.Field; +end; + +function TJDBDateEdit.IsReadOnly: boolean; +begin + if FDatalink.Active then + Result := not FDatalink.CanModify + else + Result := False; +end; + +function TJDBDateEdit.getFormat: string; +begin + Result := fFormat; +end; + +procedure TJDBDateEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + if not Focused then + formatInput; +end; + +procedure TJDBDateEdit.formatInput; +begin + if FDataLink.Field <> nil then + //FDataLink.Field.DisplayText -> formatted (tdbgridcolumns/persistent field DisplayFormat + if (fFormat <> '') and (not FDataLink.Field.IsNull) then + Caption := FormatDateTime(fFormat, FDataLink.Field.AsDateTime) + else + Caption := FDataLink.Field.DisplayText + else + Caption := 'nil'; +end; + +function TJDBDateEdit.GetReadOnly: boolean; +begin + Result := FDataLink.ReadOnly; +end; + +procedure TJDBDateEdit.SetReadOnly(Value: boolean); +begin + inherited; + FDataLink.ReadOnly := Value; +end; + +procedure TJDBDateEdit.SetParent(AParent: TWinControl); +begin + inherited SetParent(AParent); + if FButton <> nil then + begin + DoPositionButton; + CheckButtonVisible; + end; +end; + +procedure TJDBDateEdit.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 TJDBDateEdit.CheckButtonVisible; +begin + if Assigned(FButton) then + FButton.Visible := True; +end; + +procedure TJDBDateEdit.CMVisibleChanged(var Msg: TLMessage); +begin + inherited CMVisibleChanged(Msg); + CheckButtonVisible; +end; + +procedure TJDBDateEdit.CMEnabledChanged(var Msg: TLMessage); +begin + inherited CMEnabledChanged(Msg); + if (FButton <> nil) then + FButton.Enabled := True; +end; + +procedure TJDBDateEdit.CMBiDiModeChanged(var Message: TLMessage); +begin + inherited; + DoPositionButton; +end; + +procedure TJDBDateEdit.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 TJDBDateEdit.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 TJDBDateEdit.SetDataField(const Value: string); +begin + FDataLink.FieldName := Value; +end; + +procedure TJDBDateEdit.SetDataSource(Value: TDataSource); +begin + if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then + ChangeDataSource(Self, FDataLink, Value); +end; + +procedure TJDBDateEdit.CMGetDataLink(var Message: TLMessage); +begin + Message.Result := PtrUInt(FDataLink); // Delphi dbctrls compatibility? +end; + +function TJDBDateEdit.IsValidCurrency(const Value: string): boolean; +begin + if StrToCurrDef(Value, MaxCurrency) = MaxCurrency then + Result := False + else + Result := True; +end; + +procedure TJDBDateEdit.Loaded; +begin + inherited Loaded; + DoPositionButton; + CheckButtonVisible; + if (csDesigning in ComponentState) then + DataChange(Self); +end; + +procedure TJDBDateEdit.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 + if (FDataLink <> nil) and (AComponent = DataSource) then + DataSource := nil; + end; +end; + +procedure TJDBDateEdit.ActiveChange(Sender: TObject); +begin + if FDatalink.Active then + datachange(Sender) + else + Text := ''; +end; + +procedure TJDBDateEdit.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; + SelectAll; + Key := VK_UNKNOWN; + end + else + if Key in [VK_DELETE, VK_BACK] then + begin + if not IsReadOnly then + FDatalink.Edit + else + Key := VK_UNKNOWN; + end; +end; + +procedure TJDBDateEdit.KeyPress(var Key: char); +begin + if not FieldIsEditable(Field) or not FDatalink.Edit then + Key := #0; + if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then + Key := #0; + inherited KeyPress(Key); +end; + +procedure TJDBDateEdit.DoEnter; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if FDataLink.Field <> nil then + Caption := FDataLink.Field.AsString; + inherited DoEnter; +end; + +constructor TJDBDateEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + ControlStyle := ControlStyle + [csReplicatable]; + FDataLink := TFieldDataLink.Create; + FDataLink.Control := Self; + FDataLink.OnDataChange := @DataChange; + FDataLink.OnUpdateData := @UpdateData; + FDataLInk.OnActiveChange := @ActiveChange; + + 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 TJDBDateEdit.Destroy; +begin + FreeAndNil(FDataLink); + FreeAndNil(FButton); + inherited Destroy; +end; + +procedure TJDBDateEdit.EditingDone; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if DataSource.State in [dsEdit, dsInsert] then + UpdateData(self) + else + formatInput; + inherited EditingDone; +end; + +end. diff --git a/components/jujiboutils/src/jdbdateedit_icon.lrs b/components/jujiboutils/src/jdbdateedit_icon.lrs new file mode 100644 index 000000000..f38adc1ae --- /dev/null +++ b/components/jujiboutils/src/jdbdateedit_icon.lrs @@ -0,0 +1,22 @@ +LazarusResources.Add('TJDBDateEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#1#172'IDATH'#199#213'T'#191'K'#2'Q'#28#255'\H'#16'D?'#28#10#130#148#132 + +#219#194#6'o'#139#202#156']'#12#151'hh0'#167#192'l'#209#193#217#193'%'#172'U' + +#28#28#164'%8'#2#255#0'M'#221'n'#18#183#3'!'#165#134#27'J'#197'!/'#227#219't' + +'r'#158'w'#199#221'EA'#31'x'#188#247#190#223#251'~>'#239'}'#191#223'{'#192'/' + +#131'Qo'#238#159'^'#169'P'#233#232'~'#24#15#251'pz'#184#197'8'#18'P'#19#223 + +'^'#238'a'#215#179#140'vw'#4#169'?'#134'4'#144'!'#245#199'xl'#188'8'#18'r'#1 + +'@'#161#210#129#159'ucgs'#9'R'#127#140'60%'#7#0'i '#195#207#186'1'#250#152 + +#192#232#134#166#2#190#237#21#180#196'7'#180'D`c'#205'7%'#213#146#197#195'>t' + +'zC'#251')J'#167#239#232''''#133#204#229#18#140#233#13#0' '#153#140'8"'#207 + +#231'yTku'#10#30#29'0'#166#2#234#0'+'#176'z '#151#211'@[E'#214'"'#146#21#1#0 + +'|'#134#157#179')P'#251'l'#9'h'#137#212#136#6#189'8'#219'_'#212#245#21#139 + +#165#185'F'#137#197#206#153#5#173#145#207#176#136#6#189#186'$'#15#213'g'#195 + +#3#180'['#245#153#17'=96N'#145#30#148#148#148#155'2"Yq.E7'#249#194#204'~'#216 + +#239#1#0#22#172#10#148#155#178#169#159#227#184#153#217#180#200'F'#233#1#188 + +#134'~A'#16#192'q'#28#4'A'#176'^du7'#241#25'V'#183#187'lw'#145'Y'#176#29#226 + +'9'#1#171#127#176'#'#129'\.'#193'Tku'#194'_'#161'X,'#209#245#213#5#17#17#133 + +'R'#13#250#156'|Q('#213#152#14#197#174#172#137#136#2#129#192#204' nil then + begin + if not Focused then + formatInput + else + Caption := EditText; + end + else + Text := ''; +end; + +procedure TJDBDateTimeEdit.UpdateData(Sender: TObject); +var + theValue: string; +begin + if FDataLink.Field <> nil then + begin + theValue := NormalizeDateTime(Text, FDataLink.Field.AsDateTime); + if Text = '' then + FDataLink.Field.Text := Text + else + if IsValidDateTimeString(theValue) then + begin + FDataLink.Field.Text := theValue; + end + else + begin + ShowMessage(Format(SInvalidDateTime, [Caption])); + Caption := EditText; + SelectAll; + SetFocus; + end; + end + else + Text := ''; +end; + +procedure TJDBDateTimeEdit.FocusRequest(Sender: TObject); +begin + SetFocus; +end; + +function TJDBDateTimeEdit.GetDataField: string; +begin + Result := FDataLink.FieldName; +end; + +function TJDBDateTimeEdit.GetDataSource: TDataSource; +begin + Result := FDataLink.DataSource; +end; + +function TJDBDateTimeEdit.GetField: TField; +begin + Result := FDataLink.Field; +end; + +function TJDBDateTimeEdit.IsReadOnly: boolean; +begin + if FDatalink.Active then + Result := not FDatalink.CanModify + else + Result := False; +end; + +function TJDBDateTimeEdit.EditText: string; +begin + if Field.IsNull then + Result := '' + else + Result := FormatDateTime(DefaultFormatSettings.ShortDateFormat, + FDataLink.Field.AsDateTime) + ' ' + + FormatDateTime(DefaultFormatSettings.ShortTimeFormat, FDataLink.Field.AsDateTime); +end; + +function TJDBDateTimeEdit.getFormat: string; +begin + Result := fFormat; +end; + +procedure TJDBDateTimeEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + if not Focused then + formatInput; +end; + +procedure TJDBDateTimeEdit.formatInput; +begin + if FDataLink.Field <> nil then + if (fFormat <> '') and (not FDataLink.Field.IsNull) then + Caption := FormatDateTime(fFormat, FDataLink.Field.AsDateTime) + else + Caption := EditText + else + Caption := 'nil'; +end; + +function TJDBDateTimeEdit.GetReadOnly: boolean; +begin + Result := FDataLink.ReadOnly; +end; + +procedure TJDBDateTimeEdit.SetReadOnly(Value: boolean); +begin + inherited; + FDataLink.ReadOnly := Value; +end; + +procedure TJDBDateTimeEdit.SetParent(AParent: TWinControl); +begin + inherited SetParent(AParent); + if FButton <> nil then + begin + DoPositionButton; + CheckButtonVisible; + end; +end; + +procedure TJDBDateTimeEdit.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 TJDBDateTimeEdit.CheckButtonVisible; +begin + if Assigned(FButton) then + FButton.Visible := True; +end; + +procedure TJDBDateTimeEdit.CMVisibleChanged(var Msg: TLMessage); +begin + inherited CMVisibleChanged(Msg); + CheckButtonVisible; +end; + +procedure TJDBDateTimeEdit.CMEnabledChanged(var Msg: TLMessage); +begin + inherited CMEnabledChanged(Msg); + if (FButton <> nil) then + FButton.Enabled := True; +end; + +procedure TJDBDateTimeEdit.CMBiDiModeChanged(var Message: TLMessage); +begin + inherited; + DoPositionButton; +end; + +procedure TJDBDateTimeEdit.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 TJDBDateTimeEdit.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 TJDBDateTimeEdit.SetDataField(const Value: string); +begin + FDataLink.FieldName := Value; +end; + +procedure TJDBDateTimeEdit.SetDataSource(Value: TDataSource); +begin + if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then + ChangeDataSource(Self, FDataLink, Value); +end; + +procedure TJDBDateTimeEdit.CMGetDataLink(var Message: TLMessage); +begin + Message.Result := PtrUInt(FDataLink); // Delphi dbctrls compatibility? +end; + +procedure TJDBDateTimeEdit.Loaded; +begin + inherited Loaded; + DoPositionButton; + CheckButtonVisible; + if (csDesigning in ComponentState) then + DataChange(Self); +end; + +procedure TJDBDateTimeEdit.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 + if (FDataLink <> nil) and (AComponent = DataSource) then + DataSource := nil; + end; +end; + +procedure TJDBDateTimeEdit.ActiveChange(Sender: TObject); +begin + if FDatalink.Active then + datachange(Sender) + else + Text := ''; +end; + +procedure TJDBDateTimeEdit.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; + SelectAll; + Key := VK_UNKNOWN; + end + else + if Key in [VK_DELETE, VK_BACK] then + begin + if not IsReadOnly then + FDatalink.Edit + else + Key := VK_UNKNOWN; + end; +end; + +procedure TJDBDateTimeEdit.KeyPress(var Key: char); +begin + if not FieldIsEditable(Field) or not FDatalink.Edit then + Key := #0; + if (not Assigned(FDataLink.Field)) or IsReadOnly then + key := #0; + if not (Key in ['0'..'9', #8, #9, '.', '-', '/', ',', ':', ' ']) then + Key := #0; + inherited KeyPress(Key); +end; + +procedure TJDBDateTimeEdit.DoEnter; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if FDataLink.Field <> nil then + Caption := EditText; + inherited DoEnter; +end; + +constructor TJDBDateTimeEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + ControlStyle := ControlStyle + [csReplicatable]; + FDataLink := TFieldDataLink.Create; + FDataLink.Control := Self; + FDataLink.OnDataChange := @DataChange; + FDataLink.OnUpdateData := @UpdateData; + FDataLInk.OnActiveChange := @ActiveChange; + + 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 TJDBDateTimeEdit.Destroy; +begin + FreeAndNil(FDataLink); + FreeAndNil(FButton); + inherited Destroy; +end; + +procedure TJDBDateTimeEdit.EditingDone; +begin + inherited EditingDone; + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if (not Assigned(FDataLink.Field)) or IsReadOnly then + exit; + if DataSource.State in [dsEdit, dsInsert] then + UpdateData(self) + else + formatInput; + inherited EditingDone; +end; + + +end. diff --git a/components/jujiboutils/src/jdbdatetimeedit_icon.lrs b/components/jujiboutils/src/jdbdatetimeedit_icon.lrs new file mode 100644 index 000000000..0567d01cd --- /dev/null +++ b/components/jujiboutils/src/jdbdatetimeedit_icon.lrs @@ -0,0 +1,45 @@ +LazarusResources.Add('TJDBDateTimeEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#3#202'IDATH'#199#213#148'{L[U'#28#199'?--'#165'Ohy'#141'=xZ'#136#176#0#14 + +#134#3#21#145#160'n'#211'DX4'#198#24'c'#162#152#25'M&'#139#9#254#193'?&'#186 + +'%'#152','#217#18#227'?f'#127'l'#9#209',&'#205#226#216#226'|'#240'Xy'#12#186 + +#201'cNH'#29#147#241#24#20',-'#180#244'qK'#143#127'`'#17#6'C6'#19#19'?'#201 + +#205'='#231#220's'#191#159'{'#127#231#220'+'#227'!i'#249#250#179'JU'#148#167 + +'A'#21#19','#140'RF'#233#151'B'#2#159#215#231#244'z'#232#246#133#212#141#213 + +#135#143'w'#1#200'V'#223#244'U'#251#164#248#242#194#200#134#129#239#188#152 + +#201'k'#229#219'e'#0#237#231#142#127#17#23'7'#255#182'1'#173':ZeHD'#165'1"D' + +#24#143'k'#18#231#248'M&'#135'Z'#188#238#5'e'#227#171'G?'#255'Dvo'#240#169 + +#247#11#216#157#170#227#198#29#15#14'W'#0#135';'#136#195#21#224#188'u'#2#128 + +#15#159'r'#144#147'2'#141')'#237' 3'#139'z'#6'o'#185'q'#204'-'#18'Z'#18#24 + +#245'1'#228'e'#233'0'#138#17'~m?'#203#180'#T/'#3#168#172#183#138'|'#179#137 + +#140'd5'#187#211#244'$'#197#169#214#132';'#220'A'#188#254'%b$'#7'5;'#154#201 + +#218#247#30'7''U'#204#186#2#228'?b"'#206' G '#195#233'^'#162'gh'#6#157'J'#206 + +#163#134'al'#23#206','#202#1'2w'#25#24#176';9o'#157'X'#19#186':|'#192#238'$#' + +'|'#13'Sj%3>'#3'SN?5'#21#233#152#244#2#167#199#131#206#160'%u'#151#129#234 + +#170','#166#23#194#204#202'sI'#206#216#161'Q'#0#196#143#183#18#255#215'j'#244 + +'5__W'#127#21#176'W'#6#169#234'1'#180#166#231#248'i'#200#201#158#220'$'#22'C' + +#2#165'R'#201#247#223'Yx'#249'P'#13'a'#223#2#157#3'vr'#179#247#208'um'#148 + +#253#217'%("!uu5'#255#184's'#250'.'#158#160#179'w'#152#201#128#153#168#219'^' + +#182'%'#234#208'j4'#28':PE'#216#183#0'@Y'#190#153'Y'#181#134#187'N?'#177#251 + +#210#255#22'D8y'#210'r_Ay'#134#31#173#219#138'O'#158#133#210#209'I`'#238'q'#2 + +'@G'#199'Uz'#7#127#161#238#221#183'P$'#236'$'#224#150#144#164'0"'#28'\/'#216 + +#236'M'#250'..'#239#180'X'#173#156#196#130'*`'#249#169'5'#9')'#28'>'#242','#4 + +#231#241#4'al'#202#139'A+gn'#162#31#249'FA5'#199#236#212#28#179#175#27'k'#27 + +'1'#161#214#197'P'#146#163'f'#166#255#135#149'k'#139#179'wI0'#26#0#208#197'@' + +#239#207#14#202#243#228#140#14't'#174#23#220#27#188#154#130#231'k'#241'y'#252 + +#152#164'n'#164#164'2'#206'^'#241'2'#229#215'!%'#149'!'#243'I'#0#132#28#227 + +#164#170#29'$'#250'.1v'#203#235'_W"K'#131#153#166#142' '#223#180#142#174#19 + +#156':7D'#190':'#147#138#153'o)'#172#240#176'-'#189#132'K'#173'.\'#11'K'#216 + +#174#143#160#215'@i'#174'`'#175#241'2='#151'{'#144#162#227#27#21'['#253#247 + +'X'#26#204#0'4u'#164#209#210#21#194#215#220'J'#194'v+'#251#179#243#136'KI'#3 + +#17#226#143'q;'#191'w'#223#224#246#172#146#156#178'Wx'#230#165#218#143#183',' + +'h'#234#8#242#250#19#209#0#12#6#10#169'{'#163#148'a'#219#143#180'5'#247#163 + +'V'#216#144'$'#9#157'1'#137#254#223#252'|'#244#233#9'4'#250#229#185'['#22',' + +#151',m'#165'oJ'#222'I'#233#11'or'#213'n'#225#192#193#199'x'#186#252'I'#138 + +#139#139#177#217'l'#0#204#187#198'6'#22#172'^'#228'H'#219#210'`'#198#210'`^' + +#211#223'*'#138#251#213'z'#179'ux'#16#20'['#249#130#255#13#10#128#198#198'#' + +#178#214#182'+'#130#255#138#211#167#207#136#163#31#212#10'!'#132#168#172#183 + +#10')'#180'$*'#235#173'+Gd<'#210#22'B'#136#162#162#162'5g'#247#220#29#177'%' + +#193#195#18#17#200'6'#18'lj'#127#0'b'#141#169'2'#254#247#252#9#178#214#9#14 + +'4'#136#229'j'#0#0#0#0'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jdbedit.pas b/components/jujiboutils/src/jdbedit.pas new file mode 100644 index 000000000..27ebec9c9 --- /dev/null +++ b/components/jujiboutils/src/jdbedit.pas @@ -0,0 +1,292 @@ +{ JDBEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit JDBEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, LResources, Controls, StdCtrls, DB, DBCtrls, + LMessages, LCLType, SysUtils; + +type + + { TJDBEdit } + + TJDBEdit = class(TCustomEdit) + private + FDataLink: TFieldDataLink; + + procedure DataChange(Sender: TObject); + procedure UpdateData(Sender: TObject); + procedure FocusRequest(Sender: TObject); + + function GetDataField: string; + function GetDataSource: TDataSource; + function GetField: TField; + + function IsReadOnly: boolean; + + procedure SetDataField(const Value: string); + procedure SetDataSource(Value: TDataSource); + procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK; + + protected + procedure Loaded; override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure ActiveChange(Sender: TObject); virtual; + procedure KeyDown(var Key: word; Shift: TShiftState); override; + procedure KeyPress(var Key: char); override; + procedure DoEnter; override; + function GetReadOnly: boolean; override; + procedure SetReadOnly(Value: boolean); override; + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + procedure EditingDone; override; + property Field: TField read GetField; + published + property DataField: string read GetDataField write SetDataField; + property DataSource: TDataSource read GetDataSource write SetDataSource; + property ReadOnly: boolean read GetReadOnly write SetReadOnly default False; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + +uses + jdbutils; + +procedure Register; +begin + {$I jdbedit_icon.lrs} + RegisterComponents('JujiboDB', [TJDBEdit]); +end; + +{ TJDBEdit } + +procedure TJDBEdit.DataChange(Sender: TObject); +begin + if FDataLink.Field <> nil then + Caption := FDataLink.Field.AsString + else + Text := ''; +end; + +procedure TJDBEdit.UpdateData(Sender: TObject); +begin + if FDataLink.Field <> nil then + FDataLink.Field.Text := Text + else + Text := ''; +end; + +procedure TJDBEdit.FocusRequest(Sender: TObject); +begin + SetFocus; +end; + +function TJDBEdit.GetDataField: string; +begin + Result := FDataLink.FieldName; +end; + +function TJDBEdit.GetDataSource: TDataSource; +begin + Result := FDataLink.DataSource; +end; + +function TJDBEdit.GetField: TField; +begin + Result := FDataLink.Field; +end; + +function TJDBEdit.IsReadOnly: boolean; +begin + if FDatalink.Active then + Result := not FDatalink.CanModify + else + Result := False; +end; + +procedure TJDBEdit.SetDataField(const Value: string); +begin + FDataLink.FieldName := Value; + if FDataLink.Field <> nil then + MaxLength := FDataLink.Field.Size + else + MaxLength := 0; +end; + +procedure TJDBEdit.SetDataSource(Value: TDataSource); +begin + if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then + ChangeDataSource(Self, FDataLink, Value); +end; + +procedure TJDBEdit.CMGetDataLink(var Message: TLMessage); +begin + Message.Result := PtrUInt(FDataLink); +end; + +procedure TJDBEdit.Loaded; +begin + inherited Loaded; + if (csDesigning in ComponentState) then + DataChange(Self); +end; + +procedure TJDBEdit.Notification(AComponent: TComponent; Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + // clean up + if (Operation = opRemove) then + begin + if (FDataLink <> nil) and (AComponent = DataSource) then + DataSource := nil; + end; +end; + +procedure TJDBEdit.ActiveChange(Sender: TObject); +begin + if FDatalink.Active then + datachange(Sender) + else + Text := ''; +end; + +procedure TJDBEdit.KeyDown(var Key: word; Shift: TShiftState); +begin + inherited KeyDown(Key, Shift); + if Key = VK_ESCAPE then + begin + FDataLink.Reset; + SelectAll; + Key := VK_UNKNOWN; + end + else + if Key in [VK_DELETE, VK_BACK] then + begin + if not IsReadOnly then + FDatalink.Edit + else + Key := VK_UNKNOWN; + end; +end; + +procedure TJDBEdit.KeyPress(var Key: char); +begin + if not FieldIsEditable(Field) or not FDatalink.Edit then + Key := #0; + inherited KeyPress(Key); +end; + +procedure TJDBEdit.DoEnter; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if FDataLink.Field <> nil then + Caption := FDataLink.Field.AsString; + inherited DoEnter; +end; + +function TJDBEdit.GetReadOnly: boolean; +begin + Result := FDataLink.ReadOnly; +end; + +procedure TJDBEdit.SetReadOnly(Value: boolean); +begin + inherited; + FDataLink.ReadOnly := Value; +end; + +constructor TJDBEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + ControlStyle := ControlStyle + [csReplicatable]; + FDataLink := TFieldDataLink.Create; + FDataLink.Control := Self; + FDataLink.OnDataChange := @DataChange; + FDataLink.OnUpdateData := @UpdateData; + FDataLInk.OnActiveChange := @ActiveChange; +end; + +destructor TJDBEdit.Destroy; +begin + FDataLink.Free; + FDataLink := nil; + inherited Destroy; +end; + +procedure TJDBEdit.EditingDone; +begin + inherited EditingDone; + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if DataSource.State in [dsEdit, dsInsert] then + UpdateData(self); +end; + +end. + diff --git a/components/jujiboutils/src/jdbedit_icon.lrs b/components/jujiboutils/src/jdbedit_icon.lrs new file mode 100644 index 000000000..77ba37e8a --- /dev/null +++ b/components/jujiboutils/src/jdbedit_icon.lrs @@ -0,0 +1,27 @@ +LazarusResources.Add('TJDBEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#2#25'IDATH'#199#213#149'OH'#154'q'#24#199'?'#134'('#131'5'#173'-'#133'bJA' + +'(L'#221'!'#217#16'$h'#135#14'c'#208'9<,V;'#13#25';'#7#171#14'^v'#24#27#30'%' + +'h'#7#233','#180#139#135#9'M'#8#226#245#226#222' '#144'\'#26#6#211'p'#154#142 + +'e'#204#222']z'#223'2'#255#132#175#237#176#239#229#253#189#207#251#252#158 + +#239#243#255#133#127#12#205#229#151#245#205'C)'#180#145'n'#169#248#242#217#24 + +#179#147#195#26'U'#4#151#13#127'|'#245#16#135#229'6b'#182'J'#190'T#_>%_'#170 + +#17#137#231'T'#17'i'#1'B'#27'i\'#227#131#140#154'o'#145'/'#213#16#161#193'x' + +#190'|'#138'k|'#144#234#201#31#218'E'#216#14'}'#0'c'#247#239#144'L'#21#137 + +#196's'#13'F'#1'LF='#191'N'#234'<'#182#25'qZ'#251#153#241#142'tE'#160#149#15 + +#30#231#16'&'#131#174#173#135#201'TQ'#137#162'k'#130#244#193'1f'#227#16#0#139 + +'>;O\w'#17#179'U'#196'L'#5#206#211#165#22'Z9E'#219';G'#212#207'$'#28'V{'#199 + +#11#223#206'I'#187'N'#209#163#7#247'0'#25't'#4#194#187#4#194#173#149'g'#188 + +'#8'#173#253'7'#151#162#171#157#244#253#199'o'#146#169'b'#247's'#176#16'LJ' + +#153'\'#133#250#153#196#162#207#206#190#240#249'F'#166'x~'#254#185'F!0'#27 + +#245#152#12':"'#241#28'>'#219#30'b'#242'kO'#198#151#151#223'b'#24#176'h'#180 + +#0#153'\'#5#179'Q'#175#164'h_'#216#3#224#253#135#144'j'#130#227#210#193#197 + +#160#189'x:'#202#246#206#145#178#14#174#131#199#31'k'#146#185#221#238#134'gC' + +#145#229#221#178#190'y('#5#194#187#248'l'#221'{,'#8#2'n'#183#27'A'#16#154'W' + +#133#140#217#201'a'#205#151'w'#222#134'E'#22'M'#20#240#248'cx'#252'1'#162#137 + +'BC'#20'We'#29#231#160#29#166''''#134#152#158#152'R'#140#202#231#173'`'#179 + +'L'#21'A4Q`iMT]'#236#190#235#20#150#214'D'#182#130'S'#138#199#170'vQ'''#172 + +#204'9Zv'#141',['#153's('#221#211#174#208'MX]'#253'$'#189'y'#189' '#245#130 + +#242#207#172#212#244'O'#150'!'#127#236#21#134#1#139#134#255#30#127#1#207'",' + +#20'q'#10#211'e'#0#0#0#0'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jdbfloatedit.pas b/components/jujiboutils/src/jdbfloatedit.pas new file mode 100644 index 000000000..0ccb6bc51 --- /dev/null +++ b/components/jujiboutils/src/jdbfloatedit.pas @@ -0,0 +1,448 @@ +{ JDBFloatEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit JDBFloatEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, LResources, Controls, StdCtrls, DB, DBCtrls, Graphics, + LMessages, LCLType, Dialogs, + SysUtils, jinputconsts; + +type + + { TJDBFloatEdit } + + TJDBFloatEdit = class(TCustomEdit) + private + fFormat: string; + fEFormat: string; + FDataLink: TFieldDataLink; + fDecimales: integer; + fNColor: TColor; + fPColor: TColor; + fNull: boolean; + + procedure DataChange(Sender: TObject); + function getDecimals: integer; + procedure setDecimals(AValue: integer); + procedure setNegativeColor(AValue: TColor); + procedure UpdateData(Sender: TObject); + procedure FocusRequest(Sender: TObject); + + function GetDataField: string; + function GetDataSource: TDataSource; + function GetField: TField; + + function IsReadOnly: boolean; + + function getFormat: string; + procedure setFormat(const AValue: string); + procedure formatInput; + + procedure SetDataField(const Value: string); + procedure SetDataSource(Value: TDataSource); + procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK; + + function IsValidFloat(const Value: string): boolean; + function ScaleTo(const AValue: double; const NDecimals: integer): double; + + protected + procedure Loaded; override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure ActiveChange(Sender: TObject); virtual; + procedure KeyDown(var Key: word; Shift: TShiftState); override; + procedure KeyPress(var Key: char); override; + procedure DoEnter; override; + function GetReadOnly: boolean; override; + procedure SetReadOnly(Value: boolean); override; + + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + procedure EditingDone; override; + property Field: TField read GetField; + + published + property DisplayFormat: string read getFormat write setFormat; + property EditFormat: string read fEFormat write fEFormat; + property DataField: string read GetDataField write SetDataField; + property DataSource: TDataSource read GetDataSource write SetDataSource; + property Decimals: integer read getDecimals write setDecimals; + property ReadOnly: boolean read GetReadOnly write SetReadOnly default False; + property AllowNull: boolean read fNull write fNull default False; + property NegativeColor: TColor read fNColor write setNegativeColor; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + +uses + Math, FMTBcd, jdbutils; + +procedure Register; +begin + {$I jdbfloatedit_icon.lrs} + RegisterComponents('JujiboDB', [TJDBFloatEdit]); +end; + + +procedure TJDBFloatEdit.DataChange(Sender: TObject); +begin + if FDataLink.Field <> nil then + begin + if not Focused then + formatInput + else + if Length(EditFormat) > 0 then + Caption := FormatFloat(EditFormat, FDataLink.Field.AsFloat) + else + Caption := FloatToStr(FDataLink.Field.AsFloat); + end + else + Text := ''; +end; + +function TJDBFloatEdit.getDecimals: integer; +begin + Result := fDecimales; +end; + +procedure TJDBFloatEdit.setDecimals(AValue: integer); +begin + if AValue >= 0 then + fDecimales := AValue; +end; + +procedure TJDBFloatEdit.setNegativeColor(AValue: TColor); +begin + if fNColor = AValue then + Exit; + fNColor := AValue; + formatInput; +end; + + +procedure TJDBFloatEdit.UpdateData(Sender: TObject); +var + theValue: double; +begin + if FDataLink.Field <> nil then + begin + if fNull and (Length(Caption) = 0) then + FDataLink.Field.Value := Null + else + if IsValidFloat(Text) then + begin + theValue := StrToFloat(Text); + if fDecimales > 0 then + theValue := ScaleTo(theValue, fDecimales); + if Length(EditFormat) > 0 then + Caption := FormatFloat(EditFormat, theValue) + else + Caption := FloatToStr(theValue); + //writeln(FDataLink.Field.FieldDef.DataType); + case FDataLink.Field.FieldDef.DataType of + ftFMTBcd: FDataLink.Field.AsBCD := StrToBCD(FormatFloat('0.'+StringOfChar('0', Decimals), theValue)); + else + FDataLink.Field.Value := theValue; + end; + + end + else + begin + if FDataLink.Field <> nil then + begin + ShowMessage(Format(SInvalidNumber, [Caption])); + if Length(EditFormat) > 0 then + Caption := FormatFloat(EditFormat, FDataLink.Field.AsFloat) + else + Caption := FloatToStr(FDataLink.Field.AsFloat); + SelectAll; + SetFocus; + end; + end; + end + else + Text := ''; +end; + +procedure TJDBFloatEdit.FocusRequest(Sender: TObject); +begin + SetFocus; +end; + +function TJDBFloatEdit.GetDataField: string; +begin + Result := FDataLink.FieldName; +end; + +function TJDBFloatEdit.GetDataSource: TDataSource; +begin + Result := FDataLink.DataSource; +end; + +function TJDBFloatEdit.GetField: TField; +begin + Result := FDataLink.Field; +end; + +function TJDBFloatEdit.IsReadOnly: boolean; +begin + if FDatalink.Active then + Result := not FDatalink.CanModify + else + Result := False; +end; + +function TJDBFloatEdit.getFormat: string; +begin + Result := fFormat; +end; + +procedure TJDBFloatEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + if not Focused then + formatInput; +end; + +procedure TJDBFloatEdit.formatInput; +begin + if Font.Color <> fNColor then + fPColor := Font.Color; // store original font color + if FDataLink.Field <> nil then + begin + //FDataLink.Field.DisplayText -> formatted (tdbgridcolumns/persistent field DisplayFormat + if FDataLink.Field.IsNull then + Caption := '' + else + if fFormat <> '' then + Caption := FormatFloat(fFormat, FDataLink.Field.AsFloat) + else + Caption := FDataLink.Field.DisplayText; + if FDataLink.Field.AsFloat < 0 then + font.Color := fNColor + else + font.Color := fPColor; + end + else + begin + Caption := 'nil'; + font.Color := fPColor; + end; +end; + +function TJDBFloatEdit.GetReadOnly: boolean; +begin + Result := FDataLink.ReadOnly; +end; + +procedure TJDBFloatEdit.SetReadOnly(Value: boolean); +begin + inherited; + FDataLink.ReadOnly := Value; +end; + +procedure TJDBFloatEdit.SetDataField(const Value: string); +begin + FDataLink.FieldName := Value; +end; + +procedure TJDBFloatEdit.SetDataSource(Value: TDataSource); +begin + if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then + ChangeDataSource(Self, FDataLink, Value); +end; + +procedure TJDBFloatEdit.CMGetDataLink(var Message: TLMessage); +begin + Message.Result := PtrUInt(FDataLink); // Delphi dbctrls compatibility? +end; + +function TJDBFloatEdit.IsValidFloat(const Value: string): boolean; +begin + if StrToFloatDef(Value, MaxDouble) = MaxDouble then + Result := False + else + Result := True; +end; + +function TJDBFloatEdit.ScaleTo(const AValue: double; + const NDecimals: integer): double; +begin + Result := round(AValue * power(10, NDecimals)) / power(10, NDecimals); +end; + +procedure TJDBFloatEdit.Loaded; +begin + inherited Loaded; + if (csDesigning in ComponentState) then + DataChange(Self); +end; + +procedure TJDBFloatEdit.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + // clean up + if (Operation = opRemove) then + begin + if (FDataLink <> nil) and (AComponent = DataSource) then + DataSource := nil; + end; +end; + +procedure TJDBFloatEdit.ActiveChange(Sender: TObject); +begin + if FDatalink.Active then + datachange(Sender) + else + Text := ''; +end; + +procedure TJDBFloatEdit.KeyDown(var Key: word; Shift: TShiftState); +begin + inherited KeyDown(Key, Shift); + if Key = VK_ESCAPE then + begin + FDataLink.Reset; + SelectAll; + Key := VK_UNKNOWN; + end + else + if Key in [VK_DELETE, VK_BACK] then + begin + if not IsReadOnly then + FDatalink.Edit + else + Key := VK_UNKNOWN; + end; +end; + +procedure TJDBFloatEdit.KeyPress(var Key: char); +begin + if not FieldIsEditable(Field) or not FDatalink.Edit then + Key := #0; + if (Key in ['.', ',']) then + Key := DefaultFormatSettings.Decimalseparator; + if (key = DefaultFormatSettings.DecimalSeparator) and (Pos(key, Text) > 0) then + key := #0; + if not (Key in ['0'..'9', DefaultFormatSettings.DecimalSeparator, + '+', '-', #8, #9]) then + Key := #0; + if (Key <> #0) and (not IsReadOnly) then + FDatalink.Edit; + inherited KeyPress(Key); +end; + +procedure TJDBFloatEdit.DoEnter; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if FDataLink.Field <> nil then + if Length(EditFormat) > 0 then + Caption := FormatFloat(EditFormat, FDataLink.Field.AsFloat) + else + Caption := FloatToStr(FDataLink.Field.AsFloat); //FDataLink.Field.AsString; + inherited DoEnter; +end; + +constructor TJDBFloatEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + ControlStyle := ControlStyle + [csReplicatable]; + FDataLink := TFieldDataLink.Create; + FDataLink.Control := Self; + FDataLink.OnDataChange := @DataChange; + FDataLink.OnUpdateData := @UpdateData; + FDataLInk.OnActiveChange := @ActiveChange; + fEFormat := ''; + fPColor := Font.Color; + fNColor := Font.Color; + // Set default values + //fDecimales := 2; + //fFormat := '0.00'; +end; + +destructor TJDBFloatEdit.Destroy; +begin + FDataLink.Free; + FDataLink := nil; + inherited Destroy; +end; + +procedure TJDBFloatEdit.EditingDone; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if DataSource.State in [dsEdit, dsInsert] then + UpdateData(self) + else + formatInput; + inherited EditingDone; +end; + + +end. diff --git a/components/jujiboutils/src/jdbfloatedit_icon.lrs b/components/jujiboutils/src/jdbfloatedit_icon.lrs new file mode 100644 index 000000000..b23e4d289 --- /dev/null +++ b/components/jujiboutils/src/jdbfloatedit_icon.lrs @@ -0,0 +1,28 @@ +LazarusResources.Add('TJDBFloatEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#2'8IDATH'#199#213#148'1H[Q'#20#134#191'WB'#130'PLLk'#2#22'S'#18#144#10#181 + +#233'`('#148#136'C'#220'J'#161#179'8'#20#170#157':'#148'.q'#16#138#139'C:HKG' + +'q'#232' '#206#1';&'#131'}.'#146#197'4B!'#152#170'!B'#31#193'&'#154'R'#19'LN' + +#7#251#210#23#243#162'Il'#135#254#203#185#231#222#203#249#239'9'#247'?'#7#254 + +'1'#20#163#179#186'~ Kk'#25#211#139#207#31#251#152#28#31'P'#186'"0'#6'~'#247 + +#226'>#'#158#235#164#246'Kh'#133'2Z'#177#130'V('#19'Us]'#17'Y'#0#150#214'2' + +#248#135#156'x'#221'=h'#133'2)8'#179'{'#199#0'h'#197#10#254'!'''#165#147'SZe' + +#216#10#215#0'|'#131#189'$'#211#135'D'#213#28'Z'#177'B|+_'#15#14#240#227#164 + +#138#215#221'C&{'#196#147#177'['#29#17'X'#244#197#195'{'#253#184#236#214#150 + +'/L'#166#193'?'#228#228#179#129#184'm'#130'L'#246#8#183#163#31#128#185#169'a' + +'B'#254#27#164#246'K'#196#183#242#184#28'6'#180'B'#185'k'#21'Y'#244#18'mn' + +#231#169#214#132#145#219#195'-/G'#213#28#190#193#222#238'J'#244#224#238'M\v+' + +#11'+_XX1'#191#220'i'#253'/-'#145'Q'#166'Z'#177#194#215'o?I'#166#15';'#239 + +#131#153#247'I'#217#203#29'S'#173#9'sS'#195#236'&>'#254#149'.'#158#158'~'#170 + +#212#9#220#14#27'.'#187#149#168#154'c'#234#206#14#169#228#167'+'#5#159#159 + +#127#141#189#207#163'X'#0#246'r'#199#184#29#182'z'#137'v'#19';'#0','#190']' + +#234#154#224#168#144#253#211'h'#207#30'y'#217#220#206#215#199#129#17#19#179 + +#27'M'#190#190'wZ'#173'5'#248#129'@'#160#193'6au'#253'@BaU'#150#151'?'#200 + +#171#151'3""'#18#10#171'b'#134'PX'#149'Z'#173#214#224#139#136#140#142#142#138 + +#136'H'#241#251#190#212'3'#208'19>'#160#196#223#140']8'#200'D'#164#201'?'#191 + +'g'#218#7#151'ADP'#206'4'#193#196#236#6#177'H'#176#161#132#186'o:'#236#218 + +#210#243#239#224#186#213'Ic'#145' '#177'H'#176#233#175':&0~'#178#254'Z#'#217 + +#133#227#186#221#192'fJ'#210#215#177'H'#144'@ @"'#145'h'#173'"'#29'F'#21#157 + +'WI'#187#208'Ud'#154#163'~xU'#216#251'<'#10#255'=~'#1#26#174'h'#189'o,bQ'#0#0 + +#0#0'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jdbintegeredit.pas b/components/jujiboutils/src/jdbintegeredit.pas new file mode 100644 index 000000000..7b45d4849 --- /dev/null +++ b/components/jujiboutils/src/jdbintegeredit.pas @@ -0,0 +1,387 @@ +{ jdbintegeredit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit jdbintegeredit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, LResources, Controls, StdCtrls, DB, DBCtrls, Graphics, + LMessages, LCLType, Dialogs, + SysUtils, jinputconsts; + +type + + { TJDBIntegerEdit } + + TJDBIntegerEdit = class(TCustomEdit) + private + fFormat: string; + FDataLink: TFieldDataLink; + fNColor: TColor; + fPColor: TColor; + fNull: boolean; + + procedure DataChange(Sender: TObject); + procedure setNegativeColor(AValue: TColor); + procedure UpdateData(Sender: TObject); + procedure FocusRequest(Sender: TObject); + + function GetDataField: string; + function GetDataSource: TDataSource; + function GetField: TField; + + function IsReadOnly: boolean; + + function getFormat: string; + procedure setFormat(const AValue: string); + procedure formatInput; + + procedure SetDataField(const Value: string); + procedure SetDataSource(Value: TDataSource); + procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK; + + function IsValidInteger(const Value: string): boolean; + + protected + procedure Loaded; override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure ActiveChange(Sender: TObject); virtual; + procedure KeyDown(var Key: word; Shift: TShiftState); override; + procedure KeyPress(var Key: char); override; + procedure DoEnter; override; + function GetReadOnly: boolean; override; + procedure SetReadOnly(Value: boolean); override; + + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + procedure EditingDone; override; + property Field: TField read GetField; + + published + property DisplayFormat: string read getFormat write setFormat; + property DataField: string read GetDataField write SetDataField; + property DataSource: TDataSource read GetDataSource write SetDataSource; + property ReadOnly: boolean read GetReadOnly write SetReadOnly default False; + property AllowNull: boolean read fNull write fNull default False; + property NegativeColor: TColor read fNColor write setNegativeColor; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + + +implementation + +uses + jdbutils; + +procedure Register; +begin + {$I jdbintegeredit_icon.lrs} + RegisterComponents('JujiboDB', [TJDBIntegerEdit]); +end; + +{ TJDBIntegerEdit } + +procedure TJDBIntegerEdit.DataChange(Sender: TObject); +begin + if FDataLink.Field <> nil then + begin + if not Focused then + formatInput + else + Caption := FDataLink.Field.AsString; + end + else + Text := ''; +end; + +procedure TJDBIntegerEdit.setNegativeColor(AValue: TColor); +begin + if fNColor = AValue then + Exit; + fNColor := AValue; + formatInput; +end; + + +procedure TJDBIntegerEdit.UpdateData(Sender: TObject); +begin + if FDataLink.Field <> nil then + begin + if fNull and (Length(Caption) = 0) then + FDataLink.Field.Value := Null + else + if IsValidInteger(Caption) then + begin + FDataLink.Field.Text := Text; + end + else + begin + ShowMessage(Format(SInvalidNumber, [Caption])); + Caption := FDataLink.Field.AsString; + SelectAll; + SetFocus; + end; + end + else + Text := ''; +end; + +procedure TJDBIntegerEdit.FocusRequest(Sender: TObject); +begin + SetFocus; +end; + +function TJDBIntegerEdit.GetDataField: string; +begin + Result := FDataLink.FieldName; +end; + +function TJDBIntegerEdit.GetDataSource: TDataSource; +begin + Result := FDataLink.DataSource; +end; + +function TJDBIntegerEdit.GetField: TField; +begin + Result := FDataLink.Field; +end; + +function TJDBIntegerEdit.IsReadOnly: boolean; +begin + if FDatalink.Active then + Result := not FDatalink.CanModify + else + Result := False; +end; + +function TJDBIntegerEdit.getFormat: string; +begin + Result := fFormat; +end; + +procedure TJDBIntegerEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + if not Focused then + formatInput; +end; + +procedure TJDBIntegerEdit.formatInput; +begin + if Font.Color <> fNColor then + fPColor := Font.Color; // store original font color + if FDataLink.Field <> nil then + begin + //FDataLink.Field.DisplayText -> formatted (tdbgridcolumns/persistent field DisplayFormat + if FDataLink.Field.IsNull then + Caption := '' + else + if fFormat <> '' then + Caption := FormatFloat(fFormat, FDataLink.Field.AsInteger) + else + Caption := FDataLink.Field.DisplayText; + if FDataLink.Field.AsInteger < 0 then + font.Color := fNColor + else + font.Color := fPColor; + end + else + begin + Caption := 'nil'; + font.Color := fPColor; + end; +end; + +function TJDBIntegerEdit.GetReadOnly: boolean; +begin + Result := FDataLink.ReadOnly; +end; + +procedure TJDBIntegerEdit.SetReadOnly(Value: boolean); +begin + inherited; + FDataLink.ReadOnly := Value; +end; + +procedure TJDBIntegerEdit.SetDataField(const Value: string); +begin + FDataLink.FieldName := Value; +end; + +procedure TJDBIntegerEdit.SetDataSource(Value: TDataSource); +begin + if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then + ChangeDataSource(Self, FDataLink, Value); +end; + +procedure TJDBIntegerEdit.CMGetDataLink(var Message: TLMessage); +begin + Message.Result := PtrUInt(FDataLink); // Delphi dbctrls compatibility? +end; + +function TJDBIntegerEdit.IsValidInteger(const Value: string): boolean; +begin + if StrToIntDef(Value, MaxInt) = MaxInt then + Result := False + else + Result := True; +end; + +procedure TJDBIntegerEdit.Loaded; +begin + inherited Loaded; + if (csDesigning in ComponentState) then + DataChange(Self); +end; + +procedure TJDBIntegerEdit.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + // clean up + if (Operation = opRemove) then + begin + if (FDataLink <> nil) and (AComponent = DataSource) then + DataSource := nil; + end; +end; + +procedure TJDBIntegerEdit.ActiveChange(Sender: TObject); +begin + if FDatalink.Active then + datachange(Sender) + else + Text := ''; +end; + +procedure TJDBIntegerEdit.KeyDown(var Key: word; Shift: TShiftState); +begin + inherited KeyDown(Key, Shift); + if Key = VK_ESCAPE then + begin + FDataLink.Reset; + SelectAll; + Key := VK_UNKNOWN; + end + else + if Key in [VK_DELETE, VK_BACK] then + begin + if not IsReadOnly then + FDatalink.Edit + else + Key := VK_UNKNOWN; + end; +end; + +procedure TJDBIntegerEdit.KeyPress(var Key: char); +begin + if not FieldIsEditable(Field) or not FDatalink.Edit then + Key := #0; + if not (Key in ['0'..'9', #8, #9, '-']) then + Key := #0; + inherited KeyPress(Key); +end; + +procedure TJDBIntegerEdit.DoEnter; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if FDataLink.Field <> nil then + Caption := FDataLink.Field.AsString; + inherited DoEnter; +end; + +constructor TJDBIntegerEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + ControlStyle := ControlStyle + [csReplicatable]; + FDataLink := TFieldDataLink.Create; + FDataLink.Control := Self; + FDataLink.OnDataChange := @DataChange; + FDataLink.OnUpdateData := @UpdateData; + FDataLInk.OnActiveChange := @ActiveChange; + fPColor := Font.Color; + fNColor := Font.Color; +end; + +destructor TJDBIntegerEdit.Destroy; +begin + FDataLink.Free; + FDataLink := nil; + inherited Destroy; +end; + +procedure TJDBIntegerEdit.EditingDone; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if DataSource.State in [dsEdit, dsInsert] then + UpdateData(self) + else + formatInput; + inherited EditingDone; +end; + +end. diff --git a/components/jujiboutils/src/jdbintegeredit_icon.lrs b/components/jujiboutils/src/jdbintegeredit_icon.lrs new file mode 100644 index 000000000..93416c9fa --- /dev/null +++ b/components/jujiboutils/src/jdbintegeredit_icon.lrs @@ -0,0 +1,27 @@ +LazarusResources.Add('TJDBIntegerEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#2#25'IDATH'#199#213#148'1h'#19'q'#20#198#127'WBBA'#154#180#218#4'*'#141'$' + +'P'#12'X'#227#144'C'#16'K'#135't'#19#193#185'd'#16'l'#157#28#196'%'#29#10#210 + +#165#131#14'Eq'#12#29#28'J'#231'B'#29#205'P'#211#165'd1'#164' '#132#198'&%'#5 + +#143'P'#147'&'#197'$'#228#238#239' w\'#146'k0'#151':'#248'-'#239#189#187'?' + +#223'w'#239#251#191'w'#240#143'!'#153#139#237#189'S'#145#216#205'['#30'|'#254 + +'8'#200#226#252#148'dK'#192'L'#252#254#197'=f'#253#215#200#22#235'('#149'&J' + +#181#133'Ri'#178#147'*'#217#18'r'#0'$v'#243#132'g&'#8#248'FQ*M'#178#240'''' + +#22'j'#0'('#213#22#225#153#9#234#141'6'#151'u'#216'W 8=F&wF&'#7'^O'#16#192' ' + +#7#184'h'#168'drg'#182#238#192#161''''#15#238'N'#226'u;/'#253#194'''s7'#249 + +#254#227#23#245'F'#155#228#160#2#249#147's|'#158'I'#0'Vc!'#162#225#235'd'#139 + +'u'#146'_'#203'x=.'#148'J'#19#128#128'o'#212#184#139#129'-:8,'#163'j'#130#217 + +'[!'#203#131':qpzl'#240#14#0#238#223#185#129#215#237'd}'#235#27#235'['#214#22 + +#153#133#174#196'"'#243#152'*'#213#22#23#13#213#222#162'-'#127#200#136'B'#169 + +#134#170#9'Vc!'#142#211#159#174'd'#139#151#150#158'J'#134#128#207#227#194#235 + +'v'#178#147'*'#17#187'}D6'#243'e('#242#181#181#215#184#199#253#146#3#160'P' + +#170#225#243#184#12#139#142#211'G'#0'l'#188'K'#216#22'8'#175#156#0'0'#2#240 + +#236'Q'#128#131#195#178#229#5'.'#172#236#27'Q'#207#219#170#214'Q'#3#200#178 + +#220#17'-'#177#189'w*'#162#241#148#216#220#252'(^'#189'\'#22'B'#8#17#141#167 + +#132#25#209'xJh'#154#214'Q'#235#136'D"F^'#253'Y'#20'F'#7':'#22#231#167#164 + +#228#219'9'#203#31#153#16#162#167#238'~'#214'w'#15#250'A''ZX'#217#231#243#155 + +#135#29#214#233#245'P'#2#146'$'#245#8#154#133#250#137#140#252#237'T'#152#137 + +#186#5#135#238#160#173'j='#182't[$'#203'2'#233't'#218#136'}a'#158'"'#187#208 + +#167#200#178'W'#253#229#176'p'#143#251'%'#254'{'#252#6#186#199'k~'#228':F-'#0 + +#0#0#0'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jdbtimeedit.pas b/components/jujiboutils/src/jdbtimeedit.pas new file mode 100644 index 000000000..c188240ee --- /dev/null +++ b/components/jujiboutils/src/jdbtimeedit.pas @@ -0,0 +1,343 @@ +{ JDBTimeEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit JDBTimeEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, LResources, Controls, StdCtrls, DB, DBCtrls, LMessages, LCLType, Dialogs, + SysUtils, jcontrolutils, jinputconsts, jdbutils; + +type + TJDBTimeEdit = class(TCustomEdit) + private + fFormat: string; + FDataLink: TFieldDataLink; + + procedure DataChange(Sender: TObject); + procedure UpdateData(Sender: TObject); + procedure FocusRequest(Sender: TObject); + + function GetDataField: string; + function GetDataSource: TDataSource; + function GetField: TField; + + function IsReadOnly: boolean; + + function getFormat: string; + procedure setFormat(const AValue: string); + procedure formatInput; + + procedure SetDataField(const Value: string); + procedure SetDataSource(Value: TDataSource); + procedure CMGetDataLink(var Message: TLMessage); message CM_GETDATALINK; + + protected + procedure Loaded; override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure ActiveChange(Sender: TObject); virtual; + procedure KeyDown(var Key: word; Shift: TShiftState); override; + procedure KeyPress(var Key: char); override; + procedure DoEnter; override; + function GetReadOnly: boolean; override; + procedure SetReadOnly(Value: boolean); override; + + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + procedure EditingDone; override; + property Field: TField read GetField; + + published + property DisplayFormat: string read getFormat write setFormat; + property DataField: string read GetDataField write SetDataField; + property DataSource: TDataSource read GetDataSource write SetDataSource; + property ReadOnly: boolean read GetReadOnly write SetReadOnly default False; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + +procedure Register; +begin + {$I jdbtimeedit_icon.lrs} + RegisterComponents('JujiboDB', [TJDBTimeEdit]); +end; + +procedure TJDBTimeEdit.DataChange(Sender: TObject); +begin + if FDataLink.Field <> nil then + begin + if not Focused then + formatInput + else + Caption := FDataLink.Field.AsString; + end + else + Text := ''; +end; + +procedure TJDBTimeEdit.UpdateData(Sender: TObject); +var + theValue: string; +begin + if FDataLink.Field <> nil then + begin + theValue := NormalizeTime(Text, FDataLink.Field.AsDateTime); + if Text = '' then + begin + Field.Value := Null; + end + else + if IsValidTimeString(theValue) then + begin + FDataLink.Field.Text := theValue; + end + else + begin + ShowMessage(Format(SInvalidTime, [Text])); + Caption := FDataLink.Field.AsString; + SelectAll; + SetFocus; + end; + end + else + Text := ''; +end; + +procedure TJDBTimeEdit.FocusRequest(Sender: TObject); +begin + SetFocus; +end; + +function TJDBTimeEdit.GetDataField: string; +begin + Result := FDataLink.FieldName; +end; + +function TJDBTimeEdit.GetDataSource: TDataSource; +begin + Result := FDataLink.DataSource; +end; + +function TJDBTimeEdit.GetField: TField; +begin + Result := FDataLink.Field; +end; + +function TJDBTimeEdit.IsReadOnly: boolean; +begin + if FDatalink.Active then + Result := not FDatalink.CanModify + else + Result := False; +end; + +function TJDBTimeEdit.getFormat: string; +begin + Result := fFormat; +end; + +procedure TJDBTimeEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + if not Focused then + formatInput; +end; + +procedure TJDBTimeEdit.formatInput; +begin + if FDataLink.Field <> nil then + if (fFormat <> '') and (not FDataLink.Field.IsNull) then + Caption := FormatDateTime(fFormat, FDataLink.Field.AsDateTime) + else + Caption := FDataLink.Field.DisplayText + else + Caption := 'nil'; +end; + +function TJDBTimeEdit.GetReadOnly: boolean; +begin + Result := FDataLink.ReadOnly; +end; + +procedure TJDBTimeEdit.SetReadOnly(Value: boolean); +begin + inherited; + FDataLink.ReadOnly := Value; +end; + +procedure TJDBTimeEdit.SetDataField(const Value: string); +begin + FDataLink.FieldName := Value; +end; + +procedure TJDBTimeEdit.SetDataSource(Value: TDataSource); +begin + if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then + ChangeDataSource(Self, FDataLink, Value); +end; + +procedure TJDBTimeEdit.CMGetDataLink(var Message: TLMessage); +begin + Message.Result := PtrUInt(FDataLink); // Delphi dbctrls compatibility? +end; + +procedure TJDBTimeEdit.Loaded; +begin + inherited Loaded; + if (csDesigning in ComponentState) then + DataChange(Self); +end; + +procedure TJDBTimeEdit.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + // clean up + if (Operation = opRemove) then + begin + if (FDataLink <> nil) and (AComponent = DataSource) then + DataSource := nil; + end; +end; + +procedure TJDBTimeEdit.ActiveChange(Sender: TObject); +begin + if FDatalink.Active then + datachange(Sender) + else + Text := ''; +end; + +procedure TJDBTimeEdit.KeyDown(var Key: word; Shift: TShiftState); +begin + inherited KeyDown(Key, Shift); + if Key = VK_ESCAPE then + begin + FDataLink.Reset; + SelectAll; + Key := VK_UNKNOWN; + end + else + if Key in [VK_DELETE, VK_BACK] then + begin + if not IsReadOnly then + FDatalink.Edit + else + Key := VK_UNKNOWN; + end; +end; + +procedure TJDBTimeEdit.KeyPress(var Key: char); +begin + if not FieldIsEditable(Field) or not FDatalink.Edit then + Key := #0; + if not (Key in ['0'..'9', #8, #9, ':']) then + Key := #0; + inherited KeyPress(Key); +end; + +procedure TJDBTimeEdit.DoEnter; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if FDataLink.Field <> nil then + Caption := FDataLink.Field.AsString; + inherited DoEnter; +end; + +constructor TJDBTimeEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + ControlStyle := ControlStyle + [csReplicatable]; + FDataLink := TFieldDataLink.Create; + FDataLink.Control := Self; + FDataLink.OnDataChange := @DataChange; + FDataLink.OnUpdateData := @UpdateData; + FDataLInk.OnActiveChange := @ActiveChange; + // Set default values + //fFormat := ShortDateFormat; +end; + +destructor TJDBTimeEdit.Destroy; +begin + FDataLink.Free; + FDataLink := nil; + inherited Destroy; +end; + +procedure TJDBTimeEdit.EditingDone; +begin + if not FieldIsEditable(Field) or IsReadOnly then + exit; + if DataSource.State in [dsEdit, dsInsert] then + UpdateData(self) + else + formatInput; + inherited EditingDone; +end; + +end. + diff --git a/components/jujiboutils/src/jdbtimeedit_icon.lrs b/components/jujiboutils/src/jdbtimeedit_icon.lrs new file mode 100644 index 000000000..2840ed76b --- /dev/null +++ b/components/jujiboutils/src/jdbtimeedit_icon.lrs @@ -0,0 +1,48 @@ +LazarusResources.Add('TJDBTimeEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#4'7IDATH'#199#213#149']LSg'#28#198#127#231#180'P('#20'ZJ'#219'!'#131'Np' + +#232#228'c.0@a:'#171#217#140'#'#19#179'Mc'#188#218#208',q'#23#139#187#128'%\' + +'ns'#171#198'}'#196'e7L'#18']2'#183'e'#9's#f1'#2#25'+'#31'Jc'#2'T&S'#208#162 + +'0'#173#29#22#10#148'B{'#222']'#176'6et'#139#209#171'='#201#201'9'#239#199 + +#249'?'#239#251';O'#206'+'#241#16#234#248#230#168'M'#163#154'i'#212'$-lP%' + +#168't'#225#144' 0'#27#152#156#157#161'7'#16'J'#182#215#190'y'#164'''2W'#138 + +'}'#241'L'#231#132'hj'#29#141'['#244'`M'#30#251'6'#175#146':'#191';'#242#133 + +'^?]g'#176#214'&j'#210'Lh'#180#6#132'P'#152#241'M0y{'#136#137#171#29#179'S' + +#254#4#251#222#195#159#191#23'5'#136'-'#252#217'[OS'#148#155#138'kl'#6#143'/' + +#136'gj'#1#143'/'#200'Y'#199'8/>~'#157'W6'#5#200#176#238#228#222#156#142#193 + +#145')<'#247#231#8#133#5#6']'#18#133#249#169#24#196'('#191'u'#158#230#174'''' + +'T'#255'z'#227#151#199'$'#0'['#189'C'#148'<'#153#193'jK2EV'#29'f'#189#134#246 + +'~/f'#189'&j'#146#24#244#176#195#252'#'#249#21#135#24#154#208#224#245#5')Y' + +#147#129'>MF 19'#21#198'dN'#229#151#139'n'#158'J'#27#198#217'zj.'#160#202#168 + +'V'#3#228#229#164'1pm'#146#129'k`'#214#231#225'r'#251#1#162#197#159'I'#30'$E' + +#244#145'U'#252'*rz.w\n'#182'WYa'#222#143'wf'#134'L'#163#25#147'y'#9#229#150 + +#10'+C'#195'*,'#171#179#181'#W'''#222#145'#'#140'7'#22#155#216'U'#157'MS'#235 + +'(g'#29#227#209#171'g'#240#30#227#137#165#0#168'e-'#0'E'#5'F'#218'[[ IG'#166 + +#209'L{k'#11'j'#22#1'p'#141#249#233#25#242#241'XA9*'#177'P-'#3#140#222#154 + +#142'~'#204#198#253#235'h'#179'W'#177#171':'#155#198#253#235'8X'#147#23#29#11 + +')s'#0#24#141#201#216'jvG'#251#231#229#4'>'#248#208#14#128#193#172#229#143 + +#201'y'#210'MO'#160'B'#178#200#17'D'#151#174'x9'#235#24#255#215'h'#134#231 + +#166#209#166'dr'#226#204#0#193'0K;'#248'[I'#202'"/'#213'.'#25#6'C'#176#184 + +#168' '#148'y'#132'"'#150'Rt'#224#196#128#176#232'5'#152#211#19#227#154#28'*' + +#191'C'#202'\'#31#0#21'{'#142'0x'#203'Oq'#142#142#217#133'0'#131#151#251#168 + +#172#172'dA-'#147#24'R'#0'8'#254#149#147#215#214'^'#164#235#167#246'['#234#8 + +'"'#139#222#20'Ed+1.'#139#233#184'/'#27#233#246'MJ'#178#188'\'#29#30#161'gX' + +#176'>?'#157#20'Y'#166#250#185'M '#129#164'@(A'#230#147#175#127'gK'#161#140 + +#251'r7'#139'B'#221#171#142'E'#20'V'#4'E'#214'u47'#159'^'#182#131'T'#128'$-' + +#238'a7'#21#249#189#228#232#10'i'#254'~'#152#23#158#181#176#198#146#2#2#198 + +'<'#179#180#246#222'!7'#217#139')'#208'A'#247'h'#0')'#217'x,.'#162#253'kGp' + +#13#252#186#2#149'1I!'#207#224'g'#195#243'['#185'+'#151#211's%'#132#207#31'&' + +#172#8'tZ'#216#184'^'#144#25' '#132#16#194'V'#239'Xv'#143#200'V'#239#16#138 + +#162',k'#11'!Dii'#169#16'B'#136#169#251'c'#2'@'#142'5'#216#183'y'#149#212'~' + +#180'Z'#250#175'_'#181#16'bE'#251#159'}'#177'R?'#232#25'p'#225#163'Mq'#177'm' + +'k'#232#2'X'#134'1V'#242#131#26'l'#127#183'{'#233#0#145#164'e'#171'o'#179'W' + +#209'f'#175#138#26'='#180'A'#188#213#199#154'=2'#162'X'#4#177'Xb'#159#203#202 + +#202'p:'#157#148#149#149#197'OQD'#177')zXER'#20'w'#143#145#193'GU'#186'!W' + +#226#127#175#191#0#16'{CjJ'#170#9'F'#0#0#0#0'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jfloatedit.pas b/components/jujiboutils/src/jfloatedit.pas new file mode 100644 index 000000000..c6d4cd03f --- /dev/null +++ b/components/jujiboutils/src/jfloatedit.pas @@ -0,0 +1,256 @@ +{ JFloatEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit JFloatEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Graphics, + Dialogs, jinputconsts; + +type + + { TJFloatEdit } + + TJFloatEdit = class(TCustomEdit) + private + fNColor: TColor; + fPColor: TColor; + theValue: double; + fFormat: string; + fEFormat: string; + fDecimals: integer; + function getDecimals: integer; + function getFormat: string; + function getValue: double; + function getCurrentValue: double; + procedure formatInput; + procedure setDecimals(const AValue: integer); + procedure setFormat(const AValue: string); + function scaleTo(const AValue: double; const NDecimals: integer): double; + function IsValidFloat(const Value: string): boolean; + procedure setNegativeColor(AValue: TColor); + procedure setValue(const AValue: double); + protected + procedure DoEnter; override; + procedure DoExit; override; + procedure KeyPress(var Key: char); override; + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + property CurrentValue: double read getCurrentValue; + published + property DisplayFormat: string read getFormat write setFormat; + property EditFormat: string read fEFormat write fEFormat; + property Decimals: integer read getDecimals write setDecimals; + property Value: double read getValue write setValue; + property NegativeColor: TColor read fNColor write setNegativeColor; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ReadOnly; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + +uses + Math; + +procedure Register; +begin + {$I jfloatedit_icon.lrs} + RegisterComponents('Jujibo', [TJFloatEdit]); +end; + +function TJFloatEdit.getDecimals: integer; +begin + Result := fDecimals; +end; + +function TJFloatEdit.getFormat: string; +begin + Result := fFormat; +end; + +function TJFloatEdit.getValue: double; +begin + Result := theValue; +end; + +function TJFloatEdit.getCurrentValue: double; +begin + Result := StrToFloatDef(Text, Value); +end; + +procedure TJFloatEdit.formatInput; +begin + if Font.Color <> fNColor then + fPColor := Font.Color; // store original font color + Caption := FormatFloat(DisplayFormat, theValue); + if theValue < 0 then + font.Color := fNColor + else + font.Color := fPColor; +end; + +procedure TJFloatEdit.setDecimals(const AValue: integer); +begin + if (AValue >= 0) and (AValue < 12) then + fDecimals := AValue; +end; + +procedure TJFloatEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + formatInput; +end; + +function TJFloatEdit.scaleTo(const AValue: double; + const NDecimals: integer): double; +begin + Result := round(AValue * power(10, NDecimals)) / power(10, NDecimals); +end; + +function TJFloatEdit.IsValidFloat(const Value: string): boolean; +begin + if StrToFloatDef(Value, MaxDouble) = MaxDouble then + Result := False + else + Result := True; +end; + +procedure TJFloatEdit.setNegativeColor(AValue: TColor); +begin + if fNColor = AValue then + Exit; + fNColor := AValue; + formatInput; +end; + +procedure TJFloatEdit.setValue(const AValue: double); +begin + if fDecimals > 0 then + theValue := scaleTo(AValue, fDecimals) + else + theValue := AValue; + formatInput; +end; + +procedure TJFloatEdit.DoEnter; +begin + inherited DoEnter; + if ReadOnly then + exit; + if EditFormat <> '' then + Text := FormatFloat(EditFormat, theValue) + else + Text := FloatToStr(theValue); + SelectAll; +end; + +procedure TJFloatEdit.DoExit; +begin + inherited DoExit; + if ReadOnly then + exit; + if IsValidFloat(Text) then + theValue := StrToFloat(Text) + else + begin + ShowMessage(Format(SInvalidNumber, [Text])); + SetFocus; + end; + if fDecimals > 0 then + theValue := scaleTo(theValue, fDecimals); + formatInput; +end; + +procedure TJFloatEdit.KeyPress(var Key: char); +begin + if (Key in ['.', ',']) then + Key := DefaultFormatSettings.Decimalseparator; + if (key = DefaultFormatSettings.DecimalSeparator) and (Pos(key, Text) > 0) then + key := #0; + if not (Key in ['0'..'9', DefaultFormatSettings.DecimalSeparator, + '+', '-', #8, #9]) then + Key := #0; + inherited KeyPress(Key); +end; + +constructor TJFloatEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + Text := ''; + fEFormat := ''; + fFormat := '#,0.00'; + fDecimals := 2; + fPColor := Font.Color; + fNColor := Font.Color; + formatInput; +end; + +destructor TJFloatEdit.Destroy; +begin + inherited Destroy; +end; + +end. diff --git a/components/jujiboutils/src/jfloatedit_icon.lrs b/components/jujiboutils/src/jfloatedit_icon.lrs new file mode 100644 index 000000000..edf7ef619 --- /dev/null +++ b/components/jujiboutils/src/jfloatedit_icon.lrs @@ -0,0 +1,14 @@ +LazarusResources.Add('TJFloatEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#0#233'IDATH'#199#237#148'='#18#130'0'#16#133'7'#14#189#227#5#188#4#233#232 + +#240' '#22#177'wl'#176'shi'#28'{'#135#130#131'P'#137#29#149#227#9#244#0#254 + +#212#202#179'Z'#135#240#163'Dl'#152#225'k'#146#183#201#188#205'&;!'#234#233 + +#233#233'>'#162'*'#24#134#17#254'a'#174#212'TXu'#139#199#195#174#149#185#239 + +#175'H)"'#235#211#166#245'f'#251's'#130#251#245'LDD'#131'o'#27''''#203'}Is' + +#236#241#204'4-'#165#212#198'Z'#194'0'#194'b>'#3#0#184'^'#130'*\/A'#150'e' + +#154#6#0#219#182#1#0#183#203#9#141'*('#2#160#164#139#177'<'#150#137#177#16 + +#226'}Mq'#224'hW'#200#186'H'#227#10#216#156'GN'#26#7#14#197#129'Sz+'#227#4 + +#249'G'#230#211#230#147#213'101'#174#234'$'#158#199#129'CRJJ'#211#212#172#139 + +#138']'#210#20#238#162#202#26'y'#177'-'#195#209'Xt'#255'7}'#1'gj'#198#221#220 + +#206#141#188#0#0#0#0'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jintegeredit.pas b/components/jujiboutils/src/jintegeredit.pas new file mode 100644 index 000000000..6fca9dbb6 --- /dev/null +++ b/components/jujiboutils/src/jintegeredit.pas @@ -0,0 +1,238 @@ +{ JIntegerEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit JIntegerEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Graphics, + Dialogs, jinputconsts; + +type + + { TJIntegerEdit } + + TJIntegerEdit = class(TCustomEdit) + private + fNColor: TColor; + fPColor: TColor; + fNull: boolean; + theValue: integer; + fFormat: string; + function getFormat: string; + function getValue: integer; + function getCurrentValue: integer; + procedure setFormat(const AValue: string); + procedure setNegativeColor(AValue: TColor); + procedure setValue(const AValue: integer); + function IsValidInteger(const Value: string): boolean; + procedure FormatInput; + protected + procedure DoEnter; override; + procedure DoExit; override; + procedure KeyPress(var Key: char); override; + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + function isNull: boolean; + property CurrentValue: integer read getCurrentValue; + published + property DisplayFormat: string read getFormat write setFormat; + property Value: integer read getValue write setValue; + property AllowNull: boolean read fNull write fNull default False; + property NegativeColor: TColor read fNColor write setNegativeColor; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ReadOnly; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + end; + +procedure Register; + +implementation + + +procedure Register; +begin + {$I jintegeredit_icon.lrs} + RegisterComponents('Jujibo', [TJIntegerEdit]); +end; + +{ TJIntegerEdit } + +function TJIntegerEdit.getFormat: string; +begin + Result := fFormat; +end; + +function TJIntegerEdit.getValue: integer; +begin + Result := theValue; +end; + +function TJIntegerEdit.getCurrentValue: integer; +begin + Result := StrToIntDef(Text, Value); +end; + +procedure TJIntegerEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + formatInput; +end; + +procedure TJIntegerEdit.setNegativeColor(AValue: TColor); +begin + if fNColor = AValue then + Exit; + fNColor := AValue; + FormatInput; +end; + +procedure TJIntegerEdit.setValue(const AValue: integer); +begin + theValue := AValue; + formatInput; +end; + +function TJIntegerEdit.IsValidInteger(const Value: string): boolean; +begin + if StrToIntDef(Value, MaxInt) = MaxInt then + Result := False + else + Result := True; +end; + +procedure TJIntegerEdit.FormatInput; +begin + if Font.Color <> fNColor then + fPColor := Font.Color; // store original font color + if isNull then + begin + Text := ''; + font.Color := fNColor; + end + else + begin + Text := FormatFloat(fFormat, theValue); + if theValue < 0 then + font.Color := fNColor + else + font.Color := fPColor; + end; +end; + +procedure TJIntegerEdit.DoEnter; +begin + inherited DoEnter; + if ReadOnly then + exit; + if not isNull then + Text := IntToStr(theValue); + SelectAll; +end; + +procedure TJIntegerEdit.DoExit; +begin + inherited DoExit; + if ReadOnly then + exit; + if fNull and (Length(Caption) = 0) then + theValue := Low(integer) // min integer value means null + else + if IsValidInteger(Text) then + theValue := StrToInt(Text) + else + begin + ShowMessage(Format(SInvalidNumber, [Text])); + SetFocus; + end; + formatInput; +end; + +procedure TJIntegerEdit.KeyPress(var Key: char); +begin + if not (Key in ['0'..'9', #8, #9, '-']) then + Key := #0; + inherited KeyPress(Key); +end; + +constructor TJIntegerEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + // Set initial values + Text := ''; + DisplayFormat := '0'; + Value := 0; + fPColor := Font.Color; + fNColor := Font.Color; +end; + +destructor TJIntegerEdit.Destroy; +begin + inherited Destroy; +end; + +function TJIntegerEdit.isNull: boolean; +begin + Result := fNull and (theValue = Low(integer)); +end; + +end. diff --git a/components/jujiboutils/src/jintegeredit_icon.lrs b/components/jujiboutils/src/jintegeredit_icon.lrs new file mode 100644 index 000000000..33e03db40 --- /dev/null +++ b/components/jujiboutils/src/jintegeredit_icon.lrs @@ -0,0 +1,13 @@ +LazarusResources.Add('TJIntegerEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#0#219'IDATH'#199'c`'#24#5#163'`'#20#12'}'#192#136'Mp'#238#220#133#255#169 + +'axrr<#'#11'.'#201'+'#151#14'SdxCC'#29'Cr2'#3#3#11'>E}'#19'f'#147'm'#193#167 + +#15#143#25#24#24#24#24#152#8')t.?'#10#167'a'#236'?'#127#255#161#240#25#24#24 + +#24'LLLPh'#188'`'#238#220#133#255#11#243'S'#254#255#255#255#255#191'S'#217 + +#145#255#200#192#169#236#200#255#127#255#254#161#240'a'#192#216#216#24#206 + +#254#248#254#209#127#162'|'#0#3#255#255#255#199#224#163#139'a'#3','#164#24 + +#238'\~'#148'ao'#167'5J'#208#193#248#20'Y'#192#200#200#136'a!'#178'E'#248',!' + +':'#136#144#13'B'#183#144'b'#31#252#249#251#15'#X'#208#131#200#196#196#132 + +#225#204#153'3p'#154#232'TD.'#128#165'"'#172'~'#133'IR'#10#248#5#229#24#135 + +'~i'#10#0#129#153#202#187#129't'#210#19#0#0#0#0'IEND'#174'B`'#130 +]); diff --git a/components/jujiboutils/src/jtimeedit.pas b/components/jujiboutils/src/jtimeedit.pas new file mode 100644 index 000000000..30ca8e574 --- /dev/null +++ b/components/jujiboutils/src/jtimeedit.pas @@ -0,0 +1,230 @@ +{ TJTimeEdit + + Copyright (C) 2011 Julio Jiménez Borreguero + Contact: jujibo at gmail dot com + + This library is free software; you can redistribute it and/or modify it + under the same terms as the Lazarus Component Library (LCL) + + See the file license-jujiboutils.txt and COPYING.LGPL, included in this distribution, + for details about the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +} + +unit JTimeEdit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Graphics, + Dialogs, jcontrolutils, jinputconsts; + +type + + { TJTimeEdit } + + TJTimeEdit = class(TCustomEdit) + private + theValue: TTime; + hasValue: boolean; + fFormat: string; + function getFormat: string; + function getValue: TTime; + function getCurrentValue: TTime; + procedure setFormat(const AValue: string); + procedure setValue(const AValue: TTime); + procedure FormatInput; + protected + procedure DoEnter; override; + procedure DoExit; override; + procedure KeyPress(var Key: char); override; + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + property CurrentValue: TTime read getCurrentValue; + published + function isNull: boolean; + property DisplayFormat: string read getFormat write setFormat; + property Value: TTime read getValue write setValue; + + property Action; + property Align; + property Alignment; + property Anchors; + property AutoSelect; + property AutoSize; + property BidiMode; + property BorderSpacing; + property BorderStyle; + property CharCase; + property Color; + property Constraints; + property DragCursor; + property DragMode; + property Enabled; + property Font; + property MaxLength; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ReadOnly; + property ShowHint; + property TabOrder; + property TabStop; + property Visible; + property OnChange; + property OnClick; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnEditingDone; + property OnEndDrag; + property OnEnter; + property OnExit; + property OnKeyDown; + property OnKeyPress; + property OnKeyUp; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + property OnUTF8KeyPress; + + end; + +procedure Register; + +implementation + +procedure Register; +begin + {$I jtimeedit_icon.lrs} + RegisterComponents('Jujibo', [TJTimeEdit]); +end; + + +function TJTimeEdit.getFormat: string; +begin + Result := fFormat; +end; + +function TJTimeEdit.getValue: TTime; +begin + Result := theValue; +end; + +function TJTimeEdit.getCurrentValue: TTime; +var + aText: string; + aValue: TTime; +begin + aText := NormalizeTime(Text, theValue); + if Length(aText) = 0 then + begin + aValue := 0; + end + else + if IsValidTimeString(aText) then + begin + aValue := StrToTime(aText); + end + else + begin + aValue := Value; + end; + Result:= aValue; +end; + +procedure TJTimeEdit.setFormat(const AValue: string); +begin + fFormat := AValue; + formatInput; +end; + +procedure TJTimeEdit.setValue(const AValue: TTime); +begin + theValue := AValue; + hasValue := True; + formatInput; +end; + +procedure TJTimeEdit.FormatInput; +begin + if hasValue then + Text := FormatDateTime(fFormat, theValue) + else + Text := ''; +end; + +procedure TJTimeEdit.DoEnter; +begin + inherited DoEnter; + if ReadOnly then + exit; + if not hasValue then + Text := '' + else + Text := TimeToStr(theValue); + SelectAll; +end; + +procedure TJTimeEdit.DoExit; +begin + inherited DoExit; + if ReadOnly then + exit; + Text := NormalizeTime(Text, theValue); + if Length(Text) = 0 then + begin + theValue := 0; + hasValue := False; + end + else + if IsValidTimeString(Text) then + begin + theValue := StrToTime(Text); + hasValue := True; + end + else + begin + ShowMessage(Format(SInvalidTime, [Text])); + SetFocus; + end; + formatInput; +end; + +procedure TJTimeEdit.KeyPress(var Key: char); +begin + if not (Key in ['0'..'9', #8, #9, ':']) then + Key := #0; + inherited KeyPress(Key); +end; + +constructor TJTimeEdit.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + Text := ''; + DisplayFormat := 'hh:mm:ss'; + Value := 0; + hasValue := True; +end; + +destructor TJTimeEdit.Destroy; +begin + inherited Destroy; +end; + +function TJTimeEdit.isNull: boolean; +begin + Result := not hasValue; +end; + +end. + diff --git a/components/jujiboutils/src/jtimeedit_icon.lrs b/components/jujiboutils/src/jtimeedit_icon.lrs new file mode 100644 index 000000000..8b90515fb --- /dev/null +++ b/components/jujiboutils/src/jtimeedit_icon.lrs @@ -0,0 +1,40 @@ +LazarusResources.Add('TJTimeEdit','PNG',[ + #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0 + +#0#3'TIDATH'#199#213#146']l'#147'e'#20#199#127#253'x'#215#174'['#187'~@&'#136 + +'ld'#179#137't[4'#27#5#3#154#217#197#15'F'#162'#'#13'z'#227#133'd&K4'#145'`' + +#204'0rc4'#162'Sc0!'#222#200'L'#166'7h'#210#136#17#135'C'#177#132#13'VG'#193 + +#8#163#162'('#19#152's'#31#165#31#235#247#250#246'}'#188#128'.s'#29#179'cW' + +#254'o'#222#231#156#243#228#252#158#243#127#143#138';'#144#247#208#187'.'#157 + +'&'#190'W'#167#159#185'_#i'#140'9Y'#144'J'#164'B'#137'8'#190#148'\'#218#213 + +#214#177'o0'#127'W'#181#212#230''''#191#216#247#145#217'<'#221'n'#169'j+'#209 + +#153'V'#162'3X'#16'B!'#30#25'#4'#26'`'#236#146'7'#17#141'I]'#207#236'>'#240 + +#230#146#1''''#14#189#245#225#154'Z'#235'K'#214#170'V'#166#146'F.'#252#17'e2' + +#156'D'#206#9',F='#142#154'r,'#226#10#191#156#252#148#137'I'#185's'#231#222 + +#131#239#21#13#232#251#236#157'-6s'#240#135'j'#231#139'R`LG0'#146#161#161#214 + +#138#217#164'F'#160'"'#20#205'1ti'#138'r'#157#154#251'L'#191#226'?'#210#147 + +'Li'#172'['#212#197#2'4J'#248#181#138'5-'#210'T'#202#196'x('#205#246#230'j' + +#172'FA('#30#167#220'T'#198#218'{L<'#251'h'#13#19'1'#133#160'z='#149#235#238 + +'6'#228#146#225#151#139#6'd'#229#204#214#223#207#245'q'#209#239#165#206'n'#3 + +'@'#146'$'#190#235#251#22'='#160#191'u'#175'c['#13#131#129#8'w'#217#157'h' + +#196'L'#241#19#148'h'#229#244#198#167'^aT'#185#23#155#173#20#143#199'C'#185 + +#193#192#11';'#159#195#227#241#240#234#235'o'#0'0'#28#205#242'w(M'#197#202'j' + +'4'#168'*'#139#6#204#200'Z'#253#143'_'#189#15'@&'#7#15#181'n'#159#173#157#185 + +'p'#145'mm7'#227#140#12#217#172#130'P'#210#8'EP4 '#25#13#141#216#157#143#3'0' + +'2'#158#164#191#247#203#217#218#134'z'#7#246#250'z'#0#174#143'''0'#149#169#9 + +#255#245'3i9'#23','#26'`'#168#176#174#251'm'#168#143'];'#26#24#252'i'#2#183 + +#219'M8'#11'1'#5#220'n7'#186'['#247#174#6#174#241#176'C'#205#213#243#167#201 + +#10#173'o'#193'5'#237#238#238#17#133#127'9'#129'v'#178#159#141#173'[9;'#229 + +'`4V'#198'c'#27'*'#169#173','#3#1'W&'#19#28#241#141'c'#147#130'8-^N'#127's' + +#150'\'#169#205#169#189#221#139#135#207#247#23#228'l'#250'R'#164#239#191#230 + +#129#230'8'#171'mN'#142#158#136#16#137#229#200')'#2#163#1#30'\/X'#145'9'#198 + +#208#177'!'#28#205'O'#243#200#147#237'g'#180#139#217#242#193#254#143#11'r~' + +#239'a|'#189#159'c[5'#192#19'v'#7#230'UU dn'#140'^'#230'O'#223'0#A'#137'zW;u' + +#206'M'#0'h'#255#203#251#150'='#167'8'#222#181#153#150'='#167#0'8'#222#213 + +#198#234#154':'#246#31#248#132#21#151#3'XJ'#206#1'pc:E'#195'&'#23#7'{'#15#211 + +#241#246#14#166'#'#215'o'#223#180#187#187'G'#236#222#245#188#16'B'#8'W'#231 + +#128#152'+W'#231#128'P'#20#229'_q^'#141#141#141#179#231'h'#248#154#0#138'_S!' + +'DA