unit uDBSelectionListUtils; interface uses Classes, DB, cxGridTableView, uDADataTable, uIntegerListUtils, cxGridCustomView; type { ISelectedRowList = interface '1886B04A-DB0D-40AE-BCAE-DA57CD4CD582' function GetSelectedRows : TSelectedRowList; property SelectedRows : TSelectedRowList read GetSelectedRows; end;} TSelectedRecords = class; ISelectedRecords = interface ['{4B0FA100-15E1-4511-A897-7DF787E2DCD4}'] function GetCount: Integer; property Count: Integer read GetCount; function GetItem(Index: Integer): Integer; property Items[Index: Integer]: Integer read GetItem; default; function SelectedRecordsObj : TSelectedRecords; end; TSelectedRecords = class(TInterfacedObject, ISelectedRecords) private FDataTable: TDADataTable; FLisinteger : TIntegerList; FSelectedRecordsObj: TSelectedRecords; function GetCount: Integer; function GetCurrentRowSelected: Boolean; function GetItem(Index: Integer): integer; procedure SetCurrentRowSelected(Value: Boolean); procedure SetSelectedRecordsObj(const Value: TSelectedRecords); protected function CurrentRow: integer; function Compare(const Item1, Item2: integer): Boolean; function SelectedRecordsObj : TSelectedRecords; public constructor Create(ADataTable : TDADataTable); destructor Destroy; override; procedure Clear; // free all bookmarks function Find(const Item: integer; var Index: Integer): Boolean; function IndexOf(const Item: integer): Integer; property Count: Integer read GetCount; property CurrentRowSelected: Boolean read GetCurrentRowSelected write SetCurrentRowSelected; property Items[Index: Integer]: integer read GetItem; default; function LocateItem(const Index : Integer) : Boolean; end; implementation uses DBConsts, cxGridCustomTableView, cxControls, Math, Variants, Dialogs; { TSelectedRowList } constructor TSelectedRecords.Create(ADataTable : TDADataTable); begin inherited Create; FLisinteger := TIntegerList.Create; FDataTable := ADataTable; end; destructor TSelectedRecords.Destroy; begin Clear; FLisinteger.Free; FDataTable := NIL; inherited Destroy; end; procedure TSelectedRecords.Clear; begin if FLisinteger.Count = 0 then Exit; FLisinteger.Clear; end; function TSelectedRecords.Compare(const Item1, Item2: integer): Boolean; begin Result := (Item1 = Item2); end; function TSelectedRecords.CurrentRow: integer; begin if not FDataTable.Active then raise EDatabaseError.Create(sDataSetClosed); Result := FDataTable.FieldByName('ID').AsInteger; end; function TSelectedRecords.GetCurrentRowSelected: Boolean; var Index: Integer; begin Result := Find(CurrentRow, Index); end; function TSelectedRecords.Find(const Item: integer; var Index: Integer): Boolean; begin Result := FLisinteger.Find(Item, Index) end; function TSelectedRecords.GetCount: Integer; begin Result := FLisinteger.Count; end; function TSelectedRecords.GetItem(Index: Integer): integer; begin Result := FLisinteger.Integers[Index]; end; function TSelectedRecords.IndexOf(const Item: integer): Integer; var AIndex : Integer; begin Result := -1; if FLisinteger.Find(Item, AIndex) then Result := AIndex end; function TSelectedRecords.SelectedRecordsObj: TSelectedRecords; begin Result := Self; end; procedure TSelectedRecords.SetCurrentRowSelected(Value: Boolean); var Index: Integer; Current: integer; begin Current := CurrentRow; if (Find(Current, Index) = Value) then Exit; if Value then FLisinteger.Add(Current) else FLisinteger.Delete(Index); end; procedure TSelectedRecords.SetSelectedRecordsObj(const Value: TSelectedRecords); begin FSelectedRecordsObj := Value; end; function TSelectedRecords.LocateItem(const Index: Integer) : Boolean; begin if not FDataTable.Active then raise EDatabaseError.Create(sDataSetClosed); Result := FDataTable.Locate('ID', Items[Index], []); end; end.