diff --git a/components/rx/trunk/demos/rxdbgrid/WordWrap/WordWrapDemo.lps b/components/rx/trunk/demos/rxdbgrid/WordWrap/WordWrapDemo.lps
index 70378cfd7..46f8640f3 100644
--- a/components/rx/trunk/demos/rxdbgrid/WordWrap/WordWrapDemo.lps
+++ b/components/rx/trunk/demos/rxdbgrid/WordWrap/WordWrapDemo.lps
@@ -3,7 +3,7 @@
-
+
@@ -11,7 +11,7 @@
-
+
@@ -20,49 +20,51 @@
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -70,163 +72,170 @@
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
diff --git a/components/rx/trunk/rxdb/rxdbgrid.pas b/components/rx/trunk/rxdb/rxdbgrid.pas
index 0fde1c26c..48cf239f8 100644
--- a/components/rx/trunk/rxdb/rxdbgrid.pas
+++ b/components/rx/trunk/rxdb/rxdbgrid.pas
@@ -54,6 +54,7 @@ type
TRxColumn = class;
TRxDBGridAbstractTools = class;
TRxDbGridColumnsEnumerator = class;
+ TRxColumnFooterItemsEnumerator = class;
TRxQuickSearchNotifyEvent = procedure(Sender: TObject; Field: TField;
@@ -358,10 +359,25 @@ type
procedure Update(Item: TCollectionItem); override;
public
constructor Create(AOwner: TPersistent);
+ function GetEnumerator: TRxColumnFooterItemsEnumerator;
public
property Items[Index: integer]: TRxColumnFooterItem read GetItem write SetItem; default;
end;
+ { TRxColumnFooterItemsEnumerator }
+
+ TRxColumnFooterItemsEnumerator = class
+ private
+ FList: TRxColumnFooterItems;
+ FPosition: Integer;
+ public
+ constructor Create(AList: TRxColumnFooterItems);
+ function GetCurrent: TRxColumnFooterItem;
+ function MoveNext: Boolean;
+ property Current: TRxColumnFooterItem read GetCurrent;
+ end;
+
+
{ TRxColumnFilter }
TRxFilterState = (rxfsAll, rxfsEmpty, rxfsNonEmpty, rxfsFilter{, rxfsTopXXXX});
@@ -463,6 +479,64 @@ type
property Items[Index: integer]: TRxColumnEditButton read GetItem write SetItem; default;
end;
+ TColumnGroupItemValue = class
+ FieldName:string;
+ GroupValue:Double;
+ end;
+
+ { TColumnGroupItem }
+
+ TColumnGroupItem = class
+ RecordNo:integer;
+ FieldValue:string;
+ RecordCount:integer;
+ constructor Create;
+ destructor Destroy; override;
+ end;
+
+ { TColumnGroupItems }
+
+ TColumnGroupItems = class
+ private
+ FActive: boolean;
+ procedure SetActive(AValue: boolean);
+ public
+ constructor Create;
+ destructor Destroy; override;
+ function FindGroup(ARecordNo:integer):TColumnGroupItem;
+ procedure Clear;
+ procedure UpdateValues;
+ published
+ property Active:boolean read FActive write SetActive;
+ end;
+
+
+
+ { TRxColumnGroupParam }
+
+ TRxColumnGroupParam = class(TCollectionItem)
+ private
+ FFileName: string;
+ FValueType: TFooterValueType;
+ published
+ property FileName:string read FFileName write FFileName;
+ property ValueType:TFooterValueType read FValueType write FValueType;
+ end;
+
+ { TRxColumnGroupParams }
+
+ TRxColumnGroupParams = class(TOwnedCollection)
+ private
+ function GetItem(Index: integer): TRxColumnGroupParam;
+ procedure SetItem(Index: integer; AValue: TRxColumnGroupParam);
+ protected
+ public
+ function Add: TRxColumnGroupParam;
+ public
+ property Items[Index: integer]: TRxColumnGroupParam read GetItem write SetItem; default;
+ end;
+
+
{ TRxColumn }
TRxColumn = class(TColumn)
@@ -482,6 +556,8 @@ type
FSortPosition: integer;
FWordWrap: boolean;
FFooters: TRxColumnFooterItems;
+ //Group support
+ FGroupItems:TColumnGroupItems;
function GetConstraints: TRxDBGridCollumnConstraints;
function GetFooter: TRxColumnFooterItem;
function GetFooters: TRxColumnFooterItems;
@@ -1093,6 +1169,89 @@ type
procedure EditingDone; override;
end;
+{ TRxColumnGroupParams }
+
+function TRxColumnGroupParams.GetItem(Index: integer): TRxColumnGroupParam;
+begin
+ Result:= TRxColumnGroupParam(inherited Items[Index]);
+end;
+
+procedure TRxColumnGroupParams.SetItem(Index: integer;
+ AValue: TRxColumnGroupParam);
+begin
+ inherited SetItem(Index, AValue);
+end;
+
+function TRxColumnGroupParams.Add: TRxColumnGroupParam;
+begin
+ Result:=TRxColumnGroupParam.Create(Self);
+end;
+
+{ TRxColumnFooterItemsEnumerator }
+
+constructor TRxColumnFooterItemsEnumerator.Create(AList: TRxColumnFooterItems);
+begin
+ FList := AList;
+ FPosition := -1;
+end;
+
+function TRxColumnFooterItemsEnumerator.GetCurrent: TRxColumnFooterItem;
+begin
+ Result := FList[FPosition];
+end;
+
+function TRxColumnFooterItemsEnumerator.MoveNext: Boolean;
+begin
+ Inc(FPosition);
+ Result := FPosition < FList.Count;
+end;
+
+{ TColumnGroupItems }
+
+procedure TColumnGroupItems.SetActive(AValue: boolean);
+begin
+ if FActive=AValue then Exit;
+ FActive:=AValue;
+end;
+
+constructor TColumnGroupItems.Create;
+begin
+ inherited Create;
+ FActive:=false;
+end;
+
+destructor TColumnGroupItems.Destroy;
+begin
+ inherited Destroy;
+end;
+
+function TColumnGroupItems.FindGroup(ARecordNo: integer): TColumnGroupItem;
+begin
+ Result:=nil;
+end;
+
+procedure TColumnGroupItems.Clear;
+begin
+
+end;
+
+procedure TColumnGroupItems.UpdateValues;
+begin
+
+end;
+
+{ TColumnGroupItem }
+
+constructor TColumnGroupItem.Create;
+begin
+
+end;
+
+destructor TColumnGroupItem.Destroy;
+begin
+ inherited Destroy;
+end;
+
{ TRxDbGridColumnsEnumerator }
constructor TRxDbGridColumnsEnumerator.Create(AList: TRxDbGridColumns);
@@ -1615,6 +1774,11 @@ begin
inherited Create(AOwner, TRxColumnFooterItem);
end;
+function TRxColumnFooterItems.GetEnumerator: TRxColumnFooterItemsEnumerator;
+begin
+ Result:=TRxColumnFooterItemsEnumerator.Create(Self);
+end;
+
{ TRxDBGridAbstractTools }
procedure TRxDBGridAbstractTools.SetRxDBGrid(AValue: TRxDBGrid);
@@ -4824,60 +4988,54 @@ var
SaveAfterScroll:TDataSetNotifyEvent;
SaveBeforeScroll:TDataSetNotifyEvent;
- RCol:TRxColumn;
+ C:TRxColumn;
AValue:Variant;
- FCList:TFPList;
+ FCList, FCList2:TFPList;
j: Integer;
+ F: TRxColumnFooterItem;
begin
if (not (FFooterOptions.Active and DatalinkActive)) or (Columns.Count = 0) or (gsAddingAutoColumns in GridStatus) then
Exit;
- //Дополнительно проверим - а стоит ли делать пробег по данным - есть ли агрегатные функции
+
if Assigned(OnRxCalcFooterValues)then
begin
Inc(FInProcessCalc);
- for i := 0 to Columns.Count - 1 do
+ for C in Columns do
begin
- RCol := TRxColumn(Columns[i]);
- RCol.Footer.ResetTestValue;
+ C.Footer.ResetTestValue;
AValue:=Null;
- OnRxCalcFooterValues(Self, RCol, AValue);
- if AValue<>null then RCol.Footer.FTestValue := AValue;
+ OnRxCalcFooterValues(Self, C, AValue);
+ if AValue<>null then C.Footer.FTestValue := AValue;
end;
Dec(FInProcessCalc);
Exit;
end;
APresent := False;
- for i := 0 to Columns.Count - 1 do
+ for C in Columns do
begin
- APresent := TRxColumn(Columns[i]).Footer.FValueType in
- [fvtSum, fvtAvg, fvtMax, fvtMin, fvtCount];
-
+ APresent := (C.Footer.FValueType in [fvtSum, fvtAvg, fvtMax, fvtMin, fvtCount]) or (C.FGroupItems.Active);
if not APresent then
- for j:=0 to TRxColumn(Columns[i]).Footers.Count-1 do
+ for F in C.Footers do
begin
- APresent:=TRxColumn(Columns[i]).Footers[j].FValueType in [fvtSum, fvtAvg, fvtMax, fvtMin, fvtCount];
+ APresent:=F.FValueType in [fvtSum, fvtAvg, fvtMax, fvtMin, fvtCount];
if APresent then
break;
end;
-
- if APresent then
- break;
end;
- if not APresent then
- exit;
+ if not APresent then Exit;
Inc(FInProcessCalc);
cnt:=0;
- for i := 0 to Columns.Count - 1 do
+ for C in Columns do
begin
- TRxColumn(Columns[i]).Footer.ResetTestValue;
- for j:=0 to TRxColumn(Columns[i]).Footers.Count - 1 do
- TRxColumn(Columns[i]).Footers[j].ResetTestValue;
+ C.Footer.ResetTestValue;
+ for F in C.Footers do F.ResetTestValue;
+ C.FGroupItems.Clear;
end;
if (DataSource.DataSet.RecordCount<=0) then
@@ -4906,24 +5064,27 @@ begin
SavePos:=DHS.RecNo;
FCList:=TFPList.Create;
- for i:=0 to Columns.Count-1 do
+ FCList2:=TFPList.Create;
+
+ for C in Columns do
begin
- RCol:=TRxColumn(Columns[i]);
- if (RCol.Footer.ValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and RCol.Visible then
+ if (C.Footer.ValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and C.Visible then
begin
- FCList.Add(RCol);
- RCol.Footer.FField:=DHS.FieldByName(RCol.Footer.FieldName);
+ FCList.Add(C);
+ C.Footer.FField:=DHS.FieldByName(C.Footer.FieldName);
end;
- for j:=0 to RCol.Footers.Count - 1 do
+ for F in C.Footers do
begin
- if (RCol.Footers[j].ValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and RCol.Visible then
+ if (F.ValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and C.Visible then
begin
- if FCList.IndexOf(RCol) < 0 then
- FCList.Add(RCol);
- RCol.Footers[j].FField:=DHS.FieldByName(RCol.Footers[j].FieldName);
+ if FCList.IndexOf(C) < 0 then
+ FCList.Add(C);
+ F.FField:=DHS.FieldByName(F.FieldName);
end;
end;
+
+ if C.FGroupItems.Active then FCList2.Add(C);
end;
DHS.First;
@@ -4931,38 +5092,42 @@ begin
begin
for i:=0 to FCList.Count-1 do
begin
- RCol:=TRxColumn(FCList[i]);
- if (RCol.FFooter.FValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and Assigned(RCol.FFooter.FField) then
- RCol.FFooter.UpdateTestValueFromVar( RCol.FFooter.FField.AsVariant);
+ C:=TRxColumn(FCList[i]);
+ if (C.FFooter.FValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and Assigned(C.FFooter.FField) then
+ C.FFooter.UpdateTestValueFromVar(C.FFooter.FField.AsVariant);
- for j:=0 to RCol.FFooters.Count-1 do
+ for F in C.FFooters do
begin
- if (RCol.FFooters[j].FValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and Assigned(RCol.FFooters[j].FField) then
- RCol.FFooters[j].UpdateTestValueFromVar( RCol.FFooters[j].FField.AsVariant)
+ if (F.FValueType in [fvtSum, fvtAvg, fvtMax, fvtMin]) and Assigned(F.FField) then
+ F.UpdateTestValueFromVar( F.FField.AsVariant)
end;
end;
+
+ for i:=0 to FCList2.Count-1 do
+ TRxColumn(FCList[i]).FGroupItems.UpdateValues;
+
inc(cnt);
DHS.Next;
end;
+ FCList2.Free;
FCList.Free;
- for i:=0 to Columns.Count-1 do
+ for C in Columns do
begin
- RCol:=TRxColumn(Columns[i]);
- if RCol.Footer.ValueType = fvtCount then
- RCol.FFooter.FCountRec:=Cnt
+ if C.Footer.ValueType = fvtCount then
+ C.FFooter.FCountRec:=Cnt
else
- if RCol.Footer.ValueType = fvtAvg then
- RCol.FFooter.FTestValue:=RCol.FFooter.FTestValue / Cnt;
+ if C.Footer.ValueType = fvtAvg then
+ C.FFooter.FTestValue:=C.FFooter.FTestValue / Cnt;
- for j:=0 to RCol.Footers.Count-1 do
+ for F in C.Footers do
begin
- if RCol.Footers[j].ValueType = fvtCount then
- RCol.FFooters[j].FCountRec:=Cnt
+ if F.ValueType = fvtCount then
+ F.FCountRec:=Cnt
else
- if RCol.Footers[j].ValueType = fvtAvg then
- RCol.FFooters[j].FTestValue:=RCol.FFooter.FTestValue / Cnt;
+ if F.ValueType = fvtAvg then
+ F.FTestValue:=F.FTestValue / Cnt;
end;
end;
@@ -5953,10 +6118,12 @@ begin
FEditButtons:=TRxColumnEditButtons.Create(Self);
FOptions:=[coCustomizeVisible, coCustomizeWidth];
FFooters:=TRxColumnFooterItems.Create(Self);
+ FGroupItems:=TColumnGroupItems.Create;
end;
destructor TRxColumn.Destroy;
begin
+ FreeAndNil(FGroupItems);
FreeAndNil(FFooters);
FreeAndNil(FEditButtons);
if FKeyList <> nil then