555 lines
15 KiB
ObjectPascal
555 lines
15 KiB
ObjectPascal
|
|
{******************************************}
|
|
{ }
|
|
{ FastReport v4.0 }
|
|
{ Variables editor }
|
|
{ }
|
|
{ Copyright (c) 1998-2008 }
|
|
{ by Alexander Tzyganenko, }
|
|
{ Fast Reports Inc. }
|
|
{ }
|
|
{******************************************}
|
|
|
|
unit FMX.frxEditVar;
|
|
|
|
interface
|
|
|
|
{$I frx.inc}
|
|
|
|
uses
|
|
System.SysUtils, System.Classes, System.UITypes, System.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
|
|
FMX.frxClass, FMX.frxVariables, FMX.frxDataTree, FMX.Memo, FMX.Types, FMX.frxFMX,
|
|
FMX.Layouts, FMX.TreeView, System.Variants, FMX.Edit, FMX.frxBaseModalForm
|
|
{$IFDEF DELPHI18}
|
|
,FMX.StdCtrls
|
|
{$ENDIF}
|
|
{$IFDEF DELPHI22}
|
|
,FMX.Memo.Types
|
|
{$ENDIF}
|
|
{$IFDEF DELPHI28}
|
|
, FMX.BaseTypeAliases, FMX.FormTypeAliases
|
|
{$ENDIF};
|
|
|
|
|
|
type
|
|
TfrxVarEditorForm = class(TfrxForm)
|
|
ToolBar: TToolBar;
|
|
NewCategoryB: TfrxToolButton;
|
|
NewVarB: TfrxToolButton;
|
|
EditB: TfrxToolButton;
|
|
DeleteB: TfrxToolButton;
|
|
EditListB: TfrxToolButton;
|
|
OkB: TfrxToolButton;
|
|
CancelB: TfrxToolButton;
|
|
ExprMemo: TMemo;
|
|
Splitter1: TSplitter;
|
|
Splitter2: TSplitter;
|
|
ExprPanel: TPanel;
|
|
LoadB: TfrxToolButton;
|
|
SaveB: TfrxToolButton;
|
|
OpenDialog1: TOpenDialog;
|
|
SaveDialog1: TSaveDialog;
|
|
Panel: TPanel;
|
|
VarTree: TfrxTreeView;
|
|
procedure FormShow(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure DeleteBClick(Sender: TObject);
|
|
procedure NewCategoryBClick(Sender: TObject);
|
|
procedure NewVarBClick(Sender: TObject);
|
|
procedure OkBClick(Sender: TObject);
|
|
procedure EditBClick(Sender: TObject);
|
|
procedure VarTreeEdited(Sender: TObject; Node: TfrxTreeViewItem; var S: String);
|
|
procedure ExprMemoDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF; var Accept: Boolean);
|
|
procedure ExprMemoDragDrop(Sender: TObject; const Data: TDragObject; const Point: TPointF);
|
|
procedure VarTreeChange(Sender: TObject);
|
|
procedure VarTreeChanging(Sender: TObject; OldNode: TfrxTreeViewItem; NewNode: TfrxTreeViewItem);
|
|
//procedure VarTreeChanging(Sender: TObject; Node: TTreeNode;
|
|
// var AllowChange: Boolean);
|
|
procedure CancelBClick(Sender: TObject);
|
|
procedure EditListBClick(Sender: TObject);
|
|
procedure FormHide(Sender: TObject);
|
|
procedure LoadBClick(Sender: TObject);
|
|
procedure SaveBClick(Sender: TObject);
|
|
procedure FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: WideChar; Shift: TShiftState);
|
|
procedure Splitter2Moved(Sender: TObject);
|
|
procedure VarTreeResize(Sender: TObject);
|
|
procedure FormActivate(Sender: TObject);
|
|
procedure ExprMemoChange(Sender: TObject);
|
|
procedure ExprMemoEnter(Sender: TObject);
|
|
private
|
|
FReport: TfrxReport;
|
|
FUpdating: Boolean;
|
|
FVariables: TfrxVariables;
|
|
FDataTree: TfrxDataTreeForm;
|
|
FExprMemoModified: Boolean;
|
|
FNodeOldText: String;
|
|
function Root: TfrxTreeViewItem;
|
|
procedure CreateUniqueName(var s: String);
|
|
procedure FillVariables;
|
|
procedure UpdateItem0;
|
|
procedure OnDataTreeDblClick(Sender: TObject);
|
|
procedure VarTreeKeyDown(Sender: TObject; var Key: Word; var KeyChar: WideChar; Shift: TShiftState);
|
|
public
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
{$R *.FMX}
|
|
|
|
uses FMX.frxEditStrings, FMX.frxUtils, FMX.frxRes, System.IniFiles;
|
|
|
|
var
|
|
lastPosition: TPoint;
|
|
|
|
|
|
procedure SetImageIndex(Node: TfrxTreeViewItem; Index: Integer);
|
|
begin
|
|
Node.OpenImageIndex := Index;
|
|
Node.CloseImageIndex := Index;
|
|
end;
|
|
|
|
{ TfrxVarEditorForm }
|
|
|
|
procedure TfrxVarEditorForm.FormActivate(Sender: TObject);
|
|
begin
|
|
if FDataTree <> nil then FDataTree.FormResize(FDataTree);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.FormCreate(Sender: TObject);
|
|
begin
|
|
|
|
FReport := TfrxCustomDesigner(Owner).Report;
|
|
//VarTree.Images := frxResources.MainButtonImages;
|
|
//Toolbar.Images := VarTree.Images;
|
|
VarTree.Editable := True;
|
|
VarTree.OnKeyDown := VarTreeKeyDown;
|
|
|
|
FVariables := TfrxVariables.Create;
|
|
FVariables.Assign(FReport.Variables);
|
|
|
|
FDataTree := TfrxDataTreeForm.Create(Owner);
|
|
FDataTree.Report := FReport;
|
|
FDataTree.MainDataPanel.Parent := Self.Panel;
|
|
FDataTree.MainDataPanel.Align := TAlignLayout.alClient;
|
|
FDataTree.Visible := False;
|
|
FDataTree.MainDataPanel.OnDblClick := OnDataTreeDblClick;
|
|
//FDataTree.OnDblClick := OnDataTreeDblClick;
|
|
//FDataTree.SetControlsParent(Panel);
|
|
FDataTree.HintPanel.Height := 64;
|
|
FDataTree.UpdateItems;
|
|
|
|
Caption := frxGet(2900);
|
|
NewCategoryB.Hint := frxGet(2901);
|
|
NewVarB.Hint := frxGet(2902);
|
|
EditB.Hint := frxGet(2903);
|
|
DeleteB.Hint := frxGet(2904);
|
|
EditListB.Hint := frxGet(2905);
|
|
LoadB.Hint := frxGet(2906);
|
|
SaveB.Hint := frxGet(2907);
|
|
CancelB.Hint := frxGet(2);
|
|
OkB.Hint := frxGet(1);
|
|
OpenDialog1.Filter := frxGet(2909);
|
|
SaveDialog1.Filter := frxGet(2910);
|
|
VarTree.OnEdited := VarTreeEdited;
|
|
//if UseRightToLeftAlignment then
|
|
// FlipChildren(True);
|
|
FillVariables;
|
|
VarTree.SetFocus;
|
|
FDataTree.SetLastPosition(lastPosition);
|
|
frxResources.LoadImageFromResouce(NewCategoryB.Bitmap, 20, 2);
|
|
frxResources.LoadImageFromResouce(NewVarB.Bitmap, 6, 0);
|
|
frxResources.LoadImageFromResouce(EditB.Bitmap, 11, 3);
|
|
frxResources.LoadImageFromResouce(DeleteB.Bitmap, 5, 1);
|
|
frxResources.LoadImageFromResouce(EditListB.Bitmap, 10, 5);
|
|
frxResources.LoadImageFromResouce(LoadB.Bitmap, 0, 1);
|
|
frxResources.LoadImageFromResouce(SaveB.Bitmap, 0, 2);
|
|
frxResources.LoadImageFromResouce(CancelB.Bitmap, 21, 2);
|
|
frxResources.LoadImageFromResouce(OkB.Bitmap, 21, 0);
|
|
VarTree.SetImages(frxResources.Images);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.FormDestroy(Sender: TObject);
|
|
begin
|
|
FDataTree.Free;
|
|
FVariables.Free;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.FormShow(Sender: TObject);
|
|
//var
|
|
// Ini: TCustomIniFile;
|
|
begin
|
|
// Ini := FReport.GetIniFile;
|
|
// Ini.WriteBool('Form4.TfrxVarEditorForm', 'Visible', True);
|
|
// frxRestoreFormPosition(Ini, Self);
|
|
// ExprMemo.Height := Ini.ReadInteger('Form4.TfrxVarEditorForm', 'Split1Pos', 76);
|
|
// Panel.Width := Ini.ReadInteger('Form4.TfrxVarEditorForm', 'Split2Pos', 400);
|
|
// FDataTree.UpdateSize;
|
|
// Ini.Free;
|
|
|
|
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.FormHide(Sender: TObject);
|
|
//var
|
|
// Ini: TCustomIniFile;
|
|
begin
|
|
// Ini := FReport.GetIniFile;
|
|
// frxSaveFormPosition(Ini, Self);
|
|
// Ini.WriteInteger('Form4.TfrxVarEditorForm', 'Split1Pos', ExprMemo.Height);
|
|
// Ini.WriteInteger('Form4.TfrxVarEditorForm', 'Split2Pos', Panel.Width);
|
|
// Ini.Free;
|
|
lastPosition := FDataTree.GetLastPosition;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.OkBClick(Sender: TObject);
|
|
begin
|
|
FExprMemoModified := True; //save variable's value if OkB pressed without leaving of ExprMemo
|
|
ModalResult := mrOk;
|
|
VarTree.Selected := VarTree.ItemByGlobalIndex(0);
|
|
FReport.Variables.Assign(FVariables);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.CancelBClick(Sender: TObject);
|
|
begin
|
|
ModalResult := mrCancel;
|
|
end;
|
|
|
|
function TfrxVarEditorForm.Root: TfrxTreeViewItem;
|
|
begin
|
|
//VarTree.UpdateGlobalIndexes;
|
|
// Result := TfrxTreeViewItem(VarTree.ItemByGlobalIndex(0));
|
|
Result := TfrxTreeViewItem(VarTree.Items[0]);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.UpdateItem0;
|
|
begin
|
|
if Root.Count = 0 then
|
|
Root.Text := frxResources.Get('vaNoVar') else
|
|
Root.Text := frxResources.Get('vaVar');
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.CreateUniqueName(var s: String);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
i := 0;
|
|
repeat
|
|
Inc(i);
|
|
until FVariables.IndexOf(s + IntToStr(i)) = -1;
|
|
s := s + IntToStr(i);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.FillVariables;
|
|
var
|
|
i: Integer;
|
|
CategoriesList, VariablesList: TStrings;
|
|
Node: TfrxTreeViewItem;
|
|
|
|
procedure AddVariables(Node: TfrxTreeViewItem);
|
|
var
|
|
i: Integer;
|
|
Node1: TfrxTreeViewItem;
|
|
begin
|
|
for i := 0 to VariablesList.Count - 1 do
|
|
begin
|
|
Node1 := VarTree.AddItem(Node, VariablesList[i]);
|
|
SetImageIndex(Node1, 80);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
FUpdating := True;
|
|
CategoriesList := TStringList.Create;
|
|
VariablesList := TStringList.Create;
|
|
FVariables.GetCategoriesList(CategoriesList);
|
|
|
|
VarTree.Clear;
|
|
VarTree.AddItem(VarTree, '');
|
|
|
|
|
|
SetImageIndex(Root, 66);
|
|
VarTree.BeginUpdate;
|
|
for i := 0 to CategoriesList.Count - 1 do
|
|
begin
|
|
FVariables.GetVariablesList(CategoriesList[i], VariablesList);
|
|
Node := VarTree.AddItem(Root, CategoriesList[i]);
|
|
SetImageIndex(Node, 66);
|
|
AddVariables(Node);
|
|
end;
|
|
|
|
if CategoriesList.Count = 0 then
|
|
begin
|
|
FVariables.GetVariablesList('', VariablesList);
|
|
AddVariables(Root);
|
|
end;
|
|
VarTree.EndUpdate;
|
|
UpdateItem0;
|
|
VarTree.ExpandAll;
|
|
|
|
CategoriesList.Free;
|
|
VariablesList.Free;
|
|
FUpdating := False;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.DeleteBClick(Sender: TObject);
|
|
var
|
|
Node: TTreeViewItem;
|
|
begin
|
|
Node := VarTree.Selected;
|
|
if (Node = nil) or (Node = Root) then Exit;
|
|
|
|
FUpdating := True;
|
|
if Node.ParentItem <> Root then
|
|
FVariables.DeleteVariable(Node.Text) else
|
|
FVariables.DeleteCategory(Node.Text);
|
|
Node.Free;
|
|
FUpdating := False;
|
|
UpdateItem0;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.NewCategoryBClick(Sender: TObject);
|
|
var
|
|
Node: TfrxTreeViewItem;
|
|
s: String;
|
|
begin
|
|
s := ' New Category';
|
|
CreateUniqueName(s);
|
|
VarTree.BeginUpdate;
|
|
Node := VarTree.AddItem(Root, Trim(s));
|
|
VarTree.EndUpdate;
|
|
SetImageIndex(Node, 66);
|
|
FVariables.Add.Name := s;
|
|
VarTree.ExpandAll;
|
|
UpdateItem0;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.NewVarBClick(Sender: TObject);
|
|
var
|
|
Node: TTreeViewItem;
|
|
s: String;
|
|
begin
|
|
if Root.Count = 0 then Exit;
|
|
Node := VarTree.Selected;
|
|
if (Node = nil) or (Node = Root) then
|
|
Node := VarTree.ItemByGlobalIndex(Root.Count - 1)
|
|
else if (Node.ParentItem <> Root) and (Node.ParentItem is TTreeViewItem) then
|
|
Node := TTreeViewItem(Node.ParentItem);
|
|
|
|
s := 'New Variable';
|
|
CreateUniqueName(s);
|
|
FVariables.AddVariable(Node.Text, s, '');
|
|
VarTree.BeginUpdate;
|
|
Node := VarTree.AddItem(Node, s);
|
|
VarTree.EndUpdate;
|
|
SetImageIndex(TfrxTreeViewItem(Node), 80);
|
|
|
|
VarTree.ExpandAll;
|
|
UpdateItem0;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.EditBClick(Sender: TObject);
|
|
var
|
|
Node: TTreeViewItem;
|
|
begin
|
|
Node := VarTree.Selected;
|
|
if (Node = nil) or (Node = Root) then Exit;
|
|
VarTree.DoEdit;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.VarTreeEdited(Sender: TObject; Node: TfrxTreeViewItem; var S: String);
|
|
var
|
|
s1, s2: String;
|
|
begin
|
|
if (FNodeOldText = s) or (Root.Count = 0) then Exit;
|
|
s1 := s;
|
|
s2 := FNodeOldText;
|
|
|
|
if Node.ParentItem = Root then
|
|
begin
|
|
s1 := ' ' + s1;
|
|
s2 := ' ' + s2;
|
|
end;
|
|
|
|
if FVariables.IndexOf(s1) <> -1 then
|
|
begin
|
|
s := FNodeOldText;
|
|
frxErrorMsg(frxResources.Get('vaDupName'));
|
|
end
|
|
else
|
|
FVariables.Items[FVariables.IndexOf(s2)].Name := s1;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.VarTreeKeyDown(Sender: TObject; var Key: Word; var KeyChar: WideChar; Shift: TShiftState);
|
|
begin
|
|
case Key of
|
|
vkInsert:
|
|
if not VarTree.IsEditing then
|
|
if Root.Count = 0 then
|
|
NewCategoryBClick(nil) else
|
|
NewVarBClick(nil);
|
|
vkDelete:
|
|
if not VarTree.IsEditing then
|
|
DeleteBClick(nil);
|
|
vkReturn, vkF2:
|
|
if not VarTree.IsEditing then
|
|
EditBClick(nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.VarTreeResize(Sender: TObject);
|
|
begin
|
|
if Assigned(FDataTree) then
|
|
FDataTree.UpdateSize;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.ExprMemoDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF; var Accept: Boolean);
|
|
begin
|
|
Accept := (Data.Source is TTreeView) and (TControl(Data.Source).Owner = FDataTree) and
|
|
(FDataTree.GetFieldName <> '');
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.ExprMemoDragDrop(Sender: TObject; const Data: TDragObject; const Point: TPointF);
|
|
var
|
|
SelStart: TCaretPosition;
|
|
SelLen: Integer;
|
|
begin
|
|
SelLen := ExprMemo.SelLength;
|
|
SelStart := ExprMemo.TextPosToPos(ExprMemo.SelStart);
|
|
ExprMemo.DeleteFrom(SelStart, SelLen, []);
|
|
ExprMemo.InsertAfter(SelStart, FDataTree.GetFieldName, []);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.ExprMemoEnter(Sender: TObject);
|
|
begin
|
|
FExprMemoModified := False;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.ExprMemoChange(Sender: TObject);
|
|
begin
|
|
FExprMemoModified := True;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.OnDataTreeDblClick(Sender: TObject);
|
|
var
|
|
SelStart: TCaretPosition;
|
|
SelLen: Integer;
|
|
begin
|
|
SelLen := ExprMemo.SelLength;
|
|
SelStart := ExprMemo.TextPosToPos(ExprMemo.SelStart);
|
|
ExprMemo.DeleteFrom(SelStart, SelLen, []);
|
|
ExprMemo.InsertAfter(SelStart, FDataTree.GetFieldName, []);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.VarTreeChange(Sender: TObject);
|
|
begin
|
|
if FUpdating then Exit;
|
|
FNodeOldText := VarTree.Selected.Text;
|
|
if (VarTree.Selected = nil) or (VarTree.Selected = Root) or (VarTree.Selected.ParentItem = Root) then
|
|
ExprMemo.Text := '' else
|
|
ExprMemo.Text := VarToStr(FVariables[VarTree.Selected.Text]);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.VarTreeChanging(Sender: TObject; OldNode: TfrxTreeViewItem; NewNode: TfrxTreeViewItem);
|
|
begin
|
|
if FUpdating then Exit;
|
|
|
|
if FExprMemoModified then
|
|
if not ((OldNode = nil) or (OldNode = Root) or (OldNode.ParentItem = Root) or (csDestroying in OldNode.ComponentState)) then
|
|
begin
|
|
FVariables[OldNode.Text] := ExprMemo.Text;
|
|
FExprMemoModified := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.EditListBClick(Sender: TObject);
|
|
|
|
procedure VarToStrings(Lines: TStrings);
|
|
var
|
|
i: Integer;
|
|
s: String;
|
|
begin
|
|
for i := 0 to FVariables.Count - 1 do
|
|
begin
|
|
s := FVariables.Items[i].Name;
|
|
if s <> '' then
|
|
if s[1] = ' ' then
|
|
s := Copy(s, 2, 255) else
|
|
s := ' ' + s;
|
|
Lines.Add(s);
|
|
end;
|
|
end;
|
|
|
|
procedure StringsToVar(Lines: TStrings);
|
|
var
|
|
i: Integer;
|
|
v: TfrxVariables;
|
|
s: String;
|
|
begin
|
|
v := TfrxVariables.Create;
|
|
for i := 0 to Lines.Count - 1 do
|
|
begin
|
|
s := Lines[i];
|
|
if Trim(s) <> '' then
|
|
begin
|
|
if s[1] = ' ' then
|
|
s := Copy(s, 2, 255) else
|
|
s := ' ' + s;
|
|
if FVariables.IndexOf(s) <> -1 then
|
|
v[s] := FVariables[s] else
|
|
v[s] := '';
|
|
end;
|
|
end;
|
|
|
|
FVariables.Assign(v);
|
|
FillVariables;
|
|
v.Free;
|
|
end;
|
|
|
|
begin
|
|
with TfrxStringsEditorForm.Create(Owner) do
|
|
begin
|
|
VarToStrings(Memo.Lines);
|
|
if ShowModal = mrOk then
|
|
StringsToVar(Memo.Lines);
|
|
VarTree.Selected := VarTree.ItemByGlobalIndex(0);
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.LoadBClick(Sender: TObject);
|
|
begin
|
|
if OpenDialog1.Execute then
|
|
begin
|
|
FVariables.LoadFromFile(OpenDialog1.FileName);
|
|
FillVariables;
|
|
end;
|
|
PeekLastModalResult;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.SaveBClick(Sender: TObject);
|
|
begin
|
|
VarTree.Selected := VarTree.Items[0];
|
|
if SaveDialog1.Execute then
|
|
FVariables.SaveToFile(SaveDialog1.FileName);
|
|
PeekLastModalResult;
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: WideChar; Shift: TShiftState);
|
|
begin
|
|
if (Shift = [ssCtrl]) and (Key = vkReturn) then
|
|
OkBClick(nil);
|
|
if Key = VKESCAPE then
|
|
CancelBClick(nil);
|
|
if Key = VKF1 then
|
|
frxResources.Help(Self);
|
|
end;
|
|
|
|
procedure TfrxVarEditorForm.Splitter2Moved(Sender: TObject);
|
|
begin
|
|
if FDataTree <> nil then FDataTree.UpdateSize;
|
|
end;
|
|
|
|
end.
|