mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 09:37:56 +02:00
1041 lines
26 KiB
ObjectPascal
1041 lines
26 KiB
ObjectPascal
{
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
|
|
* *
|
|
***************************************************************************
|
|
}
|
|
unit dicteditor;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, fpdatadict,
|
|
Controls, ComCtrls, ExtCtrls, Graphics, Menus, Dialogs, RTTIGrids,
|
|
LazUTF8;
|
|
|
|
Type
|
|
TEditObjectType = (eotUnknown,eotDictionary,
|
|
eotTables,eotTable,
|
|
eotFields,eotField,
|
|
eotConnection,eotTableData,
|
|
eotIndexes,eotIndex,
|
|
eotSequences,eotSequence,
|
|
eotForeignKeys,eotForeignKey,
|
|
eotDomains,eotDomain);
|
|
Const
|
|
SingleObjectTypes = [eotTable,eotDomain,eotSequence,
|
|
eotField,eotIndex,eotForeignKey];
|
|
|
|
|
|
Type
|
|
{ TDataDictEditor }
|
|
|
|
TDataDictEditor = Class(TTabSheet)
|
|
private
|
|
FDD: TFPDataDictionary;
|
|
FImageOffset: Integer;
|
|
FModified: Boolean;
|
|
FTV : TTreeView;
|
|
FEdit : TPanel;
|
|
FSplit : TSplitter;
|
|
FAllowDoubleClick : TEditObjectType;
|
|
FDDNode,
|
|
FTablesNode : TTreeNode;
|
|
FMenu : TPopupMenu;
|
|
FMINewTable,
|
|
FMINewField,
|
|
FMINewIndex,
|
|
FMINewSequence,
|
|
FMINewForeignKey,
|
|
FMINewDomain,
|
|
FMIDeleteObject: TMenuItem;
|
|
{$ifndef onlyoldobjects}
|
|
FSequencesNode,
|
|
FDomainsNode : TTreeNode;
|
|
{$endif}
|
|
Function AddNewItemPopup(ObjectType: TEditObjectType; AImageIndex : Integer) : TMenuItem;
|
|
procedure CreateGUI;
|
|
procedure DoDoubleClick(Sender: TObject);
|
|
procedure DoNewObject(Sender: TObject);
|
|
procedure DoDeleteObject(Sender: TObject);
|
|
function CurrentObjectWithType(AType: TEditObjectType): TObject;
|
|
function GetCurrentObject: TPersistent;
|
|
Function NewNode (TV : TTreeView;ParentNode : TTreeNode; ACaption : String; AImageIndex : Integer) : TTreeNode;
|
|
Procedure SetCaption;
|
|
Procedure DoSelectNode(Sender : TObject);
|
|
Procedure DoPropertyModified(Sender : TObject);
|
|
Procedure ClearEditor;
|
|
procedure SetModified(const AValue: Boolean);
|
|
procedure UpdateSelectedNode;
|
|
Function GetObjectType(Node : TTreeNode): TEditObjectType;
|
|
Function CreatePropertyGrid(P : TPersistent) : TTIPropertyGrid;
|
|
Function FindNodeWithData(TV : TTreeView; P : Pointer) : TTreeNode;
|
|
Function SelectNextNode (ANode : TTreeNode; ADefault: TTreeNode) : TTreeNode;
|
|
function GetCurrentObjectType: TEditObjectType;
|
|
function GetCurrentField: TDDFieldDef;
|
|
function GetCurrentIndex: TDDIndexDef;
|
|
function GetCurrentTable: TDDTableDef;
|
|
{$ifndef onlyoldobjects}
|
|
function GetCurrentSequence: TDDSequenceDef;
|
|
function GetCurrentForeignKey : TDDForeignKeyDef;
|
|
function GetCurrentDomain : TDDDomainDef;
|
|
{$endif}
|
|
procedure DoPopup(Sender: TObject);
|
|
Procedure DeleteGlobalObject(AObject : TObject);
|
|
Procedure DeleteTableObject(AObject : TObject);
|
|
procedure SelectGlobalObjectList(AObjectType: TEditObjectType);
|
|
procedure SelectTableObjectList(AObjectType: TEditObjectType; ATableDef : TDDTableDef);
|
|
Procedure SelectSingleObject(AObject : TPersistent);
|
|
procedure GetTableObjectsList(ATabledef: TDDTableDef; AObjectType: TEditObjectType; List: TStrings);
|
|
procedure GetGlobalObjectsList(AObjectType: TEditObjectType; List: TStrings);
|
|
procedure ShowSubLists(TV: TTreeView; ParentNode: TTreeNode; AObject: TObject);
|
|
procedure ShowTableObjectList(TV: TTreeView; ParentNode: TTreeNode; ATableDef: TDDTableDef; AObjectType: TEditObjectType);
|
|
procedure ShowGlobalObjectList(TV: TTreeView; ParentNode: TTreeNode; AObjectType: TEditObjectType; AShowSubLists : Boolean = False);
|
|
Protected
|
|
procedure CreateHandle; override;
|
|
Public
|
|
Constructor Create(AOwner : TComponent); override;
|
|
Destructor Destroy; override;
|
|
// General methods.
|
|
Procedure ShowDictionary;
|
|
Procedure LoadFromFile(AFileName : String);
|
|
Procedure SaveToFile(AFileName : String);
|
|
Procedure CreateCode;
|
|
// New items.
|
|
function NewGlobalObject(AObjectName: String; AObjectType: TEditObjectType): TObject;
|
|
function NewTableObject(AObjectName: String; TD: TDDTableDef;AObjectType: TEditObjectType): TObject;
|
|
Procedure NewField(AFieldName : String; TD : TDDTableDef);
|
|
Procedure NewIndex(AIndexName : String; TD : TDDTableDef);
|
|
Procedure NewForeignKey(AKeyName : String; TD : TDDTableDef);
|
|
// Delete items
|
|
{$ifndef onlyoldobjects}
|
|
Procedure DeleteSequence(SD : TDDSequenceDef);
|
|
Procedure DeleteDomain(DD : TDDDomainDef);
|
|
Procedure DeleteForeignKey(KD : TDDForeignKeyDef);
|
|
{$endif onlyoldobjects}
|
|
Procedure DeleteTable(TD : TDDTableDef);
|
|
Procedure DeleteField(FD : TDDFieldDef);
|
|
Procedure DeleteIndex(ID : TDDIndexDef);
|
|
Procedure DeleteCurrentObject;
|
|
// Properties
|
|
Property DataDictionary : TFPDataDictionary Read FDD;
|
|
Property Modified : Boolean Read FModified Write SetModified;
|
|
Property ImageOffset : Integer Read FImageOffset Write FImageOffset;
|
|
Property CurrentObject : TPersistent Read GetCurrentObject;
|
|
Property ObjectType : TEditObjectType Read GetCurrentObjectType;
|
|
Property CurrentTable : TDDTableDef Read GetCurrentTable;
|
|
Property CurrentField : TDDFieldDef Read GetCurrentField;
|
|
Property CurrentIndex : TDDIndexDef Read GetCurrentIndex;
|
|
{$ifndef onlyoldobjects}
|
|
Property CurrentSequence : TDDSequenceDef Read GetCurrentSequence;
|
|
Property CurrentDomain : TDDDomainDef Read GetCurrentDomain;
|
|
Property CurrentForeignKey : TDDForeignKeyDef Read GetCurrentForeignKey;
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
|
|
|
|
Const
|
|
// Image index, referring to ImgDatamodule.AppImages in unit dmImages;
|
|
// iiDataDict = 32; // listed in unit dmImages
|
|
iiTables = 1;
|
|
iiTable = 2;
|
|
iiFields = 3;
|
|
iiField = 4;
|
|
iiConnection = 0;
|
|
iiTableData = 7;
|
|
iiIndexes = 5;
|
|
iiIndex = 27;
|
|
iiSequences = 6;
|
|
iiSequence = 23;
|
|
iiForeignkeys = 46;
|
|
iiForeignKey = 25;
|
|
iiDomains = 47;
|
|
iiDomain = 21;
|
|
iiDelete = 16;
|
|
|
|
implementation
|
|
|
|
uses DB, MemDS, fpcodegenerator, TypInfo, dmImages, lazdatadeskstr;
|
|
|
|
Function ObjectTypeName(ObjectType : TEditObjectType) : String;
|
|
|
|
Var
|
|
S : String;
|
|
|
|
begin
|
|
Case ObjectType of
|
|
eotTable : S:=STable;
|
|
eotField : S:=SField;
|
|
eotIndex : S:=SIndex;
|
|
eotSequence : S:=SSequence;
|
|
eotForeignKey : S:=SForeignKey;
|
|
eotDomain : S:=SDomain
|
|
else
|
|
Raise EDataDict.CreateFmt(SErrUnknownType,[Ord(ObjectType)]);
|
|
end;
|
|
Result:=S;
|
|
end;
|
|
|
|
Function NewObjectTypeName(ObjectType : TEditObjectType) : String;
|
|
|
|
Var
|
|
S : String;
|
|
|
|
begin
|
|
Case ObjectType of
|
|
eotTable : S:=SNewTableDE;
|
|
eotField : S:=SNewFieldDE;
|
|
eotIndex : S:=SNewIndexDE;
|
|
eotSequence : S:=SNewSequenceDE;
|
|
eotForeignKey : S:=SNewForeignKeyDE;
|
|
eotDomain : S:=SNewDomainDE;
|
|
else
|
|
Raise EDataDict.CreateFmt(SErrUnknownType,[Ord(ObjectType)]);
|
|
end;
|
|
Result:=S;
|
|
end;
|
|
|
|
Function CreateDatasetFromTabledef(TD : TDDTableDef;AOwner : TComponent = Nil) : TDataset;
|
|
|
|
Var
|
|
MDS : TMemDataset;
|
|
I : Integer;
|
|
FDD : TDDFieldDef;
|
|
|
|
begin
|
|
MDS:=TMemDataset.Create(AOwner);
|
|
try
|
|
For I:=0 to TD.Fields.Count-1 do
|
|
begin
|
|
FDD:=TD.Fields[i];
|
|
MDS.FieldDefs.Add(FDD.FieldName,FDD.FieldType);
|
|
end;
|
|
MDS.CreateTable;
|
|
MDS.Open;
|
|
except
|
|
MDS.Free;
|
|
Raise;
|
|
end;
|
|
Result:=MDS;
|
|
end;
|
|
|
|
|
|
{ TDataDictEditor }
|
|
|
|
function TDataDictEditor.NewNode(TV : TTreeView;ParentNode: TTreeNode; ACaption: String; AImageIndex : Integer
|
|
): TTreeNode;
|
|
begin
|
|
Result:=TV.Items.AddChild(ParentNode,ACaption);
|
|
If AImageIndex>=0 then
|
|
begin
|
|
Result.ImageIndex:=FImageOffset+AImageIndex;
|
|
Result.SelectedIndex:=Result.ImageIndex;
|
|
end;
|
|
end;
|
|
|
|
function TDataDictEditor.GetCurrentObjectType: TEditObjectType;
|
|
begin
|
|
Result:=GetObjectType(FTV.Selected);
|
|
end;
|
|
|
|
function TDataDictEditor.CurrentObjectWithType(AType : TEditObjectType) : TObject;
|
|
|
|
Var
|
|
N : TTreeNode;
|
|
|
|
begin
|
|
Result:=Nil;
|
|
N:=FTV.Selected;
|
|
While (N<>Nil) and (GetObjectType(N)<>AType) do
|
|
N:=N.Parent;
|
|
if (N<>Nil) then
|
|
Result:=TObject(N.Data);
|
|
end;
|
|
|
|
function TDataDictEditor.GetCurrentObject: TPersistent;
|
|
|
|
Var
|
|
N : TTreeNode;
|
|
|
|
begin
|
|
Result:=Nil;
|
|
N:=FTV.Selected;
|
|
While (N<>Nil) and Not (GetObjectType(N) in SingleObjectTypes) do
|
|
N:=N.Parent;
|
|
If Assigned(N) then
|
|
Result:=TPersistent(N.Data);
|
|
end;
|
|
|
|
function TDataDictEditor.GetCurrentField: TDDFieldDef;
|
|
|
|
begin
|
|
Result:=TDDFieldDef(CurrentObjectWithType(eotField));
|
|
end;
|
|
|
|
function TDataDictEditor.GetCurrentIndex: TDDIndexDef;
|
|
|
|
begin
|
|
Result:=TDDIndexDef(CurrentObjectWithType(eotIndex));
|
|
end;
|
|
|
|
function TDataDictEditor.GetCurrentTable: TDDTableDef;
|
|
|
|
begin
|
|
Result:=TDDTableDef(CurrentObjectWithType(eotTable));
|
|
end;
|
|
|
|
{$ifndef onlyoldobjects}
|
|
function TDataDictEditor.GetCurrentSequence: TDDSequenceDef;
|
|
|
|
begin
|
|
Result:=TDDSequenceDef(CurrentObjectWithType(eotSequence));
|
|
end;
|
|
|
|
function TDataDictEditor.GetCurrentDomain: TDDDomainDef;
|
|
|
|
begin
|
|
Result:=TDDDomainDef(CurrentObjectWithType(eotDomain));
|
|
end;
|
|
|
|
function TDataDictEditor.GetCurrentForeignKey: TDDForeignKeyDef;
|
|
|
|
begin
|
|
Result:=TDDForeignKeyDef(CurrentObjectWithType(eotForeignKey));
|
|
end;
|
|
{$endif onlyoldobjects}
|
|
|
|
procedure TDataDictEditor.DoPopup(Sender: TObject);
|
|
|
|
Var
|
|
B : Boolean;
|
|
EOT : TEditObjectType;
|
|
|
|
begin
|
|
// Check availablility of items;
|
|
B:=CurrentTable<>Nil;
|
|
FMINewField.Enabled:=B;
|
|
FMINewIndex.Enabled:=B;
|
|
FMINewForeignKey.Enabled:=B;
|
|
EOT:=ObjectType;
|
|
B:=EOT in SingleObjectTypes;
|
|
FMIDeleteObject.Enabled:=B;
|
|
If B then
|
|
FMIDeleteObject.Caption:=Format(SDeleteObject,[ObjectTypeName(EOT)])
|
|
else
|
|
FMIDeleteObject.Caption:=Format(SDeleteObject,[SObject]);
|
|
end;
|
|
|
|
|
|
Function TDataDictEditor.AddNewItemPopup(ObjectType : TEditObjectType; AImageIndex : Integer) : TMenuItem;
|
|
|
|
begin
|
|
Result:=TMenuItem.Create(Self);
|
|
Result.Name:='NewItem'+GetEnumName(TypeInfo(TEditObjectType),Ord(ObjectType));
|
|
Result.Tag:=Ord(ObjectType);
|
|
Result.Caption:=NewObjectTypeName(ObjectType);
|
|
Result.OnClick:=@DoNewObject;
|
|
Result.ImageIndex:=AImageIndex;
|
|
FMenu.Items.Add(Result);
|
|
end;
|
|
|
|
constructor TDataDictEditor.Create(AOwner: TComponent);
|
|
|
|
|
|
begin
|
|
inherited Create(AOwner);
|
|
FDD:=TFPDataDictionary.Create;
|
|
CreateGUI;
|
|
end;
|
|
|
|
Procedure TDataDictEditor.CreateGUI;
|
|
Var
|
|
P : TPortableNetworkGraphic;
|
|
I : Integer;
|
|
begin
|
|
FEdit:=TPanel.Create(Self);
|
|
FEdit.Parent:=Self;
|
|
FEdit.Name:='FEdit';
|
|
FEdit.Align:=alRight;
|
|
FEdit.Caption:='';
|
|
FEdit.Width:=200;
|
|
FSplit:=TSplitter.Create(Self);
|
|
FSplit.Parent:=Self;
|
|
FSplit.Align:=alRight;
|
|
FTV:=TTreeView.Create(Self);
|
|
FTV.Name:='FTV';
|
|
FTV.Parent:=Self;
|
|
FTV.Align:=alClient;
|
|
FTV.OnSelectionChanged:=@DoSelectNode;
|
|
FTV.ShowLines:=True;
|
|
FTV.HideSelection:=false;
|
|
FMenu:=TPopupMenu.Create(Self);
|
|
FMenu.Name:='FMenu';
|
|
FMenu.OnPopup:=@DoPopup;
|
|
FMINewTable:=AddNewItemPopup(eotTable,iiTable);
|
|
FMINewField:=AddNewItemPopup(eotField,iiField);
|
|
FMINewIndex:=AddNewItemPopup(eotIndex,iiIndex);
|
|
FMINewSequence:=AddNewItemPopup(eotSequence,iiSequence);
|
|
FMINewForeignKey:=AddNewItemPopup(eotForeignKey,iiForeignKey);
|
|
FMINewDomain:=AddNewItemPopup(eotDomain,iiDomain);
|
|
FMenu.Items.Add(NewLine);
|
|
FMIDeleteObject:=TMenuItem.Create(Self);
|
|
FMIDeleteObject.Caption:=Format(SDeleteObject,[SObject]);
|
|
FMIDeleteObject.OnClick:=@DoDeleteObject;
|
|
FMIDeleteObject.ImageIndex:=IIDelete;
|
|
FMenu.Items.Add(FMIDeleteObject);
|
|
FTV.PopupMenu:=FMenu;
|
|
FTV.Images:=ImgDatamodule.AppImages;
|
|
FMenu.Images:=ImgDatamodule.AppImages;
|
|
end;
|
|
|
|
procedure TDataDictEditor.CreateHandle;
|
|
begin
|
|
inherited;
|
|
ShowDictionary;
|
|
end;
|
|
|
|
destructor TDataDictEditor.Destroy;
|
|
begin
|
|
FreeAndNil(FTV);
|
|
FreeAndNil(FDD);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TDataDictEditor.ShowDictionary;
|
|
|
|
var
|
|
S : String;
|
|
|
|
begin
|
|
FTV.Items.BeginUpdate;
|
|
try
|
|
FTV.Items.Clear;
|
|
S:=FDD.Name;
|
|
If (S='') then
|
|
S:=SNodeDataDictionary;
|
|
FDDNode:=NewNode(FTV,Nil,S,iiDataDict);
|
|
FDDNode.Data:=FDD;
|
|
FTablesNode:=NewNode(FTV,FDDNode,SNodeTables,iiTables);
|
|
ShowGlobalObjectList(FTV,FTablesNode,eotTable,True);
|
|
{$ifndef onlyoldobjects}
|
|
FSequencesNode:=NewNode(FTV,FDDNode,SNodeSequences,iiSequences);
|
|
ShowGlobalObjectList(FTV,FSequencesNode,eotSequence,True);
|
|
FDomainsNode:=NewNode(FTV,FDDNode,SNodeDomains,iiDomains);
|
|
ShowGlobalObjectList(FTV,FDomainsNode,eotDomain,True);
|
|
{$endif onlyoldobjects}
|
|
SetCaption;
|
|
FTV.Selected:=FDDNode;
|
|
finally
|
|
FTV.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
Function TDataDictEditor.NewGlobalObject(AObjectName: String; AObjectType : TEditObjectType) : TObject;
|
|
|
|
Var
|
|
II : Integer;
|
|
N,PN : TTreeNode;
|
|
begin
|
|
Case AObjectType of
|
|
eotTable :
|
|
begin
|
|
Result:=FDD.Tables.AddTable(AObjectName);
|
|
II:=IITable;
|
|
PN:=FTablesNode;
|
|
end;
|
|
{$ifndef onlyoldobjects}
|
|
eotSequence :
|
|
begin
|
|
Result:=FDD.Sequences.AddSequence(AObjectName);
|
|
II:=IISequence;
|
|
PN:=FSequencesNode;
|
|
end;
|
|
eotDomain :
|
|
begin
|
|
Result:=FDD.Domains.AddDomain(AObjectName);
|
|
II:=IIDomain;
|
|
PN:=FDomainsNode;
|
|
end;
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
N:=NewNode(FTV,PN,AObjectName,II);
|
|
N.Data:=Result;
|
|
FTV.Selected:=N;
|
|
ShowSubLists(FTV,N,Result);
|
|
Modified:=True;
|
|
end;
|
|
|
|
|
|
Function TDataDictEditor.NewTableObject(AObjectName: String; TD: TDDTableDef; AObjectType : TEditObjectType) : TObject;
|
|
|
|
Var
|
|
TN : TTreeNode;
|
|
POT : TEditObjectType;
|
|
II : Integer;
|
|
|
|
begin
|
|
Case AObjectType of
|
|
eotField :
|
|
begin
|
|
POT:=eotFields;
|
|
Result:=TD.Fields.AddField(AObjectName);
|
|
II:=IIfield;
|
|
end;
|
|
{$ifndef onlyoldobjects}
|
|
eotIndex:
|
|
begin
|
|
POT:=eotIndexes;
|
|
Result:=TD.Indexes.AddIndex(AObjectName);
|
|
II:=IIIndex;
|
|
end;
|
|
eotForeignKey :
|
|
begin
|
|
POT:=eotForeignKeys;
|
|
Result:=TD.foreignKeys.AddForeignKeyDef(AObjectName);
|
|
II:=IIForeignkey;
|
|
end;
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
TN:=FindNodeWithData(FTV,TD);
|
|
TN:=TN.GetFirstChild;
|
|
While (TN<>Nil) and (GetObjectType(TN)<>POT) do
|
|
TN:=TN.GetNextSibling;
|
|
If (TN<>Nil) then
|
|
begin
|
|
TN:=NewNode(FTV,TN,AObjectName,II);
|
|
TN.Data:=Result;
|
|
FTV.Selected:=TN;
|
|
Modified:=True;
|
|
end
|
|
else
|
|
FreeAndNil(Result); // Error !!
|
|
end;
|
|
|
|
|
|
procedure TDataDictEditor.NewField(AFieldName: String; TD: TDDTableDef);
|
|
|
|
begin
|
|
NewTableObject(AFieldName,TD,eotField);
|
|
end;
|
|
|
|
procedure TDataDictEditor.NewIndex(AIndexName: String; TD: TDDTableDef);
|
|
|
|
begin
|
|
NewTableObject(AIndexName,TD,eotIndex);
|
|
end;
|
|
|
|
procedure TDataDictEditor.NewForeignKey(AKeyName: String; TD: TDDTableDef);
|
|
|
|
begin
|
|
NewTableObject(AKeyName,TD,eotForeignKey);
|
|
end;
|
|
|
|
procedure TDataDictEditor.SetCaption;
|
|
|
|
Var
|
|
S : String;
|
|
|
|
begin
|
|
If (FDD.Name<>'') then
|
|
S:=FDD.Name
|
|
else
|
|
S:=ChangeFileExt(ExtractFileName(FDD.FileName),'');
|
|
If (S='') then
|
|
S:=SNewDictionary;
|
|
if FModified then
|
|
S:=S+' *';
|
|
Caption:=S;
|
|
end;
|
|
|
|
procedure TDataDictEditor.DoSelectNode(Sender: TObject);
|
|
|
|
Var
|
|
N : TTreeNode;
|
|
O,OP : TObject;
|
|
|
|
begin
|
|
N:=FTV.Selected;
|
|
If N=Nil then
|
|
exit;
|
|
O:=TObject(N.Data);
|
|
If Assigned(N.Parent) then
|
|
OP:=TObject(N.Parent.Data);
|
|
Case ObjectType of
|
|
eotUnknown : ;
|
|
eotDictionary : SelectSingleObject(FDD);
|
|
eotTables : SelectGlobalObjectList(eotTable);
|
|
eotTable : SelectSingleObject(O as TPersistent);
|
|
eotFields : SelectTableObjectList(eotField,OP as TDDTableDef);
|
|
eotField : SelectSingleObject(O as TPersistent);
|
|
{$ifndef onlyoldobjects}
|
|
eotIndexes : SelectTableObjectList(eotIndex,OP as TDDTableDef);
|
|
eotIndex : SelectSingleObject(O as TPersistent);
|
|
eotDomains : SelectGlobalObjectList(eotDomain);
|
|
eotDomain : SelectSingleObject(O as TPersistent);
|
|
eotSequences : SelectGlobalObjectList(eotSequence);
|
|
eotSequence : SelectSingleObject(O as TPersistent);
|
|
eotForeignKeys : SelectTableObjectList(eotForeignKey,OP as TDDTableDef);
|
|
eotForeignKey : SelectSingleObject(O as TPersistent);
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.DoPropertyModified(Sender: TObject);
|
|
begin
|
|
Modified:=True;
|
|
UpdateSelectedNode;
|
|
end;
|
|
|
|
procedure TDataDictEditor.UpdateSelectedNode;
|
|
|
|
Var
|
|
N : TTreeNode;
|
|
|
|
begin
|
|
N:=FTV.Selected;
|
|
If (N.Data=Nil) then
|
|
Exit;
|
|
With N do
|
|
Case ObjectType of
|
|
eotField : Text:=TDDFieldDef(N.Data).FieldName;
|
|
eotDictionary : Text:=TFPDataDictionary(N.Data).Name;
|
|
eotTable : Text:=TDDTableDef(N.Data).TableName;
|
|
{$ifndef onlyoldobjects}
|
|
eotSequence : Text:=TDDSequenceDef(N.Data).SequenceName;
|
|
eotDomain : Text:=TDDDomainDef(N.Data).DomainName;
|
|
eotForeignKey : Text:=TDDForeignkeyDef(N.Data).KeyName;
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.SelectGlobalObjectList(AObjectType : TEditObjectType);
|
|
|
|
Var
|
|
TV : TTreeView;
|
|
|
|
begin
|
|
ClearEditor;
|
|
TV:=TTreeView.Create(Self);
|
|
TV.ShowLines:=True;
|
|
TV.Parent:=FEdit;
|
|
TV.Align:=alClient;
|
|
TV.HideSelection := false;
|
|
TV.Images := ImgDataModule.AppImages;
|
|
ShowGlobalObjectList(TV,Nil,AObjectType,False);
|
|
TV.OnDblClick:=@DoDoubleClick;
|
|
FAllowDoubleClick:=AObjectType;
|
|
end;
|
|
|
|
procedure TDataDictEditor.SelectTableObjectList(AObjectType: TEditObjectType; ATableDef : TDDTableDef);
|
|
|
|
Var
|
|
TV : TTreeView;
|
|
|
|
begin
|
|
ClearEditor;
|
|
TV:=TTreeView.Create(Self);
|
|
TV.ShowLines:=True;
|
|
TV.Parent:=FEdit;
|
|
TV.Align:=alClient;
|
|
TV.HideSelection := false;
|
|
TV.Images := ImgDatamodule.AppImages;
|
|
ShowTableObjectList(TV,Nil,ATableDef,AObjectType);
|
|
TV.OnDblClick:=@DoDoubleClick;
|
|
FAllowDoubleClick:=AObjectType;
|
|
end;
|
|
|
|
procedure TDataDictEditor.DoDoubleClick(Sender : TObject);
|
|
|
|
Var
|
|
TV : TTreeView;
|
|
N: TTreeNode;
|
|
|
|
begin
|
|
TV:=Sender As TTreeView;
|
|
N:=TV.Selected;
|
|
If (GetObjectType(N)=FAllowDoubleClick) and (N.Data<>Nil) then
|
|
FTV.Selected:=FindNodeWithData(FTV,N.Data);
|
|
end;
|
|
|
|
procedure TDataDictEditor.DoNewObject(Sender: TObject);
|
|
|
|
Var
|
|
EOT : TEditObjectType;
|
|
S,N : String;
|
|
|
|
begin
|
|
EOT:=TEditObjectType((Sender as TMenuItem).Tag);
|
|
S:=ObjectTypeName(EOT);
|
|
N:='';
|
|
if InputQuery(Format(SNewObject,[S]),Format(SNameFor,[S]),N) then
|
|
begin
|
|
case EOT of
|
|
eotField : NewField(N,CurrentTable);
|
|
eotIndex : NewIndex(N,CurrentTable);
|
|
eotForeignKey : NewForeignKey(N,CurrentTable);
|
|
else
|
|
NewGlobalObject(N,EOT);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.DoDeleteObject(Sender: TObject);
|
|
begin
|
|
DeleteCurrentObject;
|
|
end;
|
|
|
|
function TDataDictEditor.SelectNextNode(ANode: TTreeNode; ADefault : TTreeNode): TTreeNode;
|
|
|
|
Var
|
|
NN : TTreeNode;
|
|
|
|
begin
|
|
NN:=ANode.GetNextSibling;
|
|
If (NN=Nil) then
|
|
begin
|
|
NN:=ANode.GetPrevSibling;
|
|
If (NN=Nil) then
|
|
if Assigned(ADefault) then
|
|
NN:=ADefault
|
|
else
|
|
begin
|
|
NN:=Anode.Parent;
|
|
If Assigned(NN) then
|
|
NN:=NN.Parent;
|
|
end;
|
|
end;
|
|
ANode.Free;
|
|
FTV.Selected:=NN;
|
|
Result:=NN;
|
|
end;
|
|
|
|
procedure TDataDictEditor.SetModified(const AValue: Boolean);
|
|
begin
|
|
FModified:=AValue;
|
|
SetCaption;
|
|
end;
|
|
|
|
Function TDataDictEditor.FindNodeWithData(TV : TTreeView; P : Pointer) : TTreeNode;
|
|
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
I:=0;
|
|
Result:=Nil;
|
|
While (Result=Nil) and (I<TV.Items.Count) do
|
|
begin
|
|
if (TV.Items[i].Data=P) then
|
|
Result:=TV.Items[i];
|
|
Inc(i);
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.ClearEditor;
|
|
|
|
begin
|
|
With FEdit do
|
|
While (ControlCount>0) do
|
|
Controls[ControlCount-1].Free;
|
|
end;
|
|
|
|
procedure TDataDictEditor.SelectSingleObject(AObject: TPersistent);
|
|
begin
|
|
ClearEditor;
|
|
CreatePropertyGrid(AObject);
|
|
end;
|
|
|
|
Function TDataDictEditor.CreatePropertyGrid(P : TPersistent) : TTIPropertyGrid;
|
|
|
|
begin
|
|
Result:=TTIPropertyGrid.Create(Self);
|
|
With Result do
|
|
begin
|
|
Parent:=FEdit;
|
|
Align:=alClient;
|
|
TIObject:=P;
|
|
OnModified:=@DoPropertyModified;
|
|
end;
|
|
end;
|
|
|
|
function TDataDictEditor.GetObjectType(Node: TTreeNode): TEditObjectType;
|
|
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
Result:=eotUnknown;
|
|
If Node<>Nil then
|
|
begin
|
|
I:=Node.ImageIndex;
|
|
I:=I-ImageOffset+1;
|
|
If (I>=0) and (I<=Ord(High(TEditObjectType))) then
|
|
Result:=TEditObjectType(I);
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.GetTableObjectsList(ATabledef :TDDTableDef; AObjectType : TEditObjectType; List : TStrings);
|
|
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
Case AObjectType of
|
|
eotField : For I:=0 to ATableDef.Fields.Count-1 do
|
|
List.AddObject(ATableDef.Fields[i].FieldName,ATableDef.Fields[i]);
|
|
{$ifndef onlyoldobjects}
|
|
eotIndex : For I:=0 to ATableDef.Indexes.Count-1 do
|
|
List.AddObject(ATableDef.Indexes[i].IndexName,ATableDef.Indexes[i]);
|
|
eotForeignKey : For I:=0 to ATableDef.ForeignKeys.Count-1 do
|
|
List.AddObject(ATableDef.ForeignKeys[i].KeyName,ATableDef.ForeignKeys[i]);
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
If List is TStringList then
|
|
TStringList(List).Sorted:=True;
|
|
end;
|
|
|
|
procedure TDataDictEditor.ShowTableObjectList(TV : TTreeView; ParentNode: TTreeNode; ATableDef: TDDTableDef;AObjectType : TEditObjectType);
|
|
|
|
Var
|
|
TN : TTreeNode;
|
|
TL : TStringList;
|
|
II, I : Integer;
|
|
|
|
begin
|
|
TL:=TStringList.Create;
|
|
Try
|
|
Case AObjectType of
|
|
eotField : II:=iiField;
|
|
{$ifndef onlyoldobjects}
|
|
eotIndex : II:=iiIndex;
|
|
eotForeignKey : II:=iiForeignKey;
|
|
{$endif}
|
|
end;
|
|
GetTableObjectsList(ATableDef,AObjectType,TL);
|
|
For I:=0 to TL.Count-1 do
|
|
begin
|
|
TN:=NewNode(TV,ParentNode,TL[i],II);
|
|
TN.Data:=TL.Objects[i];
|
|
end;
|
|
If Assigned(ParentNode) then
|
|
ParentNode.Expand(False);
|
|
Finally
|
|
FreeAndNil(TL);
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.GetGlobalObjectsList(AObjectType: TEditObjectType;
|
|
List: TStrings);
|
|
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
Case AObjectType of
|
|
eotTable:
|
|
For I:=0 to FDD.Tables.Count-1 do
|
|
List.AddObject(FDD.Tables[i].TableName,FDD.Tables[i]);
|
|
{$ifndef onlyoldobjects}
|
|
eotSequence:
|
|
For I:=0 to FDD.Sequences.Count-1 do
|
|
List.AddObject(FDD.Sequences[i].SequenceName,FDD.Sequences[i]);
|
|
|
|
eotDomain:
|
|
For I:=0 to FDD.Domains.Count-1 do
|
|
List.AddObject(FDD.Domains[i].DomainName,FDD.Domains[i]);
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
If List is TStringList then
|
|
TStringList(List).Sorted:=True;
|
|
end;
|
|
|
|
procedure TDataDictEditor.ShowSubLists(TV: TTreeView; ParentNode: TTreeNode; AObject : TObject);
|
|
|
|
Var
|
|
TD : TDDTableDef;
|
|
N : TTreeNode;
|
|
begin
|
|
If AObject is TDDTableDef then
|
|
begin
|
|
TD:=AObject as TDDTableDef;
|
|
N:=NewNode(TV,ParentNode,SNodeFields,iiFields);
|
|
ShowTableObjectList(TV,N,TD,eotField);
|
|
{$ifndef onlyoldobjects}
|
|
N:=NewNode(TV,ParentNode,SNodeIndexes,iiIndexes);
|
|
ShowTableObjectList(TV,N,TD,eotIndex);
|
|
N:=NewNode(TV,ParentNode,SNodeForeignKeys,iiForeignKeys);
|
|
ShowTableObjectList(TV,N,TD,eotForeignKey);
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.ShowGlobalObjectList(TV: TTreeView;
|
|
ParentNode: TTreeNode; AObjectType: TEditObjectType; AShowSubLists : Boolean = False);
|
|
|
|
Var
|
|
TN : TTreeNode;
|
|
TL : TStringList;
|
|
II, I : Integer;
|
|
|
|
begin
|
|
TL:=TStringList.Create;
|
|
Try
|
|
Case AObjectType of
|
|
eotTable : II:=iiTable;
|
|
{$ifndef onlyoldobjects}
|
|
eotSequence : II:=iiSequence;
|
|
eotDomain : II:=iiDomain;
|
|
{$endif onlyoldobjects}
|
|
end;
|
|
GetGlobalObjectsList(AObjectType,TL);
|
|
For I:=0 to TL.Count-1 do
|
|
begin
|
|
TN:=NewNode(TV,ParentNode,TL[i],II);
|
|
TN.Data:=TL.Objects[i];
|
|
If AShowSubLists then
|
|
ShowSubLists(TV,TN,TL.Objects[i]);
|
|
end;
|
|
If Assigned(ParentNode) then
|
|
ParentNode.Expand(False);
|
|
Finally
|
|
FreeAndNil(TL);
|
|
end;
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteGlobalObject(AObject: TObject);
|
|
|
|
Var
|
|
N : TTreeNode;
|
|
|
|
begin
|
|
N:=FindNodeWithData(FTV,Pointer(AObject));
|
|
SelectNextNode(N,FDDNode);
|
|
AObject.Free;
|
|
Modified:=True;
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteTableObject(AObject: TObject);
|
|
|
|
Var
|
|
N : TTreeNode;
|
|
|
|
begin
|
|
N:=FindNodeWithData(FTV,Pointer(AObject));
|
|
SelectNextNode(N,Nil);
|
|
AObject.Free;
|
|
Modified:=True;
|
|
end;
|
|
|
|
procedure TDataDictEditor.LoadFromFile(AFileName: String);
|
|
begin
|
|
FDD.LoadFromFile(UTF8ToSys(AFileName));
|
|
ShowDictionary;
|
|
SetCaption;
|
|
end;
|
|
|
|
procedure TDataDictEditor.SaveToFile(AFileName: String);
|
|
begin
|
|
With FDD do
|
|
begin
|
|
If (Name='') then
|
|
Name:=ChangeFileExt(ExtractFileName(AFileName),'');
|
|
SaveToFile(AFileName);
|
|
end;
|
|
Modified:=False;
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteTable(TD: TDDTableDef);
|
|
|
|
begin
|
|
DeleteGlobalObject(TD);
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteField(FD: TDDFieldDef);
|
|
|
|
begin
|
|
DeleteTableObject(FD);
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteIndex(ID: TDDIndexDef);
|
|
|
|
begin
|
|
DeleteTableObject(ID);
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteCurrentObject;
|
|
|
|
Var
|
|
N : TTreeNode;
|
|
|
|
begin
|
|
N:=FTV.Selected;
|
|
If GetCurrentObjectType in [eotField,eotIndex,eotForeignKey] then
|
|
DeleteTableObject(TObject(N.Data))
|
|
else
|
|
DeleteGlobalObject(TObject(N.Data))
|
|
end;
|
|
|
|
{$ifndef onlyoldobjects}
|
|
procedure TDataDictEditor.DeleteSequence(SD: TDDSequenceDef);
|
|
|
|
begin
|
|
DeleteGlobalObject(SD);
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteDomain(DD: TDDDomainDef);
|
|
|
|
begin
|
|
DeleteGlobalObject(DD);
|
|
end;
|
|
|
|
procedure TDataDictEditor.DeleteForeignKey(KD: TDDForeignKeyDef);
|
|
|
|
begin
|
|
DeleteTableObject(KD);
|
|
end;
|
|
{$endif onlyoldobjects}
|
|
|
|
procedure TDataDictEditor.CreateCode;
|
|
|
|
Var
|
|
TD : TDDTableDef;
|
|
DS : TDataset;
|
|
|
|
begin
|
|
TD:=CurrentTable;
|
|
If Not assigned(TD) then
|
|
exit;
|
|
DS:=CreateDatasetFromTabledef(TD,Self);
|
|
try
|
|
With TFPCodeGenerator.Create(DS) do
|
|
try
|
|
DataSet:=DS;
|
|
TableNameHint:=TD.TableName;
|
|
Execute;
|
|
Finally
|
|
Free;
|
|
end;
|
|
finally
|
|
DS.Free;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|