📄 jvdbultimgrid.pas
字号:
{-----------------------------------------------------------------------------
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: JvDBUltimGrid.PAS, released on 2004-07-22.
The Initial Developers of the Original Code are: Fr閐閞ic Leneuf-Magaud
Copyright (c) 2004 Fr閐閞ic Leneuf-Magaud
All Rights Reserved.
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
-----------------------------------------------------------------------------
HOW TO SORT FIELDS:
-----------------------------------------------------------------------------
---= Delphi example =---
// Don't forget to set SortWith and assign OnIndexNotFound/OnUserSort if needed
var
MyFields: TSortFields;
SetLength(MyFields, 2);
MyFields[0].Name := 'Country';
MyFields[0].Order := JvGridSort_ASC;
MyFields[1].Name := 'Sales';
MyFields[1].Order := JvGridSort_DESC;
MyUltimGrid.Sort(MyFields);
if not MyUltimGrid.SortOK then ...
---= BCB example =---
// Don't forget to set SortWith and assign OnIndexNotFound/OnUserSort if needed
TSortFields MyFields;
MyFields.set_length(2);
MyFields[0].Name = "Country";
MyFields[0].Order = JvGridSort_ASC;
MyFields[1].Name = "Sales";
MyFields[1].Order = JvGridSort_DESC;
MyUltimGrid->Sort(MyFields);
if (!MyUltimGrid->SortOK) ...
---= MANUAL SORTING =---
if TitleButtons is true then...
First click = the selected field is sorted in ascending order
Second click = the selected field is sorted in descending order
Shift+Click / Ctrl+Click = multi-column sorting
-----------------------------------------------------------------------------
HOW TO SEARCH A VALUE:
-----------------------------------------------------------------------------
---= Delphi example =---
var
// Declare these vars as global vars if you want to use SearchNext
ResultCol: Integer;
ResultField: TField;
with MyUltimGrid do
begin
SearchFields.Clear;
SearchFields.Add('Category');
SearchFields.Add('Common_Name');
SearchFields.Add('Species Name');
SearchFields.Add('Notes');
if not Search('fish', ResultCol, ResultField, False, False, True) then ...
end;
// then:
if not MyUltimGrid.SearchNext(ResultCol, ResultField, False, False, True) then ...
---= BCB example =---
// Declare these vars as global vars if you want to use SearchNext
int ResultCol;
TField *ResultField;
MyUltimGrid->SearchFields->Clear();
MyUltimGrid->SearchFields->Add("Category");
MyUltimGrid->SearchFields->Add("Common_Name");
MyUltimGrid->SearchFields->Add("Species Name");
MyUltimGrid->SearchFields->Add("Notes");
if (!MyUltimGrid->Search("fish", ResultCol, ResultField, false, false, true)) ...
// then:
if (!MyUltimGrid->SearchNext(ResultCol, ResultField, false, false, true)) ...
-----------------------------------------------------------------------------
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvDBUltimGrid.pas,v 1.9 2005/02/17 10:20:21 marquardt Exp $
unit JvDBUltimGrid;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
{$IFDEF VCL}
Windows,
{$ENDIF VCL}
{$IFDEF HAS_UNIT_VARIANTS}
Variants,
{$ENDIF HAS_UNIT_VARIANTS}
Classes, Graphics, Controls, DB,
JvDBGrid, JvTypes; {JvTypes contains Exception base class}
const
JvGridSort_ASC = True;
JvGridSort_UP = True;
JvGridSort_DESC = False;
JvGridSort_DOWN = False;
type
TSortField = record
Name: string;
Order: Boolean;
end;
TSortFields = array of TSortField;
TJvDBUltimGrid = class;
TIndexNotFoundEvent = procedure(Sender: TJvDBUltimGrid; FieldsToSort: TSortFields;
IndexFieldNames: string; DescFields: string; var Retry: Boolean) of object;
TUserSortEvent = procedure(Sender: TJvDBUltimGrid; var FieldsToSort: TSortFields;
SortString: string; var SortOK: Boolean) of object;
TRestoreGridPosEvent = procedure(Sender: TJvDBUltimGrid; SavedBookmark: TBookmark;
SavedRowPos: Integer) of object;
TSortWith = (swIndex, swFields, swUserFunc);
TJvDBUltimGrid = class(TJvDBGrid)
private
FSortedFields: TSortFields;
FSortWith: TSortWith;
FSortOK: Boolean;
FMultiColSort: Boolean;
FOnIndexNotFound: TIndexNotFoundEvent;
FOnUserSort: TUserSortEvent;
FSavedBookmark: TBookmarkStr;
FSavedRowPos: Integer;
FOnRestoreGridPosition: TRestoreGridPosEvent;
FValueToSearch: Variant;
FSearchFields: TStringList;
procedure SetMultiColSort(const Value: Boolean);
function PrivateSearch(var ResultCol: Integer; var ResultField: TField;
const CaseSensitive, WholeFieldOnly, Next: Boolean): Boolean;
protected
function SortMarkerAssigned(const AFieldName: string): Boolean; override;
procedure DoTitleClick(ACol: Longint; AField: TField); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Sort(FieldsToSort: TSortFields);
property SortedFields: TSortFields read FSortedFields;
property SortOK: Boolean read FSortOK;
procedure SaveGridPosition;
procedure RestoreGridPosition;
property SearchFields: TStringList read FSearchFields write FSearchFields;
function Search(const ValueToSearch: Variant; var ResultCol: Integer;
var ResultField: TField; const CaseSensitive, WholeFieldOnly, Focus: Boolean): Boolean;
function SearchNext(var ResultCol: Integer; var ResultField: TField;
const CaseSensitive, WholeFieldOnly, Focus: Boolean): Boolean;
published
property SortedField stored False; // Property of JvDBGrid not used in JvDBUltimGrid
property SortMarker stored False; // Property of JvDBGrid hidden in JvDBUltimGrid
{ SortWith:
swIndex : for BDE tables (assignment of OnIndexNotFound is recommended)
swFields : for ADO tables
swUserFunc : for other data providers (assignment of OnUserSort is mandatory) }
property SortWith: TSortWith read FSortWith write FSortWith default swIndex;
{ MultiColSort: is the sorting allowed on several columns or only one ? }
property MultiColSort: Boolean read FMultiColSort write SetMultiColSort default True;
{ OnIndexNotFound: fired when SortWith = swIndex and the sorting index is not found }
property OnIndexNotFound: TIndexNotFoundEvent
read FOnIndexNotFound write FOnIndexNotFound;
{ OnUserSort: fired when SortWith = swUserFunc }
property OnUserSort: TUserSortEvent read FOnUserSort write FOnUserSort;
{ OnRestoreGridPosition: fired when RestoreGridPosition is called }
property OnRestoreGridPosition: TRestoreGridPosEvent
read FOnRestoreGridPosition write FOnRestoreGridPosition;
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvDBUltimGrid.pas,v $';
Revision: '$Revision: 1.9 $';
Date: '$Date: 2005/02/17 10:20:21 $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
implementation
uses
TypInfo, Forms, SysUtils, DBGrids,
JclStrings,
JvResources;
constructor TJvDBUltimGrid.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FSortedFields := nil;
FSortWith := swIndex;
FSortOK := True;
FMultiColSort := True;
FOnIndexNotFound := nil;
FOnUserSort := nil;
FSavedBookmark := '';
FSavedRowPos := 0;
FOnRestoreGridPosition := nil;
FValueToSearch := Null;
FSearchFields := TStringList.Create;
end;
destructor TJvDBUltimGrid.Destroy;
begin
FSearchFields.Free;
inherited Destroy;
end;
function TJvDBUltimGrid.SortMarkerAssigned(const AFieldName: string): Boolean;
var
SF: Integer;
begin
Result := False;
if Assigned(FSortedFields) then
for SF := 0 to Length(FSortedFields) - 1 do
if AnsiSameText(AFieldName, FSortedFields[SF].Name) then
begin
if FSortedFields[SF].Order = JvGridSort_UP then
inherited ChangeSortMarker(smUp)
else
inherited ChangeSortMarker(smDown);
Result := True;
Break;
end;
end;
procedure TJvDBUltimGrid.Sort(FieldsToSort: TSortFields);
const
cIndexDefs = 'IndexDefs';
cIndexName = 'IndexName';
cIndexFieldNames = 'IndexFieldNames';
var
DSet: TDataSet;
procedure UpdateProp(const PropName: string; const Value: string);
begin
SetStrProp(DSet, PropName, Value);
FSortedFields := FieldsToSort;
FSortOK := True;
end;
var
SortString, DescString: string;
MaxFTS: Integer;
procedure SearchIndex;
var
IndexDefs: TIndexDefs;
I, J: Integer;
begin
IndexDefs := TIndexDefs(GetOrdProp(DSet, cIndexDefs));
IndexDefs.Update;
for I := 0 to IndexDefs.Count - 1 do
if AnsiSameText(SortString, IndexDefs.Items[I].Fields) then
begin
// The search succeeds if:
// - no descending order is requested
// and the index found has no desc fields nor the flag ixDescending set to true
// - descending order is requested
// and the index found has exactly the same desc fields
// - descending order is requested
// and the index found has no desc fields but its flag ixDescending is true
if DescString = '' then
begin
if (IndexDefs.Items[I].DescFields = '') and
not (ixDescending in IndexDefs.Items[I].Options) then
begin
UpdateProp(cIndexName, IndexDefs.Items[I].Name);
Break;
end;
end
else
if AnsiSameText(DescString, IndexDefs.Items[I].DescFields) then
begin
UpdateProp(cIndexName, IndexDefs.Items[I].Name);
Break;
end
else
if (IndexDefs.Items[I].DescFields = '') and
(ixDescending in IndexDefs.Items[I].Options) then
begin
for J := 0 to MaxFTS do
FieldsToSort[J].Order := JvGridSort_DESC;
UpdateProp(cIndexName, IndexDefs.Items[I].Name);
Break;
end;
end;
end;
var
FTS: Integer;
SortField: TField;
Retry: Boolean;
begin
FSortOK := False;
if Assigned(DataLink) and DataLink.Active and Assigned(FieldsToSort) then
begin
// Dataset must be in browse mode
DSet := DataSource.DataSet;
DSet.CheckBrowseMode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -