--- ibx/trunk/ibcontrols/IBLookupComboEditBox.pas 2015/03/13 10:26:52 23 +++ ibx/trunk/ibcontrols/IBLookupComboEditBox.pas 2015/04/14 13:10:23 27 @@ -31,7 +31,7 @@ interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, DbCtrls, - ExtCtrls, IBSQLParser, DB, StdCtrls; + ExtCtrls, IBSQLParser, DB, StdCtrls, IBCustomDataSet; type @@ -54,13 +54,23 @@ type FOwner: TIBLookupComboEditBox; protected procedure ActiveChanged; override; - procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; procedure RecordChanged(Field: TField); override; procedure UpdateData; override; public constructor Create(AOwner: TIBLookupComboEditBox); end; + { TIBLookupControlLink } + + TIBLookupControlLink = class(TIBControlLink) + private + FOwner: TIBLookupComboEditBox; + protected + procedure UpdateSQL(Sender: TObject); override; + public + constructor Create(AOwner: TIBLookupComboEditBox); + end; + { TIBLookupComboEditBox } @@ -69,6 +79,7 @@ type FCanAutoInsert: TCanAutoInsert; { Private declarations } FDataLink: TIBLookupComboDataLink; + FIBLookupControlLink: TIBLookupControlLink; FAutoComplete: boolean; FAutoInsert: boolean; FKeyPressInterval: integer; @@ -87,6 +98,7 @@ type function GetListSource: TDataSource; function GetRelationNameQualifier: string; procedure HandleTimer(Sender: TObject); + procedure IBControlLinkChanged; procedure ResetParser; procedure RecordChanged(Sender: TObject; aField: TField); procedure SetAutoCompleteText(AValue: TComboBoxAutoCompleteText); @@ -102,8 +114,11 @@ type procedure DoEnter; override; procedure DoExit; override; procedure KeyUp(var Key: Word; Shift: TShiftState); override; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure SetItemIndex(const Val: integer); override; + function SQLSafe(aText: string): string; procedure UpdateShowing; override; + public { Public declarations } constructor Create(TheComponent: TComponent); override; @@ -118,7 +133,7 @@ type property ItemHeight; property ItemWidth; property ListSource: TDataSource read GetListSource write SetListSource; - property KeyPressInterval: integer read FKeyPressInterval write FKeyPressInterval default 500; + property KeyPressInterval: integer read FKeyPressInterval write FKeyPressInterval default 200; property RelationName: string read FRelationName write FRelationName; property OnAutoInsert: TAutoInsert read FOnAutoInsert write FOnAutoInsert; property OnCanAutoInsert: TCanAutoInsert read FOnCanAutoInsert write FOnCanAutoInsert; @@ -127,30 +142,26 @@ type implementation -uses IBQuery, IBCustomDataSet, LCLType, Variants, LCLProc; +uses IBQuery, LCLType, Variants, LCLProc; -{ TIBLookupComboDataLink } +{ TIBLookupControlLink } -procedure TIBLookupComboDataLink.ActiveChanged; +constructor TIBLookupControlLink.Create(AOwner: TIBLookupComboEditBox); begin - FOwner.ActiveChanged(self) + inherited Create; + FOwner := AOwner; end; -procedure TIBLookupComboDataLink.DataEvent(Event: TDataEvent; Info: Ptrint); +procedure TIBLookupControlLink.UpdateSQL(Sender: TObject); begin - {If we are not visible then avoid unnecessary work} - if not FOwner.Showing then Exit; + FOwner.UpdateSQL(self,TIBParserDataSet(Sender).Parser) +end; - if (Event = deCheckBrowseMode) and (Info = 1) and not DataSet.Active then - begin - if (DataSet is TIBDataSet) then - FOwner.UpdateSQL(self,TIBDataSet(DataSet).Parser) - else - if (DataSet is TIBQuery) then - FOwner.UpdateSQL(self,TIBQuery(DataSet).Parser) - end - else - inherited DataEvent(Event, Info); +{ TIBLookupComboDataLink } + +procedure TIBLookupComboDataLink.ActiveChanged; +begin + FOwner.ActiveChanged(self) end; procedure TIBLookupComboDataLink.RecordChanged(Field: TField); @@ -179,6 +190,14 @@ begin UpdateList end; +procedure TIBLookupComboEditBox.IBControlLinkChanged; +begin + if (ListSource <> nil) and (ListSource.DataSet <> nil) and (ListSource.DataSet is TIBParserDataSet) then + FIBLookupControlLink.IBDataSet := TIBCustomDataSet(ListSource.DataSet) + else + FIBLookupControlLink.IBDataSet := nil; +end; + function TIBLookupComboEditBox.GetListSource: TDataSource; begin Result := inherited ListSource; @@ -196,6 +215,7 @@ procedure TIBLookupComboEditBox.ActiveCh begin if not FInserting and not FUpdating then Application.QueueAsyncCall(@DoActiveChanged,0); + IBControlLinkChanged; end; procedure TIBLookupComboEditBox.DoActiveChanged(Data: PtrInt); @@ -237,11 +257,15 @@ begin end; procedure TIBLookupComboEditBox.ResetParser; +var curKeyValue: variant; begin if FFiltered then begin FFiltered := false; + curKeyValue := KeyValue; + Text := ''; {Ensure full list} UpdateList; + KeyValue := curKeyValue; UpdateData(self); {Force Scroll} end; end; @@ -276,6 +300,7 @@ begin begin FDataLink.DataSource := AValue; inherited ListSource := AValue; + IBControlLinkChanged; end; end; @@ -336,9 +361,11 @@ begin if FFiltered then begin if cbactSearchCaseSensitive in AutoCompleteText then - Parser.Add2WhereClause(GetRelationNameQualifier + '"' + ListField + '" Like ''' + Text + '%''') + Parser.Add2WhereClause(GetRelationNameQualifier + '"' + ListField + '" Like ''' + + SQLSafe(Text) + '%''') else - Parser.Add2WhereClause(GetRelationNameQualifier + 'Upper("' + ListField + '") Like Upper(''' + Text + '%'')'); + Parser.Add2WhereClause(GetRelationNameQualifier + 'Upper("' + ListField + '") Like Upper(''' + + SQLSafe(Text) + '%'')'); end; if cbactSearchAscending in AutoCompleteText then @@ -352,7 +379,7 @@ end; procedure TIBLookupComboEditBox.HandleEnter(Data: PtrInt); begin - SelectAll + SelectAll end; procedure TIBLookupComboEditBox.UpdateLinkData(Sender: TObject); @@ -462,12 +489,31 @@ begin FTimer.Interval := 0 end; +procedure TIBLookupComboEditBox.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + if (Operation = opRemove) and (AComponent = DataSource) then + ListSource := nil; +end; + procedure TIBLookupComboEditBox.SetItemIndex(const Val: integer); begin inherited SetItemIndex(Val); FLastKeyValue := KeyValue; end; +function TIBLookupComboEditBox.SQLSafe(aText: string): string; +var I: integer; +begin + Result := ''; + for I := 1 to length(aText) do + if aText[I] = '''' then + Result := Result + '''''' + else + Result := Result + aText[I]; +end; + procedure TIBLookupComboEditBox.UpdateShowing; begin inherited UpdateShowing; @@ -479,7 +525,8 @@ constructor TIBLookupComboEditBox.Create begin inherited Create(TheComponent); FDataLink := TIBLookupComboDataLink.Create(self); - FKeyPressInterval := 500; + FIBLookupControlLink := TIBLookupControlLink.Create(self); + FKeyPressInterval := 200; FAutoComplete := true; FTimer := TTimer.Create(nil); FTimer.Interval := 0; @@ -490,6 +537,7 @@ end; destructor TIBLookupComboEditBox.Destroy; begin if assigned(FDataLink) then FDataLink.Free; + if assigned(FIBLookupControlLink) then FIBLookupControlLink.Free; if assigned(FTimer) then FTimer.Free; inherited Destroy; end;