fix bugs in RxLookupEdit

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@696 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
alexs75
2009-02-04 20:30:44 +00:00
parent 1b1a30f00c
commit 27d10098c4

View File

@ -5,16 +5,16 @@ unit rxlookup;
interface interface
uses uses
LCLType, LCLProc, LCLIntf, LCLType, LCLProc, LCLIntf, Classes, SysUtils, LResources, Forms,
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Controls, Graphics, Dialogs, DB, EditBtn, DBGrids, StdCtrls, Buttons,
DB, EditBtn, DBGrids, StdCtrls, Buttons, LMessages, DbCtrls, GraphType, LMessages, DbCtrls, GraphType, dbutils, RxDbGrid, rxpopupunit;
dbutils, RxDbGrid, rxpopupunit;
const const
TextMargin = 5; TextMargin = 5;
type type
TRxCustomDBLookupCombo = class; TRxCustomDBLookupCombo = class;
TRxCustomDBLookupEdit = class;
{ TLookupSourceLink } { TLookupSourceLink }
TDataSourceLink = class(TDataLink) TDataSourceLink = class(TDataLink)
@ -32,68 +32,70 @@ type
TLookupSourceLink = class(TDataLink) TLookupSourceLink = class(TDataLink)
private private
FDataControl: TRxCustomDBLookupCombo; FOnActiveChanged:TNotifyEvent;
FOnLayoutChanged:TNotifyEvent;
FOnDataSetChanged:TNotifyEvent;
protected protected
procedure ActiveChanged; override; procedure ActiveChanged; override;
procedure LayoutChanged; override; procedure LayoutChanged; override;
procedure DataSetChanged; override; procedure DataSetChanged; override;
end; end;
{ TPopupWindow } { TRxCustomDBLookupEdit }
TPopupWindow = class(TForm) TRxCustomDBLookupEdit = class(TEditButton)
public
constructor Create(AOwner: TComponent); override;
end;
{ TCustomDBLookupEdit }
TCustomDBLookupEdit = class(TEditButton)
private private
FDropDownCount: Integer;
FDropDownWidth: Integer;
FLookupDisplayIndex: Integer; FLookupDisplayIndex: Integer;
FLookupField: string; FLookupField: string;
FLookupDisplay: string; FLookupDisplay: string;
FLookupSource:TDataSource; FKeyField:TField;
// //
FPopupWindow:TPopupWindow; FLookupDataLink:TLookupSourceLink;
FList:TDBGrid; FLocateObject:TLocateObject;
FPopupVisible:boolean; //
FSaveAfterScroll:TDataSetNotifyEvent; FRxPopUpForm:TPopUpForm;
FFieldList:TStringList; FFieldList:TStringList;
FPopUpFormOptions:TPopUpFormOptions;
function GetDropDownCount: Integer;
function GetDropDownWidth: Integer;
function GetLookupSource: TDataSource; function GetLookupSource: TDataSource;
function GetPopupVisible: boolean;
procedure SetDropDownCount(const AValue: Integer); procedure SetDropDownCount(const AValue: Integer);
procedure SetDropDownWidth(const AValue: Integer);
procedure SetLookupDisplay(const AValue: string); procedure SetLookupDisplay(const AValue: string);
procedure SetLookupDisplayIndex(const AValue: Integer); procedure SetLookupDisplayIndex(const AValue: Integer);
procedure SetLookupField(const AValue: string); procedure SetLookupField(const AValue: string);
procedure SetLookupSource(AValue: TDataSource); procedure SetLookupSource(AValue: TDataSource);
procedure SetPopUpFormOptions(const AValue: TPopUpFormOptions);
// //
procedure ShowList; procedure ShowList;
procedure HideList; procedure HideList;
procedure ShowPopUp; procedure ShowPopUp;
procedure DoMouseUp(Sender: TOBject; AButton: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure UpdateKeyValue;
procedure DoAfterScroll(DataSet: TDataSet);
procedure DoPopupWindowDeactivate(Sender: TObject);
procedure DoPopupWindowKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
protected protected
property PopUpFormOptions:TPopUpFormOptions read FPopUpFormOptions write SetPopUpFormOptions;
procedure DoButtonClick (Sender: TObject); override; procedure DoButtonClick (Sender: TObject); override;
function GetDefaultGlyphName: String; override; function GetDefaultGlyphName: String; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure OnClosePopup(AResult:boolean);virtual;
// //
property DropDownCount: Integer read FDropDownCount write SetDropDownCount default 8; procedure LookupDataSetChanged(Sender: TObject); virtual;
property DropDownWidth: Integer read FDropDownWidth write FDropDownWidth default 0; procedure ListLinkActiveChanged(Sender: TObject); virtual;
//
property DropDownCount: Integer read GetDropDownCount write SetDropDownCount default 8;
property DropDownWidth: Integer read GetDropDownWidth write SetDropDownWidth default 0;
property LookupDisplay: string read FLookupDisplay write SetLookupDisplay; property LookupDisplay: string read FLookupDisplay write SetLookupDisplay;
property LookupDisplayIndex: Integer read FLookupDisplayIndex write SetLookupDisplayIndex default 0; property LookupDisplayIndex: Integer read FLookupDisplayIndex write SetLookupDisplayIndex default 0;
property LookupField: string read FLookupField write SetLookupField; property LookupField: string read FLookupField write SetLookupField;
property LookupSource: TDataSource read FLookupSource write SetLookupSource; property LookupSource: TDataSource read GetLookupSource write SetLookupSource;
property PopupVisible:boolean read FPopupVisible; property PopupVisible:boolean read GetPopupVisible;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
end; end;
TRxLookupEdit = class(TCustomDBLookupEdit) TRxLookupEdit = class(TRxCustomDBLookupEdit)
published published
property DropDownCount; property DropDownCount;
property DropDownWidth; property DropDownWidth;
@ -101,6 +103,7 @@ type
property LookupDisplayIndex; property LookupDisplayIndex;
property LookupField; property LookupField;
property LookupSource; property LookupSource;
property PopUpFormOptions;
end; end;
{ TRxCustomDBLookupCombo } { TRxCustomDBLookupCombo }
@ -202,8 +205,8 @@ type
procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override; procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
procedure Paint; override; procedure Paint; override;
procedure LookupDataSetChanged; virtual; procedure LookupDataSetChanged(Sender: TObject); virtual;
procedure ListLinkActiveChanged; virtual; procedure ListLinkActiveChanged(Sender: TObject); virtual;
// //
property Button: TSpeedButton read FButton; property Button: TSpeedButton read FButton;
@ -311,26 +314,39 @@ type
end; end;
{ TCustomDBLookupEdit } { TRxCustomDBLookupEdit }
function TCustomDBLookupEdit.GetLookupSource: TDataSource; function TRxCustomDBLookupEdit.GetLookupSource: TDataSource;
begin begin
Result:=FLookupSource; Result:=FLookupDataLink.DataSource;
end; end;
procedure TCustomDBLookupEdit.SetDropDownCount(const AValue: Integer); function TRxCustomDBLookupEdit.GetPopupVisible: boolean;
begin begin
if FDropDownCount=AValue then exit; Result:=Assigned(FRxPopUpForm);
if AValue>50 then
FDropDownCount:=50
else
if AValue<0 then
FDropDownCount:=8
else
FDropDownCount:=AValue;
end; end;
procedure TCustomDBLookupEdit.SetLookupDisplay(const AValue: string); function TRxCustomDBLookupEdit.GetDropDownCount: Integer;
begin
Result:=FPopUpFormOptions.DropDownCount;
end;
function TRxCustomDBLookupEdit.GetDropDownWidth: Integer;
begin
Result:=FPopUpFormOptions.DropDownWidth;
end;
procedure TRxCustomDBLookupEdit.SetDropDownCount(const AValue: Integer);
begin
FPopUpFormOptions.DropDownCount:=AValue;
end;
procedure TRxCustomDBLookupEdit.SetDropDownWidth(const AValue: Integer);
begin
FPopUpFormOptions.DropDownWidth:=AValue;
end;
procedure TRxCustomDBLookupEdit.SetLookupDisplay(const AValue: string);
var var
S1, S2:string; S1, S2:string;
K:integer; K:integer;
@ -356,131 +372,76 @@ begin
end; end;
end; end;
procedure TCustomDBLookupEdit.SetLookupDisplayIndex(const AValue: Integer); procedure TRxCustomDBLookupEdit.SetLookupDisplayIndex(const AValue: Integer);
begin begin
if FLookupDisplayIndex=AValue then exit; if FLookupDisplayIndex=AValue then exit;
FLookupDisplayIndex:=AValue; FLookupDisplayIndex:=AValue;
end; end;
procedure TCustomDBLookupEdit.SetLookupField(const AValue: string); procedure TRxCustomDBLookupEdit.SetLookupField(const AValue: string);
begin begin
if FLookupField = AValue then exit; if FLookupField = AValue then exit;
FLookupField:=AValue; FLookupField:=AValue;
end; end;
procedure TCustomDBLookupEdit.SetLookupSource(AValue: TDataSource); procedure TRxCustomDBLookupEdit.SetLookupSource(AValue: TDataSource);
begin begin
if LookupSource = AValue then exit; FLookupDataLink.DataSource:=AValue;
FLookupSource:=AValue;
end; end;
procedure TCustomDBLookupEdit.ShowList; procedure TRxCustomDBLookupEdit.SetPopUpFormOptions(
const AValue: TPopUpFormOptions);
begin
FPopUpFormOptions.Assign(AValue);
end;
procedure TRxCustomDBLookupEdit.ShowList;
var var
i,W:integer; i,W:integer;
GC:TColumn; GC:TColumn;
begin begin
if Assigned(FLookupSource) and if FLookupDataLink.Active and not PopupVisible then
Assigned(FLookupSource.DataSet) and
FLookupSource.DataSet.Active then
if not FPopupVisible then
begin begin
ShowPopUp; ShowPopUp;
{ FList.Columns.Clear;
W:=16;
for I:=0 to FFieldList.Count-1 do
begin;
GC:=TDbGridColumns(FList.Columns).Add;
GC.Field:=FLookupSource.DataSet.FieldByName(FFieldList[i]);
if (W+GC.Field.DisplayWidth * FList.Canvas.TextWidth('W')) > FList.Width then
GC.Width:=FList.Width - W
else
GC.Width:=GC.Field.DisplayWidth * FList.Canvas.TextWidth('W');
W:=W+GC.Width + 4;
end;
FPopupVisible:=true;}
end; end;
end; end;
procedure TCustomDBLookupEdit.HideList; procedure TRxCustomDBLookupEdit.HideList;
begin begin
if Assigned(FPopupWindow) then
begin
FList.Parent:=nil;
FPopupWindow.Close;
FPopupVisible:=false;
FLookupSource.DataSet.AfterScroll:=FSaveAfterScroll;
FList.DataSource:=nil;
FPopupWindow:=nil;
end;
end; end;
procedure TCustomDBLookupEdit.ShowPopUp; procedure TRxCustomDBLookupEdit.ShowPopUp;
var var
R:TPoint; R:TPoint;
FValue:string;
begin begin
if not Assigned(FList) then
FList:=TDBGrid.Create(Owner);
FPopupWindow:=TPopupWindow.Create(Application);
FList.Parent:=FPopupWindow;
FList.Align:=alClient; if FLookupDataLink.Active then
FList.OnMouseUp:=@DoMouseUp; if not PopupVisible then
FList.DataSource:=FLookupSource; begin
FList.Options:=FList.Options -
[dgTabs, dgEditing, dgTitles, dgIndicator, dgColumnResize, dgRowLines] + [dgRowSelect]; FValue := Text;
FSaveAfterScroll:=FLookupSource.DataSet.AfterScroll;
FLookupSource.DataSet.AfterScroll:=@DoAfterScroll; FLocateObject.Locate(FLookupField, FValue, true, false);
FRxPopUpForm:=ShowRxDBPopUpForm(Self, FLookupDataLink.DataSet, @OnClosePopup,
FPopUpFormOptions, FLookupDisplay, LookupDisplayIndex, 0 {ButtonWidth}, Font);
end
R.X:=Left;
R.Y:=Top+Height;
R:=Parent.ClientToScreen(R);
FPopupWindow.Top:=R.Y;
FPopupWindow.Left:=R.X;
FPopupWindow.Width:=Width+Button.Width;
FPopupWindow.OnDeactivate:=@DoPopupWindowDeactivate;
FPopupWindow.OnKeyDown:=@DoPopupWindowKeyDown;
if FDropDownCount>0 then
FPopupWindow.Height:=FList.Canvas.TextHeight('W')*FDropDownCount
else
FPopupWindow.Height:=FList.Canvas.TextHeight('W')*8;
FPopupWindow.ShowModal;
end; end;
procedure TCustomDBLookupEdit.DoMouseUp(Sender: TOBject; AButton: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (X>0) and (Y>0) and (X<FList.ClientWidth) and (Y<Flist.ClientHeight) then
HideList;
end;
procedure TCustomDBLookupEdit.DoAfterScroll(DataSet: TDataSet); procedure TRxCustomDBLookupEdit.UpdateKeyValue;
var var
S:string; S:string;
begin begin
S:=FFieldList[FLookupDisplayIndex]; S:=FFieldList[FLookupDisplayIndex];
Text:=FLookupSource.DataSet.FieldByName(S).AsString; if FLookupDataLink.Active then
if Assigned(FSaveAfterScroll) then Text:=FLookupDataLink.DataSet.FieldByName(S).AsString;
FSaveAfterScroll(DataSet);
end; end;
procedure TCustomDBLookupEdit.DoPopupWindowDeactivate(Sender: TObject); procedure TRxCustomDBLookupEdit.DoButtonClick(Sender: TObject);
begin
HideList;
end;
procedure TCustomDBLookupEdit.DoPopupWindowKeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
case Key of
vk_Return: HideList;
else
TDbGridAccess(FList).KeyDown(Key, Shift);
exit;
end;
Key:=0;
end;
procedure TCustomDBLookupEdit.DoButtonClick(Sender: TObject);
begin begin
inherited DoButtonClick(Sender); inherited DoButtonClick(Sender);
if PopupVisible then if PopupVisible then
@ -489,19 +450,19 @@ begin
ShowList; ShowList;
end; end;
function TCustomDBLookupEdit.GetDefaultGlyphName: String; function TRxCustomDBLookupEdit.GetDefaultGlyphName: String;
begin begin
Result:='rxbtn_downarrow'; Result:='rxbtn_downarrow';
end; end;
procedure TCustomDBLookupEdit.KeyDown(var Key: Word; Shift: TShiftState); procedure TRxCustomDBLookupEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin begin
if (Key in [VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN, VK_RETURN]) and PopupVisible then if (Key in [VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN, VK_RETURN]) and PopupVisible then
begin begin
if Key=VK_RETURN then HideList { if Key=VK_RETURN then HideList
else else
TDbGridAccess(Flist).KeyDown(Key, Shift); TDbGridAccess(Flist).KeyDown(Key, Shift);
Key := 0; Key := 0;}
end end
else else
if (Key = VK_DOWN) and ((ssAlt in Shift) or (ssCtrl in Shift)) then if (Key = VK_DOWN) and ((ssAlt in Shift) or (ssCtrl in Shift)) then
@ -514,37 +475,70 @@ begin
if not (PopupVisible or ReadOnly) and (Key in [VK_UP, VK_DOWN]) and (Shift = []) then if not (PopupVisible or ReadOnly) and (Key in [VK_UP, VK_DOWN]) and (Shift = []) then
begin begin
case Key of case Key of
VK_UP: if not FLookupSource.DataSet.BOF then FLookupSource.DataSet.Prior; VK_UP: if not FLookupDataLink.DataSet.BOF then FLookupDataLink.DataSet.Prior;
VK_DOWN: if not FLookupSource.DataSet.EOF then FLookupSource.DataSet.Next; VK_DOWN: if not FLookupDataLink.DataSet.EOF then FLookupDataLink.DataSet.Next;
end; end;
Text:=FLookupSource.DataSet.FieldByName(FFieldList[FLookupDisplayIndex]).AsString; Text:=FLookupDataLink.DataSet.FieldByName(FFieldList[FLookupDisplayIndex]).AsString;
Key:=0; Key:=0;
end; end;
end; end;
constructor TCustomDBLookupEdit.Create(AOwner: TComponent); procedure TRxCustomDBLookupEdit.OnClosePopup(AResult: boolean);
begin
end;
procedure TRxCustomDBLookupEdit.LookupDataSetChanged(Sender: TObject);
begin
UpdateKeyValue;
Invalidate;
end;
procedure TRxCustomDBLookupEdit.ListLinkActiveChanged(Sender: TObject);
var
DataSet: TDataSet;
begin
FKeyField := nil;
DataSet:=nil;
if FLookupDataLink.Active and (FLookupField <> '') then
begin
DataSet := FLookupDataLink.DataSet;
FKeyField := DataSet.FieldByName(FLookupField);
end;
FLocateObject.DataSet := DataSet;
UpdateKeyValue
end;
constructor TRxCustomDBLookupEdit.Create(AOwner: TComponent);
begin begin
inherited Create(AOwner); inherited Create(AOwner);
FDropDownCount:=8; FLocateObject:=CreateLocate(nil);
//Lookup
FLookupDataLink:=TLookupSourceLink.Create;
FLookupDataLink.FOnActiveChanged:=@ListLinkActiveChanged;
FLookupDataLink.FOnLayoutChanged:=@ListLinkActiveChanged;
FLookupDataLink.FOnDataSetChanged:=@LookupDataSetChanged;
// FDropDownCount:=8;
FFieldList:=TStringList.Create; FFieldList:=TStringList.Create;
Glyph:=CreateArrowBitmap; Glyph:=CreateArrowBitmap;
ButtonWidth:=15; ButtonWidth:=15;
FPopUpFormOptions:=TPopUpFormOptions.Create;
end; end;
destructor TCustomDBLookupEdit.Destroy; destructor TRxCustomDBLookupEdit.Destroy;
begin begin
FreeAndNil(FLocateObject);
FreeAndNil(FPopUpFormOptions);
FFieldList.Clear; FFieldList.Clear;
FreeAndNil(FFieldList); FreeAndNil(FFieldList);
inherited Destroy; inherited Destroy;
end; end;
{ TPopupWindow }
constructor TPopupWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
BorderStyle:=bsNone;
end;
{ TRxCustomDBLookupCombo } { TRxCustomDBLookupCombo }
@ -1206,7 +1200,7 @@ begin
end; end;
end; end;
procedure TRxCustomDBLookupCombo.LookupDataSetChanged; procedure TRxCustomDBLookupCombo.LookupDataSetChanged(Sender: TObject);
begin begin
if PopupVisible then if PopupVisible then
begin begin
@ -1215,7 +1209,7 @@ begin
end; end;
end; end;
procedure TRxCustomDBLookupCombo.ListLinkActiveChanged; procedure TRxCustomDBLookupCombo.ListLinkActiveChanged(Sender: TObject);
var var
DataSet: TDataSet; DataSet: TDataSet;
begin begin
@ -1246,10 +1240,12 @@ begin
FValuesList:= TStringList.Create; FValuesList:= TStringList.Create;
FLocateObject:=CreateLocate(nil); FLocateObject:=CreateLocate(nil);
FPopUpFormOptions:=TPopUpFormOptions.Create; FPopUpFormOptions:=TPopUpFormOptions.Create;
//Lookup //Lookup
FLookupDataLink:=TLookupSourceLink.Create; FLookupDataLink:=TLookupSourceLink.Create;
FLookupDataLink.FDataControl:=Self; // FLookupDataLink.FDataControl:=Self;
FLookupDataLink.FOnActiveChanged:=@ListLinkActiveChanged;
FLookupDataLink.FOnLayoutChanged:=@ListLinkActiveChanged;
FLookupDataLink.FOnDataSetChanged:=@LookupDataSetChanged;
//Data //Data
FDataLink:=TDataSourceLink.Create; FDataLink:=TDataSourceLink.Create;
@ -1328,20 +1324,26 @@ end;
procedure TLookupSourceLink.ActiveChanged; procedure TLookupSourceLink.ActiveChanged;
begin begin
if FDataControl <> nil then { if FDataControl <> nil then
FDataControl.ListLinkActiveChanged; FDataControl.ListLinkActiveChanged;}
if Assigned(FOnActiveChanged) then
FOnActiveChanged(DataSet);
end; end;
procedure TLookupSourceLink.LayoutChanged; procedure TLookupSourceLink.LayoutChanged;
begin begin
if FDataControl <> nil then { if FDataControl <> nil then
FDataControl.ListLinkActiveChanged; FDataControl.ListLinkActiveChanged;}
if Assigned(FOnLayoutChanged) then
FOnLayoutChanged(DataSet);
end; end;
procedure TLookupSourceLink.DataSetChanged; procedure TLookupSourceLink.DataSetChanged;
begin begin
if FDataControl <> nil then { if FDataControl <> nil then
FDataControl.LookupDataSetChanged; FDataControl.LookupDataSetChanged;}
if Assigned(FOnDataSetChanged) then
FOnDataSetChanged(DataSet);
end; end;
{ TRxDBLookupCombo } { TRxDBLookupCombo }
@ -1357,3 +1359,4 @@ begin
end; end;
end. end.