Files
lazarus-ccr/components/jvcllaz/run/JvCtrls/jvautocomplete.pas

888 lines
25 KiB
ObjectPascal

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvAutoComplete.pas, released on 2004-09-04.
The Initial Developer of the Original Code is Andreas Hausladen [Andreas dott Hausdaden att gmx dott de]
Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
All Rights Reserved.
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.delphi-jedi.org
Known Issues:
-----------------------------------------------------------------------------}
// $Id$
unit JvAutoComplete;
{$mode objfpc}{$H+}
interface
uses
LCLIntf, LCLType, LMessages,
SysUtils, Classes, Controls, StdCtrls;
type
TJvGetSearchItemPrefixEvent = procedure(Sender: TObject; var Prefix: string) of object;
{ TControlAutoComplete implements an autocomplete code for controls. It is an
abstract base class. After you have created an instance of a derived class
you must either assign the AutoCompleteEvent to the OnKeyPress event of the
control or you must call the AutoComplete method in a KeyPress event handler.
(ahuser) 2005-01-31: changed from TObject to TComponent due to Notification()
Do not register this component it is more a "TObject" than a TComponent. }
TJvControlAutoComplete = class(TComponent)
private
FFilter: string;
FLastTime: Cardinal;
FMaxFilterTime: Cardinal;
FListSearch: Boolean;
FActive: Boolean;
FOnDropDown: TNotifyEvent;
FOnValidateItems: TNotifyEvent;
FOnChange: TNotifyEvent;
FOnValueChange: TNotifyEvent;
FOnGetSearchItemPrefix: TJvGetSearchItemPrefixEvent;
protected
function GetText: TCaption; virtual; abstract;
procedure SetText(const Value: TCaption); virtual; abstract;
procedure GetEditSel(out StartPos, EndPos: Integer); virtual; abstract;
procedure SetEditSel(StartPos, EndPos: Integer); virtual; abstract;
procedure SetItemIndex(Index: Integer); virtual; abstract;
function GetItemIndex: Integer; virtual; abstract;
function FindItemPrefix(IndexStart: Integer; const Prefix: string): Integer; virtual; abstract;
function GetItemAt(Index: Integer): string; virtual; abstract;
function GetEditHandle: THandle; virtual; abstract;
function GetActive: Boolean; virtual;
procedure SetFilter(const Value: string);
procedure DoDropDown; dynamic;
procedure DoValidateItems; dynamic;
procedure DoChange; dynamic;
procedure DoValueChange; dynamic;
procedure GetSearchItemPrefix(var Prefix: string); dynamic;
public
constructor Create; reintroduce;
procedure AutoCompleteEvent(Sender: TObject; var Key: Char);
procedure AutoComplete(var Key: Char); virtual;
property ListSearch: Boolean read FListSearch write FListSearch; // no edit possible
property MaxFilterTime: Cardinal read FMaxFilterTime write FMaxFilterTime; // only with ListSearch
property Active: Boolean read GetActive write FActive;
property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
property OnValidateItems: TNotifyEvent read FOnValidateItems write FOnValidateItems;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnValueChange: TNotifyEvent read FOnValueChange write FOnValueChange;
property OnGetSearchItemPrefix: TJvGetSearchItemPrefixEvent read FOnGetSearchItemPrefix write FOnGetSearchItemPrefix;
end;
TJvBaseEditListAutoComplete = class(TJvControlAutoComplete)
private
FEditCtrl: TCustomEdit;
FList: TStrings;
procedure SetEditCtrl(Value: TCustomEdit);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
function GetText: TCaption; override;
procedure SetText(const Value: TCaption); override;
procedure GetEditSel(out StartPos, EndPos: Integer); override;
procedure SetEditSel(StartPos, EndPos: Integer); override;
function FindItemPrefix(IndexStart: Integer; const Prefix: string): Integer; override;
function GetItemAt(Index: Integer): string; override;
function GetEditHandle: THandle; override;
function GetActive: Boolean; override;
property List: TStrings read FList write FList;
public
constructor Create(AEditCtrl: TCustomEdit; AList: TStrings);
destructor Destroy; override;
property EditCtrl: TCustomEdit read FEditCtrl write SetEditCtrl;
end;
{ TEditListAutoComplete implements an autocomplete code for a Edit/TStrings
pair. After you have created an instance of this class you must either
assign the AutoCompleteEvent to the OnKeyPress event of the edit control
or you must call the AutoComplete method in a KeyPress event handler. }
TJvEditListAutoComplete = class(TJvBaseEditListAutoComplete)
private
FOnItemIndexChange: TNotifyEvent;
FOnValidateItemIndex: TNotifyEvent;
public
FItemIndex: Integer;
function GetList: TStrings;
procedure SetList(Value: TStrings);
procedure SetInternalItemIndex(Value: Integer);
protected
procedure SetItemIndex(Index: Integer); override;
function GetItemIndex: Integer; override;
public
constructor Create(AEditCtrl: TCustomEdit; AList: TStrings);
property ItemIndex: Integer read FItemIndex write SetInternalItemIndex;
property List: TStrings read GetList write SetList;
property OnItemIndexChange: TNotifyEvent read FOnItemIndexChange write FOnItemIndexChange;
property OnValidateItemIndex: TNotifyEvent read FOnValidateItemIndex write FOnValidateItemIndex;
end;
{ TEditListBoxAutoComplete implements an autocomplete code for a Edit/ListBox
pair. After you have created an instance of this class you must either
assign the AutoCompleteEvent to the OnKeyPress event of the edit control
or you must call the AutoComplete method in a KeyPress event handler. }
TJvEditListBoxAutoComplete = class(TJvBaseEditListAutoComplete)
private
FListBox: TCustomListBox;
procedure SetListBox(Value: TCustomListBox);
protected
procedure SetItemIndex(Index: Integer); override;
function GetItemIndex: Integer; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
constructor Create(AEditCtrl: TCustomEdit; AListBox: TCustomListBox);
destructor Destroy; override;
property ListBox: TCustomListBox read FListBox write SetListBox;
end;
{ TComboBoxAutoComplete implements an autocomplete code for a ComboBox.
After you have created an instance of this class you must either assign the
AutoCompleteEvent to the OnKeyPress event of the edit control or you must
call the AutoComplete method in a KeyPress event handler. }
TJvComboBoxAutoComplete = class(TJvControlAutoComplete)
private
FComboBox: TCustomComboBox;
procedure SetComboBox(Value: TCustomComboBox);
protected
function GetText: TCaption; override;
procedure SetText(const Value: TCaption); override;
procedure GetEditSel(out StartPos, EndPos: Integer); override;
procedure SetEditSel(StartPos, EndPos: Integer); override;
procedure SetItemIndex(Index: Integer); override;
function GetItemIndex: Integer; override;
function FindItemPrefix(IndexStart: Integer; const Prefix: string): Integer; override;
function GetItemAt(Index: Integer): string; override;
function GetEditHandle: THandle; override;
function GetActive: Boolean; override;
public
constructor Create(AComboBox: TCustomComboBox);
property ComboBox: TCustomComboBox read FComboBox write SetComboBox;
end;
TJvLookupAutoCompleteKind = (akListBox, akStrings);
TJvLookupAutoComplete = class(TComponent)
private
FAutoComplete: TJvEditListAutoComplete;
FListBox: TCustomListBox;
FStrings: TStrings;
FKind: TJvLookupAutoCompleteKind;
FOrgKeyPress: TKeyPressEvent;
FOnChange: TNotifyEvent;
FOnValidateStrings: TNotifyEvent;
FOnDropDown: TNotifyEvent;
FOnValueChange: TNotifyEvent;
function GetEdit: TCustomEdit;
function GetItemIndex: Integer;
function GetListSearch: Boolean;
procedure SetEdit(Value: TCustomEdit);
procedure SetItemIndex(Value: Integer);
procedure SetKind(Value: TJvLookupAutoCompleteKind);
procedure SetListBox(Value: TCustomListBox);
procedure SetListSearch(Value: Boolean);
procedure SetStrings(Value: TStrings);
function GetActive: Boolean;
procedure SetActive(const Value: Boolean);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure EvKeyPress(Sender: TObject; var Key: Char); dynamic;
procedure EvDropDown(Sender: TObject); dynamic;
procedure EvValidateStrings(Sender: TObject); dynamic;
procedure EvChange(Sender: TObject); dynamic;
procedure EvValueChange(Sender: TObject); dynamic;
procedure EvItemIndexChange(Sender: TObject); dynamic;
procedure EvValidateItemIndex(Sender: TObject); dynamic;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property ItemIndex: Integer read GetItemIndex write SetItemIndex;
published
property Active: Boolean read GetActive write SetActive default True;
property Edit: TCustomEdit read GetEdit write SetEdit;
property ListBox: TCustomListBox read FListBox write SetListBox;
property Strings: TStrings read FStrings write SetStrings;
property Kind: TJvLookupAutoCompleteKind read FKind write SetKind default akListBox;
property ListSearch: Boolean read GetListSearch write SetListSearch default False;
property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
property OnValidateStrings: TNotifyEvent read FOnValidateStrings write FOnValidateStrings;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnValueChange: TNotifyEvent read FOnValueChange write FOnValueChange;
end;
implementation
uses
StrUtils,
JvConsts, JvJVCLUtils;
//=== { TJvControlAutoComplete } =============================================
constructor TJvControlAutoComplete.Create;
begin
inherited Create(nil);
FActive := True;
FMaxFilterTime := 500;
end;
function TJvControlAutoComplete.GetActive: Boolean;
begin
Result := FActive;
end;
procedure TJvControlAutoComplete.SetFilter(const Value: string);
begin
FFilter := Value;
end;
procedure TJvControlAutoComplete.DoValidateItems;
begin
if Assigned(FOnValidateItems) then
FOnValidateItems(Self);
end;
procedure TJvControlAutoComplete.DoChange;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TJvControlAutoComplete.DoDropDown;
begin
if Assigned(FOnDropDown) then
FOnDropDown(Self);
end;
procedure TJvControlAutoComplete.DoValueChange;
begin
if Assigned(FOnValueChange) then
FOnValueChange(Self);
end;
procedure TJvControlAutoComplete.GetSearchItemPrefix(var Prefix: string);
begin
if Assigned(FOnGetSearchItemPrefix) then
FOnGetSearchItemPrefix(Self, Prefix);
end;
procedure TJvControlAutoComplete.AutoCompleteEvent(Sender: TObject; var Key: Char);
begin
AutoComplete(Key);
end;
procedure TJvControlAutoComplete.AutoComplete(var Key: Char);
var
StartPos, EndPos: Integer;
SaveText, OldText: TCaption;
LastByte: Integer;
LT: Int64;
Msg: TMsg;
function HasSelectedText(out StartPos, EndPos: Integer): Boolean;
begin
GetEditSel(StartPos, EndPos);
Result := EndPos > StartPos;
end;
procedure DeleteSelectedText;
var
StartPos, EndPos: Integer;
OldText: string;
begin
OldText := GetText;
GetEditSel(StartPos, EndPos);
Delete(OldText, StartPos + 1, EndPos - StartPos);
SetItemIndex(-1);
SetText(OldText);
SetEditSel(StartPos, StartPos);
end;
function SelectItem(const AnItem: string): Boolean;
var
Idx: Integer;
ValueChange: Boolean;
PartToFind: string;
begin
Result := False;
PartToFind := AnItem;
GetSearchItemPrefix(PartToFind);
if PartToFind = '' then
begin
SetItemIndex(-1);
DoChange;
Exit;
end;
Idx := FindItemPrefix(-1, PartToFind);
if Idx < 0 then
Exit;
Result := True;
ValueChange := Idx <> GetItemIndex;
SetItemIndex(Idx);
if ListSearch then
begin
SetItemIndex(Idx);
FFilter := PartToFind;
end
else
begin
SetText(AnItem + Copy(GetItemAt(Idx), Length(PartToFind) + 1, MaxInt));
SetEditSel(Length(AnItem), Length(GetText));
end;
if ValueChange then
DoValueChange;
end;
begin
if not Active then
Exit;
if ListSearch then
begin
LT := GetTickCount64;
if FLastTime > LT then
LT := $100000000 + LT; // double limit.
if LT - FLastTime >= MaxFilterTime then
FFilter := '';
FLastTime := GetTickCount64;
end
else
FFilter := GetText;
case Key of
Esc {VK_ESCAPE}:
Exit;
Tab {VK_TAB}:
begin
DoValidateItems;
DoDropDown;
end;
BackSpace {VK_BACK}:
begin
DoValidateItems;
if HasSelectedText(StartPos, EndPos) then
DeleteSelectedText
else
if not ListSearch and (GetText <> '') then
begin
SaveText := GetText;
LastByte := StartPos;
while ByteType(SaveText, LastByte) = mbTrailByte do
Dec(LastByte);
OldText := Copy(SaveText, 1, LastByte - 1);
SetItemIndex(-1);
SetText(OldText + Copy(SaveText, EndPos + 1, MaxInt));
SetEditSel(LastByte - 1, LastByte - 1);
FFilter := GetText;
end
else
begin
while ByteType(FFilter, Length(FFilter)) = mbTrailByte do
Delete(FFilter, Length(FFilter), 1);
Delete(FFilter, Length(FFilter), 1);
end;
Key := #0;
DoChange;
end;
else
DoValidateItems;
DoDropDown;
if HasSelectedText(StartPos, EndPos) then
SaveText := Copy(FFilter, 1, StartPos) + Key
else
SaveText := FFilter + Key;
if CharInSet(Key, LeadBytes) then
begin
if PeekMessage(Msg{%H-}, GetEditHandle, 0, 0, PM_NOREMOVE) and (Msg.Message = LM_CHAR) then
begin
if SelectItem(SaveText + Char(Msg.WParam)) then
begin
PeekMessage(Msg, GetEditHandle, 0, 0, PM_REMOVE);
Key := #0;
end;
end;
end
else
if SelectItem(SaveText) then
Key := #0;
end;
end;
//=== { TJvBaseEditListAutoComplete } ========================================
constructor TJvBaseEditListAutoComplete.Create(AEditCtrl: TCustomEdit;
AList: TStrings);
begin
inherited Create;
FList := AList;
EditCtrl := AEditCtrl;
end;
destructor TJvBaseEditListAutoComplete.Destroy;
begin
EditCtrl := nil;
inherited Destroy;
end;
procedure TJvBaseEditListAutoComplete.Notification(AComponent: TComponent;
Operation: TOperation);
begin
if (Operation = opRemove) and (AComponent = FEditCtrl) then
begin
FEditCtrl := nil;
SetFilter('');
end;
inherited Notification(AComponent, Operation);
end;
procedure TJvBaseEditListAutoComplete.SetEditCtrl(Value: TCustomEdit);
begin
ReplaceComponentReference(Self, Value, TComponent(FEditCtrl));
if FEditCtrl <> nil then
SetFilter(FEditCtrl.Text)
else
SetFilter('');
end;
type
TCustomEditAccess = class(TCustomEdit);
function TJvBaseEditListAutoComplete.GetText: TCaption;
begin
Result := EditCtrl.Text;
end;
procedure TJvBaseEditListAutoComplete.SetText(const Value: TCaption);
begin
EditCtrl.Text := Value;
end;
procedure TJvBaseEditListAutoComplete.GetEditSel(out StartPos, EndPos: Integer);
begin
// SendMessage(EditCtrl.Handle, EM_GETSEL, WPARAM(@StartPos), LPARAM(@EndPos));
StartPos := EditCtrl.SelStart;
EndPos := StartPos + EditCtrl.SelLength;
end;
procedure TJvBaseEditListAutoComplete.SetEditSel(StartPos, EndPos: Integer);
begin
EditCtrl.SelStart := StartPos;
EditCtrl.SelLength := EndPos - StartPos;
end;
function TJvBaseEditListAutoComplete.FindItemPrefix(IndexStart: Integer; const Prefix: string): Integer;
begin
if List <> nil then
begin
for Result := IndexStart + 1 to List.Count - 1 do
if AnsiStartsText(Prefix, List[Result]) then
Exit;
for Result := 0 to IndexStart do
if AnsiStartsText(Prefix, List[Result]) then
Exit;
end;
Result := -1;
end;
function TJvBaseEditListAutoComplete.GetItemAt(Index: Integer): string;
begin
Result := List[Index];
end;
function TJvBaseEditListAutoComplete.GetEditHandle: THandle;
begin
Result := FEditCtrl.Handle;
end;
function TJvBaseEditListAutoComplete.GetActive: Boolean;
begin
Result := inherited GetActive and (EditCtrl <> nil) and (List <> nil) and
not TCustomEditAccess(EditCtrl).ReadOnly;
end;
//=== { TJvEditListAutoComplete } ============================================
constructor TJvEditListAutoComplete.Create(AEditCtrl: TCustomEdit;
AList: TStrings);
begin
inherited Create(AEditCtrl, AList);
FItemIndex := -1;
end;
procedure TJvEditListAutoComplete.SetInternalItemIndex(Value: Integer);
begin
if (Value < 0) or (List = nil) then
Value := -1;
FItemIndex := Value;
if (List <> nil) and (FItemIndex >= List.Count) then
FItemIndex := List.Count - 1;
end;
function TJvEditListAutoComplete.GetList: TStrings;
begin
Result := FList;
end;
procedure TJvEditListAutoComplete.SetList(Value: TStrings);
begin
FItemIndex := -1;
FList := Value;
end;
procedure TJvEditListAutoComplete.SetItemIndex(Index: Integer);
begin
FItemIndex := Index;
if Assigned(FOnItemIndexChange) then
FOnItemIndexChange(Self);
end;
function TJvEditListAutoComplete.GetItemIndex: Integer;
begin
if Assigned(FOnValidateItemIndex) then
FOnValidateItemIndex(Self);
Result := FItemIndex;
end;
//=== { TJvEditListBoxAutoComplete } =========================================
constructor TJvEditListBoxAutoComplete.Create(AEditCtrl: TCustomEdit; AListBox: TCustomListBox);
begin
if AListBox = nil then
inherited Create(AEditCtrl, nil)
else
inherited Create(AEditCtrl, AListBox.Items);
ListBox := AListBox;
end;
destructor TJvEditListBoxAutoComplete.Destroy;
begin
ListBox := nil;
inherited Destroy;
end;
procedure TJvEditListBoxAutoComplete.Notification(AComponent: TComponent; Operation: TOperation);
begin
if (Operation = opRemove) and (AComponent = FListBox) then
begin
FListBox := nil;
List := nil;
end;
inherited Notification(AComponent, Operation);
end;
procedure TJvEditListBoxAutoComplete.SetListBox(Value: TCustomListBox);
begin
ReplaceComponentReference(Self, Value, TComponent(FListBox));
if FListBox <> nil then
List := FListBox.Items
else
List := nil;
end;
procedure TJvEditListBoxAutoComplete.SetItemIndex(Index: Integer);
begin
ListBox.ItemIndex := Index;
end;
function TJvEditListBoxAutoComplete.GetItemIndex: Integer;
begin
Result := ListBox.ItemIndex;
end;
//=== { TJvComboBoxAutoComplete } ============================================
constructor TJvComboBoxAutoComplete.Create(AComboBox: TCustomComboBox);
begin
inherited Create;
FComboBox := AComboBox;
end;
type
TCustomComboBoxAccess = class(TCustomComboBox);
function TJvComboBoxAutoComplete.GetActive: Boolean;
begin
Result := inherited GetActive and (ComboBox <> nil);
if ComboBox <> nil then
FListSearch := not (TCustomComboBoxAccess(ComboBox).Style in [csDropDown , csSimple ]);
end;
function TJvComboBoxAutoComplete.GetEditHandle: THandle;
begin
Result := ComboBox.Handle;
end;
procedure TJvComboBoxAutoComplete.GetEditSel(out StartPos, EndPos: Integer);
begin
// SendMessage(ComboBox.Handle, CB_GETEDITSEL, WPARAM(@StartPos), LPARAM(@EndPos));
StartPos := ComboBox.SelStart;
EndPos := StartPos + ComboBox.SelLength;
end;
procedure TJvComboBoxAutoComplete.SetEditSel(StartPos, EndPos: Integer);
begin
ComboBox.SelStart := StartPos;
ComboBox.SelLength := EndPos - StartPos;
end;
function TJvComboBoxAutoComplete.FindItemPrefix(IndexStart: Integer;
const Prefix: string): Integer;
begin
for Result := IndexStart + 1 to ComboBox.Items.Count - 1 do
if AnsiStartsText(Prefix, ComboBox.Items[Result]) then
Exit;
for Result := 0 to IndexStart do
if AnsiStartsText(Prefix, ComboBox.Items[Result]) then
Exit;
Result := -1;
end;
procedure TJvComboBoxAutoComplete.SetItemIndex(Index: Integer);
begin
ComboBox.ItemIndex := Index;
end;
function TJvComboBoxAutoComplete.GetItemIndex: Integer;
begin
Result := ComboBox.ItemIndex;
end;
function TJvComboBoxAutoComplete.GetItemAt(Index: Integer): string;
begin
Result := ComboBox.Items[Index];
end;
function TJvComboBoxAutoComplete.GetText: TCaption;
begin
Result := TCustomComboBoxAccess(ComboBox).Text;
end;
procedure TJvComboBoxAutoComplete.SetText(const Value: TCaption);
begin
TCustomComboBoxAccess(ComboBox).Text := Value;
end;
procedure TJvComboBoxAutoComplete.SetComboBox(Value: TCustomComboBox);
begin
FComboBox := Value;
if FComboBox <> nil then
SetFilter(GetText)
else
SetFilter('');
end;
//=== { TJvLookupAutoComplete } ==============================================
constructor TJvLookupAutoComplete.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAutoComplete := TJvEditListAutoComplete.Create(nil, nil);
FAutoComplete.OnDropDown := @EvDropDown;
FAutoComplete.OnValidateItems := @EvValidateStrings;
FAutoComplete.OnChange := @EvChange;
FAutoComplete.OnValueChange := @EvValueChange;
FAutoComplete.OnItemIndexChange := @EvItemIndexChange;
FAutoComplete.OnValidateItemIndex := @EvValidateItemIndex;
FStrings := TStringList.Create;
end;
destructor TJvLookupAutoComplete.Destroy;
begin
SetEdit(nil); // SetEdit accesses FAutoComplete
FAutoComplete.Free;
SetListBox(nil);
FStrings.Free;
inherited Destroy;
end;
procedure TJvLookupAutoComplete.EvChange(Sender: TObject);
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TJvLookupAutoComplete.EvDropDown(Sender: TObject);
begin
if Assigned(FOnDropDown) then
FOnDropDown(Self);
end;
procedure TJvLookupAutoComplete.EvItemIndexChange(Sender: TObject);
begin
ItemIndex := FAutoComplete.ItemIndex;
end;
procedure TJvLookupAutoComplete.EvKeyPress(Sender: TObject; var Key: Char);
begin
{ Make sure to use the current Items of the ListBox }
if FKind = akListBox then SetKind(FKind);
if Assigned(FOrgKeyPress) then
FOrgKeyPress(Sender, Key);
FAutoComplete.AutoComplete(Key);
end;
procedure TJvLookupAutoComplete.EvValidateItemIndex(Sender: TObject);
begin
FAutoComplete.ItemIndex := ItemIndex;
end;
procedure TJvLookupAutoComplete.EvValidateStrings(Sender: TObject);
begin
if Assigned(FOnValidateStrings) then
FOnValidateStrings(Self);
end;
procedure TJvLookupAutoComplete.EvValueChange(Sender: TObject);
begin
if Assigned(FOnValueChange) then
FOnValueChange(Self);
end;
function TJvLookupAutoComplete.GetActive: Boolean;
begin
Result := FAutoComplete.Active;
end;
function TJvLookupAutoComplete.GetEdit: TCustomEdit;
begin
Result := FAutoComplete.EditCtrl;
end;
function TJvLookupAutoComplete.GetItemIndex: Integer;
begin
Result := -1;
case Kind of
akListBox:
if ListBox <> nil then
Result := ListBox.ItemIndex;
akStrings:
Result := FAutoComplete.ItemIndex;
end;
end;
function TJvLookupAutoComplete.GetListSearch: Boolean;
begin
Result := FAutoComplete.ListSearch;
end;
procedure TJvLookupAutoComplete.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then
begin
if AComponent = Edit then
Edit := nil
else
if AComponent = ListBox then
ListBox := nil;
end;
end;
procedure TJvLookupAutoComplete.SetActive(const Value: Boolean);
begin
FAutoComplete.Active := Value;
end;
procedure TJvLookupAutoComplete.SetEdit(Value: TCustomEdit);
begin
if Value <> Edit then
begin
if Edit <> nil then
begin
TCustomEditAccess(Edit).OnKeyPress := FOrgKeyPress;
Edit.RemoveFreeNotification(Self);
end;
FAutoComplete.EditCtrl := Value;
if Edit <> nil then
begin
Edit.FreeNotification(Self);
FOrgKeyPress := TCustomEditAccess(Edit).OnKeyPress;
TCustomEditAccess(Edit).OnKeyPress := @EvKeyPress;
end;
end;
end;
procedure TJvLookupAutoComplete.SetItemIndex(Value: Integer);
begin
case Kind of
akListBox:
if ListBox <> nil then
ListBox.ItemIndex := Value;
akStrings:
FAutoComplete.ItemIndex := Value;
end;
end;
procedure TJvLookupAutoComplete.SetKind(Value: TJvLookupAutoCompleteKind);
begin
FKind := Value;
case FKind of
akListBox:
if ListBox <> nil then
FAutoComplete.List := ListBox.Items
else
FAutoComplete.List := nil;
akStrings:
FAutoComplete.List := FStrings;
end;
end;
procedure TJvLookupAutoComplete.SetListBox(Value: TCustomListBox);
begin
if Value <> FListBox then
begin
ReplaceComponentReference(Self, Value, TComponent(FListBox));
if Kind = akListBox then
begin
if FListBox <> nil then
FAutoComplete.List := FListBox.Items
else
FAutoComplete.List := nil;
end;
end;
end;
procedure TJvLookupAutoComplete.SetListSearch(Value: Boolean);
begin
FAutoComplete.ListSearch := Value;
end;
procedure TJvLookupAutoComplete.SetStrings(Value: TStrings);
begin
if Value <> FStrings then
begin
FStrings.Assign(Value);
if Kind = akStrings then
FAutoComplete.List := FStrings;
end;
end;
end.