diff --git a/components/jujiboutils/changes.txt b/components/jujiboutils/changes.txt
index 0818a9c0a..fcc3b94ea 100644
--- a/components/jujiboutils/changes.txt
+++ b/components/jujiboutils/changes.txt
@@ -5,6 +5,7 @@ JUJIBOUTILS
Version pre-1.0
--------------------------------------------------
+2011-09-21 Added: TJDBGridControl and example (testgridctr)
2011-09-20 Added: TJIntegerEdit, TJLabeledIntegerEdit
TJCurrencyEdit, TJLabeledCurrencyEdit
TJDateEdit, TJLabeledDateEdit
diff --git a/components/jujiboutils/jujibo-utils/jujibocontrols.lpk b/components/jujiboutils/jujibo-utils/jujibocontrols.lpk
index d6d410841..58fcbf238 100644
--- a/components/jujiboutils/jujibo-utils/jujibocontrols.lpk
+++ b/components/jujiboutils/jujibo-utils/jujibocontrols.lpk
@@ -8,11 +8,17 @@
+
+
+
+
+
+
-
+
@@ -77,6 +83,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/jujiboutils/jujibo-utils/jujibocontrols.pas b/components/jujiboutils/jujibo-utils/jujibocontrols.pas
index 778ea8f53..8ebaf3d75 100644
--- a/components/jujiboutils/jujibo-utils/jujibocontrols.pas
+++ b/components/jujiboutils/jujibo-utils/jujibocontrols.pas
@@ -10,7 +10,7 @@ uses
jdbintegeredit, jdblabeledintegeredit, jdbcurrencyedit,
jdblabeledcurrencyedit, jdbdateedit, jdblabeleddateedit, jcontrolutils,
JIntegerEdit, JLabeledIntegerEdit, JCurrencyEdit, JLabeledCurrencyEdit,
- JDateEdit, JLabeledDateEdit, LazarusPackageIntf;
+ JDateEdit, JLabeledDateEdit, JDBGridControl, jdbgridutils, LazarusPackageIntf;
implementation
@@ -28,6 +28,7 @@ begin
RegisterUnit('JLabeledCurrencyEdit', @JLabeledCurrencyEdit.Register);
RegisterUnit('JDateEdit', @JDateEdit.Register);
RegisterUnit('JLabeledDateEdit', @JLabeledDateEdit.Register);
+ RegisterUnit('JDBGridControl', @JDBGridControl.Register);
end;
initialization
diff --git a/components/jujiboutils/jujibo-utils/src/jdbgridcontrol.pas b/components/jujiboutils/jujibo-utils/src/jdbgridcontrol.pas
new file mode 100644
index 000000000..e72ea93e6
--- /dev/null
+++ b/components/jujiboutils/jujibo-utils/src/jdbgridcontrol.pas
@@ -0,0 +1,77 @@
+unit JDBGridControl;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, LResources, Forms, Controls, Graphics, DB, DBGrids,
+ Dialogs, jdbgridutils;
+
+type
+
+ { TJDBGridControl }
+
+ TJDBGridControl = class(TDBGrid)
+ private
+ { Private declarations }
+ dateDbGridControl: TJDbGridDateCtrl;
+ integerDbGridControl: TJDbGridIntegerCtrl;
+ doubleDbGridControl: TJDbGridDoubleCtrl;
+ protected
+ { Protected declarations }
+ procedure SelectEditor; override;
+ public
+ { Public declarations }
+ constructor Create(TheOwner: TComponent); override;
+ destructor Destroy; override;
+ published
+ { Published declarations }
+
+ end;
+
+procedure Register;
+
+implementation
+
+procedure Register;
+begin
+ {$I jdbgridcontrol_icon.lrs}
+ RegisterComponents('Data Controls', [TJDBGridControl]);
+end;
+
+{ TJDBGridControl }
+
+procedure TJDBGridControl.SelectEditor;
+begin
+ inherited SelectEditor;
+ if Editor <> nil then
+ begin
+ case SelectedField.DataType of
+ ftSmallint, ftInteger: Editor := integerDbGridControl.Editor(Self);
+ ftDate: Editor := dateDbGridControl.Editor(Self); // TODO: ftDateTime ftTime
+ ftCurrency, ftFloat, ftBCD: Editor := doubleDbGridControl.Editor(Self);
+ // TODO: strings?
+ end;
+ end;
+end;
+
+constructor TJDBGridControl.Create(TheOwner: TComponent);
+begin
+ inherited Create(TheOwner);
+ dateDbGridControl := TJDbGridDateCtrl.Create;
+ SelectEditor;
+ integerDbGridControl := TJDbGridIntegerCtrl.Create;
+ doubleDbGridControl := TJDbGridDoubleCtrl.Create;
+end;
+
+destructor TJDBGridControl.Destroy;
+begin
+ dateDbGridControl.Free;
+ integerDbGridControl.Free;
+ doubleDbGridControl.Free;
+ inherited Destroy;
+end;
+
+end.
+
diff --git a/components/jujiboutils/jujibo-utils/src/jdbgridcontrol_icon.lrs b/components/jujiboutils/jujibo-utils/src/jdbgridcontrol_icon.lrs
new file mode 100644
index 000000000..5e5c2731e
--- /dev/null
+++ b/components/jujiboutils/jujibo-utils/src/jdbgridcontrol_icon.lrs
@@ -0,0 +1,49 @@
+LazarusResources.Add('tjdbgridcontrol','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#1'sRGB'#0#174#206#28#233#0#0#0#6'bKGD'#0#255#0#255#0#255#160#189#167#147
+ +#0#0#0#9'pHYs'#0#0#11#19#0#0#11#19#1#0#154#156#24#0#0#0#7'tIME'#7#219#9#20#16
+ +#18#26#255#246#206','#0#0#3#246'IDATH'#199#205#149'_L[U'#28#199'?'#23#26'`'
+ +#225'O'#11#27't'#197#177#133'f'#27#148'A'#209#153#193#22#196#145'e3l{(Y'#140
+ +'4q'#178#196'Db'#226#147#241'aDG'#178',.'#218#140'D'#231#166#209'L'#30'x'#152
+ +#217#147#177#219#18#163#200#164#2#153#27#130#161#22'A'#152'EJ'#219#155#20'&'
+ +#5'Zho{'#239#245'aiC'#217'p'#211#185#196'or'#30#206#249#222's'#190#247#251
+ +#253#253#238'='#130#162'('#8#130#192#147#130#160#170'jrr'#165'OT/]w'#223#247
+ +#144'*K'#28#217'9'#143'47>o0'#24#242#221'n'#183''''#24#12#190#4'L'#235't'#186
+ +#1#163#209'h'#20'Eq'#222#231#243#189#231'r'#185'>q8'#28#225#20#129#213#7#159
+ +#127#163#154#202#173'9'#184'&'#9#165'z'#19#253#209#143'?'#213#249#246#7'c'#177#216'Tb'#191#6#192'='
+ +#179#136'^W'#8#192';/'#151's'#192#188'1Y'#131#209#241't'#6#174'}'#142'fa'#140
+ +#163#7'j'#217#208#184#23#199#202#7'('#242'"'#146#18'''&'#203#20#23'l'#199#180
+ +#185#150#165'H'#152#145'2'#187'6'#222#175's'#164#8#24'K'#242#184'=:'#135#172
+ +#168'Tn+Oq'#176'Q'#191#133#138#134'W'#232#185#246#25#197#133'Z'#178#178'2'#16
+ +'j%'#14'U'#158'@V'#21'dEFA'#197#191'0C'#213#150':B'#210#138#16'<'#238#24'1'
+ +#191#155#150#225'<'#165#168#201#136'jvm'#162'H'#155#193#217#203#227#156#189
+ +#188#182'Q5'#236'{'#241'4'#225#136'L('#18'G'#141#247'!'#171#10#211'w'''#137
+ +')q'#226'J'#140#152#28'c1'#186#196#211'%'#245#132'b'#203#154'[S'#253#17' s'
+ +#221#136#218#218'.'#164'H'#196']'#144#201#189#225#221#30'!.'#199#209#231'm%'
+ +#174#200#200#170#130#184#224#161' g3'#195'3'#3'8'#239'L'#176','#163'{hD'#13
+ +#13#229#184#221#243'46>'#203#204#140'7'#185'~~,J'#215#205#14#162#138'D4.a'
+ +#220'T'#193'^'#227#11#12'N'#247'3'#225#191#131'%'#189#157'C'#7#205#203#128' '
+ +#168#170#202'k'#23#127'Q'#245#186'L'#138#180#25#216#251'}'#0#236#17#134#31
+ +#249'w'#240'M'#246#219'To'#171'e'#228#183#9#14#202'o'#146#142#134#163#135#171
+ +#169#223#255#188#160#1#152#246'-'#161#215'e'#174#137'h'#152#134#134'r<'#158
+ +'%Z['#143#165#28'h'#179'uq'#242#228#137#228#188#251#253'3|?'#209#203#239'g"h'
+ +#210'5'#216'l]I.'#13#224#213'#'#165#220#30#157'K'#190'}'#2'&'#211#189#184#236
+ +'v;f'#179#25#179#217#204#224#224'`'#146'O'#172#197#190'0'#160#189'Z'#193#238
+ +'gv'#167#240#201#26'X'#235#13#130#181#222#192#149'>QMt'#209#30#1#198#198#198
+ +#1#176'X,X,'#150#228#166#27'7~'#5#192#233't>0'#178#4#159't'#144#128#181#222
+ +' '#244#216#234#132#30'['#157#240'O'#28'$'#134#221'n'#231#254#6#255#27#252'['
+ +#7#143',`2'#149#227#241#12'b'#183#219'ioo'#7#160#179#179'3'#197#193'Z'#172
+ +#230#159#152#131'uk'#240' '#7#255#251#26#164#220#201#171#209#214'vA}'#156#203
+ +'>'#241'%'#175'+'#0#208#231#248#225#177'D'#30'*'#240'_'#224'/''a'#5#159#194
+ +' '#131'*'#0#0#0#0'IEND'#174'B`'#130
+]);
diff --git a/components/jujiboutils/jujibo-utils/src/jdbgridutils.pas b/components/jujiboutils/jujibo-utils/src/jdbgridutils.pas
new file mode 100644
index 000000000..148e6b581
--- /dev/null
+++ b/components/jujiboutils/jujibo-utils/src/jdbgridutils.pas
@@ -0,0 +1,504 @@
+{ jdbgridutils
+
+ 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 jdbgridutils;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Grids, Dialogs, LCLType, DBGrids, Controls, DB,
+ jcontrolutils;
+
+type
+
+ { TJDbGridDateCtrl }
+
+ TJDbGridDateCtrl = class(TObject)
+ private
+ Field: TField;
+ updated: boolean;
+ theValue: TDateTime;
+ fFormat: string;
+ function getFormat: string;
+ procedure myEditEnter(Sender: TObject);
+ procedure myEditOnEditingDone(Sender: TObject);
+ procedure formatInput;
+ procedure setFormat(const AValue: string);
+ procedure OnKeyPress(Sender: TObject; var key: char);
+ procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
+ public
+ CellEditor: TStringCellEditor;
+ theGrid: TDBGrid;
+ function isNull: boolean;
+ property format: string read getFormat write setFormat;
+ constructor Create;
+ destructor Destroy; override;
+ function Editor(aGrid: TDBGrid): TStringCellEditor;
+ end;
+
+ { TJDbGridIntegerCtrl }
+
+ TJDbGridIntegerCtrl = class(TObject)
+ private
+ theValue: integer;
+ updated: boolean;
+ Field: TField;
+ procedure myEditOnEnter(Sender: TObject);
+ procedure OnKeyPress(Sender: TObject; var key: char);
+ procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
+ procedure myEditOnEditingDone(Sender: TObject);
+ function IsValidInteger(const Value: string): boolean;
+ public
+ CellEditor: TStringCellEditor;
+ theGrid: TDBGrid;
+ constructor Create;
+ destructor Destroy; override;
+ function Editor(aGrid: TDBGrid): TStringCellEditor;
+ end;
+
+ { TJDbGridDoubleCtrl }
+
+ TJDbGridDoubleCtrl = class(TObject)
+ private
+ Field: TField;
+ updated: boolean;
+ theValue: double;
+ fDecimales: integer;
+ function getDecimales: integer;
+ procedure myEditOnEnter(Sender: TObject);
+ procedure myEditOnEditingDone(Sender: TObject);
+ procedure setDecimales(const AValue: integer);
+ procedure OnKeyPress(Sender: TObject; var key: char);
+ procedure OnKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
+ function IsValidFloat(const Value: string): boolean;
+ function textNumber(const aValue: string): string;
+ public
+ CellEditor: TStringCellEditor;
+ theGrid: TDBGrid;
+ property decimales: integer read getDecimales write setDecimales;
+ constructor Create;
+ destructor Destroy; override;
+ function Editor(aGrid: TDBGrid; aDecimals: integer = 2): TStringCellEditor;
+ end;
+
+
+implementation
+
+uses
+ Math;
+
+{ TJDbGridDateCtrl }
+
+function TJDbGridDateCtrl.getFormat: string;
+begin
+ Result := fFormat;
+end;
+
+procedure TJDbGridDateCtrl.myEditEnter(Sender: TObject);
+begin
+ Field := theGrid.SelectedField;
+ CellEditor.BoundsRect := theGrid.SelectedFieldRect;
+ CellEditor.Text := Field.AsString;
+ CellEditor.OnKeyPress := @OnKeyPress; // Recuperamos el control :-p
+ CellEditor.OnKeyDown := @OnKeyDown;
+ theValue := Field.AsDateTime;
+ updated := False;
+ CellEditor.SelectAll;
+end;
+
+procedure TJDbGridDateCtrl.myEditOnEditingDone(Sender: TObject);
+begin
+ CellEditor.Caption := NormalizeDate(CellEditor.Caption, theValue);
+ if Length(CellEditor.Caption) = 0 then
+ theValue := 0
+ else
+ if IsValidDateString(CellEditor.Caption) then
+ begin
+ if (not updated) then
+ begin
+ theValue := StrToDate(CellEditor.Caption);
+ Field.DataSet.Edit;
+ Field.AsDateTime := theValue;
+ end;
+ end
+ else
+ begin
+ ShowMessage(CellEditor.Caption + ' no es una fecha válida');
+ CellEditor.Text := FormatDateTime(format, theValue);
+ end;
+ //formatInput;
+end;
+
+procedure TJDbGridDateCtrl.formatInput;
+begin
+ if theValue <> 0 then
+ CellEditor.Caption := FormatDateTime(format, theValue);
+end;
+
+procedure TJDbGridDateCtrl.setFormat(const AValue: string);
+begin
+ fFormat := AValue;
+ formatInput;
+end;
+
+procedure TJDbGridDateCtrl.OnKeyPress(Sender: TObject; var key: char);
+begin
+ if not (Key in ['0'..'9', #8, #9, '.', '-', '/']) then
+ Key := #0;
+end;
+
+procedure TJDbGridDateCtrl.OnKeyDown(Sender: TObject; var Key: word;
+ Shift: TShiftState);
+begin
+ if Length(CellEditor.Caption) <> 0 then
+ if (Key in [VK_RETURN, VK_TAB, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT]) and
+ (not IsValidDateString(NormalizeDate(CellEditor.Caption, theValue))) then
+ begin
+ ShowMessage(CellEditor.Caption + ' no es una fecha válida');
+ CellEditor.Text := FormatDateTime(format, theValue);
+ CellEditor.SelectAll;
+ Key := VK_UNKNOWN;
+ end
+ else
+ if key = VK_ESCAPE then
+ begin
+ if Field.IsNull then
+ CellEditor.Text := ''
+ else
+ CellEditor.Text := FormatDateTime(format, Field.AsDateTime);
+ updated := True;
+ theGrid.SetFocus; // No perder el foco
+ end
+ else
+ if Key in [VK_UP, VK_DOWN] then
+ begin
+ Key := VK_UNKNOWN;
+ end
+ else
+ if Key in [VK_RETURN, VK_TAB, VK_RIGHT, VK_LEFT] then
+ begin
+ CellEditor.Caption := NormalizeDate(CellEditor.Caption, theValue);
+ if Length(CellEditor.Caption) = 0 then
+ theValue := 0
+ else
+ if IsValidDateString(CellEditor.Caption) then
+ begin
+ theValue := StrToDate(CellEditor.Caption);
+ Field.DataSet.Edit;
+ Field.AsDateTime := theValue;
+ CellEditor.SelectAll;
+ updated := True;
+ end;
+ end;
+end;
+
+
+function TJDbGridDateCtrl.isNull: boolean;
+begin
+ Result := theValue = 0;
+end;
+
+constructor TJDbGridDateCtrl.Create;
+begin
+ inherited Create;
+ CellEditor := TStringCellEditor.Create(nil);
+ CellEditor.OnEnter := @myEditEnter;
+ CellEditor.OnKeyDown := @OnKeyDown;
+ CellEditor.OnEditingDone := @myEditOnEditingDone;
+ CellEditor.OnKeyPress := @OnKeyPress; // se sobreescribe por el Grid :(
+ format := ShortDateFormat;
+end;
+
+destructor TJDbGridDateCtrl.Destroy;
+begin
+ CellEditor.Free;
+ inherited Destroy;
+end;
+
+function TJDbGridDateCtrl.Editor(aGrid: TDBGrid): TStringCellEditor;
+begin
+ theGrid := aGrid;
+ Result := CellEditor;
+end;
+
+{ TJDbGridDoubleCtrl }
+
+function TJDbGridDoubleCtrl.getDecimales: integer;
+begin
+ Result := fDecimales;
+end;
+
+procedure TJDbGridDoubleCtrl.myEditOnEnter(Sender: TObject);
+begin
+ Field := theGrid.SelectedField;
+ CellEditor.BoundsRect := theGrid.SelectedFieldRect;
+ CellEditor.Text := Field.AsString;
+ CellEditor.OnKeyPress := @OnKeyPress; // Recuperamos el control :-p
+ CellEditor.OnKeyDown := @OnKeyDown;
+ theValue := Field.AsFloat;
+ updated := False;
+ CellEditor.SelectAll;
+end;
+
+procedure TJDbGridDoubleCtrl.myEditOnEditingDone(Sender: TObject);
+begin
+ if IsValidFloat(CellEditor.Caption) then
+ begin
+ if (not updated) then
+ begin
+ theValue := StrToFloat(CellEditor.Caption);
+ Field.DataSet.Edit;
+ //theValue := redondear(theValue, fDecimales);
+ Field.AsFloat := theValue;
+ // normalize value
+ Field.Value := textNumber(Field.DisplayText);
+ end;
+ end
+ else
+ begin
+ ShowMessage(CellEditor.Caption + ' no es un número válido');
+ CellEditor.Text := FloatToStr(theValue);
+ end;
+end;
+
+procedure TJDbGridDoubleCtrl.setDecimales(const AValue: integer);
+begin
+ if (AValue >= 0) and (AValue < 5) then
+ fDecimales := AValue;
+end;
+
+procedure TJDbGridDoubleCtrl.OnKeyPress(Sender: TObject; var key: char);
+begin
+ if (Key in ['.', ',']) then
+ Key := Decimalseparator;
+ if (key = DecimalSeparator) and (Pos(key, CellEditor.Caption) > 0) then
+ key := #0;
+ if not (Key in ['0'..'9', DecimalSeparator, '+', '-', #8, #9]) then
+ Key := #0;
+ if (Key = DecimalSeparator) and (fDecimales = 0) then
+ Key := #0;
+end;
+
+procedure TJDbGridDoubleCtrl.OnKeyDown(Sender: TObject; var Key: word;
+ Shift: TShiftState);
+begin
+ if (Key in [VK_RETURN, VK_TAB, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT]) and
+ (not IsValidFloat(CellEditor.Caption)) then
+ begin
+ ShowMessage(CellEditor.Caption + ' no es número válido');
+ CellEditor.Text := FloatToStr(theValue);
+ CellEditor.SelectAll;
+ Key := VK_UNKNOWN;
+ end
+ else
+ if key = VK_ESCAPE then
+ begin
+ if Field.IsNull then
+ CellEditor.Text := ''
+ else
+ CellEditor.Text := FloatToStr(Field.AsFloat);
+ //CellEditor.Text := CurrToStr(redondear(Field.AsCurrency, fDecimales));
+ updated := True;
+ theGrid.SetFocus; // No perder el foco
+ end
+ else
+ if key in [VK_UP, VK_DOWN] then
+ begin
+ Key := VK_UNKNOWN;
+ end
+ else
+ if Key in [VK_RETURN, VK_TAB] then
+ begin
+ if IsValidFloat(CellEditor.Caption) then
+ begin
+ theValue := StrToFloat(CellEditor.Caption);
+ Field.DataSet.Edit;
+ Field.AsFloat := theValue;//redondear(theValue, fDecimales);
+ // normalize value
+ Field.Value := textNumber(Field.DisplayText);
+ CellEditor.Text := Field.AsString;
+ updated := True;
+ end;
+ end;
+end;
+
+function TJDbGridDoubleCtrl.IsValidFloat(const Value: string): boolean;
+begin
+ if StrToFloatDef(Value, MaxDouble) = MaxDouble then
+ Result := False
+ else
+ Result := True;
+end;
+
+function TJDbGridDoubleCtrl.textNumber(const aValue: string): string;
+var
+ i: integer;
+ aText: string;
+begin
+ // Because there is no way to know the number scale (or I don't know how
+ // use display format to get a valid number with the desired scale (decimals)
+ // so if display format is 0.00 we'll get a number rounded to two decimals
+ // This is a bit tricky but works mostly...
+ aText := '';
+ if Length(aValue) = 0 then
+ aText := aValue
+ else
+ begin
+ if aValue[1] = '-' then
+ aText := '-'; // negative number?
+ for i := 1 to length(aValue) do
+ if aValue[i] in ['0'..'9', DecimalSeparator] then
+ aText += aValue[i];
+ end;
+ Result := aText;
+end;
+
+constructor TJDbGridDoubleCtrl.Create;
+begin
+ inherited Create;
+ CellEditor := TStringCellEditor.Create(nil);
+ CellEditor.OnEnter := @myEditOnEnter;
+ CellEditor.OnKeyDown := @OnKeyDown;
+ CellEditor.OnEditingDone := @myEditOnEditingDone;
+ fDecimales := 2;
+end;
+
+destructor TJDbGridDoubleCtrl.Destroy;
+begin
+ CellEditor.Free;
+ inherited Destroy;
+end;
+
+function TJDbGridDoubleCtrl.Editor(aGrid: TDBGrid;
+ aDecimals: integer): TStringCellEditor;
+begin
+ decimales := aDecimals;
+ theGrid := aGrid;
+ Result := CellEditor;
+end;
+
+{ TJDbGridIntegerCtrl }
+
+procedure TJDbGridIntegerCtrl.myEditOnEnter(Sender: TObject);
+begin
+ Field := theGrid.SelectedField;
+ CellEditor.BoundsRect := theGrid.SelectedFieldRect;
+ CellEditor.Text := Field.AsString;
+ CellEditor.OnKeyPress := @OnKeyPress; // Recuperamos el control :-p
+ CellEditor.OnKeyDown := @OnKeyDown;
+ theValue := Field.AsInteger;
+ CellEditor.SelectAll;
+ updated := False;
+end;
+
+procedure TJDbGridIntegerCtrl.OnKeyPress(Sender: TObject; var key: char);
+begin
+ if not (Key in ['0'..'9', #8, #9, '-']) then
+ Key := #0;
+end;
+
+procedure TJDbGridIntegerCtrl.OnKeyDown(Sender: TObject; var Key: word;
+ Shift: TShiftState);
+begin
+ if (Key in [VK_RETURN, VK_TAB, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT]) and
+ (not IsValidInteger(CellEditor.Caption)) then
+ begin
+ ShowMessage(CellEditor.Caption + ' no es un número válido');
+ CellEditor.Text := IntToStr(theValue);
+ CellEditor.SelectAll;
+ Key := VK_UNKNOWN;
+ end
+ else
+ if (Key = VK_ESCAPE) then
+ begin
+ if Field.IsNull then
+ CellEditor.Text := ''
+ else
+ CellEditor.Text := IntToStr(Field.AsInteger);
+ updated := True;
+ theGrid.SetFocus; // No perder el foco
+ end
+ else
+ if key in [VK_UP, VK_DOWN] then
+ begin
+ Key := VK_UNKNOWN;
+ end
+ else
+ if Key in [VK_RETURN, VK_TAB] then
+ begin
+ if IsValidInteger(CellEditor.Caption) then
+ begin
+ theValue := StrToInt(CellEditor.Caption);
+ Field.DataSet.Edit;
+ Field.AsInteger := theValue;
+ updated := True;
+ end;
+ end;
+end;
+
+procedure TJDbGridIntegerCtrl.myEditOnEditingDone(Sender: TObject);
+begin
+ if IsValidInteger(CellEditor.Caption) then
+ begin
+ if (not updated) then
+ begin
+ theValue := StrToInt(CellEditor.Caption);
+ Field.DataSet.Edit;
+ Field.AsInteger := theValue;
+ end;
+ end
+ else
+ begin
+ ShowMessage(CellEditor.Caption + ' no es un número válido');
+ CellEditor.Text := IntToStr(theValue);
+ end;
+end;
+
+function TJDbGridIntegerCtrl.IsValidInteger(const Value: string): boolean;
+begin
+ if StrToIntDef(Value, MaxInt) = MaxInt then
+ Result := False
+ else
+ Result := True;
+end;
+
+constructor TJDbGridIntegerCtrl.Create;
+begin
+ inherited Create;
+ CellEditor := TStringCellEditor.Create(nil);
+ CellEditor.OnEnter := @myEditOnEnter;
+ CellEditor.OnKeyDown := @OnKeyDown;
+ CellEditor.OnEditingDone := @myEditOnEditingDone;
+ CellEditor.OnKeyPress := @OnKeyPress; // se sobreescribe por el Grid :(
+end;
+
+destructor TJDbGridIntegerCtrl.Destroy;
+begin
+ CellEditor.Free;
+ inherited Destroy;
+end;
+
+function TJDbGridIntegerCtrl.Editor(aGrid: TDBGrid): TStringCellEditor;
+begin
+ theGrid := aGrid;
+ Result := CellEditor;
+end;
+
+end.
+
diff --git a/components/jujiboutils/jujibo-utils/testgridctr/main.lfm b/components/jujiboutils/jujibo-utils/testgridctr/main.lfm
new file mode 100644
index 000000000..d6e65ce44
--- /dev/null
+++ b/components/jujiboutils/jujibo-utils/testgridctr/main.lfm
@@ -0,0 +1,85 @@
+object Form1: TForm1
+ Left = 311
+ Height = 347
+ Top = 162
+ Width = 419
+ Caption = 'Form1'
+ ClientHeight = 347
+ ClientWidth = 419
+ OnCreate = FormCreate
+ LCLVersion = '0.9.31'
+ object DBNavigator1: TDBNavigator
+ Left = 8
+ Height = 25
+ Top = 60
+ Width = 241
+ BevelOuter = bvNone
+ ChildSizing.EnlargeHorizontal = crsScaleChilds
+ ChildSizing.EnlargeVertical = crsScaleChilds
+ ChildSizing.ShrinkHorizontal = crsScaleChilds
+ ChildSizing.ShrinkVertical = crsScaleChilds
+ ChildSizing.Layout = cclLeftToRightThenTopToBottom
+ ChildSizing.ControlsPerLine = 100
+ ClientHeight = 25
+ ClientWidth = 241
+ DataSource = Datasource1
+ Options = []
+ TabOrder = 0
+ end
+ object JDBGridControl1: TJDBGridControl
+ Left = 8
+ Height = 192
+ Top = 112
+ Width = 392
+ Color = clWindow
+ Columns = <
+ item
+ Title.Caption = 'ID'
+ Title.PrefixOption = poNone
+ FieldName = 'ID'
+ end
+ item
+ Title.Caption = 'DATE'
+ Title.PrefixOption = poNone
+ FieldName = 'DATE'
+ end
+ item
+ Title.Caption = 'QUANTITY'
+ Title.PrefixOption = poNone
+ Width = 150
+ FieldName = 'QUANTITY'
+ DisplayFormat = '#,0.00000€'
+ end>
+ DataSource = Datasource1
+ TabOrder = 1
+ end
+ object MemDataset1: TMemDataset
+ Active = True
+ FieldDefs = <
+ item
+ Name = 'ID'
+ DataType = ftInteger
+ Precision = 0
+ Size = 0
+ end
+ item
+ Name = 'DATE'
+ DataType = ftDate
+ Precision = 0
+ Size = 0
+ end
+ item
+ Name = 'QUANTITY'
+ DataType = ftFloat
+ Precision = 0
+ Size = 0
+ end>
+ left = 232
+ top = 8
+ end
+ object Datasource1: TDatasource
+ DataSet = MemDataset1
+ left = 324
+ top = 7
+ end
+end
diff --git a/components/jujiboutils/jujibo-utils/testgridctr/main.pas b/components/jujiboutils/jujibo-utils/testgridctr/main.pas
new file mode 100644
index 000000000..ba46fe565
--- /dev/null
+++ b/components/jujiboutils/jujibo-utils/testgridctr/main.pas
@@ -0,0 +1,53 @@
+unit main;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, memds, db, FileUtil, Forms, Controls, Graphics, Dialogs,
+ DbCtrls, DBGrids, JDBGridControl;
+
+type
+
+ { TForm1 }
+
+ TForm1 = class(TForm)
+ Datasource1: TDatasource;
+ DBNavigator1: TDBNavigator;
+ JDBGridControl1: TJDBGridControl;
+ MemDataset1: TMemDataset;
+ procedure FormCreate(Sender: TObject);
+ private
+ { private declarations }
+ public
+ { public declarations }
+ end;
+
+var
+ Form1: TForm1;
+
+implementation
+
+{$R *.lfm}
+
+{ TForm1 }
+
+procedure TForm1.FormCreate(Sender: TObject);
+var
+ i: integer;
+begin
+ // populate the memDataset
+ for i := 1 to 10 do
+ begin
+ MemDataset1.Append;
+ MemDataset1.FieldByName('ID').AsInteger := i;
+ MemDataset1.FieldByName('DATE').AsDateTime := Now;
+ MemDataset1.FieldByName('QUANTITY').AsFloat := i * i * i;
+ MemDataset1.Post;
+ end;
+ MemDataset1.First;
+end;
+
+end.
+
diff --git a/components/jujiboutils/jujibo-utils/testgridctr/testgridctr.lpi b/components/jujiboutils/jujibo-utils/testgridctr/testgridctr.lpi
new file mode 100644
index 000000000..6fef61aeb
--- /dev/null
+++ b/components/jujiboutils/jujibo-utils/testgridctr/testgridctr.lpi
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/jujiboutils/jujibo-utils/testgridctr/testgridctr.lpr b/components/jujiboutils/jujibo-utils/testgridctr/testgridctr.lpr
new file mode 100644
index 000000000..8df3973cb
--- /dev/null
+++ b/components/jujiboutils/jujibo-utils/testgridctr/testgridctr.lpr
@@ -0,0 +1,21 @@
+program testgridctr;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}clocale,{$ENDIF}
+ Interfaces, // this includes the LCL widgetset
+ Forms, memdslaz, main
+ { you can add units after this };
+
+{$R *.res}
+
+begin
+ RequireDerivedFormResource := True;
+ Application.Initialize;
+ Application.CreateForm(TForm1, Form1);
+ Application.Run;
+end.
+