Componentes.Terceros.DevExp.../official/x.42/ExpressPivotGrid/Sources/cxPivotGridDesigner.pas
2009-02-27 12:02:10 +00:00

936 lines
28 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressPivotGrid }
{ }
{ Copyright (c) 2005-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSPIVOTGRID AND ALL ACCOMPANYING }
{ VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxPivotGridDesigner;
interface
{$I cxVer.inc}
uses
{$IFDEF DELPHI6}
DesignIntf, Variants,
{$ELSE}
DsgnIntf,
{$ENDIF}
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, Menus, cxLookAndFeelPainters, StdCtrls, cxButtons, ComCtrls,
cxControls, cxContainer, cxListBox, cxCustomPivotGrid, cxDesignWindows,
cxTreeView, ExtCtrls;
type
TfrmPivotGridDesigner = class(TcxDesignFormEditor)
pcDesigner: TPageControl;
tbsFields: TTabSheet;
btnClose: TcxButton;
btnDelete: TcxButton;
btnMoveUp: TcxButton;
btnAdd: TcxButton;
btnMoveDown: TcxButton;
btnRetrieveFields: TcxButton;
lbFields: TcxListBox;
pmFields: TPopupMenu;
miMoveUp: TMenuItem;
miMoveDown: TMenuItem;
N1: TMenuItem;
N2: TMenuItem;
miSelectAll: TMenuItem;
miAdd: TMenuItem;
miDelete: TMenuItem;
tbsGroups: TTabSheet;
pnlGroups: TPanel;
tvGroups: TcxTreeView;
Label1: TLabel;
pnlGroupUngroup: TPanel;
pnlUnlinked: TPanel;
btnUnlink: TcxButton;
btnLink: TcxButton;
lbUnlinkedFields: TcxListBox;
btnAddGroup: TcxButton;
btnDeleteGroup: TcxButton;
Label2: TLabel;
pmGroups: TPopupMenu;
miAddGroup: TMenuItem;
miDeleteGroup: TMenuItem;
MenuItem3: TMenuItem;
miMoveUpInGroup: TMenuItem;
miMoveDownInGroup: TMenuItem;
btnMoveUpGroup: TcxButton;
btnMoveDownGroup: TcxButton;
procedure btnFieldsPageClick(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
procedure lbFieldsClick(Sender: TObject);
procedure lbFieldsDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure lbFieldsDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure tbsFieldsStartDrag(Sender: TObject;
var DragObject: TDragObject);
procedure lbFieldsEndDrag(Sender, Target: TObject; X, Y: Integer);
procedure tbsGroupsResize(Sender: TObject);
procedure tvGroupsEditing(Sender: TObject; Node: TTreeNode;
var AllowEdit: Boolean);
procedure btnGroupClick(Sender: TObject);
procedure tvGroupsCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
procedure tvGroupsClick(Sender: TObject);
procedure lbUnlinkedFieldsClick(Sender: TObject);
procedure tvGroupsDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure tvGroupsDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure tvGroupsMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure miMoveInGroupClick(Sender: TObject);
procedure tvGroupsChange(Sender: TObject; Node: TTreeNode);
procedure tvGroupsEdited(Sender: TObject; Node: TTreeNode;
var S: String);
procedure tvGroupsDblClick(Sender: TObject);
procedure lbUnlinkedFieldsDblClick(Sender: TObject);
procedure tvGroupsKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormCreate(Sender: TObject);
private
function GetPivotIntf: IcxPivotGridDesignerIntf;
function GetPivotGrid: TcxCustomPivotGrid;
protected
FIsLocked: Boolean;
FPrevDragIndex: Integer;
DeletedGroup: TObject;
procedure AddField;
procedure DeleteSelection;
function GetFieldsFromDragSource(ASource: TObject): TList;
function GetGroup(AGroupOnly: Boolean = False): TcxPivotGridFieldGroup;
function GetGroupField: TcxPivotGridField;
procedure InitFormEditor; override;
procedure SelectionMoveUp;
procedure SelectionMoveDown;
procedure SelectItem(AItem: TPersistent);
procedure ReindexFields(AList: TList; ANewIndex: Integer);
procedure RetrieveFields;
procedure SyncGroupSelection;
procedure UpdateButtons;
procedure UpdateDesigner;
procedure UpdateFieldList;
procedure UpdateFieldListBox(AListBox: TcxListBox; AUnlinkedOnly: Boolean);
// groups
procedure UpdateGroups;
procedure UpdateGroupsButtons;
procedure UpdateUnlinkedFieldList;
public
procedure DoItemsModified; override;
procedure SelectionsChanged(const ASelection: TDesignerSelectionList); override;
property PivotGrid: TcxCustomPivotGrid read GetPivotGrid;
property PivotIntf: IcxPivotGridDesignerIntf read GetPivotIntf;
end;
procedure ShowPivotGridDesigner(ADesigner: IDesigner; APivotGrid: TcxCustomPivotGrid);
implementation
{$R *.dfm}
procedure ShowPivotGridDesigner(ADesigner: IDesigner; APivotGrid: TcxCustomPivotGrid);
begin
ShowFormEditorClass(ADesigner, APivotGrid, TfrmPivotGridDesigner);
end;
procedure GetTreeViewSelections(ATreeView: TTreeView; ASelection: TList);
{$IFNDEF DELPHI6}
procedure ProcessNode(ANode: TTreeNode);
var
I: Integer;
begin
if ANode.Selected then
ASelection.Add(ANode);
for I := 0 to ANode.Count - 1 do
ProcessNode(ANode.Item[I]);
end;
var
I: Integer;
{$ENDIF}
begin
{$IFDEF DELPHI6}
ATreeView.GetSelections(ASelection);
{$ELSE}
for I := 0 to ATreeView.Items.Count - 1 do
ProcessNode(ATreeView.Items[I]);
{$ENDIF}
end;
procedure TfrmPivotGridDesigner.btnFieldsPageClick(Sender: TObject);
begin
case TComponent(Sender).Tag of
0:
AddField;
1:
DeleteSelection;
2:
SelectionMoveUp;
3:
SelectionMoveDown;
4:
RetrieveFields;
5:
ListBoxSelectAll(lbFields.InnerListBox);
end;
end;
procedure TfrmPivotGridDesigner.DoItemsModified;
begin
UpdateFieldList;
end;
procedure TfrmPivotGridDesigner.SelectionsChanged(
const ASelection: TDesignerSelectionList);
begin
if (PivotGrid = nil) or PivotGrid.IsLoading or PivotGrid.IsDestroying or FIsLocked then Exit;
ListBoxSynchronizeSelection(lbFields.InnerListBox);
UpdateGroups;
UpdateButtons;
end;
procedure TfrmPivotGridDesigner.AddField;
var
AField: TcxPivotGridField;
APrefix: string;
begin
ListBoxClearSelection(lbFields.InnerListBox);
AField := PivotIntf.CreateField;
APrefix := AField.ClassName;
APrefix := Copy(APrefix, 1, Pos('Field', APrefix) - 1);
AField.Name := CreateUniqueName(PivotGrid.Owner, PivotGrid, AField, APrefix, '');
UpdateFieldList;
ListBoxSelectByObject(lbFields.InnerListBox, AField);
lbFieldsClick(nil);
AField.Visible := True;
UpdateDesigner;
end;
procedure TfrmPivotGridDesigner.DeleteSelection;
begin
if lbFields.SelCount > 0 then
begin
BeginUpdate;
try
PivotGrid.BeginUpdate;
try
ListBoxDeleteSelection(lbFields.InnerListBox, True);
finally
PivotGrid.EndUpdate;
end;
finally
EndUpdate;
UpdateFieldList;
lbFieldsClick(nil);
UpdateDesigner;
end;
end;
end;
function TfrmPivotGridDesigner.GetFieldsFromDragSource(ASource: TObject): TList;
var
I: Integer;
begin
Result := TList.Create;
if ASource is TcxDragControlObject then
begin
if TcxDragControlObject(ASource).Control = lbUnlinkedFields then
begin
for I := 0 to lbUnlinkedFields.Items.Count - 1 do
if lbUnlinkedFields.Selected[I] then
Result.Add(lbUnlinkedFields.Items.Objects[I]);
end
else
if TcxDragControlObject(ASource).Control = tvGroups then
begin
GetTreeViewSelections(tvGroups.InnerTreeView, Result);
for I := 0 to Result.Count - 1 do
Result[I] := TTreeNode(Result[I]).Data;
end;
end;
end;
function TfrmPivotGridDesigner.GetGroup(AGroupOnly: Boolean = False): TcxPivotGridFieldGroup;
begin
Result := nil;
if tvGroups.Selected = nil then Exit;
if (tvGroups.Selected.Level = 0) then
Result := TcxPivotGridFieldGroup(tvGroups.Selected.Data)
else
if not AGroupOnly then
Result := TcxPivotGridFieldGroup(tvGroups.Selected.Parent.Data);
end;
function TfrmPivotGridDesigner.GetGroupField: TcxPivotGridField;
begin
if (tvGroups.Selected <> nil) and (tvGroups.Selected.Level = 1) then
Result := TcxPivotGridField(tvGroups.Selected.Data)
else
Result := nil;
end;
procedure TfrmPivotGridDesigner.InitFormEditor;
begin
inherited InitFormEditor;
FPrevDragIndex := -1;
UpdateFieldList;
UpdateSelection;
UpdateButtons;
end;
procedure TfrmPivotGridDesigner.SelectionMoveUp;
begin
PivotGrid.BeginUpdate;
try
ListBoxMoveUpItems(lbFields.InnerListBox, FPrevDragIndex, ReindexFields);
finally
PivotGrid.EndUpdate;
end;
UpdateDesigner;
end;
procedure TfrmPivotGridDesigner.SelectionMoveDown;
begin
PivotGrid.BeginUpdate;
try
ListBoxMoveDownItems(lbFields.InnerListBox, FPrevDragIndex, ReindexFields);
finally
PivotGrid.EndUpdate;
end;
UpdateDesigner;
end;
procedure TfrmPivotGridDesigner.SelectItem(AItem: TPersistent);
begin
if AItem = nil then
Designer.SelectComponent(AItem)
else
Designer.SelectComponent(Component);
end;
procedure TfrmPivotGridDesigner.ReindexFields(
AList: TList; ANewIndex: Integer);
var
I: Integer;
begin
if AList.Count = 0 then Exit;
if TcxPivotGridField(AList[0]).Index < ANewIndex then
begin
for I := 0 to AList.Count - 1 do
TcxPivotGridField(AList[I]).Index := ANewIndex;
end
else
begin
for I := AList.Count - 1 downto 0 do
TcxPivotGridField(AList[I]).Index := ANewIndex;
end;
UpdateDesigner;
end;
procedure TfrmPivotGridDesigner.RetrieveFields;
const
Flags = MB_YESNOCANCEL or MB_ICONWARNING;
scxConfirm = 'Confirm';
scxDeleteFields = 'Delete exisitng fields?';
begin
PivotGrid.BeginUpdate;
try
if PivotGrid.FieldCount > 0 then
begin
case MessageBox(0, scxDeleteFields, scxConfirm, Flags) of
mrCancel:
Exit;
mrYes:
PivotGrid.DeleteAllFields;
end;
end;
PivotIntf.DoCreateAllFields;
UpdateFieldList;
lbFieldsClick(nil);
UpdateDesigner;
finally
PivotGrid.EndUpdate;
end;
end;
procedure TfrmPivotGridDesigner.SyncGroupSelection;
begin
if pcDesigner.ActivePage = tbsGroups then
begin
FIsLocked := True;
if tvGroups.Selected <> nil then
SelectComponent(TPersistent(tvGroups.Selected.Data))
else
SelectComponent(PivotGrid);
FIsLocked := False;
end;
end;
function TfrmPivotGridDesigner.GetPivotIntf: IcxPivotGridDesignerIntf;
begin
Result := PivotGrid as IcxPivotGridDesignerIntf;
end;
function TfrmPivotGridDesigner.GetPivotGrid: TcxCustomPivotGrid;
begin
Result := Component as TcxCustomPivotGrid;
end;
procedure TfrmPivotGridDesigner.UpdateButtons;
var
AIsActive: Boolean;
begin
btnAdd.Enabled := CanAddComponent;
btnDelete.Enabled := (lbFields.SelCount > 0) and CanChangeComponentList(PivotGrid);
btnMoveUp.Enabled := lbFields.SelCount > 0;
btnMoveDown.Enabled := lbFields.SelCount > 0;
miMoveUp.Enabled := btnMoveUp.Enabled;
miMoveDown.Enabled := btnMoveDown.Enabled;
miDelete.Enabled := btnDelete.Enabled;
miSelectAll.Enabled := lbFields.Count > 0;
btnRetrieveFields.Visible := PivotIntf.CanRetrieveFields(AIsActive);
btnRetrieveFields.Enabled := AIsActive;
end;
procedure TfrmPivotGridDesigner.UpdateDesigner;
begin
Designer.Modified;
end;
procedure TfrmPivotGridDesigner.UpdateFieldList;
begin
UpdateFieldListBox(lbFields, False);
UpdateGroups;
end;
procedure TfrmPivotGridDesigner.UpdateFieldListBox(
AListBox: TcxListBox; AUnlinkedOnly: Boolean);
var
AField: TcxPivotGridField;
ASelection: TStringList;
I, AItemIndex, ATopIndex: Integer;
begin
// if not AUnlinkedOnly or (pcDesigner.ActivePage = tbsGroups) then
ListBoxSaveSelection(AListBox.InnerListBox, ASelection, AItemIndex, ATopIndex);
try
AListBox.Items.Clear;
for I := 0 to PivotGrid.FieldCount - 1 do
begin
AField := PivotGrid.Fields[I];
if not AUnlinkedOnly or (AField.Group = nil) then
AListBox.Items.AddObject(AField.Name, AField);
end;
finally
// if not AUnlinkedOnly or (pcDesigner.ActivePage = tbsGroups) then
ListBoxRestoreSelection(AListBox.InnerListBox, ASelection, AItemIndex, ATopIndex);
end;
UpdateButtons;
end;
procedure TfrmPivotGridDesigner.btnCloseClick(Sender: TObject);
begin
if not tvGroups.IsEditing then
Hide
else
begin
if tvGroups.Selected <> nil then
tvGroups.Selected.EndEdit(False);
end;
end;
procedure TfrmPivotGridDesigner.lbFieldsClick(Sender: TObject);
begin
ListBoxApplySelection(lbFields.InnerListBox, PivotGrid);
end;
procedure TfrmPivotGridDesigner.lbFieldsDragOver(Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
ListBoxDragOver(lbFields.InnerListBox, Sender, Source,
X, Y, State, Accept, FPrevDragIndex);
end;
procedure TfrmPivotGridDesigner.lbFieldsDragDrop(Sender, Source: TObject;
X, Y: Integer);
begin
ListBoxDragDrop(lbFields.InnerListBox, Sender, Source,
X, Y, FPrevDragIndex, ReindexFields);
UpdateDesigner;
end;
procedure TfrmPivotGridDesigner.tbsFieldsStartDrag(Sender: TObject;
var DragObject: TDragObject);
begin
FPrevDragIndex := -1;
end;
procedure TfrmPivotGridDesigner.lbFieldsEndDrag(Sender, Target: TObject; X,
Y: Integer);
begin
ListBoxEndDrag(lbFields.InnerListBox, Sender, Target, X, Y, FPrevDragIndex);
end;
// groups
procedure TfrmPivotGridDesigner.tbsGroupsResize(Sender: TObject);
var
W: Integer;
begin
W := (tbsGroups.Width - pnlGroupUngroup.Width) div 2;
pnlGroups.Width := W;
pnlUnlinked.Width := W;
end;
procedure TreeViewSaveSelection(ATreeView: TTreeView;
var ASelection: TList; var AItemIndex, ATopIndex: Integer);
function GetIndexFrom(ANode: TTreeNode): Integer;
begin
Result := 0;
if ANode <> nil then
Result := ANode.AbsoluteIndex;
end;
var
I: Integer;
begin
ASelection := TList.Create;
try
ATopIndex := GetIndexFrom(ATreeView.TopItem);
AItemIndex := GetIndexFrom(ATreeView.Selected);
GetTreeViewSelections(ATreeView, ASelection);
for I := 0 to ASelection.Count - 1 do
ASelection[I] := TTreeNode(ASelection[I]).Data;
ATreeView.Items.BeginUpdate;
except
FreeAndNil(ASelection);
end;
end;
procedure TreeViewRestoreSelection(ATreeView: TTreeView; var ASelection: TList;
var AItemIndex, ATopIndex: Integer; ASyncSelection: Boolean);
function CheckIndex(var AIndex: Integer): Boolean;
begin
while AIndex > ATreeView.Items.Count - 1 do Dec(AIndex);
Result := AIndex >= 0;
end;
var
I: Integer;
APrevOnClick: TNotifyEvent;
begin
APrevOnClick := ATreeView.OnClick;
try
ATreeView.OnClick := nil;
if ASyncSelection then
begin
for I := 0 to ATreeView.Items.Count - 1 do
if ASelection.IndexOf(ATreeView.Items[I].Data) <> -1 then
ATreeView.Items[I].Selected := True;
end;
if CheckIndex(ATopIndex) then
ATreeView.TopItem := ATreeView.Items[ATopIndex];
if ASyncSelection then
begin
if CheckIndex(AItemIndex) and (ATreeView.Selected = nil) then
ATreeView.Items[AItemIndex].Selected := True;
if ATreeView.Selected <> nil then
ATreeView.Selected.MakeVisible;
end;
finally
ATreeView.OnClick := APrevOnClick;
ATreeView.Items.EndUpdate;
FreeAndNil(ASelection);
end;
end;
procedure TfrmPivotGridDesigner.UpdateGroups;
var
I, J: Integer;
ASelection: TList;
AField: TcxPivotGridField;
ACurSelectedNode, ANode, AGroupNode: TTreeNode;
AGroup: TcxPivotGridFieldGroup;
ATopIndex, AItemIndex: Integer;
ASelList: TList;
begin
if LockCount > 0 then Exit;
ASelList := TList.Create;
ACurSelectedNode := nil;
TreeViewSaveSelection(tvGroups.InnerTreeView, ASelection, AItemIndex, ATopIndex);
try
LockWindowUpdate(tvGroups.Handle);
tvGroups.Items.Clear;
for I := 0 to PivotGrid.Groups.Count - 1 do
begin
AGroup := PivotGrid.Groups[I];
GetSelectionList(ASelList);
AGroupNode := tvGroups.Items.AddChildObject(nil, AGroup.Caption, AGroup);
if ASelList.IndexOf(AGroup) >= 0 then
ACurSelectedNode := AGroupNode;
if AGroup <> DeletedGroup then
for J := 0 to AGroup.FieldCount - 1 do
begin
AField := AGroup.Fields[J];
ANode := tvGroups.Items.AddChildObject(AGroupNode, AField.Name, AField);
if ASelList.IndexOf(AField) >= 0 then
ACurSelectedNode := ANode;
end;
end;
tvGroups.FullExpand;
finally
ASelList.Free;
TreeViewRestoreSelection(tvGroups.InnerTreeView, ASelection, AItemIndex, ATopIndex, ACurSelectedNode = nil);
tvGroups.SetScrollBarsParameters();
LockWindowUpdate(0);
tvGroups.Update;
end;
if ACurSelectedNode <> nil then
tvGroups.Selected := ACurSelectedNode;
UpdateUnlinkedFieldList;
UpdateGroupsButtons;
end;
procedure TfrmPivotGridDesigner.UpdateGroupsButtons;
function CanMoveNodeUp(ANode: TTreeNode): Boolean;
begin
Result := (ANode <> nil) and (ANode.AbsoluteIndex > 0);
if Result then
begin
if ANode.Level = 0 then
Result := (ANode.Index > 0)
else
Result := (ANode.Index > 0) or (ANode.Parent.Index > 0);
end;
end;
function CanMoveNodeDown(ANode: TTreeNode): Boolean;
begin
Result := (ANode <> nil) and (ANode.AbsoluteIndex < ANode.Owner.Count);
if Result then
begin
if ANode.Level = 0 then
Result := ANode.getNextSibling <> nil
else
Result := (ANode.getNextSibling <> nil) or (ANode.Parent.getNextSibling <> nil);
end;
end;
begin
btnDeleteGroup.Enabled := GetGroup(True) <> nil;
btnUnlink.Enabled := GetGroupField <> nil;
btnLink.Enabled := (GetGroup <> nil) and (lbUnlinkedFields.SelCount > 0);
btnMoveUpGroup.Enabled := CanMoveNodeUp(tvGroups.Selected);
btnMoveDownGroup.Enabled := CanMoveNodeDown(tvGroups.Selected);
miMoveUpInGroup.Enabled := btnMoveUpGroup.Enabled;
miMoveDownInGroup.Enabled := btnMoveDownGroup.Enabled;
end;
procedure TfrmPivotGridDesigner.UpdateUnlinkedFieldList;
begin
UpdateFieldListBox(lbUnlinkedFields, True);
end;
procedure TfrmPivotGridDesigner.tvGroupsEditing(Sender: TObject;
Node: TTreeNode; var AllowEdit: Boolean);
begin
AllowEdit := Node.Level = 0;
end;
procedure TfrmPivotGridDesigner.btnGroupClick(Sender: TObject);
var
I: Integer;
ANode: TTreeNode;
AField: TcxPivotGridField;
AGroup: TcxPivotGridFieldGroup;
begin
PivotGrid.BeginUpdate;
try
AGroup := GetGroup;
case TButton(Sender).Tag of
0:
begin
AGroup := PivotGrid.Groups.Add;
AGroup.Caption := Format('FieldGroup %d', [PivotGrid.Groups.Count]);
tvGroups.Items.AddChildObject(nil, AGroup.Caption, AGroup).Selected := True;
end;
1:
begin
DeletedGroup := AGroup;
AGroup.Free;
end;
2:
begin
AField := TcxPivotGridField(tvGroups.Selected.Data);
tvGroups.Selected := tvGroups.Selected.GetPrev;
lbUnlinkedFields.ClearSelection;
with lbUnlinkedFields do
Selected[Items.AddObject(AField.Name, AField)] := True;
AField.Group := nil;
end;
3:
if (lbUnlinkedFields.SelCount > 0) and (AGroup <> nil) then
begin
ANode := tvGroups.Selected;
if (ANode <> nil) and (ANode.Level = 1) then
ANode := ANode.Parent;
for I := 0 to lbUnlinkedFields.Items.Count - 1 do
if lbUnlinkedFields.Selected[I] then
begin
AField := TcxPivotGridField(lbUnlinkedFields.Items.Objects[I]);
AGroup.Add(AField);
if ANode <> nil then
begin
tvGroups.Items.AddChildObject(ANode,
AField.Name, AField).Selected := True;
end;
end;
end;
end;
finally
PivotGrid.EndUpdate;
UpdateDesigner;
UpdateFieldList;
end;
SyncGroupSelection;
end;
procedure TfrmPivotGridDesigner.tvGroupsCustomDrawItem(
Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState;
var DefaultDraw: Boolean);
begin
if Node.Level = 0 then
Sender.Canvas.Font.Style := Sender.Canvas.Font.Style + [fsBold]
else
Sender.Canvas.Font.Style := Sender.Canvas.Font.Style - [fsBold];
if (Node <> nil) and Node.Selected then
Sender.Canvas.Brush.Color := clHighlight;
end;
procedure TfrmPivotGridDesigner.tvGroupsClick(Sender: TObject);
begin
UpdateGroupsButtons;
SyncGroupSelection;
end;
procedure TfrmPivotGridDesigner.lbUnlinkedFieldsClick(Sender: TObject);
begin
UpdateGroupsButtons;
SyncGroupSelection;
end;
procedure TfrmPivotGridDesigner.tvGroupsDragDrop(Sender, Source: TObject;
X, Y: Integer);
var
AFields: TList;
ANode: TTreeNode;
I, AIndex: Integer;
AField: TcxPivotGridField;
AGroup: TcxPivotGridFieldGroup;
begin
ANode := tvGroups.GetNodeAt(X, Y);
if ANode = nil then Exit;
PivotGrid.BeginUpdate;
try
AFields := GetFieldsFromDragSource(Source);
try
if AFields.Count = 0 then Exit;
AIndex := ANode.Count;
if ANode.Level = 1 then
begin
AIndex := ANode.Index;
ANode := ANode.Parent;
end;
AGroup := TcxPivotGridFieldGroup(ANode.Data);
for I := 0 to AFields.Count - 1 do
begin
AField := TcxPivotGridField(AFields[I]);
if TcxDragControlObject(Source).Control <> tvGroups then
tvGroups.Items.AddChildObject(ANode, AField.Name, AField).Selected := True;
AGroup.Insert(AIndex + I, AField);
end;
finally
AFields.Free;
end;
finally
PivotGrid.EndUpdate;
UpdateDesigner;
end;
end;
procedure TfrmPivotGridDesigner.tvGroupsDragOver(Sender, Source: TObject;
X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
Accept := (Source is TcxDragControlObject) and (tvGroups.GetNodeAt(X, Y) <> nil);
if Accept then
begin
with TcxDragControlObject(Source) do
Accept := (Control = lbUnlinkedFields) or (Control = tvGroups);
end;
end;
procedure TfrmPivotGridDesigner.tvGroupsMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbLeft) and (tvGroups.GetNodeAt(X, Y) <> nil) and
(tvGroups.GetNodeAt(X, Y).Level = 1) then
begin
tvGroupsClick(nil);
tvGroups.BeginDrag(False);
end;
UpdateGroupsButtons;
end;
procedure TfrmPivotGridDesigner.miMoveInGroupClick(Sender: TObject);
procedure MoveUp(ANode: TTreeNode);
var
AField: TcxPivotGridField;
AGroup: TcxPivotGridFieldGroup;
begin
if ANode.Level = 1 then
begin
AGroup := TcxPivotGridFieldGroup(ANode.Parent.Data);
AField := TcxPivotGridField(ANode.Data);
if ANode.Index > 0 then
begin
AGroup.Remove(AField);
AGroup.Insert(ANode.Index - 1, AField);
end
else
if AGroup.Index > 0 then
begin
AGroup := AGroup.Groups[AGroup.Index - 1];
AGroup.Add(AField);
end;
end
else
begin
AGroup := TcxPivotGridFieldGroup(ANode.Data);
if AGroup.Index > 0 then
AGroup.Index := AGroup.Index - 1;
end;
end;
procedure MoveDown(ANode: TTreeNode);
var
AField: TcxPivotGridField;
AGroup: TcxPivotGridFieldGroup;
begin
if ANode.Level = 1 then
begin
AGroup := TcxPivotGridFieldGroup(ANode.Parent.Data);
AField := TcxPivotGridField(ANode.Data);
if ANode.Index < (AGroup.FieldCount - 1) then
AGroup.Insert(ANode.Index + 1, AField)
else
if AGroup.Index < (AGroup.Groups.Count - 1) then
begin
AGroup := AGroup.Groups[AGroup.Index + 1];
AGroup.Insert(0, AField);
end;
end
else
begin
AGroup := TcxPivotGridFieldGroup(ANode.Data);
if AGroup.Index < (AGroup.Groups.Count - 1) then
AGroup.Index := AGroup.Index + 1;
end;
end;
begin
if tvGroups.Selected = nil then Exit;
PivotGrid.BeginUpdate;
try
case TComponent(Sender).Tag of
2:
MoveUp(tvGroups.Selected);
3:
MoveDown(tvGroups.Selected);
end;
finally
PivotGrid.EndUpdate;
end;
UpdateDesigner;
end;
procedure TfrmPivotGridDesigner.tvGroupsChange(Sender: TObject;
Node: TTreeNode);
begin
UpdateGroupsButtons;
end;
procedure TfrmPivotGridDesigner.tvGroupsEdited(Sender: TObject;
Node: TTreeNode; var S: String);
begin
TcxPivotGridFieldGroup(Node.Data).Caption := S;
UpdateDesigner;
end;
procedure TfrmPivotGridDesigner.tvGroupsDblClick(Sender: TObject);
begin
if (tvGroups.Selected <> nil) and (tvGroups.Selected.Level = 1) then
btnUnlink.Click;
end;
procedure TfrmPivotGridDesigner.lbUnlinkedFieldsDblClick(Sender: TObject);
begin
if lbUnlinkedFields.SelCount > 0 then
btnLink.Click;
end;
procedure TfrmPivotGridDesigner.tvGroupsKeyUp(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
UpdateGroupsButtons;
SyncGroupSelection;
end;
procedure TfrmPivotGridDesigner.FormCreate(Sender: TObject);
begin
with Constraints do
begin
MinHeight := MulDiv(MinHeight, PixelsPerInch, 96);
MinWidth := MulDiv(MinWidth, PixelsPerInch, 96);
end;
end;
end.